aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2014-07-21 13:32:42 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-08-03 16:02:50 -0400
commitbae6746ff356478e1a2706072edbfb514072e0ff (patch)
treefbe396fc71f04c0684033be3a0b24db349d150a8 /net
parente655f945cd7ba2a8360ddd5462ca535a3b41e07e (diff)
SUNRPC: Enforce an upper limit on the number of cached credentials
In some cases where the credentials are not often reused, we may want to limit their total number just in order to make the negative lookups in the hash table more manageable. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 2bc7bb82b162..360decdddc78 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -80,6 +80,10 @@ static struct kernel_param_ops param_ops_hashtbl_sz = {
80module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); 80module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644);
81MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); 81MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
82 82
83static unsigned long auth_max_cred_cachesize = ULONG_MAX;
84module_param(auth_max_cred_cachesize, ulong, 0644);
85MODULE_PARM_DESC(auth_max_cred_cachesize, "RPC credential maximum total cache size");
86
83static u32 87static u32
84pseudoflavor_to_flavor(u32 flavor) { 88pseudoflavor_to_flavor(u32 flavor) {
85 if (flavor > RPC_AUTH_MAXFLAVOR) 89 if (flavor > RPC_AUTH_MAXFLAVOR)
@@ -481,6 +485,20 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
481 return freed; 485 return freed;
482} 486}
483 487
488static unsigned long
489rpcauth_cache_do_shrink(int nr_to_scan)
490{
491 LIST_HEAD(free);
492 unsigned long freed;
493
494 spin_lock(&rpc_credcache_lock);
495 freed = rpcauth_prune_expired(&free, nr_to_scan);
496 spin_unlock(&rpc_credcache_lock);
497 rpcauth_destroy_credlist(&free);
498
499 return freed;
500}
501
484/* 502/*
485 * Run memory cache shrinker. 503 * Run memory cache shrinker.
486 */ 504 */
@@ -488,9 +506,6 @@ static unsigned long
488rpcauth_cache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) 506rpcauth_cache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
489 507
490{ 508{
491 LIST_HEAD(free);
492 unsigned long freed;
493
494 if ((sc->gfp_mask & GFP_KERNEL) != GFP_KERNEL) 509 if ((sc->gfp_mask & GFP_KERNEL) != GFP_KERNEL)
495 return SHRINK_STOP; 510 return SHRINK_STOP;
496 511
@@ -498,12 +513,7 @@ rpcauth_cache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
498 if (list_empty(&cred_unused)) 513 if (list_empty(&cred_unused))
499 return SHRINK_STOP; 514 return SHRINK_STOP;
500 515
501 spin_lock(&rpc_credcache_lock); 516 return rpcauth_cache_do_shrink(sc->nr_to_scan);
502 freed = rpcauth_prune_expired(&free, sc->nr_to_scan);
503 spin_unlock(&rpc_credcache_lock);
504 rpcauth_destroy_credlist(&free);
505
506 return freed;
507} 517}
508 518
509static unsigned long 519static unsigned long
@@ -513,6 +523,21 @@ rpcauth_cache_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
513 return (number_cred_unused / 100) * sysctl_vfs_cache_pressure; 523 return (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
514} 524}
515 525
526static void
527rpcauth_cache_enforce_limit(void)
528{
529 unsigned long diff;
530 unsigned int nr_to_scan;
531
532 if (number_cred_unused <= auth_max_cred_cachesize)
533 return;
534 diff = number_cred_unused - auth_max_cred_cachesize;
535 nr_to_scan = 100;
536 if (diff < nr_to_scan)
537 nr_to_scan = diff;
538 rpcauth_cache_do_shrink(nr_to_scan);
539}
540
516/* 541/*
517 * Look up a process' credentials in the authentication cache 542 * Look up a process' credentials in the authentication cache
518 */ 543 */
@@ -566,6 +591,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
566 } else 591 } else
567 list_add_tail(&new->cr_lru, &free); 592 list_add_tail(&new->cr_lru, &free);
568 spin_unlock(&cache->lock); 593 spin_unlock(&cache->lock);
594 rpcauth_cache_enforce_limit();
569found: 595found:
570 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && 596 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
571 cred->cr_ops->cr_init != NULL && 597 cred->cr_ops->cr_init != NULL &&