Re: [PATCH v7 00/70] Introducing the Maple Tree

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

 



* Yu Zhao <yuzhao@xxxxxxxxxx> [220416 15:30]:
> On Sat, Apr 16, 2022 at 9:19 AM Liam Howlett <liam.howlett@xxxxxxxxxx> wrote:
> >
> 
> <snipped>
> 
> > How did you hit this issue?  Just on boot?
> 
> I was hoping this is known to you or you have something I can verify for you.


Thanks, yes.  I believe that both crashes are the same root cause.  The
cause is that I was not cleaning up after the kmem bulk allocation
failure on my side.  Please test with this patch.

Thanks,
Liam


From 1469ecc8c9ef662066e53d4a4a00c84d94ee9dc4 Mon Sep 17 00:00:00 2001
From: "Liam R. Howlett" <Liam.Howlett@xxxxxxxxxx>
Date: Tue, 19 Apr 2022 11:47:15 -0400
Subject: [PATCH] maple_tree: Clean up after bulk allocation failure in
 mas_alloc_nodes()

Signed-off-by: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx>
---
 lib/maple_tree.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index 6393be9d9230..3c78e63efaec 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -1206,6 +1206,8 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
 	unsigned long success = allocated;
 	unsigned int requested = mas_alloc_req(mas);
 	unsigned int count;
+	void **slots = NULL;
+	unsigned int max_req = 0;
 
 	if (!requested)
 		return;
@@ -1214,7 +1216,7 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
 	if (!allocated || mas->alloc->node_count == MAPLE_ALLOC_SLOTS - 1) {
 		node = (struct maple_alloc *)mt_alloc_one(gfp);
 		if (!node)
-			goto nomem;
+			goto nomem_one;
 
 		if (allocated)
 			node->slot[0] = mas->alloc;
@@ -1226,20 +1228,20 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
 
 	node = mas->alloc;
 	while (requested) {
-		void **slots = (void **)&node->slot;
-		unsigned int max_req = MAPLE_NODE_SLOTS - 1;
-
+		max_req = MAPLE_NODE_SLOTS - 1;
 		if (node->slot[0]) {
 			unsigned int offset = node->node_count + 1;
 
 			slots = (void **)&node->slot[offset];
 			max_req -= offset;
+		} else {
+			slots = (void **)&node->slot;
 		}
 
-		count = mt_alloc_bulk(gfp, min(requested, max_req),
-				      slots);
+		max_req = min(requested, max_req);
+		count = mt_alloc_bulk(gfp, max_req, slots);
 		if (!count)
-			goto nomem;
+			goto nomem_bulk;
 
 		node->node_count += count;
 		/* zero indexed. */
@@ -1253,7 +1255,11 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
 	}
 	mas->alloc->total = success;
 	return;
-nomem:
+
+nomem_bulk:
+	/* Clean up potential freed allocations on bulk failure */
+	memset(slots, 0, max_req * sizeof(unsigned long));
+nomem_one:
 	mas_set_alloc_req(mas, requested);
 	if (mas->alloc && !(((unsigned long)mas->alloc & 0x1)))
 		mas->alloc->total = success;
-- 
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