[PATCH RFC 4/4] nfsd: key NFSv4.1 connections by clientid for fair queueing
Benjamin Coddington <ben.coddington-F/[email protected]>
| Newsgroups | gmane.linux.nfs |
|---|---|
| Message-ID | <5f3a6acbc4f5347ddc231d5ed33500128a85c547.1780498019.git.bcodding@hammerspace.com> |
An NFSv4.1 client may bind several connections to its session. Stamp each such transport's fairness key with a value derived from the clientid in nfsd4_init_conn(), so that all of a client's connections share one key and the fair-queue dispatcher schedules them as a single client rather than per transport. A multi-connection v4.1 client is thereby held to the same per-client share as a single-connection client. Signed-off-by: Benjamin Coddington <bcodding-F/[email protected]> Co-Authored-By: Claude Opus 4.8 <noreply-IarDGxEC4Up8UrSeD/[email protected]> --- fs/nfsd/nfs4state.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 5982fc9eb6b1..52bd9bc5cdbd 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2351,11 +2351,28 @@ static int nfsd4_register_conn(struct nfsd4_conn *conn) return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); } +/* + * Derive the transport fairness key from the v4.1 clientid, so that all of a + * client's connections (bound to its session) share one key and the sunrpc + * fair-queue dispatcher schedules them as a single client rather than per + * transport. cl_boot is the server's boot time and is effectively always + * nonzero, so this overrides the source-address default that + * svc_xprt_fairq_key() would otherwise use. + */ +static unsigned long nfsd4_fairq_key(const clientid_t *clid) +{ + u64 id = ((u64)clid->cl_boot << 32) | clid->cl_id; + + return (unsigned long)(id ^ (id >> 32)); +} + static void nfsd4_init_conn(struct svc_rqst *rqstp, struct nfsd4_conn *conn, struct nfsd4_session *ses) { int ret; nfsd4_hash_conn(conn, ses); + conn->cn_xprt->xpt_fairq_key = + nfsd4_fairq_key(&ses->se_client->cl_clientid); ret = nfsd4_register_conn(conn); if (ret) /* oops; xprt is already down: */ -- 2.53.0