| From: Wei Yang <richard.weiyang@gmail.com> |
| Subject: maple_tree: assert retrieving new value on a tree containing just a leaf node |
| Date: Wed, 11 Jun 2025 01:12:53 +0000 |
| |
| Original code may not get the new value after overwriting the whole range |
| on a maple tree containing just a leaf node. The reason is we didn't set |
| the only root node dead during destroy. |
| |
| Add a test case to ensure the new value is returned when overwriting a |
| tree containing just a leaf node. |
| |
| Link: https://lkml.kernel.org/r/20250611011253.19515-4-richard.weiyang@gmail.com |
| Signed-off-by: Wei Yang <richard.weiyang@gmail.com> |
| Reviewed-by: Liam R. Howlett <Liam.Howlett@Oracle.com> |
| Cc: Matthew Wilcox (Oracle) <willy@infradead.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| tools/testing/radix-tree/maple.c | 24 ++++++++++++++++++++++++ |
| 1 file changed, 24 insertions(+) |
| |
| --- a/tools/testing/radix-tree/maple.c~maple_tree-assert-retrieving-new-value-on-a-tree-containing-just-a-leaf-node |
| +++ a/tools/testing/radix-tree/maple.c |
| @@ -35256,6 +35256,30 @@ static noinline void __init check_rcu_si |
| MT_BUG_ON(mt, mas_prev(&mas_reader, 0) != xa_mk_value(val)); |
| rcu_read_unlock(); |
| |
| + /* Clear out tree & create one with only root node */ |
| + mas_lock(&mas_writer); |
| + mas_set_range(&mas_writer, 0, ULONG_MAX); |
| + mas_store_gfp(&mas_writer, NULL, GFP_KERNEL); |
| + mas_set_range(&mas_writer, 0, 0); |
| + for (i = 0; i <= 5; i++) { |
| + mas_writer.index = i * 10; |
| + mas_writer.last = i * 10 + 5; |
| + mas_store_gfp(&mas_writer, xa_mk_value(i), GFP_KERNEL); |
| + } |
| + mas_unlock(&mas_writer); |
| + target = 10; |
| + mas_set_range(&mas_reader, target, target); |
| + rcu_read_lock(); |
| + MT_BUG_ON(mt, mas_walk(&mas_reader) != xa_mk_value(target/10)); |
| + |
| + /* Overwrite the whole range */ |
| + mas_lock(&mas_writer); |
| + mas_set_range(&mas_writer, 0, ULONG_MAX); |
| + mas_store_gfp(&mas_writer, xa_mk_value(val), GFP_KERNEL); |
| + mas_unlock(&mas_writer); |
| + MT_BUG_ON(mt, mas_walk(&mas_reader) != xa_mk_value(val)); |
| + rcu_read_unlock(); |
| + |
| rcu_unregister_thread(); |
| } |
| |
| _ |