Thread (21 messages) 21 messages, 4 authors, 3d ago

Re: [PATCH v4 1/7] md/raid10: fix r10bio leak in raid10_write_request() error paths

From: sashiko-bot@kernel.org
Date: 2026-07-10 10:31:49

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Allocation of `r10_bio` with `GFP_NOIO` can sleep, violating `REQ_NOWAIT` semantics.
- [High] Functions in the IO path (`wait_blocked_dev()` and `wait_barrier()`) sleep unconditionally, violating `REQ_NOWAIT` semantics.
--
--- Patch [1]: [PATCH v4 1/7] md/raid10: fix r10bio leak in raid10_write_request() error paths ---
commit d87114f7731cb53cc142eafbf2338e5b721f84ad
Author: Abd-Alrhman Masalkhi [off-list ref]

md/raid10: fix r10bio leak in raid10_write_request() error paths

When raid10_write_request() fails because REQ_NOWAIT is set, the
allocated r10_bio is not freed before returning, resulting in a memory
leak. Free r10_bio before returning from the REQ_NOWAIT error paths.

Closes: https://lore.kernel.org/linux-raid/20260613184042.BCEC01F000E9@smtp.kernel.org/ (local)
quoted hunk ↗ jump to hunk
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 0a3cfdd3f5df8..bd322eccdc3ff 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1365,6 +1365,7 @@ static bool raid10_write_request(struct mddev *mddev, struct bio *bio,
 		/* Bail out if REQ_NOWAIT is set for the bio */
 		if (bio->bi_opf & REQ_NOWAIT) {
 			bio_wouldblock_error(bio);
+			free_r10bio(r10_bio);
 			return false;
 		}
[Severity: High]
This isn't a bug introduced by this patch, but while looking at REQ_NOWAIT
handling, it appears the initial allocation of r10_bio in __make_request()
and raid10_handle_discard() ignores the REQ_NOWAIT flag.

Both functions call:

    r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);

Since GFP_NOIO includes __GFP_DIRECT_RECLAIM, this can sleep if the mempool
is depleted.

Could this violate the strict non-blocking guarantees of REQ_NOWAIT IO and
potentially starve async workers?
 		for (;;) {
[ ... ]
quoted hunk ↗ jump to hunk
@@ -1398,6 +1399,7 @@ static bool raid10_write_request(struct mddev *mddev, struct bio *bio,
 		if (bio->bi_opf & REQ_NOWAIT) {
 			allow_barrier(conf);
 			bio_wouldblock_error(bio);
+			free_r10bio(r10_bio);
 			return false;
 		}
[Severity: High]
This is a pre-existing issue, but further down in the IO path, several
functions seem to sleep unconditionally even for REQ_NOWAIT bios.

For example, wait_blocked_dev() does:

    md_wait_for_blocked_rdev(blocked_rdev, mddev);
    wait_barrier(conf, false);
    goto retry_wait;

Also, in raid10_write_request() and raid10_read_request(), when a bio spans a
chunk boundary and is split, the code unconditionally blocks:

    allow_barrier(conf);
    bio = bio_submit_split_bioset(bio, max_sectors, &conf->bio_split);
    wait_barrier(conf, false);

Could these calls to wait_barrier(conf, false) and md_wait_for_blocked_rdev()
deadlock async submitters that rely on the non-blocking guarantee?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260710101521.1714-1-abd.masalkhi@gmail.com?part=1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help