diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/auth.c | 44 |
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 = { | |||
80 | module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); | 80 | module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); |
81 | MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); | 81 | MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); |
82 | 82 | ||
83 | static unsigned long auth_max_cred_cachesize = ULONG_MAX; | ||
84 | module_param(auth_max_cred_cachesize, ulong, 0644); | ||
85 | MODULE_PARM_DESC(auth_max_cred_cachesize, "RPC credential maximum total cache size"); | ||
86 | |||
83 | static u32 | 87 | static u32 |
84 | pseudoflavor_to_flavor(u32 flavor) { | 88 | pseudoflavor_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 | ||
488 | static unsigned long | ||
489 | rpcauth_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 | |||
488 | rpcauth_cache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | 506 | rpcauth_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 | ||
509 | static unsigned long | 519 | static 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 | ||
526 | static void | ||
527 | rpcauth_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(); | ||
569 | found: | 595 | found: |
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 && |