All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] dm zoned: fix two idle reclaim problems
@ 2026-10-13 12:39 Kyrylo Biryuk
  2026-10-13 12:39 ` [PATCH v4 1/3] dm zoned: back off when reclaim finds no destination zone Kyrylo Biryuk
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Kyrylo Biryuk @ 2026-10-13 12:39 UTC (permalink / raw)
  To: dm-devel; +Cc: mpatocka, snitzer, agk, bmarzins, dlemoal, hare, linux-kernel

Changes in v4:
- Patch 1: added the Fixes tag (Damien Le Moal), and the Reviewed-by tags
  from Hannes Reinecke (given on v1; the code is unchanged since) and
  Damien Le Moal.
- Patch 2: added Damien Le Moal's Reviewed-by.
- Patch 3: re-arm the idle poll in dmz_schedule_reclaim() instead of
  open-coding it at the end of dmz_reclaim_work(), as Damien suggested.
  The new branch uses queue_delayed_work(), so zone allocations and
  "reclaim" messages leave an already pending poll or immediate reclaim
  alone.
- Rebased on v7.3-rc7 and tested there (see below).

Mikulas: patchwork shows v3 as accepted. If v3 is already in your tree, I
can send the patch 3 change and the Fixes tag as follow-up patches
instead; please tell me which you prefer.

Changes in v3:
- Patch 2: reworded the comment and dropped the redundant
  dmz_nr_cache_zones() test (Damien Le Moal).

Changes in v2:
- No code changes; only my author address changed.

These patches fix two problems in dm-zoned's reclaim worker, found while
running md RAID5 on three dm-zoned targets on 27 TB host-managed SMR drives
(WD Ultrastar DC HC680), each target with a regular cache device.

1. On a target with cache zones and no free sequential zone, an idle
   target keeps copying random zones into other random zones, forever
   (patch 2; patch 1 makes the resulting -ENOSPC back off instead of
   spinning). After a full md rebuild every chunk is mapped, so this
   happens right after a rebuild: the idle member read and wrote about
   72 MB/s nonstop for hours.

2. After a reclaim pass that ends while the target is busy, the idle poll
   is never re-armed, so zones filled under load are not reclaimed when the
   target goes idle (patch 3). Users notice it as "the buffer never drains";
   the workaround has been a timer sending "dmsetup message <dev> 0 reclaim".

Testing on v7.3-rc7 (kernel built from the tag, in a VM):
- reproducer with no special hardware (scsi_debug zbc=managed, 64 MiB
  zones, plus a 1 GiB loop cache device), idle target with no free
  sequential zone, 120 s: stock module 500-660 MB/s of read and the same
  of write in two runs, zone counters unchanged; with this series 0 MB/s:
  https://github.com/illofspeed/synology-host-managed-smr/tree/main/repro
- a small md RAID5 of three dm-zoned targets on emulated host-managed
  drives (tcmu-runner ZBC handler), LUKS and XFS on top: module swapped in
  and out with the files' checksums verified each time; after a 2 GiB
  write burst the filled random zones of all three targets were reclaimed
  within two minutes of going idle, with no "reclaim" message.
Earlier versions of the series have run on 7.2.6 on the three real drives
since 2026-10-05; the v4 form of patch 3 has not run there yet.

Related, not addressed here: the double-free in dmz_load_sb() reported on
dm-devel on 2026-05-30. Also not addressed: a "reclaim" message sent to a
suspended target can already queue reclaim today when reclaim is needed;
with patch 3 it can also queue the idle poll. If you would rather avoid
that, I can keep the re-arm at the end of dmz_reclaim_work() instead (as
in v3, with queue_delayed_work()), or send a separate patch that makes the
message do nothing on a suspended target.

The problems were found and the patches written with the help of an AI
coding assistant (hence Assisted-by); the analysis, the tests and this
description were reviewed by me.

Kyrylo Biryuk (3):
  dm zoned: back off when reclaim finds no destination zone
  dm zoned: do not reclaim a random zone into another random zone
  dm zoned: keep polling for idle reclaim after a reclaim pass

 drivers/md/dm-zoned-reclaim.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4 1/3] dm zoned: back off when reclaim finds no destination zone
  2026-10-13 12:39 [PATCH v4 0/3] dm zoned: fix two idle reclaim problems Kyrylo Biryuk
@ 2026-10-13 12:39 ` Kyrylo Biryuk
  2026-10-13 12:39 ` [PATCH v4 2/3] dm zoned: do not reclaim a random zone into another random zone Kyrylo Biryuk
  2026-10-13 12:39 ` [PATCH v4 3/3] dm zoned: keep polling for idle reclaim after a reclaim pass Kyrylo Biryuk
  2 siblings, 0 replies; 5+ messages in thread
