[PATCH RFC 3/4] nfsd: add a fairq module parameter

Benjamin Coddington <ben.coddington-F/[email protected]>
Newsgroups gmane.linux.nfs
Message-ID <93347e4eac42588a9533b37e09c28b4b53a55413.1780498019.git.bcodding@hammerspace.com>
Add nfsd.fairq (bool, default off).  When set, nfsd enables the sunrpc
per-client fair-queue dispatcher for its service via svc_set_fairq() at
service creation, so that a client cannot increase its share of nfsd
threads simply by opening more connections.  The parameter is read when
the service is created, so a change takes effect at the next nfsd start
(thread count 0 -> N).

With fair queueing enabled and no upper-layer identity stamped on a
transport, clients are distinguished by source address, which already
gives per-client fairness for NFSv3.

Signed-off-by: Benjamin Coddington <bcodding-F/[email protected]>
Co-Authored-By: Claude Opus 4.8 <noreply-IarDGxEC4Up8UrSeD/[email protected]>
---
 fs/nfsd/nfssvc.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 551d3cf51036..3abe4d2aec5a 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -36,6 +36,18 @@
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
 
 atomic_t			nfsd_th_cnt = ATOMIC_INIT(0);
+
+/*
+ * Per-client fair-queue dispatch.  When set, ready connections are scheduled
+ * round-robin per client (NFSv4.1 clientid, else source address) rather than
+ * per transport, so a client cannot grab a larger share of nfsd threads by
+ * opening more connections.  Read at service creation, so a change takes
+ * effect at the next nfsd start (thread count 0 -> N).
+ */
+static bool			nfsd_fairq;
+module_param_named(fairq, nfsd_fairq, bool, 0644);
+MODULE_PARM_DESC(fairq, "schedule nfsd service fairly per client (default off)");
+
 static int			nfsd(void *vrqstp);
 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 static int			nfsd_acl_rpcbind_set(struct net *,
@@ -635,6 +647,13 @@ int nfsd_create_serv(struct net *net)
 		return -ENOMEM;
 	}
 
+	error = svc_set_fairq(serv, nfsd_fairq);
+	if (error) {
+		svc_destroy(&serv);
+		percpu_ref_exit(&nn->nfsd_net_ref);
+		return error;
+	}
+
 	error = svc_bind(serv, net);
 	if (error < 0) {
 		svc_destroy(&serv);
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.