From: Chas Williams Date: Thu, 13 Jan 2005 23:50:15 +0000 (+0000) Subject: linux26-avoid-memory-zone-fun-20050113 X-Git-Tag: BP-disconnected~56 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=543d4464d8afe11e74b239abb5da20b0269259b3;p=packages%2Fo%2Fopenafs.git linux26-avoid-memory-zone-fun-20050113 FIXES 16965 " the wake_up_bit() mechanism has replaced 'per object' wait queues (atleast when testing for single bit changes). the actual wait queue to use is determined using a hash on page->flags (which encodes the zone table in the lower 8 bits). afs inodes come from a vmalloc() since afs gets all the inodes in one go. vmalloc()'d memory apparently doesnt get mapped to any particular zone. so when an afs inode uses wake_up_bit() they index off the end of the zone_page table. " --- diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 249e27228..9d4ff990b 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -2895,6 +2895,17 @@ afs_vcacheInit(int astatSize) LOCK_INIT(&afs_xvcb, "afs_xvcb"); #if !defined(AFS_OSF_ENV) +#ifdef AFS_LINUX26_ENV + printf("old style would have needed %d contiguous bytes\n", astatSize * + sizeof(struct vcache)); + Initial_freeVCList = freeVCList = tvp = (struct vcache *) + afs_osi_Alloc(sizeof(struct vcache)); + for (i = 0; i < astatSize; i++) { + tvp->nextfree = (struct vcache *) afs_osi_Alloc(sizeof(struct vcache)); + tvp = tvp->nextfree; + } + tvp->nextfree = NULL; +#else /* Allocate and thread the struct vcache entries */ tvp = (struct vcache *)afs_osi_Alloc(astatSize * sizeof(struct vcache)); memset((char *)tvp, 0, sizeof(struct vcache) * astatSize); @@ -2909,7 +2920,7 @@ afs_vcacheInit(int astatSize) pin((char *)tvp, astatSize * sizeof(struct vcache)); /* XXX */ #endif #endif - +#endif #if defined(AFS_SGI_ENV) for (i = 0; i < astatSize; i++) { @@ -3019,12 +3030,25 @@ shutdown_vcache(void) } afs_cbrSpace = 0; +#ifdef AFS_LINUX26_ENV + { + struct vcache *tvp = Initial_freeVCList; + while (tvp) { + struct vcache *next = tvp->nextfree; + + afs_osi_Free(tvp, sizeof(struct vcache)); + tvp = next; + } + } +#else #ifdef KERNEL_HAVE_PIN unpin(Initial_freeVCList, afs_cacheStats * sizeof(struct vcache)); #endif #if !defined(AFS_OSF_ENV) afs_osi_Free(Initial_freeVCList, afs_cacheStats * sizeof(struct vcache)); #endif +#endif + #if !defined(AFS_OSF_ENV) freeVCList = Initial_freeVCList = 0; #endif