Skip to content

Commit a8091f0

Browse files
howlettakpm00
authored andcommitted
maple_tree: add MAS_UNDERFLOW and MAS_OVERFLOW states
When updating the maple tree iterator to avoid rewalks, an issue was introduced when shifting beyond the limits. This can be seen by trying to go to the previous address of 0, which would set the maple node to MAS_NONE and keep the range as the last entry. Subsequent calls to mas_find() would then search upwards from mas->last and skip the value at mas->index/mas->last. This showed up as a bug in mprotect which skips the actual VMA at the current range after attempting to go to the previous VMA from 0. Since MAS_NONE may already be set when searching for a value that isn't contained within a node, changing the handling of MAS_NONE in mas_find() would make the code more complicated and error prone. Furthermore, there was no way to tell which limit was hit, and thus which action to take (next or the entry at the current range). This solution is to add two states to track what happened with the previous iterator action. This allows for the expected behaviour of the next command to return the correct item (either the item at the range requested, or the next/previous). Tests are also added and updated accordingly. Link: https://lkml.kernel.org/r/[email protected] Link: https://gist.github.com/heatd/85d2971fae1501b55b6ea401fbbe485b Link: https://lore.kernel.org/linux-mm/[email protected]/ Fixes: 3919368 ("maple_tree: try harder to keep active node with mas_prev()") Signed-off-by: Liam R. Howlett <[email protected]> Reported-by: Pedro Falcato <[email protected]> Closes: https://gist.github.com/heatd/85d2971fae1501b55b6ea401fbbe485b Closes: https://bugs.archlinux.org/task/79656 Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 5c59080 commit a8091f0

File tree

3 files changed

+237
-73
lines changed

3 files changed

+237
-73
lines changed

include/linux/maple_tree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@ struct ma_wr_state {
428428
#define MAS_ROOT ((struct maple_enode *)5UL)
429429
#define MAS_NONE ((struct maple_enode *)9UL)
430430
#define MAS_PAUSE ((struct maple_enode *)17UL)
431+
#define MAS_OVERFLOW ((struct maple_enode *)33UL)
432+
#define MAS_UNDERFLOW ((struct maple_enode *)65UL)
431433
#define MA_ERROR(err) \
432434
((struct maple_enode *)(((unsigned long)err << 2) | 2UL))
433435

0 commit comments

Comments
 (0)