Fix usage of RX_CALL_TQ_WAIT flag
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 2 Apr 2010 03:33:16 +0000 (23:33 -0400)
committerDerrick Brashear <shadow@dementia.org>
Mon, 5 Apr 2010 18:44:38 +0000 (11:44 -0700)
The usage of RX_CALL_TQ_WAIT flag was not consistent within both
rx.c and rx_rdwr.c.  When a thread is waiting on the transmit
queue it must not only set the RX_CALL_TQ_WAIT flag but also
increment the call->tqWaiters count.  Upon waking up, it must
decrement call->tqWaiters and only clear RX_CALL_TQ_WAIT if
the tqWaiters count reaches zero.

Change-Id: I7de01d27f073cddd9651fbcd9cd2038e56ac35cf
Reviewed-on: http://gerrit.openafs.org/1685
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/rx/rx.c
src/rx/rx_rdwr.c

index 70a1eb4..a2bff22 100755 (executable)
@@ -4732,11 +4732,15 @@ rxi_ResetCall(struct rx_call *call, int newcall)
     if (flags & RX_CALL_TQ_BUSY) {
        call->flags = RX_CALL_TQ_CLEARME | RX_CALL_TQ_BUSY;
        call->flags |= (flags & RX_CALL_TQ_WAIT);
+        call->tqWaiters++;
 #ifdef RX_ENABLE_LOCKS
         CV_WAIT(&call->cv_tq, &call->lock);
 #else /* RX_ENABLE_LOCKS */
         osi_rxSleep(&call->tq);
 #endif /* RX_ENABLE_LOCKS */
+        call->tqWaiters--;
+       if (call->tqWaiters == 0)
+           call->flags &= ~RX_CALL_TQ_WAIT;
     } else
 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
     {
index 9e25501..4982c7c 100644 (file)
@@ -716,11 +716,15 @@ rxi_WriteProc(struct rx_call *call, char *buf,
                 */
                while (call->flags & RX_CALL_TQ_BUSY) {
                    call->flags |= RX_CALL_TQ_WAIT;
+                    call->tqWaiters++;
 #ifdef RX_ENABLE_LOCKS
                    CV_WAIT(&call->cv_tq, &call->lock);
 #else /* RX_ENABLE_LOCKS */
                    osi_rxSleep(&call->tq);
 #endif /* RX_ENABLE_LOCKS */
+                    call->tqWaiters--;
+                    if (call->tqWaiters == 0)
+                        call->flags &= ~RX_CALL_TQ_WAIT;
                }
 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
                clock_NewTime();        /* Bogus:  need new time package */
@@ -1096,11 +1100,15 @@ rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
      * packets to the transmit queue.  */
     while (!call->error && call->flags & RX_CALL_TQ_BUSY) {
        call->flags |= RX_CALL_TQ_WAIT;
+        call->tqWaiters++;
 #ifdef RX_ENABLE_LOCKS
        CV_WAIT(&call->cv_tq, &call->lock);
 #else /* RX_ENABLE_LOCKS */
        osi_rxSleep(&call->tq);
 #endif /* RX_ENABLE_LOCKS */
+        call->tqWaiters--;
+        if (call->tqWaiters == 0)
+            call->flags &= ~RX_CALL_TQ_WAIT;
     }
 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
     /* cp is no longer valid since we may have given up the lock */
@@ -1305,11 +1313,15 @@ rxi_FlushWrite(struct rx_call *call)
         */
        while (call->flags & RX_CALL_TQ_BUSY) {
            call->flags |= RX_CALL_TQ_WAIT;
+            call->tqWaiters++;
 #ifdef RX_ENABLE_LOCKS
            CV_WAIT(&call->cv_tq, &call->lock);
 #else /* RX_ENABLE_LOCKS */
            osi_rxSleep(&call->tq);
 #endif /* RX_ENABLE_LOCKS */
+            call->tqWaiters--;
+            if (call->tqWaiters == 0)
+                call->flags &= ~RX_CALL_TQ_WAIT;
        }
 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */