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 <[email protected]>
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/[email protected]/
> 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 (;;) {
[ ... ]
> @@ -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/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.