]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
linux26-avoid-memory-zone-fun-20050113
authorChas Williams <chas@cmf.nrl.navy.mil>
Thu, 13 Jan 2005 23:50:15 +0000 (23:50 +0000)
committerDerrick Brashear <shadow@dementia.org>
Thu, 13 Jan 2005 23:50:15 +0000 (23:50 +0000)
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.
"

src/afs/afs_vcache.c

index 249e27228f3fea7cf8b6b0dd8edf3a8b1f1cf052..9d4ff990b95c2201506bb6c6b9043d3c41a41d36 100644 (file)
@@ -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