Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SUNRPC: Make the credential cache hashtable size configurable

This patch allows the user to configure the credential cache hashtable size
using a new module parameter: auth_hashtable_size
When set, this parameter will be rounded up to the nearest power of two,
with a maximum allowed value of 1024 elements.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

+56 -13
+1 -8
include/linux/sunrpc/auth.h
··· 61 61 /* 62 62 * Client authentication handle 63 63 */ 64 - #define RPC_CREDCACHE_HASHBITS 4 65 - #define RPC_CREDCACHE_NR (1 << RPC_CREDCACHE_HASHBITS) 66 - struct rpc_cred_cache { 67 - struct hlist_head hashtable[RPC_CREDCACHE_NR]; 68 - unsigned int hashbits; 69 - spinlock_t lock; 70 - }; 71 - 64 + struct rpc_cred_cache; 72 65 struct rpc_authops; 73 66 struct rpc_auth { 74 67 unsigned int au_cslack; /* call cred size estimate */
+55 -5
net/sunrpc/auth.c
··· 19 19 # define RPCDBG_FACILITY RPCDBG_AUTH 20 20 #endif 21 21 22 + #define RPC_CREDCACHE_DEFAULT_HASHBITS (4) 23 + struct rpc_cred_cache { 24 + struct hlist_head *hashtable; 25 + unsigned int hashbits; 26 + spinlock_t lock; 27 + }; 28 + 29 + static unsigned int auth_hashbits = RPC_CREDCACHE_DEFAULT_HASHBITS; 30 + 22 31 static DEFINE_SPINLOCK(rpc_authflavor_lock); 23 32 static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { 24 33 &authnull_ops, /* AUTH_NULL */ ··· 37 28 38 29 static LIST_HEAD(cred_unused); 39 30 static unsigned long number_cred_unused; 31 + 32 + #define MAX_HASHTABLE_BITS (10) 33 + static int param_set_hashtbl_sz(const char *val, struct kernel_param *kp) 34 + { 35 + unsigned long num; 36 + unsigned int nbits; 37 + int ret; 38 + 39 + if (!val) 40 + goto out_inval; 41 + ret = strict_strtoul(val, 0, &num); 42 + if (ret == -EINVAL) 43 + goto out_inval; 44 + nbits = fls(num); 45 + if (num > (1U << nbits)) 46 + nbits++; 47 + if (nbits > MAX_HASHTABLE_BITS || nbits < 2) 48 + goto out_inval; 49 + *(unsigned int *)kp->arg = nbits; 50 + return 0; 51 + out_inval: 52 + return -EINVAL; 53 + } 54 + 55 + static int param_get_hashtbl_sz(char *buffer, struct kernel_param *kp) 56 + { 57 + unsigned int nbits; 58 + 59 + nbits = *(unsigned int *)kp->arg; 60 + return sprintf(buffer, "%u", 1U << nbits); 61 + } 62 + 63 + #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int); 64 + 65 + module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); 66 + MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); 40 67 41 68 static u32 42 69 pseudoflavor_to_flavor(u32 flavor) { ··· 191 146 { 192 147 struct rpc_cred_cache *new; 193 148 unsigned int hashsize; 194 - int i; 195 149 196 150 new = kmalloc(sizeof(*new), GFP_KERNEL); 197 151 if (!new) 198 - return -ENOMEM; 199 - new->hashbits = RPC_CREDCACHE_HASHBITS; 152 + goto out_nocache; 153 + new->hashbits = auth_hashbits; 200 154 hashsize = 1U << new->hashbits; 201 - for (i = 0; i < hashsize; i++) 202 - INIT_HLIST_HEAD(&new->hashtable[i]); 155 + new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL); 156 + if (!new->hashtable) 157 + goto out_nohashtbl; 203 158 spin_lock_init(&new->lock); 204 159 auth->au_credcache = new; 205 160 return 0; 161 + out_nohashtbl: 162 + kfree(new); 163 + out_nocache: 164 + return -ENOMEM; 206 165 } 207 166 EXPORT_SYMBOL_GPL(rpcauth_init_credcache); 208 167 ··· 269 220 if (cache) { 270 221 auth->au_credcache = NULL; 271 222 rpcauth_clear_credcache(cache); 223 + kfree(cache->hashtable); 272 224 kfree(cache); 273 225 } 274 226 }