[PATCH v5 02/29] md/md-llbitmap: use GFP_NOIO for cache allocations
Yu Kuai <[email protected]> Mon, 3 Aug 2026 03:50:11 +0800
| Newsgroups | gmane.linux.raid,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Yu Kuai <[email protected]> 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 <[email protected]> Signed-off-by: Yu Kuai <[email protected]> --- drivers/md/md-llbitmap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c index 71e9a21b98b2..3cd8373bc9b2 100644 --- a/drivers/md/md-llbitmap.c +++ b/drivers/md/md-llbitmap.c @@ -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; -- 2.51.0