Skip to contentSkip to conversation

FAILED: patch "[PATCH] maple_tree: add mas_is_active() to detect in-tree walks" failed to apply to 6.5-stable tree

PATCH In review [email protected] 2 participants 7 messages Oct 4, 2023 – Oct 7, 2023

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.5-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.5.y
git checkout FETCH_HEAD
git cherry-pick -x 5c590804b6b0ff933ed4e5cee5d76de3a5048d9f
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023100439-obtuse-unchain-b580@gregkh' --subject-prefix 'PATCH 6.5.y' HEAD^..

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 5c590804b6b0ff933ed4e5cee5d76de3a5048d9f Mon Sep 17 00:00:00 2001
From: "Liam R. Howlett" <[email protected]>
Date: Thu, 21 Sep 2023 14:12:35 -0400
Subject: [PATCH] maple_tree: add mas_is_active() to detect in-tree walks

Patch series "maple_tree: Fix mas_prev() state regression".

Pedro Falcato retported an mprotect regression [1] which was bisected back to the iterator changes for maple tree. Root cause analysis showed the mas_prev() running off the end of the VMA space (previous from 0) followed by mas_find(), would skip the first value.

This patchset introduces maple state underflow/overflow so the sequence of calls on the maple state will return what the user expects.

Users who encounter this bug may see mprotect(), userfaultfd_register(), and mlock() fail on VMAs mapped with address 0.

This patch (of 2):

Instead of constantly checking each possibility of the maple state, create a fast path that will skip over checking unlikely states.

include/linux/maple_tree.h +9 -0
index e41c70ac7744..f66f5f78f8cf 100644
@@ -511,6 +511,15 @@ static inline bool mas_is_paused(const struct ma_state *mas)
 	return mas->node == MAS_PAUSE;
 }
 
