]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
rx mutex inversion fix
authorDerrick Brashear <shadow@dementia.org>
Tue, 2 Nov 2010 18:47:35 +0000 (14:47 -0400)
committerDerrick Brashear <shadow@dementia.org>
Wed, 3 Nov 2010 13:00:04 +0000 (06:00 -0700)
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.

(cherry picked from commit d5ce8d19ace9b87816dd36663420136f5f2ad746)

Change-Id: Ic4b13dcf09006d3c8171b63f254129fe202e7155
Reviewed-on: http://gerrit.openafs.org/3243
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
src/rx/rx.c

index 438254e42519e7de397ce1574c3fb30dbe766b83..378cb176b07dcdee9f9508132539fd31a9229c03 100644 (file)
@@ -2469,6 +2469,16 @@ rxi_FreeCall(struct rx_call *call)
 
     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);