mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
maple_tree: fix mas_empty_area_rev() lower bound validation
mas_empty_area_rev() was not correctly validating the start of a gap
against the lower limit. This could lead to the range starting lower than
the requested minimum.
Fix the issue by better validating a gap once one is found.
This commit also adds tests to the maple tree test suite for this issue
and tests the mas_empty_area() function for similar bound checking.
Link: https://lkml.kernel.org/r/20230111200136.1851322-1-Liam.Howlett@oracle.com
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216911
Fixes: 54a611b605
("Maple Tree: add new data structure")
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Reported-by: <amanieu@gmail.com>
Link: https://lore.kernel.org/linux-mm/0b9f5425-08d4-8013-aa4c-e620c3b10bb2@leemhuis.info/
Tested-by: Holger Hoffsttte <holger@applied-asynchrony.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
24b5308cf5
commit
7327e8111a
@@ -2517,6 +2517,91 @@ static noinline void check_bnode_min_spanning(struct maple_tree *mt)
|
||||
mt_set_non_kernel(0);
|
||||
}
|
||||
|
||||
static noinline void check_empty_area_window(struct maple_tree *mt)
|
||||
{
|
||||
unsigned long i, nr_entries = 20;
|
||||
MA_STATE(mas, mt, 0, 0);
|
||||
|
||||
for (i = 1; i <= nr_entries; i++)
|
||||
mtree_store_range(mt, i*10, i*10 + 9,
|
||||
xa_mk_value(i), GFP_KERNEL);
|
||||
|
||||
/* Create another hole besides the one at 0 */
|
||||
mtree_store_range(mt, 160, 169, NULL, GFP_KERNEL);
|
||||
|
||||
/* Check lower bounds that don't fit */
|
||||
rcu_read_lock();
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 10) != -EBUSY);
|
||||
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 6, 90, 5) != -EBUSY);
|
||||
|
||||
/* Check lower bound that does fit */
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 5) != 0);
|
||||
MT_BUG_ON(mt, mas.index != 5);
|
||||
MT_BUG_ON(mt, mas.last != 9);
|
||||
rcu_read_unlock();
|
||||
|
||||
/* Check one gap that doesn't fit and one that does */
|
||||
rcu_read_lock();
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 217, 9) != 0);
|
||||
MT_BUG_ON(mt, mas.index != 161);
|
||||
MT_BUG_ON(mt, mas.last != 169);
|
||||
|
||||
/* Check one gap that does fit above the min */
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 3) != 0);
|
||||
MT_BUG_ON(mt, mas.index != 216);
|
||||
MT_BUG_ON(mt, mas.last != 218);
|
||||
|
||||
/* Check size that doesn't fit any gap */
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 16) != -EBUSY);
|
||||
|
||||
/*
|
||||
* Check size that doesn't fit the lower end of the window but
|
||||
* does fit the gap
|
||||
*/
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 167, 200, 4) != -EBUSY);
|
||||
|
||||
/*
|
||||
* Check size that doesn't fit the upper end of the window but
|
||||
* does fit the gap
|
||||
*/
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 162, 4) != -EBUSY);
|
||||
|
||||
/* Check mas_empty_area forward */
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 9) != 0);
|
||||
MT_BUG_ON(mt, mas.index != 0);
|
||||
MT_BUG_ON(mt, mas.last != 8);
|
||||
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 4) != 0);
|
||||
MT_BUG_ON(mt, mas.index != 0);
|
||||
MT_BUG_ON(mt, mas.last != 3);
|
||||
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 11) != -EBUSY);
|
||||
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area(&mas, 5, 100, 6) != -EBUSY);
|
||||
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area(&mas, 0, 8, 10) != -EBUSY);
|
||||
|
||||
mas_reset(&mas);
|
||||
mas_empty_area(&mas, 100, 165, 3);
|
||||
|
||||
mas_reset(&mas);
|
||||
MT_BUG_ON(mt, mas_empty_area(&mas, 100, 163, 6) != -EBUSY);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static DEFINE_MTREE(tree);
|
||||
static int maple_tree_seed(void)
|
||||
{
|
||||
@@ -2765,6 +2850,10 @@ static int maple_tree_seed(void)
|
||||
check_bnode_min_spanning(&tree);
|
||||
mtree_destroy(&tree);
|
||||
|
||||
mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
|
||||
check_empty_area_window(&tree);
|
||||
mtree_destroy(&tree);
|
||||
|
||||
#if defined(BENCH)
|
||||
skip:
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user