SUNRPC: Ensure memory shrinker doesn't waste time in rpcauth_prune_expired()
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 13 May 2010 16:51:06 +0000 (12:51 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 14 May 2010 19:09:34 +0000 (15:09 -0400)
The 'cred_unused' list, that is traversed by rpcauth_cache_shrinker is
ordered by time. If we hit a credential that is under the 60 second garbage
collection moratorium, we should exit because we know at that point that
all successive credentials are subject to the same moratorium...

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/auth.c

index 0667a36aee7878c176f3c21d74305080305e0dc6..c40856f589f03f0583ada299251f56c61dd9cb30 100644 (file)
@@ -236,10 +236,13 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
 
        list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) {
 
-               /* Enforce a 60 second garbage collection moratorium */
+               /*
+                * Enforce a 60 second garbage collection moratorium
+                * Note that the cred_unused list must be time-ordered.
+                */
                if (time_in_range(cred->cr_expire, expired, jiffies) &&
                    test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
-                       continue;
+                       return 0;
 
                list_del_init(&cred->cr_lru);
                number_cred_unused--;
@@ -258,7 +261,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
                if (nr_to_scan == 0)
                        break;
        }
-       return nr_to_scan;
+       return (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
 }
 
 /*
@@ -275,8 +278,7 @@ rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
        if (list_empty(&cred_unused))
                return 0;
        spin_lock(&rpc_credcache_lock);
-       nr_to_scan = rpcauth_prune_expired(&free, nr_to_scan);
-       res = (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
+       res = rpcauth_prune_expired(&free, nr_to_scan);
        spin_unlock(&rpc_credcache_lock);
        rpcauth_destroy_credlist(&free);
        return res;