From: sashiko-bot@kernel.org
To: "Chen Cheng" <chencheng@fnnas.com>
Cc: linux-raid@vger.kernel.org, yukuai@fygo.io
Subject: Re: [RFC PATCH 2/5] md/raid1: do not move nonrot reads onto a rot disk
Date: Tue, 18 Aug 2026 07:26:22 +0000 [thread overview]
Message-ID: <20260818072623.1DDB71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260818070646.1029149-3-chencheng@fnnas.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Sequential and distance-based heuristics are broken for rotational disks when non-rotational disks fail because `has_nonrot` does not check readability.
- [High] Sequential reads on rotational disks will thrash in mixed arrays because idle sequential disks fail the early-return check and are artificially penalized.
--
--- Patch [2]: [RFC PATCH 2/5] md/raid1: do not move nonrot reads onto a rot disk ---
commit bee044f7822d405084d8b841ba855a8f7a81b6a4
Author: Chen Cheng <chencheng@fnnas.com>
md/raid1: do not move nonrot reads onto a rot disk
This patch updates the read balancing logic in RAID1 to prefer non-rotational
disks over rotational ones in mixed arrays. It modifies choose_best_rdev() to
ensure that non-rotational disks are favored during sequential I/O and
round-robin selection, aiming to prevent rotational disks from slowing down
faster NVMe or SSD drives.
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index 319b24bcab5b7..36520e48826f2 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
[ ... ]
> @@ -829,10 +849,12 @@ static int choose_best_rdev(struct r1conf *conf, struct r1bio *r1_bio)
> pending = atomic_read(&rdev->nr_pending);
> dist = abs(r1_bio->sector -
> READ_ONCE(conf->mirrors[disk].head_position));
> + nonrot = test_bit(Nonrot, &rdev->flags);
>
> /* Don't change to another disk for sequential reads */
> if (is_sequential(conf, disk, r1_bio)) {
> - if (!should_choose_next(conf, disk) && !pending)
> + if (!should_choose_next(conf, disk) && !pending &&
> + (nonrot || !has_nonrot))
> return disk;
[Severity: High]
Does has_nonrot check if the non-rotational disks are actually readable?
Since has_nonrot is initialized as READ_ONCE(conf->nonrot_disks) at the top
of the function, it appears to evaluate to true if non-rotational disks are
configured in the array, even if they have failed, are rebuilding, or have
bad blocks.
If the non-rotational disks are unreadable, and we are evaluating a
sequential read on a rotational disk, (nonrot || !has_nonrot) will evaluate
to false. This causes the logic to bypass the early return for the
sequential disk.
[Severity: High]
Will this logic also cause sequential reads to thrash between idle rotational
disks in a healthy mixed array?
If the array has non-rotational disks (has_nonrot == true) that are currently
busy, but multiple rotational disks are idle:
1. A sequential read for HDD1 is evaluated.
2. The early return is bypassed because (nonrot || !has_nonrot) is false.
3. HDD1's pending count is artificially incremented to 1 via pending++.
4. HDD2 is evaluated, and since it is idle (pending == 0), it wins the
min_pending contest against HDD1.
> /*
> @@ -844,17 +866,18 @@ static int choose_best_rdev(struct r1conf *conf, struct r1bio *r1_bio)
> * If there is no other idle disk, this disk
> * will be chosen.
> */
> - ctl.sequential_disk = disk;
> + if (ctl.sequential_disk < 0 ||
> + (nonrot && !ctl.sequential_nonrot)) {
> + ctl.sequential_disk = disk;
> + ctl.sequential_nonrot = nonrot;
> + }
> }
>
> - if (ctl.min_pending > pending ||
> - (has_nonrot && ctl.min_pending == pending &&
> - ctl.min_pending_disk >= 0 &&
> - raid1_rr_pos(disk, rr_start, conf->raid_disks) <
> - raid1_rr_pos(ctl.min_pending_disk, rr_start,
> - conf->raid_disks))) {
> + if (is_better_disk(pending, disk, nonrot, &ctl,
> + rr_start, conf->raid_disks)) {
> ctl.min_pending = pending;
> ctl.min_pending_disk = disk;
> + ctl.min_pending_nonrot = nonrot;
> }
>
> if (ctl.closest_dist > dist) {
> @@ -867,7 +890,8 @@ static int choose_best_rdev(struct r1conf *conf, struct r1bio *r1_bio)
> * sequential IO size exceeds optimal iosize, however, there is no other
> * idle disk, so choose the sequential disk.
> */
> - if (ctl.sequential_disk != -1 && ctl.min_pending != 0)
> + if (ctl.sequential_disk != -1 && ctl.min_pending != 0 &&
> + (ctl.sequential_nonrot || !has_nonrot))
> return ctl.sequential_disk;
[Severity: High]
Is it intentional that the sequential disk fallback is bypassed here?
Because HDD2 was idle (ctl.min_pending == 0), this sequential fallback
condition fails. The function will then fall through and return
ctl.min_pending_disk (HDD2), moving the I/O away from the sequential disk
(HDD1) and causing the read to ping-pong between the rotational disks.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260818070646.1029149-1-chencheng@fnnas.com?part=2
next prev parent reply other threads:[~2026-08-18 7:26 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 7:06 [RFC PATCH 0/5] md/raid1: improve choose_best_rdev read balance Chen Cheng
2026-08-18 7:06 ` [RFC PATCH 1/5] md/raid1: balance reads across non-rotational disks Chen Cheng
2026-08-18 7:16 ` sashiko-bot
2026-08-18 7:06 ` [RFC PATCH 2/5] md/raid1: do not move nonrot reads onto a rot disk Chen Cheng
2026-08-18 7:26 ` sashiko-bot [this message]
2026-08-18 7:06 ` [RFC PATCH 3/5] md/raid1: do not send random reads to " Chen Cheng
2026-08-18 7:06 ` [RFC PATCH 4/5] md/raid1: use rot policy when no nonrot disk is readable Chen Cheng
2026-08-18 7:34 ` sashiko-bot
2026-08-18 7:06 ` [RFC PATCH 5/5] md/raid1: clarify choose_best_rdev comments Chen Cheng
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=20260818072623.1DDB71F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=chencheng@fnnas.com \
--cc=linux-raid@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yukuai@fygo.io \
/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