* [PATCH 0/6] NFSv4 backchannel improvements
@ 2016-08-30 0:03 Trond Myklebust
2016-08-30 0:03 ` [PATCH 1/6] NFSv4.x: Fix a refcount leak in nfs_callback_up_net Trond Myklebust
0 siblings, 1 reply; 7+ messages in thread
From: Trond Myklebust @ 2016-08-30 0:03 UTC (permalink / raw)
To: linux-nfs
Add functionality to allow multiple client backchannel threads and
allow tuning of the advertised backchannel slot table size.
Note: the very first patch is actually a fix for an existing Oopsable
condition, and so should probably be pushed into Linux 4.8...
Trond Myklebust (6):
NFSv4.x: Fix a refcount leak in nfs_callback_up_net
NFSv4.x: Set up struct svc_serv_ops for the callback channel
SUNRPC: Initialise struct svc_serv backchannel fields during
__svc_create()
NFSv4.x: Fix up the global tracking of the callback server
NFSv4.x: Switch to using svc_set_num_threads() to manage the callback
threads
NFSv4.x: Add kernel parameter to control the callback server
Documentation/kernel-parameters.txt | 12 ++++
fs/nfs/callback.c | 137 +++++++++++++++---------------------
fs/nfs/callback.h | 3 +
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4proc.c | 7 +-
fs/nfs/nfs4session.h | 1 +
fs/nfs/super.c | 10 +++
net/sunrpc/svc.c | 17 +++++
8 files changed, 102 insertions(+), 86 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/6] NFSv4.x: Fix a refcount leak in nfs_callback_up_net 2016-08-30 0:03 [PATCH 0/6] NFSv4 backchannel improvements Trond Myklebust @ 2016-08-30 0:03 ` Trond Myklebust 2016-08-30 0:03 ` [PATCH 2/6] NFSv4.x: Set up struct svc_serv_ops for the callback channel Trond Myklebust 0 siblings, 1 reply; 7+ messages in thread From: Trond Myklebust @ 2016-08-30 0:03 UTC (permalink / raw) To: linux-nfs On error, the callers expect us to return without bumping nn->cb_users[]. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Cc: stable@vger.kernel.org # v3.7+ --- fs/nfs/callback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index a7f2e6e33305..52a28311e2a4 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -275,6 +275,7 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, err_socks: svc_rpcb_cleanup(serv, net); err_bind: + nn->cb_users[minorversion]--; dprintk("NFS: Couldn't create callback socket: err = %d; " "net = %p\n", ret, net); return ret; -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/6] NFSv4.x: Set up struct svc_serv_ops for the callback channel 2016-08-30 0:03 ` [PATCH 1/6] NFSv4.x: Fix a refcount leak in nfs_callback_up_net Trond Myklebust @ 2016-08-30 0:03 ` Trond Myklebust 2016-08-30 0:03 ` [PATCH 3/6] SUNRPC: Initialise struct svc_serv backchannel fields during __svc_create() Trond Myklebust 0 siblings, 1 reply; 7+ messages in thread From: Trond Myklebust @ 2016-08-30 0:03 UTC (permalink / raw) To: linux-nfs In order to manage the threads using svc_set_num_threads, we need to fill in a few extra fields. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/callback.c | 57 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 52a28311e2a4..478bb0a7effe 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -155,13 +155,6 @@ nfs41_callback_up(struct svc_serv *serv) return rqstp; } -static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv, - struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp)) -{ - *rqstpp = nfs41_callback_up(serv); - *callback_svc = nfs41_callback_svc; -} - static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, struct svc_serv *serv) { @@ -173,11 +166,10 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, xprt->bc_serv = serv; } #else -static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv, - struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp)) +static struct svc_rqst * +nfs41_callback_up(struct svc_serv *serv) { - *rqstpp = ERR_PTR(-ENOTSUPP); - *callback_svc = ERR_PTR(-ENOTSUPP); + return ERR_PTR(-ENOTSUPP); } static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, @@ -190,7 +182,6 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, struct svc_serv *serv) { struct svc_rqst *rqstp; - int (*callback_svc)(void *vrqstp); struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; int ret; @@ -203,11 +194,9 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, case 0: /* v4.0 callback setup */ rqstp = nfs4_callback_up(serv); - callback_svc = nfs4_callback_svc; break; default: - nfs_minorversion_callback_svc_setup(serv, - &rqstp, &callback_svc); + rqstp = nfs41_callback_up(serv); } if (IS_ERR(rqstp)) @@ -217,7 +206,8 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, cb_info->serv = serv; cb_info->rqst = rqstp; - cb_info->task = kthread_create(callback_svc, cb_info->rqst, + cb_info->task = kthread_create(serv->sv_ops->svo_function, + cb_info->rqst, "nfsv4.%u-svc", minorversion); if (IS_ERR(cb_info->task)) { ret = PTR_ERR(cb_info->task); @@ -281,14 +271,34 @@ err_bind: return ret; } -static struct svc_serv_ops nfs_cb_sv_ops = { +static struct svc_serv_ops nfs40_cb_sv_ops = { + .svo_function = nfs4_callback_svc, .svo_enqueue_xprt = svc_xprt_do_enqueue, + .svo_module = THIS_MODULE, +}; +#if defined(CONFIG_NFS_V4_1) +static struct svc_serv_ops nfs41_cb_sv_ops = { + .svo_function = nfs41_callback_svc, + .svo_enqueue_xprt = svc_xprt_do_enqueue, + .svo_module = THIS_MODULE, }; +struct svc_serv_ops *nfs4_cb_sv_ops[] = { + [0] = &nfs40_cb_sv_ops, + [1] = &nfs41_cb_sv_ops, +}; +#else +struct svc_serv_ops *nfs4_cb_sv_ops[] = { + [0] = &nfs40_cb_sv_ops, + [1] = NULL, +}; +#endif + static struct svc_serv *nfs_callback_create_svc(int minorversion) { struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; struct svc_serv *serv; + struct svc_serv_ops *sv_ops; /* * Check whether we're already up and running. @@ -302,6 +312,17 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion) return cb_info->serv; } + switch (minorversion) { + case 0: + sv_ops = nfs4_cb_sv_ops[0]; + break; + default: + sv_ops = nfs4_cb_sv_ops[1]; + } + + if (sv_ops == NULL) + return ERR_PTR(-ENOTSUPP); + /* * Sanity check: if there's no task, * we should be the first user ... @@ -310,7 +331,7 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion) printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n", cb_info->users); - serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, &nfs_cb_sv_ops); + serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops); if (!serv) { printk(KERN_ERR "nfs_callback_create_svc: create service failed\n"); return ERR_PTR(-ENOMEM); -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/6] SUNRPC: Initialise struct svc_serv backchannel fields during __svc_create() 2016-08-30 0:03 ` [PATCH 2/6] NFSv4.x: Set up struct svc_serv_ops for the callback channel Trond Myklebust @ 2016-08-30 0:03 ` Trond Myklebust 2016-08-30 0:03 ` [PATCH 4/6] NFSv4.x: Fix up the global tracking of the callback server Trond Myklebust 0 siblings, 1 reply; 7+ messages in thread From: Trond Myklebust @ 2016-08-30 0:03 UTC (permalink / raw) To: linux-nfs Clean up. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/callback.c | 3 --- net/sunrpc/svc.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 478bb0a7effe..08e16f9b3333 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -147,9 +147,6 @@ nfs41_callback_up(struct svc_serv *serv) { struct svc_rqst *rqstp; - INIT_LIST_HEAD(&serv->sv_cb_list); - spin_lock_init(&serv->sv_cb_lock); - init_waitqueue_head(&serv->sv_cb_waitq); rqstp = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); dprintk("--> %s return %d\n", __func__, PTR_ERR_OR_ZERO(rqstp)); return rqstp; diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index c5b0cb4f4056..7c8070ec93c8 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -401,6 +401,21 @@ int svc_bind(struct svc_serv *serv, struct net *net) } EXPORT_SYMBOL_GPL(svc_bind); +#if defined(CONFIG_SUNRPC_BACKCHANNEL) +static void +__svc_init_bc(struct svc_serv *serv) +{ + INIT_LIST_HEAD(&serv->sv_cb_list); + spin_lock_init(&serv->sv_cb_lock); + init_waitqueue_head(&serv->sv_cb_waitq); +} +#else +static void +__svc_init_bc(struct svc_serv *serv) +{ +} +#endif + /* * Create an RPC service */ @@ -443,6 +458,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, init_timer(&serv->sv_temptimer); spin_lock_init(&serv->sv_lock); + __svc_init_bc(serv); + serv->sv_nrpools = npools; serv->sv_pools = kcalloc(serv->sv_nrpools, sizeof(struct svc_pool), -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/6] NFSv4.x: Fix up the global tracking of the callback server 2016-08-30 0:03 ` [PATCH 3/6] SUNRPC: Initialise struct svc_serv backchannel fields during __svc_create() Trond Myklebust @ 2016-08-30 0:03 ` Trond Myklebust 2016-08-30 0:03 ` [PATCH 5/6] NFSv4.x: Switch to using svc_set_num_threads() to manage the callback threads Trond Myklebust 0 siblings, 1 reply; 7+ messages in thread From: Trond Myklebust @ 2016-08-30 0:03 UTC (permalink / raw) To: linux-nfs Ensure that the nfs_callback_info[] array correctly tracks the struct svc_serv. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/callback.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 08e16f9b3333..b125f02ddf8b 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -201,7 +201,6 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, svc_sock_update_bufs(serv); - cb_info->serv = serv; cb_info->rqst = rqstp; cb_info->task = kthread_create(serv->sv_ops->svo_function, cb_info->rqst, @@ -300,7 +299,7 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion) /* * Check whether we're already up and running. */ - if (cb_info->task) { + if (cb_info->serv) { /* * Note: increase service usage, because later in case of error * svc_destroy() will be called. @@ -333,6 +332,7 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion) printk(KERN_ERR "nfs_callback_create_svc: create service failed\n"); return ERR_PTR(-ENOMEM); } + cb_info->serv = serv; /* As there is only one thread we need to over-ride the * default maximum of 80 connections */ @@ -375,6 +375,8 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) * thread exits. */ err_net: + if (!cb_info->users) + cb_info->serv = NULL; svc_destroy(serv); err_create: mutex_unlock(&nfs_callback_mutex); @@ -396,9 +398,11 @@ void nfs_callback_down(int minorversion, struct net *net) mutex_lock(&nfs_callback_mutex); nfs_callback_down_net(minorversion, cb_info->serv, net); cb_info->users--; - if (cb_info->users == 0 && cb_info->task != NULL) { - kthread_stop(cb_info->task); - dprintk("nfs_callback_down: service stopped\n"); + if (cb_info->users == 0) { + if (cb_info->task != NULL) { + kthread_stop(cb_info->task); + dprintk("nfs_callback_down: service stopped\n"); + } svc_exit_thread(cb_info->rqst); dprintk("nfs_callback_down: service destroyed\n"); cb_info->serv = NULL; -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/6] NFSv4.x: Switch to using svc_set_num_threads() to manage the callback threads 2016-08-30 0:03 ` [PATCH 4/6] NFSv4.x: Fix up the global tracking of the callback server Trond Myklebust @ 2016-08-30 0:03 ` Trond Myklebust 2016-08-30 0:03 ` [PATCH 6/6] NFSv4.x: Add kernel parameter to control the callback server Trond Myklebust 0 siblings, 1 reply; 7+ messages in thread From: Trond Myklebust @ 2016-08-30 0:03 UTC (permalink / raw) To: linux-nfs This will allow us to bump the number of callback threads at will. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/callback.c | 79 +++++++++---------------------------------------------- fs/nfs/callback.h | 2 ++ 2 files changed, 15 insertions(+), 66 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index b125f02ddf8b..b91c49f4670b 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -31,8 +31,6 @@ struct nfs_callback_data { unsigned int users; struct svc_serv *serv; - struct svc_rqst *rqst; - struct task_struct *task; }; static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1]; @@ -89,15 +87,6 @@ nfs4_callback_svc(void *vrqstp) return 0; } -/* - * Prepare to bring up the NFSv4 callback service - */ -static struct svc_rqst * -nfs4_callback_up(struct svc_serv *serv) -{ - return svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); -} - #if defined(CONFIG_NFS_V4_1) /* * The callback service for NFSv4.1 callbacks @@ -139,19 +128,6 @@ nfs41_callback_svc(void *vrqstp) return 0; } -/* - * Bring up the NFSv4.1 callback service - */ -static struct svc_rqst * -nfs41_callback_up(struct svc_serv *serv) -{ - struct svc_rqst *rqstp; - - rqstp = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); - dprintk("--> %s return %d\n", __func__, PTR_ERR_OR_ZERO(rqstp)); - return rqstp; -} - static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, struct svc_serv *serv) { @@ -163,12 +139,6 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, xprt->bc_serv = serv; } #else -static struct svc_rqst * -nfs41_callback_up(struct svc_serv *serv) -{ - return ERR_PTR(-ENOTSUPP); -} - static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, struct svc_serv *serv) { @@ -178,42 +148,19 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, struct svc_serv *serv) { - struct svc_rqst *rqstp; - struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; + const int nrservs = NFS4_NR_CALLBACK_THREADS; int ret; nfs_callback_bc_serv(minorversion, xprt, serv); - if (cb_info->task) + if (serv->sv_nrthreads-1 == nrservs) return 0; - switch (minorversion) { - case 0: - /* v4.0 callback setup */ - rqstp = nfs4_callback_up(serv); - break; - default: - rqstp = nfs41_callback_up(serv); - } - - if (IS_ERR(rqstp)) - return PTR_ERR(rqstp); - - svc_sock_update_bufs(serv); - - cb_info->rqst = rqstp; - cb_info->task = kthread_create(serv->sv_ops->svo_function, - cb_info->rqst, - "nfsv4.%u-svc", minorversion); - if (IS_ERR(cb_info->task)) { - ret = PTR_ERR(cb_info->task); - svc_exit_thread(cb_info->rqst); - cb_info->rqst = NULL; - cb_info->task = NULL; + ret = serv->sv_ops->svo_setup(serv, NULL, nrservs); + if (ret) { + serv->sv_ops->svo_setup(serv, NULL, 0); return ret; } - rqstp->rq_task = cb_info->task; - wake_up_process(cb_info->task); dprintk("nfs_callback_up: service started\n"); return 0; } @@ -270,12 +217,14 @@ err_bind: static struct svc_serv_ops nfs40_cb_sv_ops = { .svo_function = nfs4_callback_svc, .svo_enqueue_xprt = svc_xprt_do_enqueue, + .svo_setup = svc_set_num_threads, .svo_module = THIS_MODULE, }; #if defined(CONFIG_NFS_V4_1) static struct svc_serv_ops nfs41_cb_sv_ops = { .svo_function = nfs41_callback_svc, .svo_enqueue_xprt = svc_xprt_do_enqueue, + .svo_setup = svc_set_num_threads, .svo_module = THIS_MODULE, }; @@ -394,20 +343,18 @@ err_start: void nfs_callback_down(int minorversion, struct net *net) { struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; + struct svc_serv *serv; mutex_lock(&nfs_callback_mutex); - nfs_callback_down_net(minorversion, cb_info->serv, net); + serv = cb_info->serv; + nfs_callback_down_net(minorversion, serv, net); cb_info->users--; if (cb_info->users == 0) { - if (cb_info->task != NULL) { - kthread_stop(cb_info->task); - dprintk("nfs_callback_down: service stopped\n"); - } - svc_exit_thread(cb_info->rqst); + svc_get(serv); + serv->sv_ops->svo_setup(serv, NULL, 0); + svc_destroy(serv); dprintk("nfs_callback_down: service destroyed\n"); cb_info->serv = NULL; - cb_info->rqst = NULL; - cb_info->task = NULL; } mutex_unlock(&nfs_callback_mutex); } diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index 5fe1cecbf9f0..14bd863495db 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -198,6 +198,8 @@ extern void nfs_callback_down(int minorversion, struct net *net); #define NFS41_BC_MIN_CALLBACKS 1 #define NFS41_BC_MAX_CALLBACKS 1 +#define NFS4_NR_CALLBACK_THREADS 1 + extern unsigned int nfs_callback_set_tcpport; #endif /* __LINUX_FS_NFS_CALLBACK_H */ -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6/6] NFSv4.x: Add kernel parameter to control the callback server 2016-08-30 0:03 ` [PATCH 5/6] NFSv4.x: Switch to using svc_set_num_threads() to manage the callback threads Trond Myklebust @ 2016-08-30 0:03 ` Trond Myklebust 0 siblings, 0 replies; 7+ messages in thread From: Trond Myklebust @ 2016-08-30 0:03 UTC (permalink / raw) To: linux-nfs Add support for the kernel parameter nfs.callback_nr_threads to set the number of threads that will be assigned to the callback channel. Add support for the kernel parameter nfs.nfs.max_session_cb_slots to set the maximum size of the callback channel slot table. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- Documentation/kernel-parameters.txt | 12 ++++++++++++ fs/nfs/callback.c | 5 ++++- fs/nfs/callback.h | 3 ++- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4proc.c | 7 +++---- fs/nfs/nfs4session.h | 1 + fs/nfs/super.c | 10 ++++++++++ 7 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 46c030a49186..679879384b68 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2420,6 +2420,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. nfsrootdebug [NFS] enable nfsroot debugging messages. See Documentation/filesystems/nfs/nfsroot.txt. + nfs.callback_nr_threads= + [NFSv4] set the total number of threads that the + NFS client will assign to service NFSv4 callback + requests. + nfs.callback_tcpport= [NFS] set the TCP port on which the NFSv4 callback channel should listen. @@ -2443,6 +2448,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. of returning the full 64-bit number. The default is to return 64-bit inode numbers. + nfs.max_session_cb_slots= + [NFSv4.1] Sets the maximum number of session + slots the client will assign to the callback + channel. This determines the maximum number of + callbacks the client will process in parallel for + a particular server. + nfs.max_session_slots= [NFSv4.1] Sets the maximum number of session slots the client will attempt to negotiate with the server. diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index b91c49f4670b..532d8e242d4d 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -148,11 +148,14 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, struct svc_serv *serv) { - const int nrservs = NFS4_NR_CALLBACK_THREADS; + int nrservs = nfs_callback_nr_threads; int ret; nfs_callback_bc_serv(minorversion, xprt, serv); + if (nrservs < NFS4_MIN_NR_CALLBACK_THREADS) + nrservs = NFS4_MIN_NR_CALLBACK_THREADS; + if (serv->sv_nrthreads-1 == nrservs) return 0; diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index 14bd863495db..41ad65151ec8 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -198,8 +198,9 @@ extern void nfs_callback_down(int minorversion, struct net *net); #define NFS41_BC_MIN_CALLBACKS 1 #define NFS41_BC_MAX_CALLBACKS 1 -#define NFS4_NR_CALLBACK_THREADS 1 +#define NFS4_MIN_NR_CALLBACK_THREADS 1 extern unsigned int nfs_callback_set_tcpport; +extern unsigned short nfs_callback_nr_threads; #endif /* __LINUX_FS_NFS_CALLBACK_H */ diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 9bf64eacba5b..f230aa62ca59 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -471,6 +471,7 @@ extern struct nfs_subversion nfs_v4; struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *); extern bool nfs4_disable_idmapping; extern unsigned short max_session_slots; +extern unsigned short max_session_cb_slots; extern unsigned short send_implementation_id; extern bool recover_lost_locks; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f5aecaabcb7c..e924907cccef 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7463,7 +7463,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args, args->bc_attrs.max_resp_sz = max_bc_payload; args->bc_attrs.max_resp_sz_cached = 0; args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS; - args->bc_attrs.max_reqs = NFS41_BC_MAX_CALLBACKS; + args->bc_attrs.max_reqs = min_t(unsigned short, max_session_cb_slots, 1); dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u " "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n", @@ -7510,10 +7510,9 @@ static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args return -EINVAL; if (rcvd->max_resp_sz_cached > sent->max_resp_sz_cached) return -EINVAL; - /* These would render the backchannel useless: */ - if (rcvd->max_ops != sent->max_ops) + if (rcvd->max_ops > sent->max_ops) return -EINVAL; - if (rcvd->max_reqs != sent->max_reqs) + if (rcvd->max_reqs > sent->max_reqs) return -EINVAL; out: return 0; diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index f703b755351b..3bb6af70973c 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h @@ -9,6 +9,7 @@ /* maximum number of slots to use */ #define NFS4_DEF_SLOT_TABLE_SIZE (64U) +#define NFS4_DEF_CB_SLOT_TABLE_SIZE (1U) #define NFS4_MAX_SLOT_TABLE (1024U) #define NFS4_NO_SLOT ((u32)-1) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d39601381adf..001796bcd6c8 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2848,19 +2848,23 @@ out_invalid_transport_udp: * NFS client for backwards compatibility */ unsigned int nfs_callback_set_tcpport; +unsigned short nfs_callback_nr_threads; /* Default cache timeout is 10 minutes */ unsigned int nfs_idmap_cache_timeout = 600; /* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */ bool nfs4_disable_idmapping = true; unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE; +unsigned short max_session_cb_slots = NFS4_DEF_CB_SLOT_TABLE_SIZE; unsigned short send_implementation_id = 1; char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = ""; bool recover_lost_locks = false; +EXPORT_SYMBOL_GPL(nfs_callback_nr_threads); EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport); EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout); EXPORT_SYMBOL_GPL(nfs4_disable_idmapping); EXPORT_SYMBOL_GPL(max_session_slots); +EXPORT_SYMBOL_GPL(max_session_cb_slots); EXPORT_SYMBOL_GPL(send_implementation_id); EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier); EXPORT_SYMBOL_GPL(recover_lost_locks); @@ -2887,6 +2891,9 @@ static const struct kernel_param_ops param_ops_portnr = { #define param_check_portnr(name, p) __param_check(name, p, unsigned int); module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); +module_param_named(callback_nr_threads, nfs_callback_nr_threads, ushort, 0644); +MODULE_PARM_DESC(callback_nr_threads, "Number of threads that will be " + "assigned to the NFSv4 callback channels."); module_param(nfs_idmap_cache_timeout, int, 0644); module_param(nfs4_disable_idmapping, bool, 0644); module_param_string(nfs4_unique_id, nfs4_client_id_uniquifier, @@ -2896,6 +2903,9 @@ MODULE_PARM_DESC(nfs4_disable_idmapping, module_param(max_session_slots, ushort, 0644); MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 " "requests the client will negotiate"); +module_param(max_session_cb_slots, ushort, 0644); +MODULE_PARM_DESC(max_session_slots, "Maximum number of parallel NFSv4.1 " + "callbacks the client will process for a given server"); module_param(send_implementation_id, ushort, 0644); MODULE_PARM_DESC(send_implementation_id, "Send implementation ID with NFSv4.1 exchange_id"); -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-08-30 0:04 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-08-30 0:03 [PATCH 0/6] NFSv4 backchannel improvements Trond Myklebust 2016-08-30 0:03 ` [PATCH 1/6] NFSv4.x: Fix a refcount leak in nfs_callback_up_net Trond Myklebust 2016-08-30 0:03 ` [PATCH 2/6] NFSv4.x: Set up struct svc_serv_ops for the callback channel Trond Myklebust 2016-08-30 0:03 ` [PATCH 3/6] SUNRPC: Initialise struct svc_serv backchannel fields during __svc_create() Trond Myklebust 2016-08-30 0:03 ` [PATCH 4/6] NFSv4.x: Fix up the global tracking of the callback server Trond Myklebust 2016-08-30 0:03 ` [PATCH 5/6] NFSv4.x: Switch to using svc_set_num_threads() to manage the callback threads Trond Myklebust 2016-08-30 0:03 ` [PATCH 6/6] NFSv4.x: Add kernel parameter to control the callback server Trond Myklebust
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).