STABLE14-viced-avoid-tying-up-all-threads-20070730

FIXES 19461

implement a thread quota.


(cherry picked from commit ece19eefbe46400e1c28834570deed7294761167)
This commit is contained in:
Derrick Brashear 2007-08-08 20:58:51 +00:00
parent 63bf2d2ced
commit 1059d9aa6d
3 changed files with 48 additions and 2 deletions

View File

@ -319,6 +319,11 @@ CallPreamble(register struct rx_call *acall, int activecall,
H_LOCK;
retry:
tclient = h_FindClient_r(*tconn);
if (!tclient) {
ViceLog(0, ("CallPreamble: Couldn't get CPS. Too many lockers\n"));
H_UNLOCK;
return VBUSY;
}
thost = tclient->host;
if (tclient->prfail == 1) { /* couldn't get the CPS */
if (!retry_flag) {
@ -422,6 +427,8 @@ CallPostamble(register struct rx_connection *aconn, afs_int32 ret,
H_LOCK;
tclient = h_FindClient_r(aconn);
if (!tclient)
goto busyout;
thost = tclient->host;
if (thost->hostFlags & HERRORTRANS)
translate = 1;
@ -443,6 +450,7 @@ CallPostamble(register struct rx_connection *aconn, afs_int32 ret,
afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port),
thost));
}
busyout:
H_UNLOCK;
return (translate ? sys_error_to_et(ret) : ret);
} /*CallPostamble */
@ -7555,6 +7563,10 @@ SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
#else
H_LOCK;
tclient = h_FindClient_r(tcon);
if (!tclient) {
errorCode = VBUSY;
goto Bad_CallBackRxConnAddr;
}
thost = tclient->host;
/* nothing more can be done */

View File

@ -1272,6 +1272,24 @@ removeInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port)
return 0;
}
int
h_threadquota(int waiting)
{
if (lwps > 64) {
if (waiting > 5)
return 1;
} else if (lwps > 32) {
if (waiting > 4)
return 1;
} else if (lwps > 16) {
if (waiting > 3)
return 1;
} else {
if (waiting > 2)
return 1;
}
return 0;
}
/* Host is returned held */
struct host *
@ -1308,8 +1326,12 @@ h_GetHost_r(struct rx_connection *tcon)
* structure for this address. Verify that the identity
* of the caller matches the identity in the host structure.
*/
if ((host->hostFlags & HWHO_INPROGRESS) &&
h_threadquota(host->lock.num_waiting))
return 0;
h_Lock_r(host);
if (!(host->hostFlags & ALTADDR)) {
host->hostFlags &= ~HWHO_INPROGRESS;
/* Another thread is doing initialization */
h_Unlock_r(host);
if (!held)
@ -1350,6 +1372,7 @@ h_GetHost_r(struct rx_connection *tcon)
afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port)));
host->hostFlags |= HOSTDELETED;
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
if (!held)
h_Release_r(host);
@ -1375,6 +1398,7 @@ h_GetHost_r(struct rx_connection *tcon)
("Host %s:%d has changed its identity, deleting.\n",
afs_inet_ntoa_r(host->host, hoststr), host->port));
host->hostFlags |= HOSTDELETED;
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
if (!held)
h_Release_r(host);
@ -1394,6 +1418,7 @@ h_GetHost_r(struct rx_connection *tcon)
else
host->hostFlags &= ~(HERRORTRANS);
host->hostFlags |= ALTADDR;
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
} else if (host) {
if (!(host->hostFlags & ALTADDR)) {
@ -1403,6 +1428,7 @@ h_GetHost_r(struct rx_connection *tcon)
afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port)));
h_Lock_r(host);
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
if (!held)
h_Release_r(host);
@ -1435,6 +1461,7 @@ h_GetHost_r(struct rx_connection *tcon)
/* The host in the cache is not the host for this connection */
host->hostFlags |= HOSTDELETED;
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
if (!held)
h_Release_r(host);
@ -1512,6 +1539,7 @@ h_GetHost_r(struct rx_connection *tcon)
if (!(oheld = h_Held_r(oldHost)))
h_Hold_r(oldHost);
h_Lock_r(oldHost);
oldHost->hostFlags |= HWHO_INPROGRESS;
if (oldHost->interface) {
int code2;
@ -1602,6 +1630,7 @@ h_GetHost_r(struct rx_connection *tcon)
}
}
host->hostFlags |= HOSTDELETED;
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
/* release host because it was allocated by h_Alloc_r */
h_Release_r(host);
@ -1648,6 +1677,7 @@ h_GetHost_r(struct rx_connection *tcon)
else
host->hostFlags &= ~(HERRORTRANS);
host->hostFlags |= ALTADDR; /* host structure initialization complete */
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
}
if (caps.Capabilities_val)
@ -1885,6 +1915,9 @@ h_FindClient_r(struct rx_connection *tcon)
if (!client) { /* loop */
host = h_GetHost_r(tcon); /* Returns it h_Held */
if (!host)
return 0;
retryfirstclient:
/* First try to find the client structure */
for (client = host->FirstClient; client; client = client->next) {
@ -2534,6 +2567,7 @@ CheckHost(register struct host *host, int held)
}
if (host->LastCall < checktime) {
h_Lock_r(host);
host->hostFlags |= HWHO_INPROGRESS;
if (!(host->hostFlags & HOSTDELETED)) {
cb_conn = host->callback_rxcon;
rx_GetConnection(cb_conn);
@ -2603,6 +2637,7 @@ CheckHost(register struct host *host, int held)
cb_conn=NULL;
H_LOCK;
}
host->hostFlags &= ~HWHO_INPROGRESS;
h_Unlock_r(host);
}
H_UNLOCK;

View File

@ -241,5 +241,4 @@ struct host *(hosttableptrs[h_MAXHOSTTABLES]); /* Used by h_itoh */
#define RESETDONE 0x40 /* callback reset done */
#define HFE_LATER 0x80 /* host has FE_LATER callbacks */
#define HERRORTRANS 0x100 /* do error translation */
#define HWHO_INPROGRESS 0x200 /* set when WhoAreYou running */