rx-fix-resource-starvation-problem-20011113
authorNickolai Zeldovich <kolya@mit.edu>
Wed, 14 Nov 2001 04:02:27 +0000 (04:02 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 14 Nov 2001 04:02:27 +0000 (04:02 +0000)
This patch fixes a resource starvation condition in Rx.  The
  problem arises, for instance, when more than 4 daemons try to
  prefetch chunks of the same file at once.  The fifth daemon is
  stuck in MAKECALL_WAITING state, never getting a chance to run,
  because the other 4 daemons never yield to the scheduler after
  releasing the call, and just grab the call back again.

src/rx/rx.c
src/rx/rx.h

index 1a503e3..ea98ff2 100644 (file)
@@ -1006,6 +1006,21 @@ struct rx_call *rx_NewCall(conn)
     clock_GetTime(&queueTime);
     AFS_RXGLOCK();
     MUTEX_ENTER(&conn->conn_call_lock);
+
+    /*
+     * Check if there are others waiting for a new call.
+     * If so, let them go first to avoid starving them.
+     * This is a fairly simple scheme, and might not be
+     * a complete solution for large numbers of waiters.
+     */
+    if (conn->makeCallWaiters) {
+#ifdef RX_ENABLE_LOCKS
+       CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
+#else
+       osi_rxSleep(conn);
+#endif
+    }
+
     for (;;) {
        for (i=0; i<RX_MAXCALLS; i++) {
            call = conn->call[i];
@@ -1030,11 +1045,24 @@ struct rx_call *rx_NewCall(conn)
        MUTEX_ENTER(&conn->conn_data_lock);
        conn->flags |= RX_CONN_MAKECALL_WAITING;
        MUTEX_EXIT(&conn->conn_data_lock);
+
+       conn->makeCallWaiters++;
 #ifdef RX_ENABLE_LOCKS
        CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
 #else
        osi_rxSleep(conn);
 #endif
+       conn->makeCallWaiters--;
+
+       /*
+        * Wake up anyone else who might be giving us a chance to
+        * run (see code above that avoids resource starvation).
+        */
+#ifdef RX_ENABLE_LOCKS
+       CV_BROADCAST(&conn->conn_call_cv);
+#else
+       osi_rxWakeup(conn);
+#endif
     }
 
     CALL_HOLD(call, RX_CALL_REFCOUNT_BEGIN);
index a8d27bb..b85c279 100644 (file)
@@ -506,6 +506,7 @@ struct rx_connection {
     u_short secondsUntilDead;      /* Maximum silence from peer before RX_CALL_DEAD */
     u_short hardDeadTime;          /* hard max for call execution */
     u_char ackRate;                 /* how many packets between ack requests */
+    u_char makeCallWaiters;         /* how many rx_NewCalls are waiting */
     int nSpecific;                 /* number entries in specific data */
     void **specific;               /* pointer to connection specific data */
 };