md/md-llbitmap: use GFP_NOIO for cache allocations

llbitmap allocates its in-memory page cache and page-control structures from
paths that can already be holding MD reconfiguration or bitmap state locks.
For example, component_size_store() takes mddev_lock(), update_size() calls
the personality resize method, and llbitmap_resize() can grow the page cache
through llbitmap_prepare_resize().

Using GFP_KERNEL in those paths allows direct reclaim to enter filesystem or
block I/O while MD resize state is locked. That can recurse back into the
same array and wait on state that cannot make progress until the resize path
finishes.

Use GFP_NOIO for the llbitmap object, cached bitmap pages, page controls,
page-control arrays, and percpu_ref initialization. Leave the explicit
metadata zeroout path unchanged because it is intentional bitmap I/O rather
than reclaim-driven allocation.

Tested-by: Mykola Marzhan <mykola@meshstor.io>
Link: https://patch.msgid.link/20260802195038.164272-3-yukuai@kernel.org
Signed-off-by: Yu Kuai <yukuai@fygo.io>
This commit is contained in:
Yu Kuai 2026-08-03 03:50:11 +08:00
parent 2f6b2073ea
commit 4b6cdc56c8

View File

@ -521,7 +521,7 @@ static struct page *llbitmap_read_page(struct llbitmap *llbitmap, int idx)
if (page)
return page;
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
page = alloc_page(GFP_NOIO | __GFP_ZERO);
if (!page)
return ERR_PTR(-ENOMEM);
@ -616,12 +616,12 @@ static int llbitmap_cache_pages(struct llbitmap *llbitmap)
int i;
llbitmap->pctl = kmalloc_array(nr_pages, sizeof(void *),
GFP_KERNEL | __GFP_ZERO);
GFP_NOIO | __GFP_ZERO);
if (!llbitmap->pctl)
return -ENOMEM;
size = round_up(size, cache_line_size());
pctl = kmalloc_array(nr_pages, size, GFP_KERNEL | __GFP_ZERO);
pctl = kmalloc_array(nr_pages, size, GFP_NOIO | __GFP_ZERO);
if (!pctl) {
kfree(llbitmap->pctl);
return -ENOMEM;
@ -640,7 +640,7 @@ static int llbitmap_cache_pages(struct llbitmap *llbitmap)
}
if (percpu_ref_init(&pctl->active, active_release,
PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) {
PERCPU_REF_ALLOW_REINIT, GFP_NOIO)) {
__free_page(page);
llbitmap_free_pages(llbitmap);
return -ENOMEM;
@ -1110,7 +1110,7 @@ static int llbitmap_create(struct mddev *mddev)
if (ret)
return ret;
llbitmap = kzalloc_obj(*llbitmap);
llbitmap = kzalloc_obj(*llbitmap, GFP_NOIO);
if (!llbitmap)
return -ENOMEM;