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 a4f4d693e2c1287d533c0bc05d9f292f9b529720..391ddddd6698c3898cceba090cba21d1c24a8b1d 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 b91c49f4670ba4389ac98d93396456a2d99c3fca..532d8e242d4d76c44413d6c814c7548094614ebe 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 14bd863495db00cc5ed689912c044f557e64ba3c..41ad65151ec8415c5bfdb2a8fe34b54adebc8494 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 9bf64eacba5bd6d47a04ca3c9ac66b74912bdc72..f230aa62ca59e273289f9ff8341526ab3989c364 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 a9dec32ba9ba787f95693a8e7f266292376b0132..251e48e7ba16466b7453dea554ac4f94ace5965a 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 f703b755351bd8ad2217fb18009e93232f2ccc61..3bb6af70973c39b56872246fe10f66040d691d43 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 d39601381adf56fe21cd531d09b77f4960cf5060..001796bcd6c895a49e3dd277a0862545fd2205a5 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");