[RFC PATCH 5/5] md/raid1: clarify choose_best_rdev comments

From: Chen Cheng

Date: Tue Aug 18 2026 - 03:16:22 EST


From: Chen Cheng <chencheng@xxxxxxxxx>

Write the rot/nonrot read policy in short comments next to the code.

No functional change.

Signed-off-by: Chen Cheng <chencheng@xxxxxxxxx>
---
drivers/md/raid1.c | 48 +++++++++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index f476d4dea4be..897eef3a022d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -788,15 +788,17 @@ struct read_balance_ctl {
int readable_disks;
bool min_pending_nonrot;
bool sequential_nonrot;
};

+/* Offset from rr start. Replacement uses the same slot as primary. */
static int raid1_rr_pos(int disk, int start, int n)
{
return ((disk % n) - start + n) % n;
}

+/* True if some readable member is nonrot. */
static bool raid1_has_readable_nonrot(struct r1conf *conf,
struct r1bio *r1_bio)
{
int disk;

@@ -811,10 +813,11 @@ static bool raid1_has_readable_nonrot(struct r1conf *conf,
return true;
}
return false;
}

+/* Lower pending wins. Same pending: prefer nonrot, then rr order. */
static bool is_better_disk(unsigned int pending, int disk, bool nonrot,
const struct read_balance_ctl *ctl,
int rr_start, int n)
{
if (ctl->min_pending_disk < 0)
@@ -828,10 +831,24 @@ static bool is_better_disk(unsigned int pending, int disk, bool nonrot,
return nonrot && ctl->min_pending_nonrot &&
raid1_rr_pos(disk, rr_start, n) <
raid1_rr_pos(ctl->min_pending_disk, rr_start, n);
}

+/*
+ * Choose a readable disk for this read.
+ *
+ * Prefer nonrot. Use rot only if no nonrot disk is readable.
+ *
+ * Sequential idle: keep this disk. Mixed array: do not keep a
+ * rot disk (after a write every disk looks sequential).
+ * Sequential busy: try an idle disk of the same class. If none
+ * is idle, keep the sequential disk.
+ *
+ * Else fewest pending I/Os among disks we may pick. Same
+ * pending: nonrot, then round-robin. Rot-only with no idle
+ * disk: closest head.
+ */
static int choose_best_rdev(struct r1conf *conf, struct r1bio *r1_bio)
{
int disk;
int rr_start = 0;
bool has_nonrot = raid1_has_readable_nonrot(conf, r1_bio);
@@ -867,26 +884,32 @@ 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);
+ /*
+ * If a nonrot disk is readable, pick only nonrot.
+ * Else we must use rot.
+ */
can_pick = nonrot || !has_nonrot;

- /* Don't change to another disk for sequential reads */
+ /*
+ * Idle sequential disk: return it now, unless
+ * should_choose_next() wants another disk.
+ * Mixed array: do not return a rot disk.
+ */
if (is_sequential(conf, disk, r1_bio)) {
if (!should_choose_next(conf, disk) && !pending &&
can_pick)
return disk;

- /*
- * Add 'pending' to avoid choosing this disk if
- * there is other idle disk.
- */
+ /* Make an idle disk win over this busy one. */
pending++;
/*
- * If there is no other idle disk, this disk
- * will be chosen.
+ * Remember the first sequential disk.
+ * A nonrot disk may replace a rot disk.
+ * A later nonrot disk may not replace an earlier one.
*/
if (ctl.sequential_disk < 0 ||
(nonrot && !ctl.sequential_nonrot)) {
ctl.sequential_disk = disk;
ctl.sequential_nonrot = nonrot;
@@ -906,22 +929,21 @@ static int choose_best_rdev(struct r1conf *conf, struct r1bio *r1_bio)
ctl.closest_dist_disk = disk;
}
}

/*
- * sequential IO size exceeds optimal iosize, however, there is no other
- * idle disk, so choose the sequential disk.
+ * Keep the sequential disk if no idle peer should take it.
+ * If a nonrot disk is readable: keep only a nonrot sequential disk.
+ * If not: an idle rot disk may take it.
*/
if (ctl.sequential_disk != -1 && ctl.min_pending != 0 &&
(ctl.sequential_nonrot || !has_nonrot))
return ctl.sequential_disk;

/*
- * If all disks are rotational, choose the closest disk. If any disk is
- * non-rotational, choose the disk with less pending request even the
- * disk is rotational, which might/might not be optimal for raids with
- * mixed ratation/non-rotational disks depending on workload.
+ * No readable nonrot disk: closest disk, unless some disk is idle.
+ * Some readable nonrot disk: that nonrot disk with fewest pending I/Os.
*/
if (ctl.min_pending_disk != -1 &&
(has_nonrot || ctl.min_pending == 0))
return ctl.min_pending_disk;
else
--
2.55.0