]> 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>
Wed, 9 Mar 2011 18:25:13 +0000 (10:25 -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.

Change-Id: Ie5af42e7c0287d7a093f9a5884c10813dbb8cb11
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>
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 1c99d73c7f8a8345ea6f181e1248416502f01bf7..b61d466c022a33a8733f2a8515857fcfa0d7a516 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 4f2e5a87c8c9671e751bafcfb999aeaa3136fafc..ce3bb5f49dbf6175c7b46f1af58ca6ff23ad93e9 100644 (file)
@@ -27,9 +27,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) {
 
@@ -64,7 +65,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 e3e3003ef1dc142781c9960e926ddb9549e2927b..bbaf5ce2f9983f544eb590886c45b8a872f9e180 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 f7a544e9afd6de8b36c8273686c406cbe7690f25..976c8758a4ecda4766b81fa7808331b14b39cdf8 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 2bb8f26ec19d6760be0c4c19b723b7d67ee9ea7e..6bd542890ce690696b89d070b78ec2e867dc025f 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 2bb57f5a2a7680e70a5981c8448eb04fc6f91a08..548ead53d3f62bebbb76e3ba748523f87da9bb93 100644 (file)
@@ -140,7 +140,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 f3577446377b462c88343cb1500eb0adf313b49e..d96bfc022239dc4b2d4bb7d97bdbe0dce042abb4 100644 (file)
@@ -698,7 +698,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;
@@ -718,7 +718,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) {
@@ -728,8 +728,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",