[PATCH 4/4] maple_tree: fix potential allocation failure even has memory

Wei Yang richard.weiyang at gmail.com
Tue Sep 24 05:39:54 PDT 2024


We got an rare case when mas_node_count() would fail even there is
enough memory.

The reason is the maple_alloc grows downward. And when hit a full
maple_alloc, the max_req would be 0. This leads to mt_alloc_bulk()
return 0, which means failure here.

For example, here is the test code:

	expect = MAPLE_ALLOC_SLOTS + 1;
	mas_node_count(&ms, expect);
	pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms));
	expect = MAPLE_ALLOC_SLOTS * 2 + 2;
	mas_node_count(&ms, expect);
	pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms));

We will get the following output, which shows we fail to allocate the
required number of nodes.

	expect 31 allocated 31
        expect 62 allocated 61

The straight forward way to fix it is go down one level more.

Signed-off-by: Wei Yang <richard.weiyang at gmail.com>
CC: Liam R. Howlett <Liam.Howlett at Oracle.com>
CC: Sidhartha Kumar <sidhartha.kumar at oracle.com>
---
 lib/maple_tree.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index 1cbc5f7ca40d..dd33d0793dd1 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -1253,8 +1253,10 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
 	}
 
 	node = mas->alloc;
-	while (requested) {
+	for (; requested; node = node->slot[0]) {
 		max_req = MAPLE_ALLOC_SLOTS - node->node_count;
+		if (unlikely(!max_req))
+			continue;
 		slots = (void **)&node->slot[node->node_count];
 		max_req = min(requested, max_req);
 		count = mt_alloc_bulk(gfp, max_req, slots);
@@ -1268,7 +1270,6 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
 
 		node->node_count += count;
 		allocated += count;
-		node = node->slot[0];
 		requested -= count;
 	}
 	mas->alloc->total = allocated;
-- 
2.34.1




More information about the maple-tree mailing list