From: Ben Kaduk Date: Tue, 26 Jul 2011 03:39:27 +0000 (-0400) Subject: Free memory from afs_events X-Git-Tag: openafs-devel-1_7_1~56 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=dc077b83c9b1f107efbc3483743f44117748f23c Free memory from afs_events 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 Reviewed-by: Benjamin Kaduk Reviewed-by: Derrick Brashear --- diff --git a/src/afs/AIX/osi_sleep.c b/src/afs/AIX/osi_sleep.c index 3ba0e41..507ba6d 100644 --- a/src/afs/AIX/osi_sleep.c +++ b/src/afs/AIX/osi_sleep.c @@ -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) diff --git a/src/afs/DARWIN/osi_sleep.c b/src/afs/DARWIN/osi_sleep.c index d248d0a..2a4fb27 100644 --- a/src/afs/DARWIN/osi_sleep.c +++ b/src/afs/DARWIN/osi_sleep.c @@ -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; } diff --git a/src/afs/FBSD/osi_sleep.c b/src/afs/FBSD/osi_sleep.c index 926e962..a1edf0a 100644 --- a/src/afs/FBSD/osi_sleep.c +++ b/src/afs/FBSD/osi_sleep.c @@ -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) diff --git a/src/afs/IRIX/osi_sleep.c b/src/afs/IRIX/osi_sleep.c index 5b67f27..0f8c674 100644 --- a/src/afs/IRIX/osi_sleep.c +++ b/src/afs/IRIX/osi_sleep.c @@ -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; diff --git a/src/afs/LINUX/osi_module.c b/src/afs/LINUX/osi_module.c index f24dc6c..f5d6afc 100644 --- a/src/afs/LINUX/osi_module.c +++ b/src/afs/LINUX/osi_module.c @@ -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(); diff --git a/src/afs/LINUX/osi_sleep.c b/src/afs/LINUX/osi_sleep.c index d9e2967..54885e6 100644 --- a/src/afs/LINUX/osi_sleep.c +++ b/src/afs/LINUX/osi_sleep.c @@ -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;inext; - kfree(tmp); - } - } -} - /* Get and initialize event structure corresponding to lwp event (i.e. address) * */ static afs_event_t * diff --git a/src/afs/LINUX24/osi_sleep.c b/src/afs/LINUX24/osi_sleep.c index 3833b8e..2d43a03 100644 --- a/src/afs/LINUX24/osi_sleep.c +++ b/src/afs/LINUX24/osi_sleep.c @@ -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) diff --git a/src/afs/NBSD/osi_sleep.c b/src/afs/NBSD/osi_sleep.c index 1f6310a..76dab43 100644 --- a/src/afs/NBSD/osi_sleep.c +++ b/src/afs/NBSD/osi_sleep.c @@ -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) diff --git a/src/afs/OBSD/osi_sleep.c b/src/afs/OBSD/osi_sleep.c index f06f2fb..ccc74a4 100644 --- a/src/afs/OBSD/osi_sleep.c +++ b/src/afs/OBSD/osi_sleep.c @@ -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) diff --git a/src/afs/SOLARIS/osi_sleep.c b/src/afs/SOLARIS/osi_sleep.c index d84ff64..2197d9e 100644 --- a/src/afs/SOLARIS/osi_sleep.c +++ b/src/afs/SOLARIS/osi_sleep.c @@ -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) diff --git a/src/afs/afs_osi.c b/src/afs/afs_osi.c index 4829073..6b9c002 100644 --- a/src/afs/afs_osi.c +++ b/src/afs/afs_osi.c @@ -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;inext; + 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) diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h index 6dd7e61..153017e 100644 --- a/src/afs/afs_osi.h +++ b/src/afs/afs_osi.h @@ -17,6 +17,10 @@ #include #endif +#ifdef AFS_SGI_ENV +#include "sys/sema.h" /* for kcondvar_t */ +#endif + #ifdef AFS_NBSD_ENV #include #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