NFSv4.x: Add kernel parameter to control the callback server
authorTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 30 Aug 2016 00:03:52 +0000 (20:03 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Mon, 19 Sep 2016 17:08:36 +0000 (13:08 -0400)
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>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Documentation/kernel-parameters.txt
fs/nfs/callback.c
fs/nfs/callback.h
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nfs/nfs4session.h
fs/nfs/super.c

index a4f4d69..391dddd 100644 (file)
@@ -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.
index b91c49f..532d8e2 100644 (file)
@@ -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;
 
index 14bd863..41ad651 100644 (file)
@@ -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 */
index 9bf64ea..f230aa6 100644 (file)
@@ -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;
 
index a9dec32..251e48e 100644 (file)
@@ -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;
index f703b75..3bb6af7 100644 (file)
@@ -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)
 
index d396013..001796b 100644 (file)
@@ -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");