viced-avoid-tying-up-all-threads-20070730
authorDerrick Brashear <shadow@dementia.org>
Mon, 30 Jul 2007 14:17:27 +0000 (14:17 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 30 Jul 2007 14:17:27 +0000 (14:17 +0000)
FIXES 19461

implement a thread quota.

src/viced/afsfileprocs.c
src/viced/host.c
src/viced/host.h

index 30e6810..bdbd142 100644 (file)
@@ -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 */
index 87f7c13..13aeb0f 100644 (file)
@@ -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;
index 9a797b9..35e0f2d 100644 (file)
@@ -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 */