From d5ce8d19ace9b87816dd36663420136f5f2ad746 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Tue, 2 Nov 2010 14:47:35 -0400 Subject: [PATCH] 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 --- src/rx/rx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/rx/rx.c b/src/rx/rx.c index 8f9438d16a..5a189a26fa 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);