From: Derrick Brashear Date: Tue, 2 Nov 2010 18:47:35 +0000 (-0400) Subject: rx mutex inversion fix X-Git-Tag: upstream/1.8.0_pre1^2~4562 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=d5ce8d19ace9b87816dd36663420136f5f2ad746;p=packages%2Fo%2Fopenafs.git rx mutex inversion fix as discovered by Benjamin Kaduk, we were usually holding rx_refcnt_mutex but briefly, and here we held it longer, and thus around acquiring freepktQ mutex. undo it by simply setting STATE_RESET sooner as newcall does. Change-Id: I3ae6fce1832d79c7cf17e93831cf8f30aebeb82b Reviewed-on: http://gerrit.openafs.org/3219 Tested-by: Jeffrey Altman Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- diff --git a/src/rx/rx.c b/src/rx/rx.c index 8f9438d16..5a189a26f 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -2474,9 +2474,18 @@ rxi_FreeCall(struct rx_call *call, int haveCTLock) if (call->state == RX_STATE_DALLY || call->state == RX_STATE_HOLD) (*call->callNumber)++; + /* + * We are setting the state to RX_STATE_RESET to + * ensure that no one else will attempt to use this + * call once we drop the refcnt lock. We must drop + * the refcnt lock before calling rxi_ResetCall + * because it cannot be held across acquiring the + * freepktQ lock. NewCall does the same. + */ + call->state = RX_STATE_RESET; + MUTEX_EXIT(&rx_refcnt_mutex); rxi_ResetCall(call, 0); call->conn->call[channel] = (struct rx_call *)0; - MUTEX_EXIT(&rx_refcnt_mutex); MUTEX_ENTER(&rx_freeCallQueue_lock); SET_CALL_QUEUE_LOCK(call, &rx_freeCallQueue_lock);