mirror of
https://git.openafs.org/openafs.git
synced 2025-01-22 17:00:15 +00:00
rx-fix-resource-starvation-problem-20011113
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.
This commit is contained in:
parent
94bc1753e9
commit
54f0650052
28
src/rx/rx.c
28
src/rx/rx.c
@ -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,10 +1045,23 @@ 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
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user