STABLE14-macos-avoid-reclaim-hang-20060124

FIXES 25686

based on chaskiel's suggestion, implement a lookaside reclaim list


(cherry picked from commit 1649de223462f5290974b7f05d09a41f9ff29bde)
This commit is contained in:
Derrick Brashear 2006-01-25 04:47:11 +00:00
parent 079f1aeb3b
commit 6266a10f56
5 changed files with 75 additions and 16 deletions

View File

@ -1624,7 +1624,7 @@ afs_vop_reclaim(ap)
* } */ *ap;
{
int error = 0;
int sl;
int sl, writelocked;
register struct vnode *vp = ap->a_vp;
struct vcache *tvc = VTOAFS(vp);
@ -1632,25 +1632,40 @@ afs_vop_reclaim(ap)
cache_purge(vp); /* just in case... */
if (tvc) {
AFS_GLOCK();
ObtainWriteLock(&afs_xvcache, 335);
error = afs_FlushVCache(tvc, &sl); /* toss our stuff from vnode */
if (tvc->states & (CVInit
writelocked = (0 == NBObtainWriteLock(&afs_xvcache, 335));
if (!writelocked) {
ObtainWriteLock(&afs_xvreclaim, 176);
#ifdef AFS_DARWIN80_ENV
| CDeadVnode
vnode_clearfsnode(AFSTOV(tvc));
vnode_removefsref(AFSTOV(tvc));
#else
tvc->v->v_data = NULL; /* remove from vnode */
#endif
)) {
tvc->states &= ~(CVInit
AFSTOV(tvc) = NULL; /* also drop the ptr to vnode */
tvc->states |= CVInit; /* also CDeadVnode? */
tvc->nextfree = ReclaimedVCList;
ReclaimedVCList = tvc;
ReleaseWriteLock(&afs_xvreclaim);
} else {
error = afs_FlushVCache(tvc, &sl); /* toss our stuff from vnode */
if (tvc->states & (CVInit
#ifdef AFS_DARWIN80_ENV
| CDeadVnode
| CDeadVnode
#endif
);
afs_osi_Wakeup(&tvc->states);
)) {
tvc->states &= ~(CVInit
#ifdef AFS_DARWIN80_ENV
| CDeadVnode
#endif
);
afs_osi_Wakeup(&tvc->states);
}
if (!error && vnode_fsnode(vp))
panic("afs_reclaim: vnode not cleaned");
if (!error && (tvc->v != NULL))
panic("afs_reclaim: vcache not cleaned");
ReleaseWriteLock(&afs_xvcache);
}
if (!error && vnode_fsnode(vp))
panic("afs_reclaim: vnode not cleaned");
if (!error && (tvc->v != NULL))
panic("afs_reclaim: vcache not cleaned");
ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
}
return error;

View File

@ -59,7 +59,9 @@ static struct ltable {
"afs_xosi", (char *)&afs_xosi},
#endif
{
"afs_xsrvAddr", (char *)&afs_xsrvAddr}
"afs_xsrvAddr", (char *)&afs_xsrvAddr},
{
"afs_xvreclaim", (char *)&afs_xvreclaim}
};
unsigned long lastCallBack_vnode;
unsigned int lastCallBack_dv;

View File

@ -175,6 +175,9 @@ afs_Daemon(void)
/* things to do every minute */
DFlush(); /* write out dir buffers */
afs_WriteThroughDSlots(); /* write through cacheinfo entries */
ObtainWriteLock(&afs_xvcache, 736);
afs_FlushReclaimedVcaches();
ReleaseWriteLock(&afs_xvcache);
afs_FlushActiveVcaches(1); /* keep flocks held & flush nfs writes */
#ifdef AFS_DISCON_ENV
afs_StoreDirtyVcaches();

View File

@ -811,6 +811,7 @@ extern afs_int32 afs_data_pointer_to_int32(const void *p);
extern afs_int32 afs_maxvcount;
extern afs_int32 afs_vcount;
extern int afsvnumbers;
extern afs_rwlock_t afs_xvreclaim;
extern afs_rwlock_t afs_xvcache;
extern afs_lock_t afs_xvcb;
extern struct afs_q VLRU;
@ -819,6 +820,7 @@ extern unsigned int afs_paniconwarn;
extern struct afs_q afs_vhashTV[VCSIZE];
extern afs_int32 afs_bulkStatsLost;
extern int afs_norefpanic;
extern struct vcache *ReclaimedVCList;
void afs_vcacheInit(int astatSize);
extern struct vcache *afs_FindVCache(struct VenusFid *afid, afs_int32 * retry,

View File

@ -62,9 +62,11 @@ char *makesname();
/* Exported variables */
afs_rwlock_t afs_xvcache; /*Lock: alloc new stat cache entries */
afs_rwlock_t afs_xvreclaim; /*Lock: entries reclaimed, not on free list */
afs_lock_t afs_xvcb; /*Lock: fids on which there are callbacks */
#if !defined(AFS_LINUX22_ENV)
static struct vcache *freeVCList; /*Free list for stat cache entries */
struct vcache *ReclaimedVCList; /*Reclaimed list for stat entries */
static struct vcache *Initial_freeVCList; /*Initial list for above */
#endif
struct afs_q VLRU; /*vcache LRU */
@ -572,6 +574,38 @@ afs_RemoveVCB(struct VenusFid *afid)
MReleaseWriteLock(&afs_xvcb);
}
void
afs_FlushReclaimedVcaches(void)
{
#if !defined(AFS_LINUX22_ENV)
struct vcache *tvc;
int code, fv_slept;
struct vcache *tmpReclaimedVCList = NULL;
ObtainWriteLock(&afs_xvreclaim, 76);
while (ReclaimedVCList) {
tvc = ReclaimedVCList; /* take from free list */
ReclaimedVCList = tvc->nextfree;
tvc->nextfree = NULL;
code = afs_FlushVCache(tvc, &fv_slept);
if (code) {
/* Ok, so, if we got code != 0, uh, wtf do we do? */
/* Probably, build a temporary list and then put all back when we
get to the end of the list */
/* This is actually really crappy, but we need to not leak these.
We probably need a way to be smarter about this. */
tvc->nextfree = tmpReclaimedVCList;
tmpReclaimedVCList = tvc;
printf("Reclaim list flush %x failed: %d\n", tvc, code);
}
}
if (tmpReclaimedVCList)
ReclaimedVCList = tmpReclaimedVCList;
ReleaseWriteLock(&afs_xvreclaim);
#endif
}
/*
* afs_NewVCache
*
@ -603,6 +637,9 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
int code, fv_slept;
AFS_STATCNT(afs_NewVCache);
afs_FlushReclaimedVcaches();
#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV)
#if defined(AFS_OSF30_ENV) || defined(AFS_LINUX22_ENV)
if (afs_vcount >= afs_maxvcount)