From bd46d35b07dabd8789be716d989a61904f758ac7 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 5 Jan 2009 23:13:08 +0000 Subject: [PATCH] DEVEL15-rx-do-not-race-current-packet-20090105 LICENSE MIT Throughout rx_rdwr.c functions allocate a register variable 'cp' which is used to optimize access to call->currentPacket. Unfortunately, if the call->lock is dropped (for example, CV_WAIT) the synchronization between the two is lost. This delta re-syncs 'cp' and call->currentPacket after each location where the call->lock may be dropped. (cherry picked from commit 423ab97eee35f57beeb481cac2159d28dea20577) --- src/rx/rx_rdwr.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/rx/rx_rdwr.c b/src/rx/rx_rdwr.c index 3ded6c30e9..63185f8453 100644 --- a/src/rx/rx_rdwr.c +++ b/src/rx/rx_rdwr.c @@ -241,6 +241,8 @@ MTUXXX doesn't there need to be an "else" here ??? osi_rxSleep(&call->rq); #endif } + /* cp is no longer valid since we may have given up the lock */ + cp = call->currentPacket; call->startWait = 0; #ifdef RX_ENABLE_LOCKS @@ -1116,7 +1118,7 @@ rx_WritevAlloc(struct rx_call *call, struct iovec *iov, int *nio, int maxio, int rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes) { - struct rx_packet *cp = call->currentPacket; + struct rx_packet *cp = NULL; struct rx_call *p, *np; int nextio; int requestCount; @@ -1143,6 +1145,8 @@ rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes) #endif /* RX_ENABLE_LOCKS */ } #endif /* AFS_GLOBAL_RXLOCK_KERNEL */ + /* cp is no longer valid since we may have given up the lock */ + cp = call->currentPacket; if (call->error) { if (cp) { @@ -1278,6 +1282,8 @@ rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes) #endif call->startWait = 0; } + /* cp is no longer valid since we may have given up the lock */ + cp = call->currentPacket; if (call->error) { if (cp) { @@ -1310,7 +1316,7 @@ rx_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes) void rxi_FlushWrite(register struct rx_call *call) { - register struct rx_packet *cp = call->currentPacket; + register struct rx_packet *cp = NULL; /* Free any packets from the last call to ReadvProc/WritevProc */ if (queue_IsNotEmpty(&call->iovq)) { @@ -1353,6 +1359,9 @@ rxi_FlushWrite(register struct rx_call *call) } #endif /* AFS_GLOBAL_RXLOCK_KERNEL */ + /* cp is no longer valid since we may have given up the lock */ + cp = call->currentPacket; + if (cp) { /* cp->length is only supposed to be the user's data */ /* cp->length was already set to (then-current)