mirror of
https://git.openafs.org/openafs.git
synced 2025-01-21 08:20:16 +00:00
Windows: cm_GetNewSCache drop lock to permit change
In cm_GetNewSCache the entire LRU queue is searched for a cm_scache_t object that is safe to recycle. If none are the LRU queue was immediately searched again without dropping the cm_scacheLock or taking a pause. As a result it is quite possible that a thread about to release a cm_scache_t was blocked from doing so. This patchset factors some of the logic a bit differently to improve readability and adds new log messages to help diagnose the cause of a problem if no cm_scache_t ever becomes available. Change-Id: Ica6ebee0ce0456e879ae7188d9c8cdc935a92e5b Reviewed-on: http://gerrit.openafs.org/7352 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com> Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
This commit is contained in:
parent
dbab42ca72
commit
46c1f1391b
@ -317,22 +317,21 @@ cm_GetNewSCache(afs_uint32 locked)
|
|||||||
if (!buf_dirty && !buf_rdr) {
|
if (!buf_dirty && !buf_rdr) {
|
||||||
cm_fid_t fid;
|
cm_fid_t fid;
|
||||||
afs_uint32 fileType;
|
afs_uint32 fileType;
|
||||||
|
int success;
|
||||||
|
|
||||||
if (!lock_TryWrite(&scp->rw)) {
|
success = lock_TryWrite(&scp->rw);
|
||||||
lock_ObtainWrite(&cm_scacheLock);
|
|
||||||
if (scp_prev != (cm_scache_t *) osi_QPrev(&scp->q) &&
|
|
||||||
scp_next != (cm_scache_t *) osi_QNext(&scp->q))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_ObtainWrite(&cm_scacheLock);
|
lock_ObtainWrite(&cm_scacheLock);
|
||||||
if (scp_prev != (cm_scache_t *) osi_QPrev(&scp->q) &&
|
if (scp_prev != (cm_scache_t *) osi_QPrev(&scp->q) &&
|
||||||
scp_next != (cm_scache_t *) osi_QNext(&scp->q))
|
scp_next != (cm_scache_t *) osi_QNext(&scp->q))
|
||||||
{
|
{
|
||||||
|
osi_Log1(afsd_logp, "GetNewSCache scp 0x%p; LRU order changed", scp);
|
||||||
|
if (success)
|
||||||
lock_ReleaseWrite(&scp->rw);
|
lock_ReleaseWrite(&scp->rw);
|
||||||
break;
|
break;
|
||||||
|
} else if (!success) {
|
||||||
|
osi_Log1(afsd_logp, "GetNewSCache failed to obtain lock scp 0x%p", scp);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Found a likely candidate. Save type and fid in case we succeed */
|
/* Found a likely candidate. Save type and fid in case we succeed */
|
||||||
@ -351,23 +350,34 @@ cm_GetNewSCache(afs_uint32 locked)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
lock_ReleaseWrite(&scp->rw);
|
lock_ReleaseWrite(&scp->rw);
|
||||||
} else if (!buf_rdr) {
|
|
||||||
osi_Log1(afsd_logp, "GetNewSCache dirty buffers scp 0x%p", scp);
|
|
||||||
lock_ObtainWrite(&cm_scacheLock);
|
|
||||||
if (scp_prev != (cm_scache_t *) osi_QPrev(&scp->q) &&
|
|
||||||
scp_next != (cm_scache_t *) osi_QNext(&scp->q))
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
|
if (buf_rdr)
|
||||||
osi_Log1(afsd_logp,"GetNewSCache redirector is holding extents scp 0x%p", scp);
|
osi_Log1(afsd_logp,"GetNewSCache redirector is holding extents scp 0x%p", scp);
|
||||||
|
else
|
||||||
|
osi_Log1(afsd_logp, "GetNewSCache dirty buffers scp 0x%p", scp);
|
||||||
|
|
||||||
lock_ObtainWrite(&cm_scacheLock);
|
lock_ObtainWrite(&cm_scacheLock);
|
||||||
if (scp_prev != (cm_scache_t *) osi_QPrev(&scp->q) &&
|
if (scp_prev != (cm_scache_t *) osi_QPrev(&scp->q) &&
|
||||||
scp_next != (cm_scache_t *) osi_QNext(&scp->q))
|
scp_next != (cm_scache_t *) osi_QNext(&scp->q))
|
||||||
|
{
|
||||||
|
osi_Log1(afsd_logp, "GetNewSCache scp 0x%p; LRU order changed", scp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} /* for */
|
} /* for */
|
||||||
|
|
||||||
osi_Log2(afsd_logp, "GetNewSCache all scache entries in use (attempt = %d, count = %u)", attempt, count);
|
osi_Log2(afsd_logp, "GetNewSCache all scache entries in use (attempt = %d, count = %u)", attempt, count);
|
||||||
|
if (scp == NULL) {
|
||||||
|
/*
|
||||||
|
* The entire LRU queue was walked and no available cm_scache_t was
|
||||||
|
* found. Drop the cm_scacheLock and sleep for a moment to give a
|
||||||
|
* chance for cm_scache_t objects to be released.
|
||||||
|
*/
|
||||||
|
lock_ReleaseWrite(&cm_scacheLock);
|
||||||
|
Sleep(50);
|
||||||
|
lock_ObtainWrite(&cm_scacheLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* FAILURE */
|
/* FAILURE */
|
||||||
scp = NULL;
|
scp = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user