From afcc5918ff41fa661a86f46f2c436d05e2abd616 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. (cherry picked from commit d5ce8d19ace9b87816dd36663420136f5f2ad746) Change-Id: Ic4b13dcf09006d3c8171b63f254129fe202e7155 Reviewed-on: http://gerrit.openafs.org/3243 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/rx/rx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/rx/rx.c b/src/rx/rx.c index 438254e42..378cb176b 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -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); -- 2.39.5