Free memory from afs_events
authorBen Kaduk <kaduk@mit.edu>
Tue, 26 Jul 2011 03:39:27 +0000 (23:39 -0400)
committerDerrick Brashear <shadow@dementix.org>
Wed, 7 Sep 2011 14:43:06 +0000 (07:43 -0700)
DARWIN and LINUX were already doing this, but everybody else had
a memory leak.  Consolidate most of the common code to do so,
including afs_event_t definitions.

Change-Id: I5ec83cf23fd15dbbd5716995c671998e35862843
Reviewed-on: http://gerrit.openafs.org/5314
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Derrick Brashear <shadow@dementix.org>

12 files changed:
src/afs/AIX/osi_sleep.c
src/afs/DARWIN/osi_sleep.c
src/afs/FBSD/osi_sleep.c
src/afs/IRIX/osi_sleep.c
src/afs/LINUX/osi_module.c
src/afs/LINUX/osi_sleep.c
src/afs/LINUX24/osi_sleep.c
src/afs/NBSD/osi_sleep.c
src/afs/OBSD/osi_sleep.c
src/afs/SOLARIS/osi_sleep.c
src/afs/afs_osi.c
src/afs/afs_osi.h

index 3ba0e41..507ba6d 100644 (file)
@@ -82,19 +82,8 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
 
 
 
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-    tid_t cond;
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
index d248d0a..2a4fb27 100644 (file)
@@ -71,19 +71,6 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
 
 
 
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-#ifdef AFS_DARWIN80_ENV
-   lck_mtx_t *lck;
-   thread_t owner;
-#endif
-} afs_event_t;
-
 #ifdef AFS_DARWIN80_ENV
 #define EVTLOCK_INIT(e) \
     do { \
@@ -110,9 +97,8 @@ typedef struct afs_event {
 #define EVTLOCK_UNLOCK(e)
 #define EVTLOCK_DESTROY(e)
 #endif
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
-#define afs_evhash(event)       (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
+#define afs_evhash(event)       (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
@@ -321,7 +307,7 @@ void
 shutdown_osisleep(void) {
     struct afs_event *evp, *nevp, **pevpp;
     int i;
-    for (i=0; i < HASHSIZE; i++) {
+    for (i=0; i < AFS_EVHASHSIZE; i++) {
        evp = afs_evhasht[i];
        pevpp = &afs_evhasht[i];
        while (evp) {
@@ -333,6 +319,7 @@ shutdown_osisleep(void) {
                osi_FreeSmallSpace(evp);
                afs_evhashcnt--;
            } else {
+               afs_warn("nonzero refcount in shutdown_osisleep()\n");
                EVTLOCK_UNLOCK(evp);
                pevpp = &evp->next;
            }
index 926e962..a1edf0a 100644 (file)
@@ -75,22 +75,8 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
     return code;
 }
 
-/*
- * All this gluck should probably also be replaced with CVs.
- */
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-    int cond;
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
index 5b67f27..0f8c674 100644 (file)
@@ -71,22 +71,11 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
 
 
 
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-    kcondvar_t cond;           /* Currently associated condition variable */
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
 #if (_MIPS_SZPTR == 64)
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>3) & (HASHSIZE-1));
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>3) & (AFS_EVHASHSIZE-1));
 #else
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 #endif
 int afs_evhashcnt = 0;
 
index f24dc6c..f5d6afc 100644 (file)
@@ -103,7 +103,7 @@ afs_cleanup(void)
 #if !defined(AFS_NONFSTRANS)
     osi_linux_nfssrv_shutdown();
 #endif
-    osi_event_shutdown();
+    shutdown_osisleep();
     osi_linux_free_afs_memory();
 
     osi_ioctl_clean();
index d9e2967..54885e6 100644 (file)
@@ -67,35 +67,10 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
     return code;
 }
 
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-    wait_queue_head_t cond;
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
-void
-osi_event_shutdown(void)
-{
-   int i;
-
-   for (i=0;i<HASHSIZE;i++) {
-       while (afs_evhasht[i] != NULL) {
-           afs_event_t *tmp = afs_evhasht[i];
-           afs_evhasht[i] = tmp->next;
-           kfree(tmp);
-       }
-   }
-}
-
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
  * */
 static afs_event_t *
index 3833b8e..2d43a03 100644 (file)
@@ -73,23 +73,8 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
 
 
 
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-#if defined(AFS_LINUX24_ENV)
-    wait_queue_head_t cond;
-#else
-    struct wait_queue *cond;
-#endif
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
index 1f6310a..76dab43 100644 (file)
@@ -193,19 +193,8 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
 
 
 
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-    kcondvar_t cond;           /* Currently associated condition variable */
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
index f06f2fb..ccc74a4 100644 (file)
@@ -125,22 +125,8 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
     return code;
 }
 
-/*
- * All this gluck should probably also be replaced with CVs.
- */
-typedef struct afs_event {
-    struct afs_event *next;     /* next in hash chain */
-    char *event;                /* lwp event: an address */
-    int refcount;               /* Is it in use? */
-    int seq;                    /* Sequence number: this is incremented
-                                 * by wakeup calls; wait will not return until
-                                 * it changes */
-    int cond;
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];     /* Hash table for events */
-#define afs_evhash(event)       (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];     /* Hash table for events */
+#define afs_evhash(event)       (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
index d84ff64..2197d9e 100644 (file)
@@ -71,19 +71,8 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
 
 
 
