mirror of
https://git.openafs.org/openafs.git
synced 2025-01-19 23:40:13 +00:00
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. 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>
This commit is contained in:
parent
75c2f96364
commit
3105c7ff0b
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 *);
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user