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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
CC: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx>
CC: Sidhartha Kumar <sidhartha.kumar@xxxxxxxxxx>
---
 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





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux