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>
This commit is contained in:
parent
988664a0f6
commit
241269bd0b
2 changed files with 56 additions and 13 deletions
|
@ -61,14 +61,7 @@ struct rpc_cred {
|
||||||
/*
|
/*
|
||||||
* Client authentication handle
|
* Client authentication handle
|
||||||
*/
|
*/
|
||||||
#define RPC_CREDCACHE_HASHBITS 4
|
struct rpc_cred_cache;
|
||||||
#define RPC_CREDCACHE_NR (1 << RPC_CREDCACHE_HASHBITS)
|
|
||||||
struct rpc_cred_cache {
|
|
||||||
struct hlist_head hashtable[RPC_CREDCACHE_NR];
|
|
||||||
unsigned int hashbits;
|
|
||||||
spinlock_t lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rpc_authops;
|
struct rpc_authops;
|
||||||
struct rpc_auth {
|
struct rpc_auth {
|
||||||
unsigned int au_cslack; /* call cred size estimate */
|
unsigned int au_cslack; /* call cred size estimate */
|
||||||
|
|
|
@ -19,6 +19,15 @@
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RPC_CREDCACHE_DEFAULT_HASHBITS (4)
|
||||||
|
struct rpc_cred_cache {
|
||||||
|
struct hlist_head *hashtable;
|
||||||
|
unsigned int hashbits;
|
||||||
|
spinlock_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int auth_hashbits = RPC_CREDCACHE_DEFAULT_HASHBITS;
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(rpc_authflavor_lock);
|
static DEFINE_SPINLOCK(rpc_authflavor_lock);
|
||||||
static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
|
static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
|
||||||
&authnull_ops, /* AUTH_NULL */
|
&authnull_ops, /* AUTH_NULL */
|
||||||
|
@ -29,6 +38,42 @@ static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
|
||||||
static LIST_HEAD(cred_unused);
|
static LIST_HEAD(cred_unused);
|
||||||
static unsigned long number_cred_unused;
|
static unsigned long number_cred_unused;
|
||||||
|
|
||||||
|
#define MAX_HASHTABLE_BITS (10)
|
||||||
|
static int param_set_hashtbl_sz(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
unsigned long num;
|
||||||
|
unsigned int nbits;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!val)
|
||||||
|
goto out_inval;
|
||||||
|
ret = strict_strtoul(val, 0, &num);
|
||||||
|
if (ret == -EINVAL)
|
||||||
|
goto out_inval;
|
||||||
|
nbits = fls(num);
|
||||||
|
if (num > (1U << nbits))
|
||||||
|
nbits++;
|
||||||
|
if (nbits > MAX_HASHTABLE_BITS || nbits < 2)
|
||||||
|
goto out_inval;
|
||||||
|
*(unsigned int *)kp->arg = nbits;
|
||||||
|
return 0;
|
||||||
|
out_inval:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int param_get_hashtbl_sz(char *buffer, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
unsigned int nbits;
|
||||||
|
|
||||||
|
nbits = *(unsigned int *)kp->arg;
|
||||||
|
return sprintf(buffer, "%u", 1U << nbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int);
|
||||||
|
|
||||||
|
module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644);
|
||||||
|
MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
pseudoflavor_to_flavor(u32 flavor) {
|
pseudoflavor_to_flavor(u32 flavor) {
|
||||||
if (flavor >= RPC_AUTH_MAXFLAVOR)
|
if (flavor >= RPC_AUTH_MAXFLAVOR)
|
||||||
|
@ -146,18 +191,22 @@ rpcauth_init_credcache(struct rpc_auth *auth)
|
||||||
{
|
{
|
||||||
struct rpc_cred_cache *new;
|
struct rpc_cred_cache *new;
|
||||||
unsigned int hashsize;
|
unsigned int hashsize;
|
||||||
int i;
|
|
||||||
|
|
||||||
new = kmalloc(sizeof(*new), GFP_KERNEL);
|
new = kmalloc(sizeof(*new), GFP_KERNEL);
|
||||||
if (!new)
|
if (!new)
|
||||||
return -ENOMEM;
|
goto out_nocache;
|
||||||
new->hashbits = RPC_CREDCACHE_HASHBITS;
|
new->hashbits = auth_hashbits;
|
||||||
hashsize = 1U << new->hashbits;
|
hashsize = 1U << new->hashbits;
|
||||||
for (i = 0; i < hashsize; i++)
|
new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL);
|
||||||
INIT_HLIST_HEAD(&new->hashtable[i]);
|
if (!new->hashtable)
|
||||||
|
goto out_nohashtbl;
|
||||||
spin_lock_init(&new->lock);
|
spin_lock_init(&new->lock);
|
||||||
auth->au_credcache = new;
|
auth->au_credcache = new;
|
||||||
return 0;
|
return 0;
|
||||||
|
out_nohashtbl:
|
||||||
|
kfree(new);
|
||||||
|
out_nocache:
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpcauth_init_credcache);
|
EXPORT_SYMBOL_GPL(rpcauth_init_credcache);
|
||||||
|
|
||||||
|
@ -220,6 +269,7 @@ rpcauth_destroy_credcache(struct rpc_auth *auth)
|
||||||
if (cache) {
|
if (cache) {
|
||||||
auth->au_credcache = NULL;
|
auth->au_credcache = NULL;
|
||||||
rpcauth_clear_credcache(cache);
|
rpcauth_clear_credcache(cache);
|
||||||
|
kfree(cache->hashtable);
|
||||||
kfree(cache);
|
kfree(cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue