]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
linux: defer vcache evictions when sleep would be needed
authorDerrick Brashear <shadow@dementia.org>
Thu, 17 Feb 2011 05:04:06 +0000 (00:04 -0500)
committerDerrick Brashear <shadow@dementia.org>
Thu, 10 Mar 2011 02:02:01 +0000 (18:02 -0800)
because we're only willing to loop 100 times worth of "sleeps",
on a machine with heavy vcache demands we can end up just growing
the list huge. in the first pass, just clean up as many entries which
do not require sleeping as needed. if we need more entries, make
a second pass.

Reviewed-on: http://gerrit.openafs.org/3971
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
(cherry picked from commit 3105c7ff0b4ae9c372dc4c1424f63b7f259dcda1)

Change-Id: Iced11ca56ced5971ab0cb8dbb65d275754ec33d5
Reviewed-on: http://gerrit.openafs.org/4186
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
13 files changed:
src/afs/AIX/osi_vcache.c
src/afs/DARWIN/osi_vcache.c
src/afs/FBSD/osi_vcache.c
src/afs/HPUX/osi_vcache.c
src/afs/IRIX/osi_vcache.c
src/afs/LINUX/osi_vcache.c
src/afs/LINUX24/osi_vcache.c
src/afs/NBSD/osi_vcache.c
src/afs/OBSD/osi_vcache.c
src/afs/SOLARIS/osi_vcache.c
src/afs/UKERNEL/osi_vcache.c
src/afs/afs_osi.h
src/afs/afs_vcache.c

