aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
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 &&