From: Tim Menninger <tmenninger@everpuredata.com>
To: trondmy@kernel.org, anna@kernel.org
Cc: bcodding@hammerspace.com, Eric Badger <ebadger@everpuredata.com>,
Jon Curley <jcurley@everpuredata.com>,
Prabhakar Pujeri <prabhakar.pujeri@dell.com>,
linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: [PATCH v2] pNFS: avoid repeatedly cancelling I/O for the same lseg
Date: Thu, 5 Nov 2026 00:01:31 +0000 [thread overview]
Message-ID: <20261105000131.2512336-1-tmenninger@everpuredata.com> (raw)
Commit b739a5bd9d9f ("NFSv4/flexfiles: Cancel I/O if the layout is
recalled or revoked") added I/O cancellation when a layout segment is
invalidated while outstanding references remain.
The invalid segment stays on the layout's segment list until those
references drain. Subsequent scans can find it again and repeatedly
invoke the layout driver's cancel_io() callback. For flexfiles, this
cancels matching RPC tasks and disconnects data server RPC clients.
During RPC/RDMA data server recovery, repeated cancellation can cause a
reconnect loop that consumes essentially all client CPU and prevents
forward progress.
Record cancellation requests per mirror stripe in the flexfiles layout
segment. Each stripe is cancelled at most once, regardless of how many
times the invalid segment is encountered. A per-stripe bitmap rather
than a single per-segment bit preserves the ability to cancel I/O to a
different device after an earlier device-specific cancellation.
Cancellation is best-effort. An RPC that has already passed the
layout-validity check may not yet be visible to the cancellation
scan. Such I/O retains its lseg reference and remains subject to
the normal RPC completion and recovery paths. Suppress repeated
cancellation and disconnect requests without changing the existing
lseg lifetime and deferred layout-return accounting.
This reproduced on 6.8.0, 7.0.0, and 7.4.0-rc1. It was tested on
7.4.0-rc1 with sustained pNFS/flexfiles I/O over RPC/RDMA while
restarting the NFS service on a data server. Without it, repeated
cancellation led to a reconnect loop and no workload recovery. With it,
the client recovered after the data server returned.
Fixes: b739a5bd9d9f ("NFSv4/flexfiles: Cancel I/O if the layout is recalled or revoked")
Cc: stable@vger.kernel.org
Signed-off-by: Tim Menninger <tmenninger@everpuredata.com>
---
Changes in v2:
- Rework cancellation tracking to accommodate per-device cancellation.
- Track cancellation per stripe rather than per layout segment.
- Clarify that cancellation is best-effort.
- Document the data-server restart reproducer.
- Drop Reviewed-by tag due to substantial implementation changes.
v1: https://lore.kernel.org/all/20260916232906.4101987-1-tmenninger@everpuredata.com/
fs/nfs/flexfilelayout/flexfilelayout.c | 12 ++++++++++++
fs/nfs/flexfilelayout/flexfilelayout.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 9492d6bc1d1a7..4419ded8fe586 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -11,6 +11,7 @@
#include <linux/nfs_mount.h>
#include <linux/nfs_page.h>
#include <linux/module.h>
+#include <linux/bitmap.h>
#include <linux/file.h>
#include <linux/sched/mm.h>
@@ -340,6 +341,7 @@ static void _ff_layout_free_lseg(struct nfs4_ff_layout_segment *fls)
{
if (fls) {
ff_layout_free_mirror_array(fls);
+ bitmap_free(fls->cancelled_stripes);
kfree(fls);
}
}
@@ -653,6 +655,12 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
fls->mirror_array[i]->report_interval = be32_to_cpup(p);
out_sort_mirrors:
+ fls->cancelled_stripes = bitmap_zalloc(
+ fls->mirror_array_cnt * dss_count, gfp_flags);
+ if (!fls->cancelled_stripes) {
+ rc = -ENOMEM;
+ goto out_err_free;
+ }
ff_layout_sort_mirrors(fls);
ret = &fls->generic_hdr;
dprintk("<-- %s (success)\n", __func__);
@@ -2582,6 +2590,10 @@ static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg,
if (devid && memcmp(&mirror->dss[dss_id].devid, devid,
sizeof(*devid)) != 0)
continue;
+ /* Do not cancel a stripe again while this lseg drains. */
+ if (test_and_set_bit(idx * mirror->dss_count + dss_id,
+ flseg->cancelled_stripes))
+ continue;
rcu_read_lock();
mirror_ds = rcu_dereference(mirror->dss[dss_id].mirror_ds);
if (IS_ERR_OR_NULL(mirror_ds) ||
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h
index 09c3cd6964fd6..5d5587fded76f 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.h
+++ b/fs/nfs/flexfilelayout/flexfilelayout.h
@@ -109,6 +109,7 @@ struct nfs4_ff_layout_segment {
u64 stripe_unit;
u32 flags;
u32 mirror_array_cnt;
+ unsigned long *cancelled_stripes;
struct nfs4_ff_layout_mirror *mirror_array[] __counted_by(mirror_array_cnt);
};
--
2.53.0
next reply other threads:[~2026-11-05 0:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 0:01 Tim Menninger [this message]
2026-11-05 2:39 ` Trond Myklebust
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261105000131.2512336-1-tmenninger@everpuredata.com \
--to=tmenninger@everpuredata.com \
--cc=anna@kernel.org \
--cc=bcodding@hammerspace.com \
--cc=ebadger@everpuredata.com \
--cc=jcurley@everpuredata.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=prabhakar.pujeri@dell.com \
--cc=stable@vger.kernel.org \
--cc=trondmy@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®