From: Kyrylo Biryuk @ 2026-10-13 12:39 UTC (permalink / raw)
  To: dm-devel; +Cc: mpatocka, snitzer, agk, bmarzins, dlemoal, hare, linux-kernel

When dmz_do_reclaim() fails with -ENOSPC because no free zone is
available to copy the data into, dmz_reclaim_work() still ends with
dmz_schedule_reclaim(). If the target is idle, dmz_should_reclaim()
keeps returning true, the work is queued again with no delay and the
worker spins on the same failing pass.

Re-arm the idle poll instead, so that reclaim is retried after
DMZ_IDLE_PERIOD. The next patch makes -ENOSPC the expected result when
an idle target has random zones but no free sequential zone.

Tested on 7.3-rc7 together with the next two patches, on emulated
host-managed drives (scsi_debug zbc=managed, and the tcmu-runner ZBC
handler under md RAID5). Earlier versions of the series ran on 7.2.6 on
three 27 TB host-managed drives used as md RAID5 members.

Fixes: 3b1a94c88b79 ("dm zoned: drive-managed zoned block device target")
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Assisted-by: LLM
Signed-off-by: Kyrylo Biryuk <illofspeed@gmail.com>
---
 drivers/md/dm-zoned-reclaim.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c
index c041413c729..315f0da99f3 100644
--- a/drivers/md/dm-zoned-reclaim.c
+++ b/drivers/md/dm-zoned-reclaim.c
@@ -540,6 +540,14 @@ static void dmz_reclaim_work(struct work_struct *work)
 	if (ret && ret != -EINTR) {
 		if (!dmz_check_dev(zmd))
 			return;
+		if (ret == -ENOSPC) {
+			/*
+			 * No zone to copy into: nothing can progress now.
+			 * Rescheduling immediately would spin; poll instead.
+			 */
+			mod_delayed_work(zrc->wq, &zrc->work, DMZ_IDLE_PERIOD);
+			return;
+		}
 	}
 
 	dmz_schedule_reclaim(zrc);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v4 2/3] dm zoned: do not reclaim a random zone into another random zone
  2026-10-13 12:39 [PATCH v4 0/3] dm zoned: fix two idle reclaim problems Kyrylo Biryuk
  2026-10-13 12:39 ` [PATCH v4 1/3] dm zoned: back off when reclaim finds no destination zone Kyrylo Biryuk
@ 2026-10-13 12:39 ` Kyrylo Biryuk
  2026-10-13 12:39 ` [PATCH v4 3/3] dm zoned: keep polling for idle reclaim after a reclaim pass Kyrylo Biryuk
  2 siblings, 0 replies; 5+ messages in thread
From: Kyrylo Biryuk @ 2026-10-13 12:39 UTC (permalink / raw)
  To: dm-devel; +Cc: mpatocka, snitzer, agk, bmarzins, dlemoal, hare, linux-kernel

dmz_reclaim_rnd_data() falls back to a random destination zone when no
free sequential zone is available and the target has cache zones. When
the target is idle and the cache zone list is empty,
dmz_get_rnd_zone_for_reclaim() selects random zones of the zoned device
as well, so a random zone is then copied into another random zone. That
frees nothing: the next pass picks the next random zone and copies it
again, for as long as the target stays idle.

Seen on a two-device target (256 GiB regular cache device plus a 27 TB
host-managed drive) used as an md RAID5 member: after a full rebuild
every chunk was mapped and no sequential zone was free, and the idle
drive read and wrote about 72 MB/s each without pause for hours while
the free zone counters in "dmsetup status" did not change. Reproduced on
emulated host-managed drives (tcmu-runner ZBC handler): 340 MB/s of
copying on an idle target, 0 MB/s with this patch.

Only switch to a random destination zone when the zone being reclaimed
is a cache zone: moving it to the zoned device still frees cache space.

Fixes: c5c788595292 ("dm zoned: start reclaim with sequential zones")
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Assisted-by: LLM
Signed-off-by: Kyrylo Biryuk <illofspeed@gmail.com>
---
 drivers/md/dm-zoned-reclaim.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c
index 315f0da99f3..88d56d3c86d 100644
--- a/drivers/md/dm-zoned-reclaim.c
+++ b/drivers/md/dm-zoned-reclaim.c
@@ -288,7 +288,13 @@ static int dmz_reclaim_rnd_data(struct dmz_reclaim *zrc, struct dm_zone *dzone)
 again:
 	szone = dmz_alloc_zone(zmd, zrc->dev_idx,
 			       alloc_flags | DMZ_ALLOC_RECLAIM);
-	if (!szone && alloc_flags == DMZ_ALLOC_SEQ && dmz_nr_cache_zones(zmd)) {
+	/*
+	 * If no free sequential zone is available, a cache zone can still be
+	 * moved into a free random zone of the zoned device, which frees cache
+	 * space. Do not do this for a random zone: moving it into another
+	 * random zone frees nothing and, on an idle target, repeats forever.
+	 */
+	if (!szone && alloc_flags == DMZ_ALLOC_SEQ && dmz_is_cache(dzone)) {
 		alloc_flags = DMZ_ALLOC_RND;
 		goto again;
 	}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v4 3/3] dm zoned: keep polling for idle reclaim after a reclaim pass
  2026-10-13 12:39 [PATCH v4 0/3] dm zoned: fix two idle reclaim problems Kyrylo Biryuk
  2026-10-13 12:39 ` [PATCH v4 1/3] dm zoned: back off when reclaim finds no destination zone Kyrylo Biryuk
  2026-10-13 12:39 ` [PATCH v4 2/3] dm zoned: do not reclaim a random zone into another random zone Kyrylo Biryuk
@ 2026-10-13 12:39 ` Kyrylo Biryuk
  2026-10-13 12:48   ` Damien Le Moal
  2 siblings, 1 reply; 5+ messages in thread
From: Kyrylo Biryuk @ 2026-10-13 12:39 UTC (permalink / raw)
  To: dm-devel; +Cc: mpatocka, snitzer, agk, bmarzins, dlemoal, hare, linux-kernel

dmz_reclaim_work() re-arms its DMZ_IDLE_PERIOD poll only when
dmz_should_reclaim() returns false at the start of a pass (and, with the
first patch of this series, when a pass fails with -ENOSPC). After a pass
it calls dmz_schedule_reclaim(), which queues the work only if reclaim
is needed right now. When a pass ends while the target is still busy and
has enough free zones, nothing is queued at all. Once the target goes
idle, nothing re-evaluates dmz_should_reclaim() until another zone
allocation, a "reclaim" message or a resume schedules the work, so the
random or cache zones that filled up under load stay full.

Seen on md RAID5 members on 27 TB host-managed drives: after heavy
writes the random zones stayed full for hours on idle targets; the
workaround was a timer sending "dmsetup message <dev> 0 reclaim". With
this patch the emptied and filled zones were reclaimed within minutes of
the targets going idle, without the timer.

When reclaim is not needed right now, make dmz_schedule_reclaim() queue
the idle poll, so the work stays queued after every pass. It uses
queue_delayed_work(), which leaves already pending work alone, so the
other callers (zone allocation and the "reclaim" message) neither
postpone a pending poll nor delay a pending immediate reclaim.

Fixes: 3b1a94c88b79 ("dm zoned: drive-managed zoned block device target")
Assisted-by: LLM
Signed-off-by: Kyrylo Biryuk <illofspeed@gmail.com>
---
 drivers/md/dm-zoned-reclaim.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c
index 88d56d3c86d..f1f9adf6039 100644
--- a/drivers/md/dm-zoned-reclaim.c
+++ b/drivers/md/dm-zoned-reclaim.c
@@ -641,7 +641,8 @@ void dmz_reclaim_bio_acc(struct dmz_reclaim *zrc)
 }
 
 /*
- * Start reclaim if necessary.
+ * Start reclaim if necessary. Otherwise make sure that an idle poll stays
+ * queued, without delaying work that is already pending.
  */
 void dmz_schedule_reclaim(struct dmz_reclaim *zrc)
 {
@@ -649,4 +650,6 @@ void dmz_schedule_reclaim(struct dmz_reclaim *zrc)
 
 	if (dmz_should_reclaim(zrc, p_unmap))
 		mod_delayed_work(zrc->wq, &zrc->work, 0);
+	else
+		queue_delayed_work(zrc->wq, &zrc->work, DMZ_IDLE_PERIOD);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 3/3] dm zoned: keep polling for idle reclaim after a reclaim pass
  2026-10-13 12:39 ` [PATCH v4 3/3] dm zoned: keep polling for idle reclaim after a reclaim pass Kyrylo Biryuk
