From 95c38dff3740d7e24971ceb5875c06e7abfce102 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 29 Jan 2012 13:52:17 -0500 Subject: [PATCH] rx: conn->callNumber protected by conn_call_lock The conn->callNumber array should be protected by the conn_call_lock since the conn_call_lock is what protects the binding of calls to connection channels. Change-Id: I9f9b4e8f90d1e4ebbc4429af286358807784d84f Reviewed-on: http://gerrit.openafs.org/6629 Tested-by: Jeffrey Altman Tested-by: BuildBot Reviewed-by: Alistair Ferguson Reviewed-by: Jeffrey Altman --- src/rx/rx.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/rx/rx.c b/src/rx/rx.c index f4037aff7..a832c2142 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -1495,10 +1495,11 @@ rx_NewCall(struct rx_connection *conn) * effect on overall system performance. */ call->state = RX_STATE_RESET; + CALL_HOLD(call, RX_CALL_REFCOUNT_BEGIN); + (*call->callNumber)++; MUTEX_EXIT(&conn->conn_call_lock); CALL_HOLD(call, RX_CALL_REFCOUNT_BEGIN); rxi_ResetCall(call, 0); - (*call->callNumber)++; if (MUTEX_TRYENTER(&conn->conn_call_lock)) break; @@ -1661,12 +1662,14 @@ rxi_GetCallNumberVector(struct rx_connection *aconn, SPLVAR; NETPRI; + MUTEX_ENTER(&aconn->conn_call_lock); for (i = 0; i < RX_MAXCALLS; i++) { if ((tcall = aconn->call[i]) && (tcall->state == RX_STATE_DALLY)) aint32s[i] = aconn->callNumber[i] + 1; else aint32s[i] = aconn->callNumber[i]; } + MUTEX_EXIT(&aconn->conn_call_lock); USERPRI; return 0; } @@ -1680,12 +1683,14 @@ rxi_SetCallNumberVector(struct rx_connection *aconn, SPLVAR; NETPRI; + MUTEX_ENTER(&aconn->conn_call_lock); for (i = 0; i < RX_MAXCALLS; i++) { if ((tcall = aconn->call[i]) && (tcall->state == RX_STATE_DALLY)) aconn->callNumber[i] = aint32s[i] - 1; else aconn->callNumber[i] = aint32s[i]; } + MUTEX_EXIT(&aconn->conn_call_lock); USERPRI; return 0; } @@ -3041,11 +3046,12 @@ rxi_CheckBusy(struct rx_call *call) int channel = call->channel; int freechannel = 0; int i; - afs_uint32 callNumber = *call->callNumber; + afs_uint32 callNumber; MUTEX_EXIT(&call->lock); MUTEX_ENTER(&conn->conn_call_lock); + callNumber = *call->callNumber; /* Are there any other call slots on this conn that we should try? Look for * slots that are empty and are either non-busy, or were marked as busy @@ -3079,8 +3085,6 @@ rxi_CheckBusy(struct rx_call *call) } } - MUTEX_EXIT(&conn->conn_call_lock); - MUTEX_ENTER(&call->lock); /* Since the call->lock and conn->conn_call_lock have been released it is @@ -3100,6 +3104,7 @@ rxi_CheckBusy(struct rx_call *call) rxi_CallError(call, RX_CALL_BUSY); } + MUTEX_EXIT(&conn->conn_call_lock); } /* There are two packet tracing routines available for testing and monitoring @@ -3245,22 +3250,23 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket, } channel = np->header.cid & RX_CHANNELMASK; + MUTEX_ENTER(&conn->conn_call_lock); call = conn->call[channel]; if (call) { MUTEX_ENTER(&call->lock); currentCallNumber = conn->callNumber[channel]; + MUTEX_EXIT(&conn->conn_call_lock); } else if (type == RX_SERVER_CONNECTION) { /* No call allocated */ - MUTEX_ENTER(&conn->conn_call_lock); call = conn->call[channel]; if (call) { MUTEX_ENTER(&call->lock); - MUTEX_EXIT(&conn->conn_call_lock); currentCallNumber = conn->callNumber[channel]; + MUTEX_EXIT(&conn->conn_call_lock); } else { call = rxi_NewCall(conn, channel); /* returns locked call */ - MUTEX_EXIT(&conn->conn_call_lock); *call->callNumber = currentCallNumber = np->header.callNumber; + MUTEX_EXIT(&conn->conn_call_lock); #ifdef RXDEBUG if (np->header.callNumber == 0) dpf(("RecPacket call 0 %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" len %d\n", @@ -3346,6 +3352,11 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket, return tp; } rxi_ResetCall(call, 0); + /* + * The conn_call_lock is not held but no one else should be + * using this call channel while we are processing this incoming + * packet. This assignment should be safe. + */ *call->callNumber = np->header.callNumber; #ifdef RXDEBUG if (np->header.callNumber == 0) -- 2.39.5