mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
maple_tree: add regression test for spanning store bug
Add a regression test to assert that, when performing a spanning store which consumes the entirety of the rightmost right leaf node does not result in maple tree corruption when doing so. This achieves this by building a test tree of 3 levels and establishing a store which ultimately results in a spanned store of this nature. Link: https://lkml.kernel.org/r/30cdc101a700d16e03ba2f9aa5d83f2efa894168.1728314403.git.lorenzo.stoakes@oracle.com Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Reviewed-by: Liam R. Howlett <Liam.Howlett@Oracle.com> Reviewed-by: Wei Yang <richard.weiyang@gmail.com> Cc: Bert Karwatzki <spasswolf@web.de> Cc: Matthew Wilcox <willy@infradead.org> Cc: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
bea07fd631
commit
e993457df6
|
|
@ -36432,9 +36432,93 @@ void farmer_tests(void)
|
|||
check_nomem(&tree);
|
||||
}
|
||||
|
||||
static unsigned long get_last_index(struct ma_state *mas)
|
||||
{
|
||||
struct maple_node *node = mas_mn(mas);
|
||||
enum maple_type mt = mte_node_type(mas->node);
|
||||
unsigned long *pivots = ma_pivots(node, mt);
|
||||
unsigned long last_index = mas_data_end(mas);
|
||||
|
||||
BUG_ON(last_index == 0);
|
||||
|
||||
return pivots[last_index - 1] + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assert that we handle spanning stores that consume the entirety of the right
|
||||
* leaf node correctly.
|
||||
*/
|
||||
static void test_spanning_store_regression(void)
|
||||
{
|
||||
unsigned long from = 0, to = 0;
|
||||
DEFINE_MTREE(tree);
|
||||
MA_STATE(mas, &tree, 0, 0);
|
||||
|
||||
/*
|
||||
* Build a 3-level tree. We require a parent node below the root node
|
||||
* and 2 leaf nodes under it, so we can span the entirety of the right
|
||||
* hand node.
|
||||
*/
|
||||
build_full_tree(&tree, 0, 3);
|
||||
|
||||
/* Descend into position at depth 2. */
|
||||
mas_reset(&mas);
|
||||
mas_start(&mas);
|
||||
mas_descend(&mas);
|
||||
mas_descend(&mas);
|
||||
|
||||
/*
|
||||
* We need to establish a tree like the below.
|
||||
*
|
||||
* Then we can try a store in [from, to] which results in a spanned
|
||||
* store across nodes B and C, with the maple state at the time of the
|
||||
* write being such that only the subtree at A and below is considered.
|
||||
*
|
||||
* Height
|
||||
* 0 Root Node
|
||||
* / \
|
||||
* pivot = to / \ pivot = ULONG_MAX
|
||||
* / \
|
||||
* 1 A [-----] ...
|
||||
* / \
|
||||
* pivot = from / \ pivot = to
|
||||
* / \
|
||||
* 2 (LEAVES) B [-----] [-----] C
|
||||
* ^--- Last pivot to.
|
||||
*/
|
||||
while (true) {
|
||||
unsigned long tmp = get_last_index(&mas);
|
||||
|
||||
if (mas_next_sibling(&mas)) {
|
||||
from = tmp;
|
||||
to = mas.max;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BUG_ON(from == 0 && to == 0);
|
||||
|
||||
/* Perform the store. */
|
||||
mas_set_range(&mas, from, to);
|
||||
mas_store_gfp(&mas, xa_mk_value(0xdead), GFP_KERNEL);
|
||||
|
||||
/* If the regression occurs, the validation will fail. */
|
||||
mt_validate(&tree);
|
||||
|
||||
/* Cleanup. */
|
||||
__mt_destroy(&tree);
|
||||
}
|
||||
|
||||
static void regression_tests(void)
|
||||
{
|
||||
test_spanning_store_regression();
|
||||
}
|
||||
|
||||
void maple_tree_tests(void)
|
||||
{
|
||||
#if !defined(BENCH)
|
||||
regression_tests();
|
||||
farmer_tests();
|
||||
#endif
|
||||
maple_tree_seed();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user