All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kyrylo Biryuk <illofspeed@gmail.com>
To: dm-devel@lists.linux.dev
Cc: mpatocka@redhat.com, snitzer@kernel.org, agk@redhat.com,
	bmarzins@redhat.com, dlemoal@kernel.org, hare@suse.de,
	linux-kernel@vger.kernel.org
Subject: [PATCH v5 4/4] dm zoned: do not busy-loop idle reclaim when no zone needs reclaim
Date: Tue, 13 Oct 2026 16:55:22 +0200	[thread overview]
Message-ID: <20261013145522.17499-5-illofspeed@gmail.com> (raw)
In-Reply-To: <20261013145522.17499-1-illofspeed@gmail.com>

An idle target whose random (and cache) zones are all unmapped keeps its
reclaim work running without pause:

  - since commit 90a9b8693f1b ("dm zoned: reclaim random zones when
    idle"), dmz_should_reclaim() returns true when the target is idle and
    the total number of random (and cache) zones is non-zero, whether or
    not any of them holds data;
  - dmz_do_reclaim() then finds no candidate and returns -EBUSY;
  - dmz_reclaim_work() runs dmz_check_dev(), which checks every device
    for media events (a TEST UNIT READY on SCSI disks), and
    dmz_schedule_reclaim() requeues the work with no delay because
    dmz_should_reclaim() is still true.

Without the previous patch, a pass ending while the target is busy and
has enough free zones can leave reclaim unqueued, which ends the loop;
keeping the idle poll armed makes it recur whenever the target becomes
idle. On three 27 TB host-managed drives used
without cache devices (all random zones free) it kept about three CPUs
busy and sent about 155,000 TEST UNIT READY commands per second to each
drive while the target was idle.

Only reclaim on idle when a random or cache zone actually holds data (the
intent of the "p_unmap < 100" test that commit replaced), and
handle -EBUSY like -ENOSPC: nothing can progress and no I/O failed, so
poll again after the idle period instead of rescheduling at once, and
skip the device check. Use queue_delayed_work() for that poll so work an
allocation has already queued is not postponed.

Fixes: 90a9b8693f1b ("dm zoned: reclaim random zones when idle")
Assisted-by: LLM
Signed-off-by: Kyrylo Biryuk <illofspeed@gmail.com>
---
 drivers/md/dm-zoned-reclaim.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c
index f1f9adf6039..0d62ade1466 100644
--- a/drivers/md/dm-zoned-reclaim.c
+++ b/drivers/md/dm-zoned-reclaim.c
@@ -470,9 +470,10 @@ static unsigned int dmz_reclaim_percentage(struct dmz_reclaim *zrc)
  */
 static bool dmz_should_reclaim(struct dmz_reclaim *zrc, unsigned int p_unmap)
 {
-	unsigned int nr_reclaim;
+	unsigned int nr_reclaim, nr_unmap;
 
 	nr_reclaim = dmz_nr_rnd_zones(zrc->metadata, zrc->dev_idx);
+	nr_unmap = dmz_nr_unmap_rnd_zones(zrc->metadata, zrc->dev_idx);
 
 	if (dmz_nr_cache_zones(zrc->metadata)) {
 		/*
@@ -483,10 +484,11 @@ static bool dmz_should_reclaim(struct dmz_reclaim *zrc, unsigned int p_unmap)
 		if (zrc->dev_idx == 0)
 			return false;
 		nr_reclaim += dmz_nr_cache_zones(zrc->metadata);
+		nr_unmap += dmz_nr_unmap_cache_zones(zrc->metadata);
 	}
 
-	/* Reclaim when idle */
-	if (dmz_target_idle(zrc) && nr_reclaim)
+	/* Reclaim when idle, but only if a random or cache zone holds data */
+	if (dmz_target_idle(zrc) && nr_reclaim > nr_unmap)
 		return true;
 
 	/* If there are still plenty of cache zones, do not reclaim */
@@ -543,17 +545,19 @@ static void dmz_reclaim_work(struct work_struct *work)
 		dmz_nr_rnd_zones(zmd, zrc->dev_idx));
 
 	ret = dmz_do_reclaim(zrc);
+	if (ret == -ENOSPC || ret == -EBUSY) {
+		/*
+		 * No zone to copy into (-ENOSPC) or no zone to reclaim
+		 * (-EBUSY): nothing can progress now and no I/O failed.
+		 * Rescheduling immediately would spin; poll instead, without
+		 * postponing work that an allocation has already queued.
+		 */
+		queue_delayed_work(zrc->wq, &zrc->work, DMZ_IDLE_PERIOD);
+		return;
+	}
 	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


  parent reply	other threads:[~2026-10-13 14:55 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 14:55 [PATCH v5 0/4] dm zoned: fix idle reclaim problems Kyrylo Biryuk
2026-10-13 14:55 ` [PATCH v5 1/4] dm zoned: back off when reclaim finds no destination zone Kyrylo Biryuk
2026-10-13 14:55 ` [PATCH v5 2/4] dm zoned: do not reclaim a random zone into another random zone Kyrylo Biryuk
2026-10-13 14:55 ` [PATCH v5 3/4] dm zoned: keep polling for idle reclaim after a reclaim pass Kyrylo Biryuk
2026-10-13 14:55 ` Kyrylo Biryuk [this message]
2026-10-13 14:59   ` [PATCH v5 4/4] dm zoned: do not busy-loop idle reclaim when no zone needs reclaim Damien Le Moal
2026-10-13 15:47 ` [PATCH v5 0/4] dm zoned: fix idle reclaim problems Mikulas Patocka

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=20261013145522.17499-5-illofspeed@gmail.com \
    --to=illofspeed@gmail.com \
    --cc=agk@redhat.com \
    --cc=bmarzins@redhat.com \
    --cc=dlemoal@kernel.org \
    --cc=dm-devel@lists.linux.dev \
    --cc=hare@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpatocka@redhat.com \
    --cc=snitzer@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 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.