The patch titled Subject: maple_tree: Fix use of node for global range in mas_wr_spanning_store() has been added to the -mm mm-unstable branch. Its filename is maple-tree-add-new-data-structure-fix-3.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/maple-tree-add-new-data-structure-fix-3.patch This patch will later appear in the mm-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Liam Howlett <liam.howlett@xxxxxxxxxx> Subject: maple_tree: Fix use of node for global range in mas_wr_spanning_store() Date: Wed, 6 Jul 2022 02:05:37 +0000 When writing a range with a NULL which expands to 0 - ULONG_MAX, don't use a node to store this value. Instead, call mas_new_root() which will set the tree pointer to NULL and free all the nodes. Fix a comment for the allocations in mas_wr_spanning_store(). Add mas_node_count_gfp() and use it to clean up mas_preallocate(). Clean up mas_preallocate() and ensure the ma_state is safe on return. Update maple_tree.h to set alloc = NULL. Link: https://lkml.kernel.org/r/20220706020526.1869453-1-Liam.Howlett@xxxxxxxxxx Fixes: d0aac5e48048 (Maple Tree: add new data structure) Signed-off-by: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/maple_tree.h | 1 + lib/maple_tree.c | 34 +++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) --- a/include/linux/maple_tree.h~maple-tree-add-new-data-structure-fix-3 +++ a/include/linux/maple_tree.h @@ -434,6 +434,7 @@ struct ma_wr_state { .node = MAS_START, \ .min = 0, \ .max = ULONG_MAX, \ + .alloc = NULL, \ } #define MA_WR_STATE(name, ma_state, wr_entry) \ --- a/lib/maple_tree.c~maple-tree-add-new-data-structure-fix-3 +++ a/lib/maple_tree.c @@ -1293,18 +1293,32 @@ static inline void mas_free(struct ma_st * there is not enough nodes. * @mas: The maple state * @count: The number of nodes needed + * @gfp: the gfp flags */ -static void mas_node_count(struct ma_state *mas, int count) +static void mas_node_count_gfp(struct ma_state *mas, int count, gfp_t gfp) { unsigned long allocated = mas_allocated(mas); if (allocated < count) { mas_set_alloc_req(mas, count - allocated); - mas_alloc_nodes(mas, GFP_NOWAIT | __GFP_NOWARN); + mas_alloc_nodes(mas, gfp); } } /* + * mas_node_count() - Check if enough nodes are allocated and request more if + * there is not enough nodes. + * @mas: The maple state + * @count: The number of nodes needed + * + * Note: Uses GFP_NOWAIT | __GFP_NOWARN for gfp flags. + */ +static void mas_node_count(struct ma_state *mas, int count) +{ + return mas_node_count_gfp(mas, count, GFP_NOWAIT | __GFP_NOWARN); +} + +/* * mas_start() - Sets up maple state for operations. * @mas: The maple state. * @@ -3962,7 +3976,7 @@ static inline int mas_wr_spanning_store( if (unlikely(!mas->index && mas->last == ULONG_MAX)) return mas_new_root(mas, wr_mas->entry); /* - * Node rebalancing may occur due to this store, so there may be two new + * Node rebalancing may occur due to this store, so there may be three new * entries per level plus a new root. */ height = mas_mt_height(mas); @@ -3995,6 +4009,12 @@ static inline int mas_wr_spanning_store( mas->last = l_mas.last = r_mas.last; } + /* expanding NULLs may make this cover the entire range */ + if (!l_mas.index && r_mas.last == ULONG_MAX) { + mas_set_range(mas, 0, ULONG_MAX); + return mas_new_root(mas, wr_mas->entry); + } + memset(&b_node, 0, sizeof(struct maple_big_node)); /* Copy l_mas and store the value in b_node. */ mas_store_b_node(&l_wr_mas, &b_node, l_wr_mas.node_end); @@ -5657,15 +5677,15 @@ int mas_preallocate(struct ma_state *mas { int ret; - mas_set_alloc_req(mas, 1 + mas_mt_height(mas) * 3); - mas_alloc_nodes(mas, gfp); + mas_node_count_gfp(mas, 1 + mas_mt_height(mas) * 3, gfp); if (likely(!mas_is_err(mas))) return 0; mas_set_alloc_req(mas, 0); - mas_destroy(mas); ret = xa_err(mas->node); - mas->node = MAS_START; + mas_reset(mas); + mas_destroy(mas); + mas_reset(mas); return ret; } _ Patches currently in -mm which might be from liam.howlett@xxxxxxxxxx are android-binder-fix-lockdep-check-on-clearing-vma.patch maple-tree-add-new-data-structure-fix.patch maple-tree-add-new-data-structure-fix-2.patch maple-tree-add-new-data-structure-fix-3.patch lib-test_maple_tree-add-testing-for-maple-tree-fix.patch lib-test_maple_tree-add-testing-for-maple-tree-fix-2.patch mm-mlock-drop-dead-code-in-count_mm_mlocked_page_nr.patch