Skip to content

Commit

Permalink
maple_tree: make maple state reusable after mas_empty_area_rev()
Browse files Browse the repository at this point in the history
commit fad8e42 upstream.

Stop using maple state min/max for the range by passing through pointers
for those values.  This will allow the maple state to be reused without
resetting.

Also add some logic to fail out early on searching with invalid
arguments.

Link: https://lkml.kernel.org/r/20230414145728.4067069-1-Liam.Howlett@oracle.com
Fixes: 54a611b ("Maple Tree: add new data structure")
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Reported-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
howlett authored and gregkh committed Apr 26, 2023
1 parent be100a8 commit c51b9ef
Showing 1 changed file with 13 additions and 14 deletions.
27 changes: 13 additions & 14 deletions lib/maple_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -4968,7 +4968,8 @@ static inline void *mas_prev_entry(struct ma_state *mas, unsigned long min)
* Return: True if found in a leaf, false otherwise.
*
*/
static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
static bool mas_rev_awalk(struct ma_state *mas, unsigned long size,
unsigned long *gap_min, unsigned long *gap_max)
{
enum maple_type type = mte_node_type(mas->node);
struct maple_node *node = mas_mn(mas);
Expand Down Expand Up @@ -5033,8 +5034,8 @@ static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)

if (unlikely(ma_is_leaf(type))) {
mas->offset = offset;
mas->min = min;
mas->max = min + gap - 1;
*gap_min = min;
*gap_max = min + gap - 1;
return true;
}

Expand Down Expand Up @@ -5310,6 +5311,9 @@ int mas_empty_area(struct ma_state *mas, unsigned long min,
unsigned long *pivots;
enum maple_type mt;

if (min >= max)
return -EINVAL;

if (mas_is_start(mas))
mas_start(mas);
else if (mas->offset >= 2)
Expand Down Expand Up @@ -5364,6 +5368,9 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
{
struct maple_enode *last = mas->node;

if (min >= max)
return -EINVAL;

if (mas_is_start(mas)) {
mas_start(mas);
mas->offset = mas_data_end(mas);
Expand All @@ -5383,7 +5390,7 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
mas->index = min;
mas->last = max;

while (!mas_rev_awalk(mas, size)) {
while (!mas_rev_awalk(mas, size, &min, &max)) {
if (last == mas->node) {
if (!mas_rewind_node(mas))
return -EBUSY;
Expand All @@ -5398,17 +5405,9 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
if (unlikely(mas->offset == MAPLE_NODE_SLOTS))
return -EBUSY;

/*
* mas_rev_awalk() has set mas->min and mas->max to the gap values. If
* the maximum is outside the window we are searching, then use the last
* location in the search.
* mas->max and mas->min is the range of the gap.
* mas->index and mas->last are currently set to the search range.
*/

/* Trim the upper limit to the max. */
if (mas->max <= mas->last)
mas->last = mas->max;
if (max <= mas->last)
mas->last = max;

mas->index = mas->last - size + 1;
return 0;
Expand Down

0 comments on commit c51b9ef

Please sign in to comment.