-typedef struct afs_event {
-    struct afs_event *next;    /* next in hash chain */
-    char *event;               /* lwp event: an address */
-    int refcount;              /* Is it in use? */
-    int seq;                   /* Sequence number: this is incremented
-                                * by wakeup calls; wait will not return until
-                                * it changes */
-    kcondvar_t cond;           /* Currently associated condition variable */
-} afs_event_t;
-
-#define HASHSIZE 128
-afs_event_t *afs_evhasht[HASHSIZE];    /* Hash table for events */
-#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
+afs_event_t *afs_evhasht[AFS_EVHASHSIZE];      /* Hash table for events */
+#define afs_evhash(event)      (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1));
 int afs_evhashcnt = 0;
 
 /* Get and initialize event structure corresponding to lwp event (i.e. address)
index 4829073..6b9c002 100644 (file)
@@ -271,6 +271,9 @@ shutdown_osi(void)
        afs_osi_ctxtp = NULL;
        afs_osi_ctxtp_initialized = 0;
     }
+#endif
+#if !defined(AFS_HPUX_ENV) && !defined(UKERNEL) && !defined(AFS_DFBSD_ENV) && !defined(AFS_LINUX_ENV)
+    /* LINUX calls this from afs_cleanup() which hooks into module_exit */
     shutdown_osisleep();
 #endif
     if (afs_cold_shutdown) {
@@ -278,6 +281,37 @@ shutdown_osi(void)
     }
 }
 
+#if !defined(AFS_HPUX_ENV) && !defined(UKERNEL) && !defined(AFS_DFBSD_ENV) && !defined(AFS_DARWIN_ENV)
+/* DARWIN uses locking, and so must provide its own */
+void
+shutdown_osisleep(void)
+{
+    afs_event_t *tmp;
+    int i;
+
+    for (i=0;i<AFS_EVHASHSIZE;i++) {
+       while ((tmp = afs_evhasht[i]) != NULL) {
+           afs_evhasht[i] = tmp->next;
+           if (tmp->refcount > 0) {
+               afs_warn("nonzero refcount in shutdown_osisleep()\n");
+           } else {
+#if defined(AFS_AIX_ENV)
+               xmfree(tmp);
+#elif defined(AFS_FBSD_ENV)
+               afs_osi_Free(tmp, sizeof(*tmp));
+#elif defined(AFS_SGI_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_SOLARIS_ENV)
+               osi_FreeSmallSpace(tmp);
+#elif defined(AFS_LINUX_ENV)
+               kfree(tmp);
+#elif defined(AFS_LINUX24_ENV)
+               osi_linux_free(tmp);
+#endif
+           }
+       }
+    }
+}
+#endif
+
 #if !defined(AFS_OBSD_ENV) && !defined(AFS_NBSD40_ENV)
 int
 afs_osi_suser(void *cr)
index 6dd7e61..153017e 100644 (file)
 #include <sys/condvar.h>
 #endif
 
+#ifdef AFS_SGI_ENV
+#include "sys/sema.h"          /* for kcondvar_t */
+#endif
+
 #ifdef AFS_NBSD_ENV
 #include <sys/lock.h>
 #endif
@@ -124,6 +128,37 @@ struct afs_osi_WaitHandle {
 
 #define        osi_NPACKETS    20      /* number of cluster pkts to alloc */
 
+/*
+ * Various definitions for osi_sleep and its event hash table
+ * DFBSD and SUNOS have no osi_sleep, and HPUX has its own hack for this stuff
+ */
+#define AFS_EVHASHSIZE 128     /* size of afs_evhasht, must be power of 2 */
+typedef struct afs_event {
+    struct afs_event *next;    /* next in hash chain */
+    char *event;               /* lwp event: an address */
+    int refcount;              /* Is it in use? */
+    int seq;                   /* Sequence number: this is incremented
+                                * by wakeup calls; wait will not return until
+                                * it changes */
+#if defined(AFS_AIX_ENV)
+    tid_t cond;
+#elif defined(AFS_DARWIN_ENV)
+#ifdef AFS_DARWIN80_ENV
+    lck_mtx_t *lck;
+    thread_t owner;
+#endif
+    /* no cond member */
+#elif defined(AFS_FBSD_ENV) || defined(AFS_OBSD_ENV)
+    int cond;                  /* "all this gluck should probably be replaced by CVs" */
+#elif defined(AFS_LINUX_ENV) || defined(AFS_LINUX24_ENV)
+    wait_queue_head_t cond;
+#elif defined(AFS_NBSD_ENV) || defined(AFS_SOLARIS_ENV) || defined(AFS_SGI_ENV)
+    kcondvar_t cond;           /* Currently associated condition variable */
+#endif
+} afs_event_t;
+extern afs_event_t *afs_evhasht[AFS_EVHASHSIZE];       /* Hash table for events */
+extern void shutdown_osisleep(void);
+
 
 /*
  * Default vnode related macros