From nobody Fri Sep 25 07:21:12 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 698BE34250E; Tue, 15 Sep 2026 14:20:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482057; cv=none; b=s0mZYxczutSB4lQ2CJXte+ES4MzFbMvQHKQl8uQ/gsP7ukfza/EbLPt52sVb4aAEJ0IGGMgzHusSFfB4nq7AfVRVqRoIGKY6pWWpIff/X4hm55zFPwYczzmCnG1nbsLW6SLsy3yoIxGocnaixbdxaopQyveRyNrbRLXhtIFecXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482057; c=relaxed/simple; bh=Awy5+gwh0rQDeMWDu61RRk6Jl4HDmD2yiFuj1eEImRg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UFQYVj2CCat831Lwhflv0zC8Hovvv/4UyM/D/yEj7eFjO2HX6weRHjMZcoB6oe7zWFdM8tKLW9GvzJQoJ53UeX3HCzSj6sPwao9/8b4TzGuHAej1wbNyFCqV1m/qkmNyFwM9DLMDuT8WP9i0N5Z/zzNIqdVdViTXA5ciLUAamxg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JToynxhs; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JToynxhs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85FC41F00893; Tue, 15 Sep 2026 14:20:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789482056; bh=dpB20xJYi1VEUnx78YqG5jvGGAspVyU+zm/IYjxVoDM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=JToynxhsk0wiy6MNWt06/gALfuescFnCBodQJUxPWaeiH8W1k1JvI+L9RvRSsHHyO jziWReuLKh2QdmHzF1RUK2UKzuRW6BOlcsBPSBDr2o/mGR5ZoWU/wlEMCtqsrunYkn 9N3HXVIw+Zj6mCdrsvwbwGuB+da5e1Nx9X0gwEmdHZ9FcKXwoxh8rqsX1jdD77yXt0 wxz62q9B7w4eYBG2vjutWBtXd1yDeuWwQZPS19AmiKHz0Zgjoc/0DXIyuWFzPJCKqD fr5KmeVrMzAZ0qCIQ9GkoKLSJe7G4eH/BUfw7hig+qtABi/+J3F4KArjzOSP5I9hog bvN7vRuY4o2hw== From: Chuck Lever Date: Tue, 15 Sep 2026 10:20:41 -0400 Subject: [PATCH v3 1/4] SUNRPC: Use atomic_t for XID allocation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260915-performance-v3-1-ae26d460bfd3@kernel.org> References: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> In-Reply-To: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> To: Trond Myklebust , Anna Schumaker Cc: Jeff Layton , NeilBrown , Tim Menninger , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Chuck Lever X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1882; i=cel@kernel.org; h=from:subject:message-id; bh=Awy5+gwh0rQDeMWDu61RRk6Jl4HDmD2yiFuj1eEImRg=; b=owEBbQKS/ZANAwAKATNqszNvZn+XAcsmYgBqqVRGRSHTJe2CEwQscWK7NazXXz08S5bbw5HYa j+Bw83t+X2JAjMEAAEKAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCaqlURgAKCRAzarMzb2Z/ l0VXD/9o7u7JdDxubha8wG867idoHbBqfv7fuHBmX5hTtPxBBE/T0jmCtfa1cAO/WuKGmK2VgEJ 8XwENmryqcOz4T63ld8fEvRyt5Ayn0xlacQD0vZqrrds7MJ9BbKHKfpokGUupbu/CXAM9maYczW fWNQjyMKCUQD3DCQK7rfpK/VRpHBZKwtDndhRID96F3VAI+5lAEOOJls0yp8Pr7L2sFLcdve+nq Jx/mvGFrqhpl4hPhyvLgWpHxpnYpkcQODuuGtxwrw0LtLFtCUWvQwCSBGybUMsM1IP8L90C+kJ0 wTPTt+hg6pi9iNN0RE8mZdyDJYDXgwzvxEB9sDQQZxvw2hydbwqoqJAx9u05VMT3a834ZK2EgJx O3HOcof/oiL8nl8mhPPRBInKr+ZJfleGAAoX6AJLYcU1rOGgJENrF4wiRWAREleT7URxe9lcREh nfl86bWRGLzQ7WSukeDFqH5l6w2DNFcXw1OxIpEDuSMEM7Dy7+Jb+s18CWiZYz4FcNP04bUE16I n7ZYxU0H8t1VlXByv9cjOtqIJRE3aYKPHbptm0TqX57Ajh4dAO9kfds2+gWv905yqtwwqoKSeXb OXpYmuDOZ4tg60eMj0Am+lsz9u00BVZYnpQ9YKwUYcdUMayoVCofmAkcLKGzivVj4kMC9qx+39Q IM+VkOTQZvEWsBw== X-Developer-Key: i=cel@kernel.org; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 xprt_alloc_xid() acquires reserve_lock to increment a simple counter. Under a high-IOPS NFSv3 workload on 100GbE RDMA, profiling shows 1.06% of system-wide CPU cycles contending on this lock in xprt_request_init, as ~150 RPC worker threads serialize on the counter. reserve_lock protects the slot table and backlog queue, but XID allocation is an independent operation that does not require synchronization with either. Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Reviewed-by: Tim Menninger Tested-by: Tim Menninger --- include/linux/sunrpc/xprt.h | 2 +- net/sunrpc/xprt.c | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index a82045804d34..0d6c3f6bf97e 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -273,7 +273,7 @@ struct rpc_xprt { spinlock_t transport_lock; /* lock transport info */ spinlock_t reserve_lock; /* lock slot table */ spinlock_t queue_lock; /* send/receive queue lock */ - u32 xid; /* Next XID value to use */ + atomic_t xid; /* Most recently issued XID */ struct rpc_task * snd_task; /* Task blocked in send */ =20 struct list_head xmit_queue; /* Send queue */ diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 48a3618cbb29..186c14f0f928 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1882,18 +1882,13 @@ xprt_init_connect_cookie(struct rpc_rqst *req, stru= ct rpc_xprt *xprt) static __be32 xprt_alloc_xid(struct rpc_xprt *xprt) { - __be32 xid; - - spin_lock(&xprt->reserve_lock); - xid =3D (__force __be32)xprt->xid++; - spin_unlock(&xprt->reserve_lock); - return xid; + return (__force __be32)atomic_inc_return(&xprt->xid); } =20 static void xprt_init_xid(struct rpc_xprt *xprt) { - xprt->xid =3D get_random_u32(); + atomic_set(&xprt->xid, get_random_u32()); } =20 static void --=20 2.54.0 From nobody Fri Sep 25 07:21:12 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4673C26E71E; Tue, 15 Sep 2026 14:20:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482059; cv=none; b=t3WtMqkw8pfUACc6I4i76XbV2o25qDJTvB2jmpkeD3vvmuFvAQP0EajJZR0lruguze+NesRA1Jt6TvMNkiSku8DYsRyodtlMFvX4LwcnBdSFneGBbMWuPMlkxAdCsX9YxDaXr1CbIPJLXQ/rUegMe+Sg3f98SdYKQKSz3TIdmXo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482059; c=relaxed/simple; bh=elbvpKbFo1ZDYXrUigcNTsrlGYkDZT8tSzIryvL1vZc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YLtghfQOAVQsbhVcgVbVFrI/sZXOncIbDfOr41oMwDh29ZmbgC5HWOlJJQXGOKMCjh/GIAanJYmqiVYBXUYy/aKInw98nOzr9SQv2lCkdmnmRYZCRkzadha+SatT9X1RaiguYbIVmIe1y+q9DtJNZkbaKLjnMhoIKuwwXCI+7oI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Rk1fI/3m; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Rk1fI/3m" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5B0221F00898; Tue, 15 Sep 2026 14:20:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789482057; bh=XCtmk83st51buT27EwKxyinXVjBXGwdJCDQb2+ZceHA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Rk1fI/3mPiSEGi2BUrYNuijhdcYBNH54/hX56Qf5UEStnwPKD7WuKS777zcUQq7Ot 92YFlfe3dBiaiJ0kQI4JZQgviqha1zSpKVtOyqVyDF3wwo4x/euOzW0tqkTY/vjjRd JelDvSmdfnVbhB22aWtUMOO3U6NV0Wz66qGwqMCRckaw3+vRJTVhUpu5dLPnJSbQ3x liNyJxxFcoJdpZ9um3FipMkok/1Cd3LPnQZYtuEB1GV7VY2ayIP0OuYO/IXHYbp8CD smvTagb15c6ECFlcWU9NdmKG+ihE+R1hHe3fk2A+eZiQdtvlHDUMNv8x5GCEJD70D5 ZqZDNPlWLtBSQ== From: Chuck Lever Date: Tue, 15 Sep 2026 10:20:42 -0400 Subject: [PATCH v3 2/4] SUNRPC: Split recv_lock out of xprt->queue_lock Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260915-performance-v3-2-ae26d460bfd3@kernel.org> References: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> In-Reply-To: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> To: Trond Myklebust , Anna Schumaker Cc: Jeff Layton , NeilBrown , Tim Menninger , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Chuck Lever X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=15822; i=cel@kernel.org; h=from:subject:message-id; bh=elbvpKbFo1ZDYXrUigcNTsrlGYkDZT8tSzIryvL1vZc=; b=owEBbQKS/ZANAwAKATNqszNvZn+XAcsmYgBqqVRGXvTeBaitUCngfGa/qoFgotMxEq86rAVJb JR7SISS5OqJAjMEAAEKAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCaqlURgAKCRAzarMzb2Z/ l7asD/9bXeZ3LRRxqtJpmdLIrZIMnPLgGpe+KRVDI/FdnK9ts5gOJT69Du1HYPI6fUEz8TcAfEw FwE0njG9SvjNJUZBy/9EVOlTpTLIE49zqu1R/4F4p//tsTcS5ThsH8Dt0RbXvoIBnQMvzCEe4vd FN/pWXtKDPuZ/lfDiYC5eZUVLRooM1V5OI8ycuzaICcRrnwk4b6e4J2E/1/HyPrvqXtCElbwlvG Z8RAfv9FU4I3iU48H87Nx7crnt+UDPV8sXNIqQvuW6s7IcTCEdUvYDYbT8Mq+c8NBVyJVWG/cu9 moHv8JsBJpstLotzFANzIDGvdf748CBg10UL9GTL7PXW1ccxlzCqak4ZxHlELnxi4+4waSIEvV5 k4OtiTgg1RImII/j2eSncTsD+5TqxNvck458yzjn8v6z7qXw0jqlmTRZUsbcT5unxXhWiZK4oQq lXMJ26KrCbl0garBdVVV3QySsmLWdh9xPOoBHM0gneovhC74RKKuamH/m8NiuSpX+ADYEoa+fU6 IEaS7tPZAtfvsLugsodbVcWulNiNn4M11oiLT0WTXUdoBg8YctanzJOH7Da4VX4QMiIP68G86JV glnZg9uG6TzUkd3+D/QfDu2gmYZqkvXYpztTteuzl190yQQUYsoPFQiLdjKar+gxxIwdQzDnKSk BgpWJdAQLHUVuog== X-Developer-Key: i=cel@kernel.org; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 xprt->queue_lock protects two independent structures: the recv_queue rb-tree for reply matching and the xmit_queue list for transmit draining. No hot path touches both in one critical section, yet every RPC submit and completion contends on the same lock. Under a 4KB NFSv3 READ workload on 100GbE RDMA, 53% of non-idle CPU cycles are spent in native_queued_spin_lock_slowpath: the CQ completion worker running rpcrdma_reply_handler serializes against ~150 kworker threads enqueuing receives and transmits. Introduce xprt->recv_lock for the receive path -- recv_queue operations, request lookup, receive-side pinning, and completion -- leaving queue_lock to the xmit_queue and the xprt_transmit drain loop. A request is pinned under the lock of the queue it was found through, so xprt_request_dequeue_xprt() drains pins once under each lock before it dequeues from that queue. The transmit dequeue has to see a zero pin count under queue_lock: it frees the send buffer's bvec that a transmitter is iterating, and it aborts a partial send only if the request is still first in the queue. A receive-side unpin runs under recv_lock rather than the lock that publishes RPC_TASK_MSG_PIN_WAIT, so xprt_unpin_rqst() wakes the waiter whenever the count reaches zero instead of testing the flag. Also move the rq_private_buf memcpy in xprt_request_enqueue_receive above the lock acquisition: until the rb-tree insert publishes the request, the reply handler cannot see it, so the copy is safe unlocked and the submitter's critical section shrinks to the insert alone. Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Reviewed-by: Tim Menninger Tested-by: Tim Menninger --- include/linux/sunrpc/xprt.h | 6 ++- net/sunrpc/svcsock.c | 6 +-- net/sunrpc/xprt.c | 76 +++++++++++++++++++-------= ---- net/sunrpc/xprtrdma/rpc_rdma.c | 14 +++--- net/sunrpc/xprtrdma/svc_rdma_backchannel.c | 8 ++-- net/sunrpc/xprtsock.c | 18 +++---- 6 files changed, 77 insertions(+), 51 deletions(-) diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 0d6c3f6bf97e..ed1e28b74f02 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -272,7 +272,7 @@ struct rpc_xprt { atomic_long_t queuelen; spinlock_t transport_lock; /* lock transport info */ spinlock_t reserve_lock; /* lock slot table */ - spinlock_t queue_lock; /* send/receive queue lock */ + spinlock_t queue_lock; /* send queue lock */ atomic_t xid; /* Most recently issued XID */ struct rpc_task * snd_task; /* Task blocked in send */ =20 @@ -292,6 +292,10 @@ struct rpc_xprt { * backchannel rpc_rqst's */ #endif /* CONFIG_SUNRPC_BACKCHANNEL */ =20 + /* + * Receive stuff + */ + spinlock_t recv_lock; /* receive queue lock */ struct rb_root recv_queue; /* Receive queue */ =20 struct { diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 50e5e7f5b762..8939ba604385 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1102,7 +1102,7 @@ static int receive_cb_reply(struct svc_sock *svsk, st= ruct svc_rqst *rqstp) =20 if (!bc_xprt) return -EAGAIN; - spin_lock(&bc_xprt->queue_lock); + spin_lock(&bc_xprt->recv_lock); req =3D xprt_lookup_rqst(bc_xprt, xid); if (!req) goto unlock_eagain; @@ -1120,10 +1120,10 @@ static int receive_cb_reply(struct svc_sock *svsk, = struct svc_rqst *rqstp) memcpy(dst->iov_base, src->iov_base, src->iov_len); xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); rqstp->rq_arg.len =3D 0; - spin_unlock(&bc_xprt->queue_lock); + spin_unlock(&bc_xprt->recv_lock); return 0; unlock_eagain: - spin_unlock(&bc_xprt->queue_lock); + spin_unlock(&bc_xprt->recv_lock); return -EAGAIN; } =20 diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 186c14f0f928..883123ec70b0 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1061,7 +1061,7 @@ xprt_request_rb_remove(struct rpc_xprt *xprt, struct = rpc_rqst *req) * @xprt: transport on which the original request was transmitted * @xid: RPC XID of incoming reply * - * Caller holds xprt->queue_lock. + * Caller holds xprt->recv_lock. */ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid) { @@ -1092,8 +1092,9 @@ xprt_is_pinned_rqst(struct rpc_rqst *req) * xprt_pin_rqst - Pin a request on the transport receive list * @req: Request to pin * - * Caller must ensure this is atomic with the call to xprt_lookup_rqst() - * so should be holding xprt->queue_lock. + * Caller must hold the lock that protects the queue through which + * it found the request: xprt->recv_lock for the receive path, + * xprt->queue_lock for the transmit drain path. */ void xprt_pin_rqst(struct rpc_rqst *req) { @@ -1105,14 +1106,10 @@ EXPORT_SYMBOL_GPL(xprt_pin_rqst); * xprt_unpin_rqst - Unpin a request on the transport receive list * @req: Request to pin * - * Caller should be holding xprt->queue_lock. + * Caller holds the lock it held for the matching xprt_pin_rqst(). */ void xprt_unpin_rqst(struct rpc_rqst *req) { - if (!test_bit(RPC_TASK_MSG_PIN_WAIT, &req->rq_task->tk_runstate)) { - atomic_dec(&req->rq_pin); - return; - } if (atomic_dec_and_test(&req->rq_pin)) wake_up_var(&req->rq_pin); } @@ -1123,6 +1120,26 @@ static void xprt_wait_on_pinned_rqst(struct rpc_rqst= *req) wait_var_event(&req->rq_pin, !xprt_is_pinned_rqst(req)); } =20 +/* + * A pin is taken under the lock of the queue the request was found + * through, so a zero count observed under @lock rules out any pinner + * that came through that queue. The lock is dropped to wait, and the + * re-test under it catches a pinner that arrived in the gap. + */ +static void xprt_request_drain_pins(struct rpc_task *task, spinlock_t *loc= k) + __must_hold(lock) +{ + struct rpc_rqst *req =3D task->tk_rqstp; + + while (xprt_is_pinned_rqst(req)) { + set_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate); + spin_unlock(lock); + xprt_wait_on_pinned_rqst(req); + spin_lock(lock); + clear_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate); + } +} + static bool xprt_request_data_received(struct rpc_task *task) { @@ -1155,16 +1172,16 @@ xprt_request_enqueue_receive(struct rpc_task *task) ret =3D xprt_request_prepare(task->tk_rqstp, &req->rq_rcv_buf); if (ret) return ret; - spin_lock(&xprt->queue_lock); - - /* Update the softirq receive buffer */ + /* Reply handlers cannot find the request until the rb-tree + * insert below publishes it, so the copy needs no lock. + */ memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(req->rq_private_buf)); =20 - /* Add request to the receive list */ + spin_lock(&xprt->recv_lock); xprt_request_rb_insert(xprt, req); set_bit(RPC_TASK_NEED_RECV, &task->tk_runstate); - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); =20 /* Turn off autodisconnect */ timer_delete_sync(&xprt->timer); @@ -1175,7 +1192,7 @@ xprt_request_enqueue_receive(struct rpc_task *task) * xprt_request_dequeue_receive_locked - Remove a request from the receive= queue * @task: RPC task * - * Caller must hold xprt->queue_lock. + * Caller must hold xprt->recv_lock. */ static void xprt_request_dequeue_receive_locked(struct rpc_task *task) @@ -1190,7 +1207,7 @@ xprt_request_dequeue_receive_locked(struct rpc_task *= task) * xprt_update_rtt - Update RPC RTT statistics * @task: RPC request that recently completed * - * Caller holds xprt->queue_lock. + * Caller holds xprt->recv_lock. */ void xprt_update_rtt(struct rpc_task *task) { @@ -1212,7 +1229,7 @@ EXPORT_SYMBOL_GPL(xprt_update_rtt); * @task: RPC request that recently completed * @copied: actual number of bytes received from the transport * - * Caller holds xprt->queue_lock. + * Caller holds xprt->recv_lock. */ void xprt_complete_rqst(struct rpc_task *task, int copied) { @@ -1309,7 +1326,7 @@ void xprt_request_wait_receive(struct rpc_task *task) * The spinlock ensures atomicity between the test of * req->rq_reply_bytes_recvd, and the call to rpc_sleep_on(). */ - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); if (test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate)) { xprt->ops->wait_for_reply_request(task); /* @@ -1321,7 +1338,7 @@ void xprt_request_wait_receive(struct rpc_task *task) rpc_wake_up_queued_task_set_status(&xprt->pending, task, -ENOTCONN); } - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); } =20 static bool @@ -1439,7 +1456,12 @@ xprt_request_dequeue_transmit(struct rpc_task *task) * @task: pointer to rpc_task * * Remove a task from the transmit and receive queues, and ensure that - * it is not pinned by the receive work item. + * it is not pinned by any concurrent work item. + * + * The transmit dequeue frees the send buffer's bvec and may abort a + * partial send, so it must not run while a transmitter holds a pin. + * Drain pins under each queue's lock before leaving that queue; once + * the request is off both, no new pin can be taken. */ void xprt_request_dequeue_xprt(struct rpc_task *task) @@ -1451,16 +1473,15 @@ xprt_request_dequeue_xprt(struct rpc_task *task) test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate) || xprt_is_pinned_rqst(req)) { spin_lock(&xprt->queue_lock); - while (xprt_is_pinned_rqst(req)) { - set_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate); - spin_unlock(&xprt->queue_lock); - xprt_wait_on_pinned_rqst(req); - spin_lock(&xprt->queue_lock); - clear_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate); - } + xprt_request_drain_pins(task, &xprt->queue_lock); xprt_request_dequeue_transmit_locked(task); - xprt_request_dequeue_receive_locked(task); spin_unlock(&xprt->queue_lock); + + spin_lock(&xprt->recv_lock); + xprt_request_drain_pins(task, &xprt->recv_lock); + xprt_request_dequeue_receive_locked(task); + spin_unlock(&xprt->recv_lock); + xdr_free_bvec(&req->rq_rcv_buf); } } @@ -2038,6 +2059,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct n= et *net) spin_lock_init(&xprt->transport_lock); spin_lock_init(&xprt->reserve_lock); spin_lock_init(&xprt->queue_lock); + spin_lock_init(&xprt->recv_lock); =20 INIT_LIST_HEAD(&xprt->free); xprt->recv_queue =3D RB_ROOT; diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 1285f04cdac1..a82d3d9bc7ae 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -1321,9 +1321,9 @@ void rpcrdma_unpin_rqst(struct rpcrdma_rep *rep) req->rl_reply =3D NULL; rep->rr_rqst =3D NULL; =20 - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); xprt_unpin_rqst(rqst); - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); } =20 /** @@ -1363,10 +1363,10 @@ void rpcrdma_complete_rqst(struct rpcrdma_rep *rep) goto out_badheader; =20 out: - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); xprt_complete_rqst(rqst->rq_task, status); xprt_unpin_rqst(rqst); - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); return; =20 out_badheader: @@ -1492,12 +1492,12 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep) /* Match incoming rpcrdma_rep to an rpcrdma_req to * get context for handling any incoming chunks. */ - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); rqst =3D xprt_lookup_rqst(xprt, rep->rr_xid); if (!rqst) goto out_norqst; xprt_pin_rqst(rqst); - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); =20 if (buf->rb_credits !=3D credits) rpcrdma_update_cwnd(r_xprt, credits); @@ -1524,7 +1524,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep) return; =20 out_norqst: - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); trace_xprtrdma_reply_rqst_err(rep); rpcrdma_rep_put(buf, rep); goto out_post; diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrd= ma/svc_rdma_backchannel.c index e5a78b761012..3c7b85427f33 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c @@ -28,7 +28,7 @@ void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp, struct rpc_rqst *req; u32 credits; =20 - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); req =3D xprt_lookup_rqst(xprt, *rdma_resp); if (!req) goto out_unlock; @@ -39,7 +39,7 @@ void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp, goto out_unlock; memcpy(dst->iov_base, src->iov_base, src->iov_len); xprt_pin_rqst(req); - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); =20 credits =3D be32_to_cpup(rdma_resp + 2); if (credits =3D=3D 0) @@ -50,13 +50,13 @@ void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp, xprt->cwnd =3D credits << RPC_CWNDSHIFT; spin_unlock(&xprt->transport_lock); =20 - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); xprt_complete_rqst(req->rq_task, rcvbuf->len); xprt_unpin_rqst(req); rcvbuf->len =3D 0; =20 out_unlock: - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); } =20 /* Send a reverse-direction RPC Call. diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 7f60723fa64d..1454da9575b3 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -673,25 +673,25 @@ xs_read_stream_reply(struct sock_xprt *transport, str= uct msghdr *msg, int flags) ssize_t ret =3D 0; =20 /* Look up and lock the request corresponding to the given XID */ - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); req =3D xprt_lookup_rqst(xprt, transport->recv.xid); if (!req || (transport->recv.copied && !req->rq_private_buf.len)) { msg->msg_flags |=3D MSG_TRUNC; goto out; } xprt_pin_rqst(req); - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); =20 ret =3D xs_read_stream_request(transport, msg, flags, req); =20 - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); if (msg->msg_flags & (MSG_EOR|MSG_TRUNC)) xprt_complete_rqst(req->rq_task, transport->recv.copied); else req->rq_private_buf.len =3D transport->recv.copied; xprt_unpin_rqst(req); out: - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); return ret; } =20 @@ -1398,13 +1398,13 @@ static void xs_udp_data_read_skb(struct rpc_xprt *x= prt, return; =20 /* Look up and lock the request corresponding to the given XID */ - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); rovr =3D xprt_lookup_rqst(xprt, *xp); if (!rovr) goto out_unlock; xprt_pin_rqst(rovr); xprt_update_rtt(rovr->rq_task); - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); task =3D rovr->rq_task; =20 if ((copied =3D rovr->rq_private_buf.buflen) > repsize) @@ -1412,7 +1412,7 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xpr= t, =20 /* Suck it into the iovec, verify checksum if not done by hw. */ if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb)) { - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); __UDPX_INC_STATS(sk, UDP_MIB_INERRORS); goto out_unpin; } @@ -1421,13 +1421,13 @@ static void xs_udp_data_read_skb(struct rpc_xprt *x= prt, spin_lock(&xprt->transport_lock); xprt_adjust_cwnd(xprt, task, copied); spin_unlock(&xprt->transport_lock); - spin_lock(&xprt->queue_lock); + spin_lock(&xprt->recv_lock); xprt_complete_rqst(task, copied); __UDPX_INC_STATS(sk, UDP_MIB_INDATAGRAMS); out_unpin: xprt_unpin_rqst(rovr); out_unlock: - spin_unlock(&xprt->queue_lock); + spin_unlock(&xprt->recv_lock); } =20 static void xs_udp_data_receive(struct sock_xprt *transport) --=20 2.54.0 From nobody Fri Sep 25 07:21:12 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59DAD3B0ADB; Tue, 15 Sep 2026 14:20:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482060; cv=none; b=ez6MhQjODBatsdRO0YSBZPW2Llcpn1caCYPKSL5T2UL2Qc95cYce0WRdzVqVz50dKQ8lBy9IHe3Vo7R1l+Y0HExGxybthiJQW86n+/2vXCjgFgAP23ClrGlqUO90K83iWkKdaUjkpbZdXHYnDJuCNEg+WI93FG6r01TC3k+OfnU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482060; c=relaxed/simple; bh=MVWfLseSKoY8UWv3qOWXRywa9v8PwRgqf50RtAy70fY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=F8gc07PaTjchX7/LT03gAucNed/KLtDqEiLQLOkwReX9fay1BH2pVjdLzrgr2VvBWwPJzGxFTxwIibVbnAaTNmr5CRbYvqRWiK0RlvUa1ds72PnFCAUvhr04Gopwf/pR/bHOpxQza3qY2CCDQPNZq2azphOcDCvxfCgps0KRfVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JVLaOBuE; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JVLaOBuE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 41B791F00899; Tue, 15 Sep 2026 14:20:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789482057; bh=uOoXR9XwKEVJv+80SOBDs9JGjW6p0beKPPbXNt3sOPw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=JVLaOBuE4NG6yO/4lO3N0SIt4l+6VPByZD09YeJmDGeITHSNG56gmY82Q+BOUF0Lx ioDcHcqedzzUz24Dge9TX9wP/NnGPIP6bqTQXZ6e7Cl+bZu8H8Ry7IjtNU88Od0hHY DFnTdCBOGTIfK9DvmhjzSNwNNGit+q3N/by3p3/XvVlHJ8gy8iAf+Df6oCgtLX4hsn nv8gDv6tue23MnFWSLyHWFyWyqQEdu9A8PiSbdxy1y+GYTyDyLqr+EOE00exOXlDPM chWzl87Uw4F4CYlTyrKsSg9ryZ6/EXXh3g6NY0vnNuf/tZ2b081/BGt+drd7Jm5TXF NahaGPvqLrEFw== From: Chuck Lever Date: Tue, 15 Sep 2026 10:20:43 -0400 Subject: [PATCH v3 3/4] SUNRPC: Set WQ_SYSFS on rpciod and xprtiod Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260915-performance-v3-3-ae26d460bfd3@kernel.org> References: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> In-Reply-To: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> To: Trond Myklebust , Anna Schumaker Cc: Jeff Layton , NeilBrown , Tim Menninger , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Chuck Lever X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1248; i=cel@kernel.org; h=from:subject:message-id; bh=MVWfLseSKoY8UWv3qOWXRywa9v8PwRgqf50RtAy70fY=; b=owEBbQKS/ZANAwAKATNqszNvZn+XAcsmYgBqqVRGyoM/WxhBmaluE0lgn0JDVdi/22fNoI1Fv gQy+82xgoOJAjMEAAEKAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCaqlURgAKCRAzarMzb2Z/ lwy0D/wJOjFQvrvrrZ3zgcALTegBuuHkGLJ36p3E35kf1L8QuzfLSqnQGBfXI05PccRpoYK5cTJ xAJ4k1wIZ+xVrEtuTN6aOw2B7UjWbSIcQz1YBjFZG0YLdaAafDDCEooekm+2ir7zfr/d6SGaOA3 vv+oQU5ADLc9KjrDhEZ/ilc4qseKEGi3zEqvSGi+glJlSecd6XI921/5bRJT1goyeVQ3AxYB6zg Faip7M56MPi6WXvxBrguDC/YiJo652iEBuhvbKmqTcsxh2h2w3rAnU3GcUSE6pXcmHooMgcbB1Z QKG9cW5xqLU28Bio5LOHvo0gq8ffo60KjD/1LULQ0TWB9MhfNFnOlYt30p87nDkGbURtiOzKzcU xfJfg82n66fkQX84wUAio1+EBHHfdi3+htXTNTgMAhsNZqQKLCs7h0ABjRBfT9pkQdG3S62JSRo jdUbsOq4eQI1W2mT+weyyHosfFYQERdr3S/0bLUEYwLe3+a8Sb87rsXnFJRzAG/sGMhi3X9pP4v AwxWeYQBDmhiR2I8iuTfW9nK4NtZxXgBSK4ML0Th8dhN41MH4v2fGQ7WgVh2Ae9C2hvpqO1MPPV XcgT9+/0MHQhzXh7j7tSv5Z+y2QjiNiJ+a3c38UNxmqevCUBlP3j4L5aBGM2SQLutE+zDKRGqyX Tf/wCSN5eHchGcg== X-Developer-Key: i=cel@kernel.org; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 An unbound workqueue's attributes can be changed at run time only through /sys/devices/virtual/workqueue/, and a workqueue appears there only when it is created with WQ_SYSFS. rpciod and xprtiod are created without it, so their affinity scope cannot be tuned without reloading the sunrpc module. Create both with WQ_SYSFS. Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Reviewed-by: Tim Menninger Tested-by: Tim Menninger --- net/sunrpc/sched.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 016f16ca5779..e81419aa553c 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -1273,16 +1273,17 @@ void rpciod_down(void) */ static int rpciod_start(void) { + const unsigned int wq_flags =3D WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS; struct workqueue_struct *wq; =20 /* * Create the rpciod thread and wait for it to start. */ - wq =3D alloc_workqueue("rpciod", WQ_MEM_RECLAIM | WQ_UNBOUND, 0); + wq =3D alloc_workqueue("rpciod", wq_flags, 0); if (!wq) goto out_failed; rpciod_workqueue =3D wq; - wq =3D alloc_workqueue("xprtiod", WQ_UNBOUND | WQ_MEM_RECLAIM, 0); + wq =3D alloc_workqueue("xprtiod", wq_flags, 0); if (!wq) goto free_rpciod; xprtiod_workqueue =3D wq; --=20 2.54.0 From nobody Fri Sep 25 07:21:12 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C73D630566F; Tue, 15 Sep 2026 14:20:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482060; cv=none; b=onljl2Pqygmhl2PyBdsfk5gEXWC48EehS2Cb74ZIhv83ctbwj6n3eo1vYQuQNNc/xX96UXgnjTzJYteSL4xm+dg4LTeW8OTthIAF1wH/oyXry7YHX7fUnlFUUdKZdc/DpdVNiDuMf7XlSDeDxH96CJAzv4OPgEgtsdalzjrCmtw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789482060; c=relaxed/simple; bh=oa5dEyn9Zsa38Ku+33+tf3H2bkwRDudrZYcsIqPtcXc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=USj2pKGXn2krz4nwP66oIl2lXIKekPHizJgnTCtGAPCgtz6mmEWElo87752oKw49rse3/SUxCWgBQHE/k/z9RS7h3f5VmbE1cXq95zEu3S0dwNMIeBRYthcL1/D0sOhL8Z8/3Vv4CGvZv93JnySG1K8MKILIpl4BL2dXf+r1pQg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Pqa2FD/H; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Pqa2FD/H" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 161361F00893; Tue, 15 Sep 2026 14:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789482058; bh=u3d1LqkKFumaGM48TyrGDB6bAw4mkY3a4wCUIMlrbQw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Pqa2FD/HWBn+vYm2bueBmQ01QSVFAY5GeT9OG3H72xc+O78I0e5EK2ZCm42XpYcfU xCKlWUjVxBtgPs7sJptTV14EnCxjHzOUeZvI2ev3DI1X9ACSErnYa0yG6xmDqraKht YpyN1Hd64TH4wfQdb7xhq/Oeq84Qf9NKeaBrzPnBrHqNbLZ7d7PTCSukWZhu0IsBCM GNKY3+dy+5BueUNI38nHHJA7ZtHwm0UDlpM+uZXk/dGXkwj5nzkX7xdSUKov+QwbHK t+xWjB0rBt2ViMZdCqFtxU5kEetqREbflOk7WaR3FNcw0vki6NB8+5/lHg+QRthoaD CKd8W2/r1zVYQ== From: Chuck Lever Date: Tue, 15 Sep 2026 10:20:44 -0400 Subject: [PATCH v3 4/4] NFS: Set WQ_SYSFS on nfsiod Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260915-performance-v3-4-ae26d460bfd3@kernel.org> References: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> In-Reply-To: <20260915-performance-v3-0-ae26d460bfd3@kernel.org> To: Trond Myklebust , Anna Schumaker Cc: Jeff Layton , NeilBrown , Tim Menninger , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Chuck Lever X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1001; i=cel@kernel.org; h=from:subject:message-id; bh=oa5dEyn9Zsa38Ku+33+tf3H2bkwRDudrZYcsIqPtcXc=; b=owEBbQKS/ZANAwAKATNqszNvZn+XAcsmYgBqqVRGivV37ULv2+5zcW1uIWejGnkKzI0uQAKQx DljsowLsomJAjMEAAEKAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCaqlURgAKCRAzarMzb2Z/ l9leD/4mBER0/xhNXqQ3QdyYXNH20NOLhnGQHH7LdsZj+zNBxrlEZLDNKqs2pvhWkHJdzBNegdy m3rAHy2VngPBv3u5qOlyzMoInrgbH8qIGo/Mp3SbuwVvT+XlzLrdtO+WaQZ1C5D/DErSz9Xjbnh sz/skBlHYonU/pkr2N/QBx9jDX9HkQspd6E2eZechQ26YaBCOGEiotJWQ+wzpKhoNoeJkKbdBL7 WLSQHMX0Wb6Kg0vMABgZQO6ni2dhj1/Uy7sVyLderIxcBfqy66rSYt6iMw1KZ8X2Me1ppBIw7vX 7At32tZLdVxpJbaBYu76gfnRkR+QpVBvGvVliflhhJaI/Q+kweEe2GDdpch8niE9H3oCvol/nQx tAwVMpDRHVAiAOlOv/IV0ucFYmc3xW7Cc4zttb0u/yy3iZ/3WjFMkmiDrYIuxhizvP5T5w5O1K9 N5ZhuJeVVLG2O0k6z9UK4mg/VHyOvivQtU46cJAVkSMs1SrgFYzoJZo3Qt7hPIW/T5jYKB7V4TA KY0UL1ulOe+/TCgbnEBnYySCaZTSDoAuH5lysB8Bar+YEt3KRh9s1wL0evt38ZaeMWGfsuu+3Yb fuD+7MwVjKi5SjkMyeoQwOzj+AseuJcgZZqhNEvR8XqEK0O3phmy8X+pjuUhNQOkpgNUzJPnT+m VsrcqG4DuH3Tlig== X-Developer-Key: i=cel@kernel.org; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 An unbound workqueue's attributes can be changed at run time only through /sys/devices/virtual/workqueue/, and a workqueue appears there only when it is created with WQ_SYSFS. nfsiod is created without it, so its affinity scope cannot be tuned without reloading the nfs module. Create nfsiod with WQ_SYSFS. Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Reviewed-by: Tim Menninger Tested-by: Tim Menninger --- fs/nfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3022454f7698..107a2135029d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -2619,7 +2619,8 @@ static void nfsiod_stop(void) static int nfsiod_start(void) { dprintk("RPC: creating workqueue nfsiod\n"); - nfsiod_workqueue =3D alloc_workqueue("nfsiod", WQ_MEM_RECLAIM | WQ_UNBOUN= D, 0); + nfsiod_workqueue =3D alloc_workqueue("nfsiod", + WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 0); if (nfsiod_workqueue =3D=3D NULL) return -ENOMEM; #if IS_ENABLED(CONFIG_NFS_LOCALIO) --=20 2.54.0