@ 2026-10-13 12:48   ` Damien Le Moal
  0 siblings, 0 replies; 5+ messages in thread
From: Damien Le Moal @ 2026-10-13 12:48 UTC (permalink / raw)
  To: Kyrylo Biryuk, dm-devel
  Cc: mpatocka, snitzer, agk, bmarzins, hare, linux-kernel

On 2026/10/13 14:39, Kyrylo Biryuk wrote:
> dmz_reclaim_work() re-arms its DMZ_IDLE_PERIOD poll only when
> dmz_should_reclaim() returns false at the start of a pass (and, with the
> first patch of this series, when a pass fails with -ENOSPC). After a pass
> it calls dmz_schedule_reclaim(), which queues the work only if reclaim
> is needed right now. When a pass ends while the target is still busy and
> has enough free zones, nothing is queued at all. Once the target goes
> idle, nothing re-evaluates dmz_should_reclaim() until another zone
> allocation, a "reclaim" message or a resume schedules the work, so the
> random or cache zones that filled up under load stay full.
> 
> Seen on md RAID5 members on 27 TB host-managed drives: after heavy
> writes the random zones stayed full for hours on idle targets; the
> workaround was a timer sending "dmsetup message <dev> 0 reclaim". With
> this patch the emptied and filled zones were reclaimed within minutes of
> the targets going idle, without the timer.
> 
> When reclaim is not needed right now, make dmz_schedule_reclaim() queue
> the idle poll, so the work stays queued after every pass. It uses
> queue_delayed_work(), which leaves already pending work alone, so the
> other callers (zone allocation and the "reclaim" message) neither
> postpone a pending poll nor delay a pending immediate reclaim.
> 
> Fixes: 3b1a94c88b79 ("dm zoned: drive-managed zoned block device target")
> Assisted-by: LLM
> Signed-off-by: Kyrylo Biryuk <illofspeed@gmail.com>

Reviewed-by: Damien Le Moal <dlemoal@kernel.org>

-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-13 12:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 12:39 [PATCH v4 0/3] dm zoned: fix two idle reclaim problems Kyrylo Biryuk
2026-10-13 12:39 ` [PATCH v4 1/3] dm zoned: back off when reclaim finds no destination zone Kyrylo Biryuk
2026-10-13 12:39 ` [PATCH v4 2/3] dm zoned: do not reclaim a random zone into another random zone Kyrylo Biryuk
2026-10-13 12:39 ` [PATCH v4 3/3] dm zoned: keep polling for idle reclaim after a reclaim pass Kyrylo Biryuk
2026-10-13 12:48   ` Damien Le Moal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.