From nobody Thu Nov 5 05:11:19 2026 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.222.225 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793844173; b=D0LumU4CestSXa4tMHN8P9s4muRu2U7nuHi7miFA10Hza6EmYNZor6ZrzOaM9gMR11ac p0SC83yE7D89I/7nOIwLqw/s/lwCNn+Rb5mjiB2LN1tu6TxIHco9KEUlvhPcCHSgs6RVA tHanYTHZMOYTdDeiA9Nx67uSZOgoNh43EGhY/qys0GfaD2pD40GdSUtCnUHTLr5mDf9F4 wN1GTFaVTpoUkNCnj7UZbzoXJrqQii4UaNvB8nPpvosj0E6slIBJ0DWBsp0iRJG7z6yLb KcWRQ//KmkN4kWv8t7HEikfafH30SkzrWfjslncKoRs32MWSvYTob/SEDBD2CKehZ+A== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793844173; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: X-Relaying-Domain:Received:From:To:Cc:Subject:Date:Message-ID: X-Mailer:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=CIdaIZY8z1tsS2yki6WybLw4WOCkZmeRMYggi7nZ5LE=; b=d6LxmyH/l76is2OCCXWBjTHhg8dMsXuVN3AoA8y5MO8Iix3iJGZUtnhNi3x+d3YDarK7 iKUwPX7xrR5uvWaOAT3dfpsauMIoFx1LrZrvTptSwj6A2Oe7FPQKGgBCnDCIlTZuC0O/Q 724d5IFZTUxvF9tTpg0V8W0ckML3OoRcXBrubeko4DAcQGGXk3dO6amfwrtQ/i/FOzem+ 42z7SlmLCqpI68dxcCbVrUg08ry/IEgDc/RvUP9TZBQbFgoBonQlAl2KU3ihe1iwAUJU6 SoalTpnhGJfhHz3qA6G/ajLDnImHpZuti4WQPG7rkNeXigcM3xnSvvlqjGKl760s7OQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass header.d=purestorage.com header.i=@purestorage.com header.a=rsa-sha256 header.s=google2022 header.b="Wx9W/u52"; arc=none smtp.remote-ip=209.85.222.225 Received: from mail-qk1-f225.google.com (mail-qk1-f225.google.com [209.85.222.225]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 98661606EEBD for ; Thu, 5 Nov 2026 02:02:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 98661606EEBD Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=purestorage.com header.i=@purestorage.com header.a=rsa-sha256 header.s=google2022 header.b=Wx9W/u52 Received: by mail-qk1-f225.google.com with SMTP id af79cd13be357-93e63ee7b4cso138263085a.2 for ; Wed, 04 Nov 2026 18:02:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1793844171; x=1794448971; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=CIdaIZY8z1tsS2yki6WybLw4WOCkZmeRMYggi7nZ5LE=; b=Wx9W/u52eNsR6V7JToB8Fjt8rdRg4XubbRH2hUXxzToYObqjL5ZldsaGPkE6Y/i2U0 0EnSkNM/Kg8CGd33sFCwE3KgJA+df1aOWOs7meiJWaUUImpCrgYLNO3vmSzDjJNlqvLX zrrglk2XVauJkAxnO1DkCzrbUIzzphT/tEQG+BClADI20eg+7Fhz6IX96Nmcqwfs95NG 7c7rApzcnBq3tghfF3tOTV8aSyUrekd39vkDNkfO80nH+KWiBLVU/44le4WzFE0MLJqG Fw5ZrbZgHjFY/dyEBaIaDqJHikA6c1BIoOAlPRTk3Saa7eJbIusEZo8i/TqqM6bfL7fq 3AqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793844171; x=1794448971; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=CIdaIZY8z1tsS2yki6WybLw4WOCkZmeRMYggi7nZ5LE=; b=e50HZofAEmtQzEKKOEdd7O8EzZe7g6oihXnYPuQgJQTjiIpr87XjoDGC0D291UCuX0 IE1U7ZBhj1J7PQrK4BKNFKLyfpuWbrtKN5fB5wZekfIVBtEsUEJjX8umxkzXZkGnqMM4 5BfT2WoOtzpqU97FQJEeDwI1aUUXpY4EyXU9Lspe3S+Vg5Xx3xJZdeV3x3v+KjGSPqzC LY1wm44tjW48cCFvEayl9v3X7/Sf0pqfmhvILi84izCsI5MXvhD+I7NWzB2TsbVXB3mY MIo7TmdQrm6fQhSXvUMkTF5kWuq8tx1NxAvnq4j/FhyP737uv5qC4aEZP5CDmoj/SUsZ nAcw== X-Forwarded-Encrypted: i=1; AKwUvBxK/e7bCXZrJSFqIn0/r1J+HezSUFuegqJGvv4HM4/p7GAHGym7gFC7hMf9CaBa7qT0ZCCO9ss3SV00MrA=@vger.kernel.org X-Gm-Message-State: APuU4Z+vRRKjSlWVBHq/a+vfBuy0nUbnTpZjM3D8EEIkZd4M2gC5XiSv pyvTCb4jo1m7x8k0HNT5JdIphB2AQ+qvnnAEkEly5Fs28F532QcCAbzQlQoGMlPJVp6lue/OGcU Dy2FMC+ciRkhXWXkk1u5Y+9ITLg3wxhc0lyDu X-Gm-Gg: AYBFou0s4Fq1beLKrHqkVrjd3Vx9v263IbYxd3Jv5YsTYV2c3iuIkCf4heQgknVpGhX ZiBjWPVuKDrjAY+UcWl9i6YU3XPYcZHJgBdfS9jFmv7oFKhZ9CtHog+QjXsapIdUEiKc0AOxDAg w/ncwUQul2j7X6D8TkKTBxcSzcr93EAAH/+W/kZClGJq+VNIHV3PlrOnmPIFFvNUkLFtARMqz3W C4btp7S1iuTbMWGl4RQwOI46bX/0I/p54PiXf0A3XlohDfUb8piWKMBJ68iUwWrSWFXkGNJERyu tmJP/jel2eWlt53lELRQ4r2TSXFwwixiOeOaxcRKkp55i8hUzF7v8KM4Mrmi4WoysrfAgeMzqqp A9Gpjn29bfAenSsILw60GWt5TCH9h6rLjqJW1Uw== X-Received: by 2002:a05:620a:2849:b0:93e:95ce:53c7 with SMTP id af79cd13be357-9442156aaa8mr3050098185a.4.1793844171167; Wed, 04 Nov 2026 18:02:51 -0800 (PST) Received: from c14-smtp-2023.dev.purestorage.com ([208.88.158.129]) by smtp-relay.gmail.com with ESMTPS id af79cd13be357-945d47853ddsm45440085a.8.2026.11.04.18.02.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 18:02:51 -0800 (PST) X-Relaying-Domain: purestorage.com Received: from irdv-tmenninger.dev.purestorage.com (irdv-tmenninger.dev.purestorage.com [10.32.149.15]) by c14-smtp-2023.dev.purestorage.com (Postfix) with ESMTPS id 9B7DA3401C8; Wed, 4 Nov 2026 18:02:49 -0800 (PST) From: tmenninger@purestorage.com To: anna@kernel.org, trondmy@kernel.org Cc: cel@kernel.org, ebadger@everpuredata.com, jcurley@everpuredata.com, jlayton@kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, netdev@vger.kernel.org, slingappa@everpuredata.com, Tim Menninger Subject: [PATCH v2 1/2] SUNRPC: add request-scoped disconnects when cancelling tasks Date: Thu, 5 Nov 2026 02:02:48 +0000 Message-ID: <20261105020249.2607367-2-tmenninger@purestorage.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261105020249.2607367-1-tmenninger@purestorage.com> References: <20261105020249.2607367-1-tmenninger@purestorage.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Tim Menninger rpc_cancel_tasks() allows callers to cancel a selected set of RPC tasks, but callers that also need to tear down the connection currently have to disconnect at the rpc_clnt level. That is broader than necessary for clients with multiple transports. A cancelled request is associated with a specific rpc_xprt and records the connection generation on which it was transmitted in rq_connect_cookie. Add rpc_cancel_tasks_and_disconnect() to cancel matching tasks and mark matching requests that remain on the transport transmit or receive queues for conditional transport disconnect when the request is released. Store the disconnect indication in struct rpc_rqst rather than struct rpc_task. An RPC task can release one request and later acquire another, so task-scoped state could otherwise be consumed by a successor request and disconnect the wrong transport generation. After cancelling matching tasks, walk the client's transports and mark matching requests belonging to that client that remain on the transmit or receive queues. An rpc_xprt may be shared by multiple rpc_clnt instances, so requests belonging to other clients are left untouched. When a marked request is released, use xprt_conditional_disconnect() with its saved rq_connect_cookie. This disconnects the transport only if it is still using the same connection generation on which the request was sent, and leaves a replacement connection untouched. Requests that were never transmitted do not require a disconnect. Signed-off-by: Tim Menninger --- include/linux/sunrpc/sched.h | 4 ++ include/linux/sunrpc/xprt.h | 5 ++ net/sunrpc/clnt.c | 94 +++++++++++++++++++++++++++++------- net/sunrpc/sunrpc.h | 5 ++ net/sunrpc/xprt.c | 76 +++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+), 17 deletions(-) diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 0dbdf3722537f..dbaad8b5f181c 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -230,6 +230,10 @@ unsigned long rpc_cancel_tasks(struct rpc_clnt *clnt, = int error, bool (*fnmatch)(const struct rpc_task *, const void *), const void *data); +unsigned long rpc_cancel_tasks_and_disconnect(struct rpc_clnt *clnt, int e= rror, + bool (*fnmatch)(const struct rpc_task *, + const void *), + const void *data); void rpc_execute(struct rpc_task *); void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *); void rpc_init_wait_queue(struct rpc_wait_queue *, const char *); diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 005730623f3be..ad8ecf8ccfb48 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -112,6 +112,11 @@ struct rpc_rqst { =20 ktime_t rq_xtime; /* transmit time stamp */ int rq_ntrans; + bool rq_disconnect_on_release; + /* + * protected by rq_xprt->queue_lock + * while the request is active + */ =20 #if defined(CONFIG_SUNRPC_BACKCHANNEL) struct lwq_node rq_bc_list; /* Callback service list */ diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 6cedc824cf826..5c33bf3fb4c34 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -901,29 +901,36 @@ void rpc_killall_tasks(struct rpc_clnt *clnt) } EXPORT_SYMBOL_GPL(rpc_killall_tasks); =20 -/** - * rpc_cancel_tasks - try to cancel a set of RPC tasks - * @clnt: Pointer to RPC client - * @error: RPC task error value to set - * @fnmatch: Pointer to selector function - * @data: User data - * - * Uses @fnmatch to define a set of RPC tasks that are to be cancelled. - * The argument @error must be a negative error value. - */ -unsigned long rpc_cancel_tasks(struct rpc_clnt *clnt, int error, - bool (*fnmatch)(const struct rpc_task *, - const void *), - const void *data) +struct rpc_cancel_disconnect_ctx { + bool (*fnmatch)(const struct rpc_task *task, const void *data); + const void *data; +}; + +static int rpc_mark_xprt_disconnect_on_release(struct rpc_clnt *clnt, + struct rpc_xprt *xprt, + void *arg) +{ + struct rpc_cancel_disconnect_ctx *ctx =3D arg; + + xprt_mark_matching_reqs_disconnect_on_release(xprt, clnt, + ctx->fnmatch, + ctx->data); + return 0; +} + +static unsigned long +__rpc_cancel_tasks(struct rpc_clnt *clnt, int error, + bool (*fnmatch)(const struct rpc_task *, + const void *), + const void *data, + bool disconnect) { struct rpc_task *task; unsigned long count =3D 0; =20 if (list_empty(&clnt->cl_tasks)) return 0; - /* - * Spin lock all_tasks to prevent changes... - */ + spin_lock(&clnt->cl_lock); list_for_each_entry(task, &clnt->cl_tasks, tk_task) { if (!RPC_IS_ACTIVATED(task)) @@ -934,10 +941,63 @@ unsigned long rpc_cancel_tasks(struct rpc_clnt *clnt,= int error, count++; } spin_unlock(&clnt->cl_lock); + + if (disconnect && count) { + struct rpc_cancel_disconnect_ctx ctx =3D { + .fnmatch =3D fnmatch, + .data =3D data, + }; + rpc_clnt_iterate_for_each_xprt(clnt, + rpc_mark_xprt_disconnect_on_release, + &ctx); + } return count; } + +/** + * rpc_cancel_tasks - try to cancel a set of RPC tasks + * @clnt: Pointer to RPC client + * @error: RPC task error value to set + * @fnmatch: Pointer to selector function + * @data: User data + * + * Uses @fnmatch to define a set of RPC tasks that are to be cancelled. + * The argument @error must be a negative error value. + */ +unsigned long rpc_cancel_tasks(struct rpc_clnt *clnt, int error, + bool (*fnmatch)(const struct rpc_task *, + const void *), + const void *data) +{ + return __rpc_cancel_tasks(clnt, error, fnmatch, data, false); +} EXPORT_SYMBOL_GPL(rpc_cancel_tasks); =20 +/** + * rpc_cancel_tasks_and_disconnect - cancel matching RPC tasks + * @clnt: Pointer to RPC client + * @error: RPC task error value to set + * @fnmatch: Pointer to selector function + * @data: User data + * + * Like rpc_cancel_tasks(), but after cancelling matching tasks, marks + * matching in-flight requests so that xprt_release() conditionally + * disconnects the connection generation on which each request was sent. + * + * @fnmatch is called while holding spinlocks and must not sleep. + * + * Returns the number of active tasks matched by @fnmatch. + */ +unsigned long +rpc_cancel_tasks_and_disconnect(struct rpc_clnt *clnt, int error, + bool (*fnmatch)(const struct rpc_task *, + const void *), + const void *data) +{ + return __rpc_cancel_tasks(clnt, error, fnmatch, data, true); +} +EXPORT_SYMBOL_GPL(rpc_cancel_tasks_and_disconnect); + static int rpc_clnt_disconnect_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt, void *dummy) { diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h index e3c6e3b63f0ba..2c0a4532891f0 100644 --- a/net/sunrpc/sunrpc.h +++ b/net/sunrpc/sunrpc.h @@ -43,4 +43,9 @@ void rpc_clients_notifier_unregister(void); void auth_domain_cleanup(void); void svc_sock_update_bufs(struct svc_serv *serv); enum svc_auth_status svc_authenticate(struct svc_rqst *rqstp); +void xprt_mark_matching_reqs_disconnect_on_release(struct rpc_xprt *xprt, + const struct rpc_clnt *clnt, + bool (*fnmatch)(const struct rpc_task *, + const void *), + const void *data); #endif /* _NET_SUNRPC_SUNRPC_H */ diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 48a3618cbb29f..66eca8e4690b6 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1434,6 +1434,69 @@ xprt_request_dequeue_transmit(struct rpc_task *task) spin_unlock(&xprt->queue_lock); } =20 +static bool +xprt_request_matches(const struct rpc_rqst *req, + const struct rpc_clnt *clnt, + bool (*fnmatch)(const struct rpc_task *, const void *), + const void *data) +{ + const struct rpc_task *task =3D req->rq_task; + + return task && task->tk_client =3D=3D clnt && fnmatch(task, data); +} + +/** + * xprt_mark_matching_reqs_disconnect_on_release - mark matching in-flight + * requests for connection-generation + * teardown at release + * @xprt: transport whose queues to walk + * @clnt: RPC client whose requests are eligible + * @fnmatch: selector called with the request's owning rpc_task + * @data: caller data forwarded to @fnmatch + * + * @fnmatch must not sleep and must be safe to call while xprt->queue_lock + * is held. + * + * Walks the transmit queue (including per-owner rq_xmit2 chains) and the + * receive tree under xprt->queue_lock and marks each matching rpc_rqst so + * that xprt_release() will call xprt_conditional_disconnect() against that + * request's snapshotted rq_connect_cookie. Requests remain eligible for m= arking + * while they are present on a transport queue. xprt_release() removes que= ue + * membership under xprt->queue_lock before consuming the marker, so a mar= ker + * installed before dequeue remains associated with that rpc_rqst and cann= ot be + * inherited by a later request using the same rpc_task. + * + * The @clnt qualification preserves the selection domain of + * rpc_cancel_tasks(). An rpc_xprt may be shared by multiple rpc_clnt + * instances, so requests belonging to other clients must not be marked. + */ +void +xprt_mark_matching_reqs_disconnect_on_release(struct rpc_xprt *xprt, + const struct rpc_clnt *clnt, + bool (*fnmatch)(const struct rpc_task *, + const void *), + const void *data) +{ + struct rpc_rqst *req, *pos; + struct rb_node *n; + + spin_lock(&xprt->queue_lock); + list_for_each_entry(req, &xprt->xmit_queue, rq_xmit) { + if (xprt_request_matches(req, clnt, fnmatch, data)) + req->rq_disconnect_on_release =3D true; + list_for_each_entry(pos, &req->rq_xmit2, rq_xmit2) { + if (xprt_request_matches(pos, clnt, fnmatch, data)) + pos->rq_disconnect_on_release =3D true; + } + } + for (n =3D rb_first(&xprt->recv_queue); n; n =3D rb_next(n)) { + req =3D rb_entry(n, struct rpc_rqst, rq_recv); + if (xprt_request_matches(req, clnt, fnmatch, data)) + req->rq_disconnect_on_release =3D true; + } + spin_unlock(&xprt->queue_lock); +} + /** * xprt_request_dequeue_xprt - remove a task from the transmit+receive que= ue * @task: pointer to rpc_task @@ -1915,6 +1978,7 @@ xprt_request_init(struct rpc_task *task) req->rq_rcv_buf.bvec =3D NULL; req->rq_release_snd_buf =3D NULL; req->rq_seqno_count =3D 0; + req->rq_disconnect_on_release =3D false; xprt_init_majortimeo(task, req, task->tk_client->cl_timeout); =20 trace_xprt_reserve(req); @@ -1979,6 +2043,7 @@ void xprt_release(struct rpc_task *task) { struct rpc_xprt *xprt; struct rpc_rqst *req =3D task->tk_rqstp; + bool disconnect; =20 if (req =3D=3D NULL) { if (task->tk_client) { @@ -1990,12 +2055,22 @@ void xprt_release(struct rpc_task *task) =20 xprt =3D req->rq_xprt; xprt_request_dequeue_xprt(task); + + spin_lock(&xprt->queue_lock); + disconnect =3D req->rq_disconnect_on_release; + req->rq_disconnect_on_release =3D false; + spin_unlock(&xprt->queue_lock); + + if (unlikely(disconnect && req->rq_ntrans > 0)) + xprt_conditional_disconnect(xprt, req->rq_connect_cookie); + spin_lock(&xprt->transport_lock); xprt->ops->release_xprt(xprt, task); if (xprt->ops->release_request) xprt->ops->release_request(task); xprt_schedule_autodisconnect(xprt); spin_unlock(&xprt->transport_lock); + if (req->rq_buffer) xprt->ops->buf_free(task); if (req->rq_cred !=3D NULL) @@ -2020,6 +2095,7 @@ xprt_init_bc_request(struct rpc_rqst *req, struct rpc= _task *task, task->tk_rqstp =3D req; req->rq_task =3D task; xprt_init_connect_cookie(req, req->rq_xprt); + req->rq_disconnect_on_release =3D false; /* * Set up the xdr_buf length. * This also indicates that the buffer is XDR encoded already. --=20 2.53.0 From nobody Thu Nov 5 05:11:19 2026 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.216.97 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793844172; b=HZRZwdv6CfINDXIjLR5Qv+s9yy61iIee7mWUD50RPm7uTXXKNDPvx6g8nZR5CaHbgV2d CNMW+Mk/F/O8zRh91aspDTJ1huhimZ2O4+ycB8HwNmMds+C8yw6SL8Mzt6JDHnhblfrzt 0R7FD5Zjpc4Zz0yqNRcynlgJmmXl5jL8UQgwb5xk56QnK7YCw+3pcL+v1Ddzo6by6Flol RGhWrU7Klfc01ZHsN5vm521NeAGHDwkLUgPReriZXqOnQRtterPJo7zrUeJSXWkapHoID 5orMGhwcW5C/KwierduM4sXk6pD0Ijcgk0XtWCmaZz7IcXm4IBVq51cnlzOt0QZEHAg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793844172; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: X-Relaying-Domain:Received:From:To:Cc:Subject:Date:Message-ID: X-Mailer:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=HpFmULoD3PKNQA7nQ1ArjNPpfG8VSqQMXNJlOpOCtTU=; b=eHnfFd8qiJ8iOHlgN5mHXmBIbm1EnIbBJcdq+kSoZ1fSk9i8+je6E0UxaRloBYoyxoiy dUuYO3hV9eF3+7aXYVz0XEM0znKk+2SV8vT32+vrb/iOrH2iXgRkErK6J9O1Fg1P+R0DE w4TWrOptgEtMszqrYX7HXsVesZV4HGKKjatbj1QxxLYLVUqAwIH9ekiCHC+VAkfDyLgqa XAliyAwN5TWSFmumge3C0M5NNduVj5y0mpdGCb9hW0G3y+Pgbu3C8Z/B291lNJFwqOmlb ZCzGIGItfZDM0ak5ilf/jgRw7ewmdDmUiLSO7UcLZSRKkwzh9tKujkDUxBMd39ojYTQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass header.d=purestorage.com header.i=@purestorage.com header.a=rsa-sha256 header.s=google2022 header.b=LB5J9swY; arc=none smtp.remote-ip=209.85.216.97 Received: from mail-pj1-f97.google.com (mail-pj1-f97.google.com [209.85.216.97]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21EF7606D82B for ; Thu, 5 Nov 2026 02:02:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 21EF7606D82B Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=purestorage.com header.i=@purestorage.com header.a=rsa-sha256 header.s=google2022 header.b=LB5J9swY Received: by mail-pj1-f97.google.com with SMTP id 98e67ed59e1d1-3b0afe09854so223522a91.3 for ; Wed, 04 Nov 2026 18:02:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1793844170; x=1794448970; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=HpFmULoD3PKNQA7nQ1ArjNPpfG8VSqQMXNJlOpOCtTU=; b=LB5J9swYrhk+rpnpdAYM+m0KVsDTZ4C4Bx7BBtl7ax5j0XJo3KQPDhhX9bb/vANb28 0lI6V+bsivTqCXJGHe+zZ6dhF6Gk2pj5Myax/kQCbQ60k/qk39nTK0zwl9vMccqEUTKE qBgeSix2/DhK4pR9v61LNGXde4KVGpC5HEkEjsAqPUNokSdH+Td6JupmHX5KaZ67VwvZ y4gu4MuZe5VFL6+Zr1zIFhvKUoYpdUX9CdjScI/p8xyXdVUkIiekxfQRIxxQtLmWPQ4d K9+6SsRG3ctncHS3Mnugm2i5sdt07SJ2zKS1ypflTGEaHhsWY04HetPYUFp1yU2ZiGIx 0wOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793844170; x=1794448970; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=HpFmULoD3PKNQA7nQ1ArjNPpfG8VSqQMXNJlOpOCtTU=; b=yts5nXI665YLodNi+xeIbRNlUvvpxQGEb3d5juCuUzfVI7FHVlLgl+8SzZFAC8pNE2 M0nRxOw9gNqzmF4JSScsKsL9Oa1tafm4Junq+pSDAGRgQ/BOJiD0vNQfU3FMxCQFPHfc g0GhpdU6yJhqUWNrMF+6UlGcU+8qE5MeNMs70nKO79tOlTakqbVmtuEzvD+6/XCBQ0HR AIvgXAYEQ4vSC4nbrqETtfBBgfysckNHemta+asRsr7Gna2pCrr7SNqPFgfOwNAFduzA oBSXr6+qKUXPOmgZze2slLlSWXLfM4ODICDO/ySCQuGHSFlNvoj/jUNJEyHemX3CVl28 05tg== X-Forwarded-Encrypted: i=1; AKwUvByHZPfOeWuQbLbI2pACtuY4aaljoeXSb/B5Y1g+VoWXBPIQ6fnsmuW4xxz2qKB4SK9bIEzRyE+I2n/efZY=@vger.kernel.org X-Gm-Message-State: APuU4Z+qyV/pVB86jVKtutoNjZgxULILXH9xnIG87PkCC9BzD01pXL2o b9wHi67r1Lo+9Rwx919fM3ChBHDmfi60AgGudDn57RF/bauhg/8GgYTO39WhO9k40JXAYml/NmB LCYBOA03s8WbcDeGFejPJp71Hv4zmkO66SBPl X-Gm-Gg: AYBFou0esCwUR8OEtjP8CCTLnc37naOV3DLkH01TozcySCXbtK+l17tbLfhX6LxleR8 K38Xyq001n/QkVln0u0/fkSK8IGv4JiavXYMiRTXkV2Ed/9AMu76Gnbs5qX81AAE5Qlyx4bZwUg JwMpw2c08cqNtmIFhdIqOR+7CPW0cW1SyJ9BOmFPuFJ6h6/KIMD+XBC5sQyVrT9VVzhOu+NRrRI E7JDpZFCSMI1R/TJpD8+18PMFLPxrmAQRSXzx7eR+86N8H17vT5WiOFQQmAWnf55A1QeBqUnjN7 L5dFWVQ/hL8JRs6Irlja0pTKbNjKBuufE0e6YpP5yDJ53n649y1zbELISLlwIQOA5/rkguzRFOJ 0QrdSzVDnZj2Gimc8nyNneMJ+5ziKt+ol7hrJTw== X-Received: by 2002:a17:90b:4d05:b0:3ad:c482:ae93 with SMTP id 98e67ed59e1d1-3ae897f55f1mr15463825a91.27.1793844170366; Wed, 04 Nov 2026 18:02:50 -0800 (PST) Received: from c14-smtp-2023.dev.purestorage.com ([208.88.158.129]) by smtp-relay.gmail.com with ESMTPS id 98e67ed59e1d1-3b0b93e8cf1sm370875a91.8.2026.11.04.18.02.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 18:02:50 -0800 (PST) X-Relaying-Domain: purestorage.com Received: from irdv-tmenninger.dev.purestorage.com (irdv-tmenninger.dev.purestorage.com [10.32.149.15]) by c14-smtp-2023.dev.purestorage.com (Postfix) with ESMTPS id A268D340292; Wed, 4 Nov 2026 18:02:49 -0800 (PST) From: tmenninger@purestorage.com To: anna@kernel.org, trondmy@kernel.org Cc: cel@kernel.org, ebadger@everpuredata.com, jcurley@everpuredata.com, jlayton@kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, netdev@vger.kernel.org, slingappa@everpuredata.com, Tim Menninger Subject: [PATCH v2 2/2] NFSv4/flexfiles: limit transport disconnects when cancelling I/O Date: Thu, 5 Nov 2026 02:02:49 +0000 Message-ID: <20261105020249.2607367-3-tmenninger@purestorage.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261105020249.2607367-1-tmenninger@purestorage.com> References: <20261105020249.2607367-1-tmenninger@purestorage.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Tim Menninger ff_layout_cancel_io() cancels RPC tasks associated with a recalled or revoked layout segment. If any matching tasks are found, it then calls rpc_clnt_disconnect(). rpc_clnt_disconnect() disconnects every transport attached to the RPC client. A data server client can have multiple transports, while the cancelled requests may have used only a subset of them. Cancelling I/O for one layout segment can therefore disrupt unrelated I/O using other transports belonging to the same data server client. This is particularly disruptive with RPC/RDMA during data server recovery, where unnecessary transport disconnects can result in repeated reconnect activity on otherwise unaffected connections. Use rpc_cancel_tasks_and_disconnect() instead. Matching tasks are still cancelled, but only matching requests belonging to that client that remain on the transport transmit or receive queues are marked for disconnect. When such a request is released, SUNRPC conditionally disconnects the connection generation on which that request was sent. This preserves cancellation and draining of I/O associated with the layout segment without disconnecting unrelated transports attached to the same RPC client. Fixes: b739a5bd9d9f ("NFSv4/flexfiles: Cancel I/O if the layout is recalled= or revoked") Signed-off-by: Tim Menninger --- fs/nfs/flexfilelayout/flexfilelayout.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout= /flexfilelayout.c index 9492d6bc1d1a7..700f0e4606e8f 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -2599,10 +2599,9 @@ static void ff_layout_cancel_io(struct pnfs_layout_s= egment *lseg, clnt =3D ds_clp->cl_rpcclient; if (!clnt) goto next; - if (!rpc_cancel_tasks(clnt, -ECANCELED, - ff_layout_match_io, lseg)) - goto next; - rpc_clnt_disconnect(clnt); + rpc_cancel_tasks_and_disconnect(clnt, -ECANCELED, + ff_layout_match_io, + lseg); next: nfs4_ff_layout_put_deviceid(mirror_ds); } --=20 2.53.0