From: sashiko-bot@kernel.org
To: "Yu Kuai" <yukuai@kernel.org>
Cc: yukuai@fygo.io, linux-raid@vger.kernel.org
Subject: Re: [PATCH v4 11/25] md/md-llbitmap: grow the page cache in place for reshape
Date: Sat, 01 Aug 2026 18:03:39 +0000 [thread overview]
Message-ID: <20260801180339.AF6551F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260801172519.2982121-12-yukuai@kernel.org>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] Deadlock during memory allocation under quiesced MD array state
- [High] Incomplete reshape logic fails to update chunksize, causing out-of-bounds array access
- [High] Non-atomic replacement of `llbitmap->pctl` exposes concurrent lockless readers to use-after-free
Pre-existing issues:
- [Critical] Bitmap sizing logic omits superblock offset, causing out-of-bounds on-disk write
--
--- Patch [11]: [PATCH v4 11/25] md/md-llbitmap: grow the page cache in place for reshape ---
commit 4834d913bd6249e72f12baf6160c3e9e149b6525
Author: Yu Kuai <yukuai@fygo.io>
md/md-llbitmap: grow the page cache in place for reshape
Use the page-control helpers to grow llbitmap's cached pages in place
for resize and later reshape preparation, instead of rebuilding the
whole cache.
> diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
> index d12b3dba6ae15..cf522fae78f8a 100644
> --- a/drivers/md/md-llbitmap.c
> +++ b/drivers/md/md-llbitmap.c
[ ... ]
> @@ -416,6 +416,19 @@ static char state_machine[BitStateCount][BitmapActionCount] = {
> };
>
> static void __llbitmap_flush(struct mddev *mddev);
> +static void llbitmap_flush(struct mddev *mddev);
> +static void llbitmap_update_sb(void *data);
> +
> +static void llbitmap_calculate_chunks(struct mddev *mddev, sector_t blocks,
> + unsigned long *chunksize,
> + unsigned long *chunks)
> +{
> + *chunks = DIV_ROUND_UP_SECTOR_T(blocks, *chunksize);
> + while (*chunks > mddev->bitmap_info.space << SECTOR_SHIFT) {
[Severity: Critical]
This isn't a bug introduced by this patch, but does this space validation
check omit the BITMAP_DATA_OFFSET?
Since the bitmap format includes a superblock at the start, it consumes
BITMAP_DATA_OFFSET bytes (typically 1024). If a geometry requires payload
bytes closely fitting the reserved space, the total footprint could exceed
the reserved sectors.
During a flush, could the bitmap write its pages to disk past the end of
the reserved space, potentially overwriting adjacent metadata or user data?
> + *chunksize = *chunksize << 1;
> + *chunks = DIV_ROUND_UP_SECTOR_T(blocks, *chunksize);
> + }
> +}
[ ... ]
> @@ -655,6 +668,48 @@ static unsigned int llbitmap_reserved_pages(struct llbitmap *llbitmap)
> PAGE_SIZE);
> }
>
> +static int llbitmap_expand_pages(struct llbitmap *llbitmap,
> + unsigned long chunks)
> +{
> + struct llbitmap_page_ctl **pctl;
> + unsigned int old_nr_pages = llbitmap->nr_pages;
> + unsigned int nr_pages = llbitmap_used_pages(llbitmap, chunks);
> + unsigned int i;
> + int ret;
> +
> + if (nr_pages <= old_nr_pages)
> + return 0;
> +
> + pctl = kcalloc(nr_pages, sizeof(*pctl), GFP_KERNEL);
[Severity: High]
Can this allocation cause a deadlock under memory pressure?
The GFP_KERNEL flag permits direct memory reclaim. If the VM attempts to
write dirty filesystem pages back to the block device to free memory, the
writeback could be directed at the MD array.
Since llbitmap_resize() suspends the array using
mddev->pers->quiesce(mddev, 1) before calling this function:
drivers/md/md-llbitmap.c:llbitmap_resize() {
...
if (mddev->pers->quiesce) {
mddev->pers->quiesce(mddev, 1);
...
ret = llbitmap_prepare_resize(...)
}
Will the I/O block indefinitely waiting for the array to unquiesce,
deadlocking the thread that is holding the quiesce state?
> + if (!pctl)
> + return -ENOMEM;
> +
> + if (llbitmap->pctl)
> + memcpy(pctl, llbitmap->pctl,
> + array_size(old_nr_pages, sizeof(*pctl)));
> +
> + for (i = old_nr_pages; i < nr_pages; i++) {
> + pctl[i] = llbitmap_alloc_page_ctl(llbitmap, i);
> + if (IS_ERR(pctl[i]))
> + goto err_alloc_ptr;
> + }
> +
> + kfree(llbitmap->pctl);
> + llbitmap->pctl = pctl;
[Severity: High]
Does freeing the old pointer array non-atomically without RCU protection
expose concurrent lockless readers to a use-after-free?
Although the array is quiesced here, background tasks such as
llbitmap_unplug_fn() (queued by blk_finish_plug() for tasks that submitted
I/O before the quiesce) might still execute concurrently.
If a lockless reader is iterating over llbitmap->nr_pages and reading from
llbitmap->pctl[i], could it be preempted while holding the old pointer and
dereference freed memory when this code executes?
> + llbitmap->nr_pages = nr_pages;
> + return 0;
[ ... ]
> @@ -1171,24 +1254,62 @@ static int llbitmap_create(struct mddev *mddev)
> static int llbitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize)
> {
[ ... ]
> + mutex_lock(&mddev->bitmap_info.mutex);
> + cache_chunks = reshape ? max(old_chunks, chunks) : chunks;
> + ret = llbitmap_prepare_resize(llbitmap, old_chunks, chunks, cache_chunks);
> + if (ret)
> + goto out;
> +
> + if (reshape) {
> + llbitmap->chunks = max(old_chunks, chunks);
> + } else {
[Severity: High]
Is the reshape logic missing updates to the chunksize and chunkshift
variables?
When reshaping an array to a larger size, the required bitmap chunksize
may increase. While llbitmap->chunks is updated here, llbitmap->chunksize
and llbitmap->chunkshift appear to be left unchanged.
When new I/O arrives, llbitmap_start_write() would calculate the chunk
index using the old, smaller chunkshift.
Could this produce a required chunk index that exceeds the newly allocated
llbitmap->chunks limit, leading to an out-of-bounds access when writing the
state in llbitmap_write():
drivers/md/md-llbitmap.c:llbitmap_write() {
...
idx = pos >> PAGE_SHIFT;
bit = offset_in_page(pos);
llbitmap->pctl[idx]->state[bit] = state;
...
}
> + if (blocks < old_blocks && chunks < old_chunks)
> + llbitmap_mark_range(llbitmap, chunks, old_chunks - 1,
> + BitUnwritten);
> + mddev->bitmap_info.chunksize = bitmap_chunksize;
> + llbitmap->chunks = chunks;
> + llbitmap->sync_size = blocks;
> + llbitmap_update_sb(llbitmap);
> + }
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260801172519.2982121-1-yukuai@kernel.org?part=11
next prev parent reply other threads:[~2026-08-01 18:03 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-01 17:24 [PATCH v4 00/25] md: improve lockless bitmap reshape support Yu Kuai
2026-08-01 17:24 ` [PATCH v4 01/25] md/md-llbitmap: clear flush state after daemon flush Yu Kuai
2026-08-01 17:43 ` sashiko-bot
2026-08-01 17:24 ` [PATCH v4 02/25] md/md-llbitmap: use GFP_NOIO for cache allocations Yu Kuai
2026-08-01 17:41 ` sashiko-bot
2026-08-01 17:24 ` [PATCH v4 03/25] md/md-llbitmap: only end fully synced chunks Yu Kuai
2026-08-01 17:42 ` sashiko-bot
2026-08-01 17:24 ` [PATCH v4 04/25] md/raid5: reject zero-sector reshape chunks Yu Kuai
2026-08-01 17:45 ` sashiko-bot
2026-08-01 17:24 ` [PATCH v4 05/25] md/raid5: round bitmap stripes with sector division Yu Kuai
2026-08-01 17:39 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 06/25] md: add exact bitmap mapping and reshape hooks Yu Kuai
2026-08-01 17:25 ` [PATCH v4 07/25] md: skip bitmap accounting for empty write ranges Yu Kuai
2026-08-01 18:05 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 08/25] md: add helper to split bios at reshape offset Yu Kuai
2026-08-01 17:41 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 09/25] md/md-llbitmap: track bitmap sync_size explicitly Yu Kuai
2026-08-01 17:44 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 10/25] md/md-llbitmap: allocate page controls independently Yu Kuai
2026-08-01 17:47 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 11/25] md/md-llbitmap: grow the page cache in place for reshape Yu Kuai
2026-08-01 18:03 ` sashiko-bot [this message]
2026-08-01 17:25 ` [PATCH v4 12/25] md/md-llbitmap: track target reshape geometry fields Yu Kuai
2026-08-01 17:51 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 13/25] md/md-llbitmap: finish reshape geometry Yu Kuai
2026-08-01 17:59 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 14/25] md/md-llbitmap: refuse reshape while llbitmap still needs sync Yu Kuai
2026-08-01 17:50 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 15/25] md/md-llbitmap: add reshape range mapping helpers Yu Kuai
2026-08-01 17:47 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 16/25] md/md-llbitmap: don't skip reshape ranges from bitmap state Yu Kuai
2026-08-01 17:41 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 17/25] md/md-llbitmap: remap checkpointed bits as reshape progresses Yu Kuai
2026-08-01 18:12 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 18/25] md/md-llbitmap: clamp state-machine walks to tracked bits Yu Kuai
2026-08-01 17:55 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 19/25] md/raid10: reject llbitmap reshape when md chunk shrinks Yu Kuai
2026-08-01 17:25 ` [PATCH v4 20/25] md/raid10: wire llbitmap reshape lifecycle Yu Kuai
2026-08-01 18:28 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 21/25] md/raid10: split reshape bios before bitmap accounting Yu Kuai
2026-08-01 17:59 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 22/25] md/raid5: add exact old and new llbitmap mapping helpers Yu Kuai
2026-08-01 18:05 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 23/25] md/raid5: reject llbitmap reshape when md chunk shrinks Yu Kuai
2026-08-01 17:25 ` [PATCH v4 24/25] md/raid5: wire llbitmap reshape lifecycle Yu Kuai
2026-08-01 18:12 ` sashiko-bot
2026-08-01 17:25 ` [PATCH v4 25/25] md/raid5: split reshape bios before bitmap accounting Yu Kuai
2026-08-01 18:43 ` sashiko-bot
2026-08-02 16:13 ` [PATCH v4 00/25] md: improve lockless bitmap reshape support Mykola Marzhan
2026-08-02 19:13 ` yu kuai
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=20260801180339.AF6551F00AC4@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-raid@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yukuai@fygo.io \
--cc=yukuai@kernel.org \
/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.