+/* Check if the mas is pointing to a node or not */
+static inline bool mas_is_active(struct ma_state *mas)
+{
+	if ((unsigned long)mas->node >= MAPLE_RESERVED_RANGE)
+		return true;
+
+	return false;
+}
+
 /**
  * mas_reset() - Reset a Maple Tree operation state.
  * @mas: Maple Tree operation state.
#1 lore raw
Quoted 8 lines · * [email protected] <[email protected]> [231004 10:59]:

The patch below does not apply to the 6.5-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

Quoted 11 lines

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.5.y
git checkout FETCH_HEAD
git cherry-pick -x 5c590804b6b0ff933ed4e5cee5d76de3a5048d9f
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023100439-obtuse-unchain-b580@gregkh' --subject-prefix 'PATCH 6.5.y' HEAD^..

Possible dependencies:

...

This applies cleanly and builds without issue following the steps above. Is there more details on the failure?

Thanks,
Liam

author maintainer
#2 lore raw
Quoted 16 lines · Liam R. Howlett
Quoted 15 lines · * [email protected] <[email protected]> [231004 10:59]:

The patch below does not apply to the 6.5-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.5.y
git checkout FETCH_HEAD
git cherry-pick -x 5c590804b6b0ff933ed4e5cee5d76de3a5048d9f
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023100439-obtuse-unchain-b580@gregkh' --subject-prefix 'PATCH 6.5.y' HEAD^..

Quoted 8 lines
Quoted 4 lines

Possible dependencies:

...

This applies cleanly and builds without issue following the steps above. Is there more details on the failure?

The patch after this does not apply, so I dropped this one as well as it is not needed without that one with the hope that both would be sent as a series :)

thanks,

greg k-h

#3 lore raw

PATCH 1/3 maple_tree: add mas_is_active() to detect in-tree walks

In reply to [email protected]

Patch series "maple_tree: Fix mas_prev() state regression".

Pedro Falcato retported an mprotect regression [1] which was bisected back to the iterator changes for maple tree. Root cause analysis showed the mas_prev() running off the end of the VMA space (previous from 0) followed by mas_find(), would skip the first value.

This patchset introduces maple state underflow/overflow so the sequence of calls on the maple state will return what the user expects.

Users who encounter this bug may see mprotect(), userfaultfd_register(), and mlock() fail on VMAs mapped with address 0.

This patch (of 2):

Instead of constantly checking each possibility of the maple state, create a fast path that will skip over checking unlikely states.

---
 include/linux/maple_tree.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/linux/maple_tree.h +9 -0
index 295548cca8b3..e1e5f38384b2 100644
@@ -503,6 +503,15 @@ static inline bool mas_is_paused(const struct ma_state *mas)
 	return mas->node == MAS_PAUSE;
 }
 
+/* Check if the mas is pointing to a node or not */
+static inline bool mas_is_active(struct ma_state *mas)
+{
+	if ((unsigned long)mas->node >= MAPLE_RESERVED_RANGE)
+		return true;
+
+	return false;
+}
+
 /**
  * mas_reset() - Reset a Maple Tree operation state.
  * @mas: Maple Tree operation state.
Signature · 1 line
2.40.1
#4 lore raw

PATCH 2/3 maple_tree: reduce resets during store setup

mas_prealloc() may walk partially down the tree before finding that a split or spanning store is needed. When the write occurs, relax the logic on resetting the walk so that partial walks will not restart, but walks that have gone too far (a store that affects beyond the current node) should be restarted.

Cc Peng Zhang <[email protected]>
Cc Suren Baghdasaryan <[email protected]>
(cherry picked from commit fec29364348fec535c55708b1f4025b321aba572)
---
 lib/maple_tree.c | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)
lib/maple_tree.c +26 -11
index f723024e1426..86e06ec6ec35 100644
@@ -5439,19 +5439,34 @@ static inline void mte_destroy_walk(struct maple_enode *enode,
 
 static void mas_wr_store_setup(struct ma_wr_state *wr_mas)
 {
+	if (mas_is_start(wr_mas->mas))
+		return;
+
 	if (unlikely(mas_is_paused(wr_mas->mas)))
-		mas_reset(wr_mas->mas);
+		goto reset;
 
-	if (!mas_is_start(wr_mas->mas)) {
-		if (mas_is_none(wr_mas->mas)) {
-			mas_reset(wr_mas->mas);
-		} else {
-			wr_mas->r_max = wr_mas->mas->max;
-			wr_mas->type = mte_node_type(wr_mas->mas->node);
-			if (mas_is_span_wr(wr_mas))
-				mas_reset(wr_mas->mas);
-		}
-	}
+	if (unlikely(mas_is_none(wr_mas->mas)))
+		goto reset;
+
+	/*
+	 * A less strict version of mas_is_span_wr() where we allow spanning
+	 * writes within this node.  This is to stop partial walks in
+	 * mas_prealloc() from being reset.
+	 */
+	if (wr_mas->mas->last > wr_mas->mas->max)
+		goto reset;
+
+	if (wr_mas->entry)
+		return;
+
+	if (mte_is_leaf(wr_mas->mas->node) &&
+	    wr_mas->mas->last == wr_mas->mas->max)
+		goto reset;
+
+	return;
+
+reset:
+	mas_reset(wr_mas->mas);
 }
 
 /* Interface */
Signature · 1 line
2.40.1
#5 lore raw

PATCH 3/3 maple_tree: add MAS_UNDERFLOW and MAS_OVERFLOW states

In reply to Liam R. Howlett

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.

---
 include/linux/maple_tree.h |   2 +
 lib/maple_tree.c           | 221 +++++++++++++++++++++++++++----------
 lib/test_maple_tree.c      |  87 ++++++++++++---
 3 files changed, 237 insertions(+), 73 deletions(-)
include/linux/maple_tree.h +2 -0
index e1e5f38384b2..c6a19ff5fb43 100644
@@ -420,6 +420,8 @@ struct ma_wr_state {
 #define MAS_ROOT	((struct maple_enode *)5UL)
 #define MAS_NONE	((struct maple_enode *)9UL)
 #define MAS_PAUSE	((struct maple_enode *)17UL)
+#define MAS_OVERFLOW	((struct maple_enode *)33UL)
+#define MAS_UNDERFLOW	((struct maple_enode *)65UL)
 #define MA_ERROR(err) \
 		((struct maple_enode *)(((unsigned long)err << 2) | 2UL))
 
lib/maple_tree.c +163 -58

458 lines not on this page · raw message

lib/test_maple_tree.c +72 -15

193 lines not on this page · raw message

Signature · 1 line
2.40.1
author maintainer
#6 lore raw

Re: [PATCH 6.5.y 1/3] maple_tree: add mas_is_active() to detect in-tree walks

In reply to Liam R. Howlett
Quoted 1 line · Liam R. Howlett

Patch series "maple_tree: Fix mas_prev() state regression".

All now queued up, thanks.

greg k-h