From ece19eefbe46400e1c28834570deed7294761167 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Mon, 30 Jul 2007 14:17:27 +0000 Subject: [PATCH 1/1] viced-avoid-tying-up-all-threads-20070730 FIXES 19461 implement a thread quota. --- src/viced/afsfileprocs.c | 12 ++++++++++++ src/viced/host.c | 35 +++++++++++++++++++++++++++++++++++ src/viced/host.h | 2 +- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index 30e6810..bdbd142 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -321,6 +321,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) { @@ -424,6 +429,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; @@ -445,6 +452,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 */ @@ -7440,6 +7448,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 */ diff --git a/src/viced/host.c b/src/viced/host.c index 87f7c13..13aeb0f 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -1299,6 +1299,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 * @@ -1335,8 +1353,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) @@ -1377,6 +1399,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); @@ -1402,6 +1425,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); @@ -1421,6 +1445,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)) { @@ -1430,6 +1455,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); @@ -1462,6 +1488,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); @@ -1539,6 +1566,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; @@ -1629,6 +1657,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); @@ -1675,6 +1704,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) @@ -1925,6 +1955,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) { @@ -3120,6 +3153,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); @@ -3189,6 +3223,7 @@ CheckHost(register struct host *host, int held) cb_conn=NULL; H_LOCK; } + host->hostFlags &= ~HWHO_INPROGRESS; h_Unlock_r(host); } H_UNLOCK; diff --git a/src/viced/host.h b/src/viced/host.h index 9a797b9..35e0f2d 100644 --- a/src/viced/host.h +++ b/src/viced/host.h @@ -286,5 +286,5 @@ 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 */ #endif /* _AFS_VICED_HOST_H */ -- 1.9.4