index a18e74df5b70539f2b2c7c304cc5e02d99a0874d..debb1c818f9e3cc448b8c5228cc5be5f62e0ac9b 100644 (file)
@@ -16,7 +16,7 @@
 extern struct vnodeops *afs_ops;
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
      int code;
      if (!VREFCOUNT_GT(avc,0)
          && avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0) {
index 6a7dbcd04e79fe2fbab3269915d378486c74b943..15c2b7bc81c7d00a433384510e1045a23dcfb557 100644 (file)
@@ -26,9 +26,10 @@ osi_NewVnode(void) {
 
 #if defined(AFS_DARWIN80_ENV)
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     *slept = 0;
 
+    /* we ignore defersleep, as we *always* need to sleep */
     if (!VREFCOUNT_GT(avc, 0) && avc->opens == 0 &&
        (avc->f.states & CUnlinkedDel) == 0) {
 
@@ -63,7 +64,7 @@ osi_TryEvictVCache(struct vcache *avc, int *slept) {
 }
 #else
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     if (!VREFCOUNT_GT(avc,0)
         || ((VREFCOUNT(avc) == 1) && (UBCINFOEXISTS(AFSTOV(avc))))
         && avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0)
index 1e48fcccc177793b6cf4eabb600cba8234abff9e..d400492daad2f444cd49fe4c7f03cd3493801218 100644 (file)
@@ -24,7 +24,7 @@
 #endif
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
 
     /*
      * essentially all we want to do here is check that the
index e08afda62446958960022552e777b1738f6bc6ef..cf669a29dc7ccfcf4162cd8c0634607b6e0ad275 100644 (file)
 #include "afsincludes.h"        /*AFS-based standard headers */
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     int code;
 
+    /* we can't control whether we sleep */
     if (!VREFCOUNT_GT(avc,0)
         && avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0) {
        code = afs_FlushVCache(avc, slept);
index a34c9b9cb89a23acd5377790b0e5ddde8b86d642..01a8d53585f324fc81db54100ceb3d6fa8f728a0 100644 (file)
@@ -14,8 +14,9 @@
 #include "afsincludes.h"        /*AFS-based standard headers */
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
      int code;
+     /* we can't control whether we sleep */
      if (!VREFCOUNT_GT(avc,0)
          && avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0) {
         code = afs_FlushVCache(avc, slept);
index 21ad7c20979c0538a6e5895019538b3e98a40d4e..e82d78e5da0b3abc24a13012ec2997730f7d4076 100644 (file)
@@ -14,7 +14,7 @@
 #include "afsincludes.h"        /*AFS-based standard headers */
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     int code;
 
     struct dentry *dentry;
@@ -22,7 +22,7 @@ osi_TryEvictVCache(struct vcache *avc, int *slept) {
     struct list_head *cur, *head;
 
     /* First, see if we can evict the inode from the dcache */
-    if (avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
+    if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
        *slept = 1;
        ReleaseWriteLock(&afs_xvcache);
         AFS_GUNLOCK();
index 7de037dc3f002cb0f91f2ae321d5f0cd92dbc599..c1d234003f982ef0f3147c92f5a8e343cfdd2599 100644 (file)
 #endif
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     int code;
     struct dentry *dentry;
     struct list_head *cur, *head;
 
     /* First, see if we can evict the inode from the dcache */
-    if (avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
+    if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
+       *slept = 1;
+       ReleaseWriteLock(&afs_xvcache);
         AFS_GUNLOCK();
        afs_linux_lock_dcache();
        head = &(AFSTOV(avc))->i_dentry;
@@ -57,13 +59,19 @@ restart:
        afs_linux_unlock_dcache();
 inuse:
        AFS_GLOCK();
+        ObtainWriteLock(&afs_xvcache, 733);
     }
 
     /* See if we can evict it from the VLRUQ */
     if (VREFCOUNT_GT(avc,0) && !VREFCOUNT_GT(avc,1) && avc->opens == 0
        && (avc->f.states & CUnlinkedDel) == 0) {
+       int didsleep = *slept;
 
        code = afs_FlushVCache(avc, slept);
+        /* flushvcache wipes slept; restore slept if we did before */
+        if (didsleep)
+            *slept = didsleep;
+
        if (code == 0)
           return 1;
     }
index 6dca058f5620cae614a7c0bc79d84adc77dacd31..db9eedd5fdf7f34894d63369be756cf4ec941852 100644 (file)
@@ -14,7 +14,7 @@
 #include "afsincludes.h"       /*AFS-based standard headers */
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     *slept = 0;
 
     if (!VREFCOUNT_GT(avc,0)
index cbd37f81c24d65fd4261c149d80d06f3fea5b83a..6598ceabdb4d835771c44b08474abd07d48c89d4 100644 (file)
@@ -14,7 +14,7 @@
 #include "afsincludes.h"       /*AFS-based standard headers */
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     *slept = 0;
 
     if (!VREFCOUNT_GT(avc,0)
index 7435ed3ec5d2b6f4d11be5a0b4aa279bb9ce3134..dd47176aa30bdedf0bd189b76b9a36807565f546 100644 (file)
@@ -14,7 +14,7 @@
 #include "afsincludes.h"        /*AFS-based standard headers */
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     int code;
 
     if (!VREFCOUNT_GT(avc,0)
index 9fe66ec71c28be03d136d8f1441c0795feb241bd..dce051e847942b7a4a7887678fed713ebf7926e0 100644 (file)
@@ -14,7 +14,7 @@
 #include "afsincludes.h"        /*AFS-based standard headers */
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
     int code;
 
     if (!VREFCOUNT_GT(avc,0)
index b5e3b8f3ad802f52bd2a385f9aaed4100a2f4bea..14c0154c8bba1a4a6779024f818ef56bf6c2aa97 100644 (file)
@@ -139,7 +139,7 @@ extern struct vnodeops *afs_ops;
 #endif
 
 struct vcache;
-extern int osi_TryEvictVCache(struct vcache *, int *);
+extern int osi_TryEvictVCache(struct vcache *, int *, int);
 extern struct vcache *osi_NewVnode(void);
 extern void osi_PrePopulateVCache(struct vcache *);
 extern void osi_PostPopulateVCache(struct vcache *);
index 90268871f30a453ba9e9a26549d5a0704da1b1aa..40fd704c8ddde2daf942a8918cf7ec4d3ba86d36 100644 (file)
@@ -651,7 +651,7 @@ afs_ShakeLooseVCaches(afs_int32 anumber)
     afs_int32 i, loop;
     struct vcache *tvc;
     struct afs_q *tq, *uq;
-    int fv_slept;
+    int fv_slept, defersleep = 0;
     afs_int32 target = anumber;
 
     i = 0;
@@ -671,7 +671,7 @@ afs_ShakeLooseVCaches(afs_int32 anumber)
        }
 
        fv_slept = 0;
-       if (osi_TryEvictVCache(tvc, &fv_slept))
+       if (osi_TryEvictVCache(tvc, &fv_slept, defersleep))
            anumber--;
 
        if (fv_slept) {
@@ -681,8 +681,14 @@ afs_ShakeLooseVCaches(afs_int32 anumber)
            i = 0;
            continue;   /* start over - may have raced. */
        }
-       if (tq == uq)
+       if (tq == uq) {
+           if (anumber && !defersleep) {
+               defersleep = 1;
+               tq = VLRU.prev;
+               continue;
+           }
            break;
+       }
     }
     if (!afsd_dynamic_vcaches && anumber == target) {
        afs_warn("afs_ShakeLooseVCaches: warning none freed, using %d of %d\n",