[PATCH] libtracecmd rbtree: Fix deletion of leaf nodes

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

 



From: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx>

In the rbtree deletion, the deletion had the logic:

	if (!node->left || !node->right)
		y = node;
	else
		y = next_node(node);

	if (y->left)
		x = y->left;
	else
		x = y->right;

	x->parent = y->parent;

Where if the node had both right and left, the y returned would not have
children. This is fine, but the x would be NULL. In that case, do not update
the parent of x. But instead, skip over and continue the work. As x->parent
would be the same as y->parent, instead of checking the x->parent (where x
could be NULL), check y->parent, which is already known to be the same as
x->parent if x is not NULL.

Also add another check_tree() at the end of the deletion routine.

Fixes: 5274db32a ("libtracecmd: Use an rbtree for mapping of cache pages")
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218357
Reported-by: pierre.gondois@xxxxxxx
Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx>
---
 lib/trace-cmd/trace-rbtree.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lib/trace-cmd/trace-rbtree.c b/lib/trace-cmd/trace-rbtree.c
index 24beabec..90671819 100644
--- a/lib/trace-cmd/trace-rbtree.c
+++ b/lib/trace-cmd/trace-rbtree.c
@@ -314,7 +314,7 @@ void trace_rbtree_delete(struct trace_rbtree *tree, struct trace_rbtree_node *no
 	struct trace_rbtree_node *x, *y;
 	bool do_fixup = false;
 
-	if (!node->left && !node->right) {
+	if (!node->left && !node->right && !node->parent) {
 		tree->node = NULL;
 		goto out;
 	}
@@ -329,9 +329,10 @@ void trace_rbtree_delete(struct trace_rbtree *tree, struct trace_rbtree_node *no
 	else
 		x = y->right;
 
-	x->parent = y->parent;
+	if (x)
+		x->parent = y->parent;
 
-	if (!x->parent) {
+	if (!y->parent) {
 		tree->node = x;
 	} else {
 		if (is_left(y))
@@ -367,6 +368,7 @@ void trace_rbtree_delete(struct trace_rbtree *tree, struct trace_rbtree_node *no
  out:
 	node->parent = node->left = node->right = NULL;
 	tree->nr_nodes--;
+	check_tree(tree);
 }
 
 __hidden struct trace_rbtree_node *trace_rbtree_next(struct trace_rbtree *tree,
-- 
2.42.0





[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux