From: "Chen Cheng" <chencheng@fnnas.com>
To: <linux-raid@vger.kernel.org>, <yukuai@fygo.io>, <xiaon@kernel.org>
Cc: <chencheng@fnnas.com>, <linux-kernel@vger.kernel.org>
Subject: [RFC PATCH 3/5] md/raid1: do not send random reads to a rot disk
Date: Tue, 18 Aug 2026 15:06:44 +0800 [thread overview]
Message-ID: <20260818070646.1029149-4-chencheng@fnnas.com> (raw)
In-Reply-To: <20260818070646.1029149-1-chencheng@fnnas.com>
From: Chen Cheng <chencheng@fnnas.com>
The previous change keeps sequential nonrot I/O off a rot disk.
Current:
1. Sequential reads stay on nonrot when a nonrot disk is readable.
2. Random reads still pick the disk with the lowest nr_pending.
3. Rot disks also join that compare.
Problem:
1. A nonrot disk is fast. It can have more pending I/O.
2. A rot disk is slow. It can have fewer pending I/O.
3. Then the next random read goes to the rot disk.
4. Why send a random 4k read to the slow disk?
Improve:
1. If a nonrot disk is readable, do not use rot disks for
min_pending.
2. Random reads stay on nonrot disks.
3. If no nonrot disk is readable, still pick a rot disk by head
position.
Tested with fio libaio direct=1 (NVMe scheduler none, SATA
scheduler mq-deadline):
- RAID1 of Predator GM9000 + SATA HDD:
4k randread QD1 jobs=1: 0.097 GB/s, 100/0 NVMe -> 0.084 GB/s,
100/0 NVMe. Both disks have pending 0, so stock already stayed
on NVMe.
4k randread QD8 jobs=1: 0.363 GB/s, 99.6/0.4 NVMe/HDD,
clat 87 us -> 0.671 GB/s, 100/0 NVMe, clat 46 us (-47%)
4k randread QD16 jobs=1: 0.668 GB/s, 99.7/0.3 NVMe/HDD,
clat 95 us -> 1.215 GB/s, 100/0 NVMe, clat 52 us (-45%)
- RAID1 of Fanxiang S103Pro + SATA HDD:
4k randread QD1 jobs=1: 0.077 GB/s, 100/0 Fanxiang -> 0.073 GB/s,
100/0 Fanxiang
4k randread QD8 jobs=1: 0.278 GB/s, 99.5/0.5 Fanxiang/HDD,
clat 114 us -> 0.389 GB/s, 100/0 Fanxiang, clat 78 us (-31%)
4k randread QD16 jobs=1: 0.395 GB/s, 99.6/0.4 Fanxiang/HDD,
clat 162 us -> 0.398 GB/s, 100/0 Fanxiang, clat 159 us
(already at the Fanxiang limit)
Signed-off-by: Chen Cheng <chencheng@fnnas.com>
---
drivers/md/raid1.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 36520e48826f..523b55d42779 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -832,10 +832,11 @@ static int choose_best_rdev(struct r1conf *conf, struct r1bio *r1_bio)
for (disk = 0 ; disk < conf->raid_disks * 2 ; disk++) {
struct md_rdev *rdev;
sector_t dist;
unsigned int pending;
bool nonrot;
+ bool can_pick;
if (r1_bio->bios[disk] == IO_BLOCKED)
continue;
rdev = conf->mirrors[disk].rdev;
@@ -848,15 +849,16 @@ 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);
+ can_pick = nonrot || !has_nonrot;
/* Don't change to another disk for sequential reads */
if (is_sequential(conf, disk, r1_bio)) {
if (!should_choose_next(conf, disk) && !pending &&
- (nonrot || !has_nonrot))
+ can_pick)
return disk;
/*
* Add 'pending' to avoid choosing this disk if
* there is other idle disk.
@@ -871,11 +873,12 @@ static int choose_best_rdev(struct r1conf *conf, struct r1bio *r1_bio)
ctl.sequential_disk = disk;
ctl.sequential_nonrot = nonrot;
}
}
- if (is_better_disk(pending, disk, nonrot, &ctl,
+ if (can_pick &&
+ 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;
}
--
2.55.0
next prev parent reply other threads:[~2026-08-18 7:07 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
2026-08-18 7:06 ` Chen Cheng [this message]
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=20260818070646.1029149-4-chencheng@fnnas.com \
--to=chencheng@fnnas.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-raid@vger.kernel.org \
--cc=xiaon@kernel.org \
--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 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.