From d83e8626db9c5dfca0402ab22796b02333503cc9 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Thu, 17 Feb 2011 00:04:06 -0500 Subject: [PATCH] linux: defer vcache evictions when sleep would be needed 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 Reviewed-by: Andrew Deason Reviewed-by: Derrick Brashear (cherry picked from commit 3105c7ff0b4ae9c372dc4c1424f63b7f259dcda1) Change-Id: Iced11ca56ced5971ab0cb8dbb65d275754ec33d5 Reviewed-on: http://gerrit.openafs.org/4186 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/afs/AIX/osi_vcache.c | 2 +- src/afs/DARWIN/osi_vcache.c | 5 +++-- src/afs/FBSD/osi_vcache.c | 2 +- src/afs/HPUX/osi_vcache.c | 3 ++- src/afs/IRIX/osi_vcache.c | 3 ++- src/afs/LINUX/osi_vcache.c | 4 ++-- src/afs/LINUX24/osi_vcache.c | 12 ++++++++++-- src/afs/NBSD/osi_vcache.c | 2 +- src/afs/OBSD/osi_vcache.c | 2 +- src/afs/SOLARIS/osi_vcache.c | 2 +- src/afs/UKERNEL/osi_vcache.c | 2 +- src/afs/afs_osi.h | 2 +- src/afs/afs_vcache.c | 12 +++++++++--- 13 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/afs/AIX/osi_vcache.c b/src/afs/AIX/osi_vcache.c index a18e74df5..debb1c818 100644 --- a/src/afs/AIX/osi_vcache.c +++ b/src/afs/AIX/osi_vcache.c @@ -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) { diff --git a/src/afs/DARWIN/osi_vcache.c b/src/afs/DARWIN/osi_vcache.c index 6a7dbcd04..15c2b7bc8 100644 --- a/src/afs/DARWIN/osi_vcache.c +++ b/src/afs/DARWIN/osi_vcache.c @@ -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) diff --git a/src/afs/FBSD/osi_vcache.c b/src/afs/FBSD/osi_vcache.c index 1e48fcccc..d400492da 100644 --- a/src/afs/FBSD/osi_vcache.c +++ b/src/afs/FBSD/osi_vcache.c @@ -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 diff --git a/src/afs/HPUX/osi_vcache.c b/src/afs/HPUX/osi_vcache.c index e08afda62..cf669a29d 100644 --- a/src/afs/HPUX/osi_vcache.c +++ b/src/afs/HPUX/osi_vcache.c @@ -14,9 +14,10 @@ #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); diff --git a/src/afs/IRIX/osi_vcache.c b/src/afs/IRIX/osi_vcache.c index a34c9b9cb..01a8d5358 100644 --- a/src/afs/IRIX/osi_vcache.c +++ b/src/afs/IRIX/osi_vcache.c @@ -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); diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c index 21ad7c209..e82d78e5d 100644 --- a/src/afs/LINUX/osi_vcache.c +++ b/src/afs/LINUX/osi_vcache.c @@ -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(); diff --git a/src/afs/LINUX24/osi_vcache.c b/src/afs/LINUX24/osi_vcache.c index 7de037dc3..c1d234003 100644 --- a/src/afs/LINUX24/osi_vcache.c +++ b/src/afs/LINUX24/osi_vcache.c @@ -22,13 +22,15 @@ #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; } diff --git a/src/afs/NBSD/osi_vcache.c b/src/afs/NBSD/osi_vcache.c index 6dca058f5..db9eedd5f 100644 --- a/src/afs/NBSD/osi_vcache.c +++ b/src/afs/NBSD/osi_vcache.c @@ -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) diff --git a/src/afs/OBSD/osi_vcache.c b/src/afs/OBSD/osi_vcache.c index cbd37f81c..6598ceabd 100644 --- a/src/afs/OBSD/osi_vcache.c +++ b/src/afs/OBSD/osi_vcache.c @@ -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) diff --git a/src/afs/SOLARIS/osi_vcache.c b/src/afs/SOLARIS/osi_vcache.c index 7435ed3ec..dd47176aa 100644 --- a/src/afs/SOLARIS/osi_vcache.c +++ b/src/afs/SOLARIS/osi_vcache.c @@ -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) diff --git a/src/afs/UKERNEL/osi_vcache.c b/src/afs/UKERNEL/osi_vcache.c index 9fe66ec71..dce051e84 100644 --- a/src/afs/UKERNEL/osi_vcache.c +++ b/src/afs/UKERNEL/osi_vcache.c @@ -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) diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h index b5e3b8f3a..14c0154c8 100644 --- a/src/afs/afs_osi.h +++ b/src/afs/afs_osi.h @@ -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 *); diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 90268871f..40fd704c8 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -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", -- 2.39.5