afs: Avoid needless W-locks for afs_FindVCache 56/12656/4
authorAndrew Deason <adeason@sinenomine.net>
Thu, 13 Jul 2017 22:40:36 +0000 (17:40 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 3 Jul 2020 01:46:45 +0000 (21:46 -0400)
The callers of afs_FindVCache must hold at least a read lock on
afs_xvcache; some hold a shared or write lock (and set IS_SLOCK or
IS_WLOCK in the given flags). Two callers (afs_EvalFakeStat_int and
afs_DoBulkStat) currently hold a write lock, but neither of them need
to.

In the optimal case, where afs_FindVCache finds the given vcache, this
means that we unnecessarily hold a write lock on afs_xvcache. This can
impact performance, since afs_xvcache can be a very frequently
accessed lock (a simple operation like afs_PutVCache briefly holds a
read lock, for example).

To avoid this, have afs_DoBulkStat hold a shared lock on afs_xvcache,
upgrading to a write lock when needed. afs_EvalFakeStat_int doesn't
ever need a write lock at all, so just convert it to a read lock.

Change-Id: I5bd58b9e3a577c9e1ebf1bc3719e65a6c0af5cb8
Reviewed-on: https://gerrit.openafs.org/12656
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/VNOPS/afs_vnop_lookup.c

index 887ff05..2f26b70 100644 (file)
@@ -377,14 +377,14 @@ afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state,
 
            do {
                retry = 0;
-               ObtainWriteLock(&afs_xvcache, 597);
-               root_vp = afs_FindVCache(tvc->mvid.target_root, &retry, IS_WLOCK);
+               ObtainReadLock(&afs_xvcache);
+               root_vp = afs_FindVCache(tvc->mvid.target_root, &retry, 0);
                if (root_vp && retry) {
-                   ReleaseWriteLock(&afs_xvcache);
+                   ReleaseReadLock(&afs_xvcache);
                    afs_PutVCache(root_vp);
                }
            } while (root_vp && retry);
-           ReleaseWriteLock(&afs_xvcache);
+           ReleaseReadLock(&afs_xvcache);
        } else {
            root_vp = afs_GetVCache(tvc->mvid.target_root, areq);
        }
@@ -821,14 +821,15 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
            tfid.Fid.Unique = ntohl(dirEntryp->fid.vunique);
            do {
                retry = 0;
-               ObtainWriteLock(&afs_xvcache, 130);
-               tvcp = afs_FindVCache(&tfid, &retry, IS_WLOCK /* no stats | LRU */ );
+               ObtainSharedLock(&afs_xvcache, 130);
+               tvcp = afs_FindVCache(&tfid, &retry, IS_SLOCK /* no stats | LRU */ );
                if (tvcp && retry) {
-                   ReleaseWriteLock(&afs_xvcache);
+                   ReleaseSharedLock(&afs_xvcache);
                    afs_PutVCache(tvcp);
                }
            } while (tvcp && retry);
            if (!tvcp) {        /* otherwise, create manually */
+               UpgradeSToWLock(&afs_xvcache, 129);
                tvcp = afs_NewBulkVCache(&tfid, hostp, statSeqNo);
                if (tvcp)
                {
@@ -852,7 +853,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
                    ReleaseWriteLock(&afs_xvcache);
                }
            } else {
-               ReleaseWriteLock(&afs_xvcache);
+               ReleaseSharedLock(&afs_xvcache);
            }
            if (!tvcp)
            {