From fd003fac7cc7d98a942a0778de76683ab731dd9c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 12 May 2026 17:56:23 -0400 Subject: maple_tree: document that "last" in mtree_insert_range() is inclusive The kernel doc of mtree_insert_range() does not state if the address represented by the "last" parameter is inclusive or exclusive. This can lead to bugs by code that assumes it is exclusive. Explicitly state that the parameter is inclusive. Link: https://lore.kernel.org/20260512175623.4c5ca8d2@gandalf.local.home Signed-off-by: Steven Rostedt Reviewed-by: "Liam R. Howlett" Acked-by: SeongJae Park Cc: Alice Ryhl Cc: Andrew Ballance Cc: Matthew Wilcox (Oracle) Signed-off-by: Andrew Morton --- lib/maple_tree.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 60ae5e6fc1ee..e52876435b77 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -5727,13 +5727,16 @@ int mtree_store(struct maple_tree *mt, unsigned long index, void *entry, EXPORT_SYMBOL(mtree_store); /** - * mtree_insert_range() - Insert an entry at a given range if there is no value. + * mtree_insert_range() - Insert an entry from [first, last] at a given range + * if there is no value. * @mt: The maple tree * @first: The start of the range - * @last: The end of the range + * @last: The end of the range (inclusive) * @entry: The entry to store * @gfp: The GFP_FLAGS to use for allocations. * + * Note that @last is inclusive. That is, @last = @first + length - 1; + * * Return: 0 on success, -EEXISTS if the range is occupied, -EINVAL on invalid * request, -ENOMEM if memory could not be allocated. */ -- cgit v1.2.3 From 8e0c2085c978ed6d9764d79fc785920360096f21 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 4 May 2026 12:06:37 +0200 Subject: lib/test_meminit: use && for bools As pointed out by Dan Carpenter, test_kmemcache() was using a bitwise AND on two bools instead of a boolean AND. Fix this for the sake of code cleanliness. Link: https://lore.kernel.org/20260504100637.1535762-1-glider@google.com Fixes: 5015a300a522 ("lib: introduce test_meminit module") Signed-off-by: Alexander Potapenko Reported-by: Dan Carpenter Closes: https://lore.kernel.org/kernel-janitors/afOcIan1ap9kD26M@stanley.mountain/ Reviewed-by: Andrew Morton Signed-off-by: Andrew Morton --- lib/test_meminit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/test_meminit.c b/lib/test_meminit.c index 6298f66c964b..d028a6552cd6 100644 --- a/lib/test_meminit.c +++ b/lib/test_meminit.c @@ -387,7 +387,7 @@ static int __init test_kmemcache(int *total_failures) ctor = flags & 1; rcu = flags & 2; zero = flags & 4; - if (ctor & zero) + if (ctor && zero) continue; num_tests += do_kmem_cache_size(size, ctor, rcu, zero, &failures); -- cgit v1.2.3 From 59f19bf6f119eecfa16355186b593abba8eb5198 Mon Sep 17 00:00:00 2001 From: Hao Ge Date: Wed, 13 May 2026 16:25:25 +0800 Subject: lib/test_hmm: use kvfree() to free kvcalloc() allocations Coccinelle scripts/coccinelle/api/kfree_mismatch.cocci reports the following warnings: lib/test_hmm.c:1256:15-16: WARNING kvmalloc is used to allocate this memory at line 1191 lib/test_hmm.c:1257:15-16: WARNING kvmalloc is used to allocate this memory at line 1196 Fix this by replacing kfree() with kvfree() to correctly handle the vmalloc() fallback path of kvcalloc(). Link: https://lore.kernel.org/20260513082525.154036-1-hao.ge@linux.dev Fixes: 775465fd26a3 ("lib/test_hmm: add zone device private THP test infrastructure") Signed-off-by: Hao Ge Acked-by: Balbir Singh Cc: Jason Gunthorpe Cc: Leon Romanovsky Cc: Signed-off-by: Andrew Morton --- lib/test_hmm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/test_hmm.c b/lib/test_hmm.c index 213504915737..38996c4baa40 100644 --- a/lib/test_hmm.c +++ b/lib/test_hmm.c @@ -1253,8 +1253,8 @@ out: mmap_read_unlock(mm); mmput(mm); free_mem: - kfree(src_pfns); - kfree(dst_pfns); + kvfree(src_pfns); + kvfree(dst_pfns); return ret; } -- cgit v1.2.3 From 6fa411adff39e4955f11aa3e854a876680444d2a Mon Sep 17 00:00:00 2001 From: Qiang Liu Date: Fri, 15 May 2026 15:03:11 +0800 Subject: lib/test_hmm: fix error path in dmirror_devmem_fault() Handle migrate_vma_setup() failure via goto err for unified cleanup. Link: https://lore.kernel.org/20260515070312.130435-1-liuqiangneo@163.com Signed-off-by: Qiang Liu Reviewed-by: Alistair Popple Cc: Jason Gunthorpe Cc: Leon Romanovsky Signed-off-by: Andrew Morton --- lib/test_hmm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/test_hmm.c b/lib/test_hmm.c index 38996c4baa40..63bf77dee987 100644 --- a/lib/test_hmm.c +++ b/lib/test_hmm.c @@ -1679,8 +1679,14 @@ static vm_fault_t dmirror_devmem_fault(struct vm_fault *vmf) if (order) args.flags |= MIGRATE_VMA_SELECT_COMPOUND; - if (migrate_vma_setup(&args)) - return VM_FAULT_SIGBUS; + /* + * In practice migrate_vma_setup() should never fail unless the + * test is wrong as it just tests some static VMA properties. + */ + if (migrate_vma_setup(&args)) { + ret = VM_FAULT_SIGBUS; + goto err; + } ret = dmirror_devmem_fault_alloc_and_copy(&args, dmirror); if (ret) -- cgit v1.2.3 From 3c3daeafcdb60e182554679fc32d2c912d1b0b6a Mon Sep 17 00:00:00 2001 From: Shivam Kalra Date: Tue, 19 May 2026 17:42:18 +0530 Subject: lib/test_vmalloc: add vrealloc test case Introduce a new test case "vrealloc_test" that exercises the vrealloc() shrink and in-place grow paths: - Grow beyond allocated pages (triggers full reallocation). - Shrink crossing a page boundary (frees tail pages). - Shrink within the same page (no page freeing). - Grow within the already allocated page count (in-place). Data integrity is validated after each realloc step by checking that the first byte of the original allocation is preserved. The test is gated behind run_test_mask bit 12 (id 4096). Link: https://lore.kernel.org/20260519-vmalloc-shrink-v14-5-70b96ee3e9c9@zohomail.in Signed-off-by: Shivam Kalra Reviewed-by: Uladzislau Rezki (Sony) Cc: Alice Ryhl Cc: Danilo Krummrich Signed-off-by: Andrew Morton --- lib/test_vmalloc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'lib') diff --git a/lib/test_vmalloc.c b/lib/test_vmalloc.c index 876c72c18a0c..b23f85e8f8ca 100644 --- a/lib/test_vmalloc.c +++ b/lib/test_vmalloc.c @@ -55,6 +55,7 @@ __param(int, run_test_mask, 7, "\t\tid: 512, name: kvfree_rcu_2_arg_vmalloc_test\n" "\t\tid: 1024, name: vm_map_ram_test\n" "\t\tid: 2048, name: no_block_alloc_test\n" + "\t\tid: 4096, name: vrealloc_test\n" /* Add a new test case description here. */ ); @@ -421,6 +422,66 @@ cleanup: return nr_allocated != map_nr_pages; } +static int vrealloc_test(void) +{ + void *ptr, *tmp; + int i; + + for (i = 0; i < test_loop_count; i++) { + int err = -1; + + ptr = vrealloc(NULL, PAGE_SIZE, GFP_KERNEL); + if (!ptr) + return -1; + + *((__u8 *)ptr) = 'a'; + + /* Grow: beyond allocated pages, triggers full realloc. */ + tmp = vrealloc(ptr, 4 * PAGE_SIZE, GFP_KERNEL); + if (!tmp) + goto error; + ptr = tmp; + + if (*((__u8 *)ptr) != 'a') + goto error; + + /* Shrink: crosses page boundary, frees tail pages. */ + tmp = vrealloc(ptr, PAGE_SIZE, GFP_KERNEL); + if (!tmp) + goto error; + ptr = tmp; + + if (*((__u8 *)ptr) != 'a') + goto error; + + /* Shrink: within same page, no page freeing. */ + tmp = vrealloc(ptr, PAGE_SIZE / 2, GFP_KERNEL); + if (!tmp) + goto error; + ptr = tmp; + + if (*((__u8 *)ptr) != 'a') + goto error; + + /* Grow: within allocated page, in-place, no realloc. */ + tmp = vrealloc(ptr, PAGE_SIZE, GFP_KERNEL); + if (!tmp) + goto error; + ptr = tmp; + + if (*((__u8 *)ptr) != 'a') + goto error; + + err = 0; +error: + vfree(ptr); + if (err) + return err; + } + + return 0; +} + struct test_case_desc { const char *test_name; int (*test_func)(void); @@ -440,6 +501,7 @@ static struct test_case_desc test_case_array[] = { { "kvfree_rcu_2_arg_vmalloc_test", kvfree_rcu_2_arg_vmalloc_test, }, { "vm_map_ram_test", vm_map_ram_test, }, { "no_block_alloc_test", no_block_alloc_test, true }, + { "vrealloc_test", vrealloc_test, }, /* Add a new test case here. */ }; -- cgit v1.2.3 From 8f7275c174bc5bcc8fc1bec8024e2b3e6fe17f46 Mon Sep 17 00:00:00 2001 From: Hao Ge Date: Thu, 28 May 2026 09:13:36 +0800 Subject: lib/test_hmm: fix memory leak in dmirror_migrate_to_system() Move the kvcalloc() calls after the early return checks to avoid leaking src_pfns and dst_pfns when end < start or mmget_not_zero() fails. Link: https://lore.kernel.org/20260528011336.20797-1-hao.ge@linux.dev Fixes: 775465fd26a3 ("lib/test_hmm: add zone device private THP test infrastructure") Signed-off-by: Hao Ge Reviewed-by: Alistair Popple Reported-by: Sashiko Reviewed-by: Balbir Singh Cc: Jason Gunthorpe Cc: Leon Romanovsky Signed-off-by: Andrew Morton --- lib/test_hmm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/test_hmm.c b/lib/test_hmm.c index 63bf77dee987..35f774ed2d99 100644 --- a/lib/test_hmm.c +++ b/lib/test_hmm.c @@ -1111,9 +1111,6 @@ static int dmirror_migrate_to_system(struct dmirror *dmirror, unsigned long *src_pfns; unsigned long *dst_pfns; - src_pfns = kvcalloc(PTRS_PER_PTE, sizeof(*src_pfns), GFP_KERNEL | __GFP_NOFAIL); - dst_pfns = kvcalloc(PTRS_PER_PTE, sizeof(*dst_pfns), GFP_KERNEL | __GFP_NOFAIL); - start = cmd->addr; end = start + size; if (end < start) @@ -1123,6 +1120,9 @@ static int dmirror_migrate_to_system(struct dmirror *dmirror, if (!mmget_not_zero(mm)) return -EINVAL; + src_pfns = kvcalloc(PTRS_PER_PTE, sizeof(*src_pfns), GFP_KERNEL | __GFP_NOFAIL); + dst_pfns = kvcalloc(PTRS_PER_PTE, sizeof(*dst_pfns), GFP_KERNEL | __GFP_NOFAIL); + cmd->cpages = 0; mmap_read_lock(mm); for (addr = start; addr < end; addr = next) { -- cgit v1.2.3 From 8198657c74170ea78808d1f1d886c7d35fd3694e Mon Sep 17 00:00:00 2001 From: Qiang Liu Date: Thu, 21 May 2026 10:18:58 +0800 Subject: lib/test_hmm: check alloc_page_vma() return value and handle OOM Check alloc_page_vma() return status for page allocation failures, free allocated pages and return VM_FAULT_OOM on error. Handle return codes of dmirror_devmem_fault_alloc_and_copy(), call migrate_vma_finalize() to remove migration entries from migrate_vma_setup(). Link: https://lore.kernel.org/20260521021858.21511-1-liuqiangneo@163.com Signed-off-by: Qiang Liu Cc: Alistair Popple Cc: Jason Gunthorpe Cc: Leon Romanovsky [akpm@linux-foundation.org: fix dmirror_devmem_fault_alloc_and_copy() retval handling] Link: https://lore.kernel.org/oe-kbuild-all/202606011329.zWs2BKy4-lkp@intel.com/ Signed-off-by: Andrew Morton --- lib/test_hmm.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/test_hmm.c b/lib/test_hmm.c index 35f774ed2d99..9c59d1ceb5b5 100644 --- a/lib/test_hmm.c +++ b/lib/test_hmm.c @@ -1063,6 +1063,25 @@ static vm_fault_t dmirror_devmem_fault_alloc_and_copy(struct migrate_vma *args, /* Try with smaller pages if large allocation fails */ if (!dpage && order) { dpage = alloc_page_vma(GFP_HIGHUSER_MOVABLE, args->vma, addr); + if (!dpage) { + /* Unlock and free pages already allocated. */ + while (i > 0) { + struct page *fpage; + + fpage = migrate_pfn_to_page(dst[--i]); + unlock_page(fpage); + __free_page(fpage); + } + /* Clear remaining dst entries to avoid + * migrate_vma_pages/finalize() using + * uninitialized values. + */ + while (i < (1 << order)) { + dst[i] = 0; + i++; + } + return VM_FAULT_OOM; + } lock_page(dpage); dst[i] = migrate_pfn(page_to_pfn(dpage)); dst_page = pfn_to_page(page_to_pfn(dpage)); @@ -1148,7 +1167,11 @@ static int dmirror_migrate_to_system(struct dmirror *dmirror, goto out; pr_debug("Migrating from device mem to sys mem\n"); - dmirror_devmem_fault_alloc_and_copy(&args, dmirror); + if (dmirror_devmem_fault_alloc_and_copy(&args, dmirror)) { + migrate_vma_finalize(&args); + ret = -ENOMEM; + goto out; + } migrate_vma_pages(&args); cmd->cpages += dmirror_successful_migrated_pages(&args); @@ -1689,8 +1712,10 @@ static vm_fault_t dmirror_devmem_fault(struct vm_fault *vmf) } ret = dmirror_devmem_fault_alloc_and_copy(&args, dmirror); - if (ret) + if (ret) { + migrate_vma_finalize(&args); goto err; + } migrate_vma_pages(&args); /* * No device finalize step is needed since -- cgit v1.2.3