xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree
@ 2017-11-21 15:19 Praveen Kumar
  2017-11-21 15:19 ` [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase() Praveen Kumar
                   ` (16 more replies)
  0 siblings, 17 replies; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

Hi All,

The patch imports the changes and updates of the rbtree implementaiton
from Linux tree. But since, the only current implementation is with tmem.c,
which am not much aware off much and therefore, was unable to test the changes
thoroughly. Having said that, I do have plans of adding futher code changes
which will be using rb-tree more in credit2 scheduler and that will help in
further testing the same.

I have not imported augmented, rcu and patches which added new rbtree
functionality, as there was no specific requirement for current planned
implementation.

Below are the categorized Linux commit versions which are not imported :

Augmented rbtree :
14b94af0b251a2c80885b60538166fb7d04a642e
9d9e6f9703bbd642f3f2f807e6aaa642a4cbcec9
9c079add0d0f45220f4bb37febf0621137ec2d38
3cb7a56344ca45ee56d71c5f8fe9f922306bff1f
f231aebfc4cae2f6ed27a46a31e2630909513d77


Add postorder iteration functions:
9dee5c51516d2c3fff22633c1272c5652e68075a

RCU related implementation :
d72da4a4d973d8a0a0d3c97e7cdebf287fbe3a99
c1adf20052d80f776849fa2c1acb472cdeb7786c
ce093a04543c403d52c1a5788d8cb92e47453aba

Please share your inputs. Thanks in advance.

Regards,

~Praveen.

Praveen Kumar (16):
  rbtree: remove redundant if()-condition in rb_erase()
  rbtree: empty nodes have no color
  rbtree: move some implementation details from rbtree.h to rbtree.c
  rbtree: break out of rb_insert_color loop after tree rotation
  rbtree: adjust root color in rb_insert_color() only when necessary
  rbtree: low level optimizations in rb_insert_color()
  rbtree: adjust node color in __rb_erase_color() only when necessary
  rbtree: optimize case selection logic in __rb_erase_color()
  rbtree: low level optimizations in __rb_erase_color()
  rbtree: coding style adjustments
  rbtree: optimize fetching of sibling node
  rbtree: add __rb_change_child() helper function
  rbtree: place easiest case first in rb_erase()
  rbtree: handle 1-child recoloring in rb_erase() instead of
    rb_erase_color()
  rbtree: low level optimizations in rb_erase()
  rbtree: fix typo in comment of rb_insert_color

 xen/common/rbtree.c      | 646 ++++++++++++++++++++++++++++++-----------------
 xen/include/xen/rbtree.h |  38 +--
 2 files changed, 428 insertions(+), 256 deletions(-)

---
Updated set of changes catering the comments provided.
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase()
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
@ 2017-11-21 15:19 ` Praveen Kumar
  2017-12-20 16:39   ` Jan Beulich
  2017-11-21 15:19 ` [PATCH v6 02/16 RESEND] rbtree: empty nodes have no color Praveen Kumar
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Wolfram Strepp <wstrepp@gmx.de>

Furthermore, notice that the initial checks:

            if (!node->rb_left)
                    child = node->rb_right;
            else if (!node->rb_right)
                    child = node->rb_left;
            else
            {
                    ...
            }
guarantee that old->rb_right is set in the final else branch, therefore
we can omit checking that again.

Signed-off-by: Wolfram Strepp <wstrepp@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 4b324126e0c6c3a5080ca3ec0981e8766ed6f1ee]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
Removed new line from previous patch to sync the changes completely with linux
code base.
---
 xen/common/rbtree.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 167ebfdc4d..62e6387dcd 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -250,15 +250,15 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 			if (child)
 				rb_set_parent(child, parent);
 			parent->rb_left = child;
+
+			node->rb_right = old->rb_right;
+			rb_set_parent(old->rb_right, node);
 		}
 
 		node->rb_parent_color = old->rb_parent_color;
-		node->rb_right = old->rb_right;
 		node->rb_left = old->rb_left;
-
 		rb_set_parent(old->rb_left, node);
-		if (old->rb_right)
-			rb_set_parent(old->rb_right, node);
+
 		goto color;
 	}
 
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 02/16 RESEND] rbtree: empty nodes have no color
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
  2017-11-21 15:19 ` [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase() Praveen Kumar
@ 2017-11-21 15:19 ` Praveen Kumar
  2017-12-20 16:43   ` Jan Beulich
  2017-11-21 15:19 ` [PATCH v6 03/16 RESEND] rbtree: move some implementation details from rbtree.h to rbtree.c Praveen Kumar
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

Empty nodes have no color.  We can make use of this property to simplify
the code emitted by the RB_EMPTY_NODE and RB_CLEAR_NODE macros.  Also,
we can get rid of the rb_init_node function which had been introduced by
commit 88d19cf37952 ("timers: Add rb_init_node() to allow for stack
allocated rb nodes") to avoid some issue with the empty node's color not
being initialized.

I'm not sure what the RB_EMPTY_NODE checks in rb_prev() / rb_next() are
doing there, though.  axboe introduced them in commit 10fd48f2376d
("rbtree: fixed reversed RB_EMPTY_NODE and rb_next/prev").  The way I
see it, the 'empty node' abstraction is only used by rbtree users to
flag nodes that they haven't inserted in any rbtree, so asking the
predecessor or successor of such nodes doesn't make any sense.

One final rb_init_node() caller was recently added in sysctl code to
implement faster sysctl name lookups.  This code doesn't make use of
RB_EMPTY_NODE at all, and from what I could see it only called
rb_init_node() under the mistaken assumption that such initialization was
required before node insertion.

[sfr@canb.auug.org.au: fix net/ceph/osd_client.c build]
Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 4c199a93a2d36b277a9fd209a0f2793f8460a215]

Ported rbtree.h and rbtree.c changes which are relevant to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c      | 4 ++--
 xen/include/xen/rbtree.h | 8 +++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 62e6387dcd..76f009f5a9 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -316,7 +316,7 @@ struct rb_node *rb_next(const struct rb_node *node)
 {
 	struct rb_node *parent;
 
-	if (rb_parent(node) == node)
+	if (RB_EMPTY_NODE(node))
 		return NULL;
 
 	/* If we have a right-hand child, go down and then left as far
@@ -345,7 +345,7 @@ struct rb_node *rb_prev(const struct rb_node *node)
 {
 	struct rb_node *parent;
 
-	if (rb_parent(node) == node)
+	if (RB_EMPTY_NODE(node))
 		return NULL;
 
 	/* If we have a left-hand child, go down and then right as far
diff --git a/xen/include/xen/rbtree.h b/xen/include/xen/rbtree.h
index 9496f099f8..e947e3800f 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -128,9 +128,11 @@ static inline void rb_set_color(struct rb_node *rb, int color)
 #define RB_ROOT	(struct rb_root) { NULL, }
 #define	rb_entry(ptr, type, member) container_of(ptr, type, member)
 
-#define RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
-#define RB_EMPTY_NODE(node)	(rb_parent(node) == node)
-#define RB_CLEAR_NODE(node)	(rb_set_parent(node, node))
+#define RB_EMPTY_ROOT(root)  ((root)->rb_node == NULL)
+
+/* 'empty' nodes are nodes that are known not to be inserted in an rbree */
+#define RB_EMPTY_NODE(node)  ((node)->rb_parent_color == (unsigned long)(node))
+#define RB_CLEAR_NODE(node)  ((node)->rb_parent_color = (unsigned long)(node))
 
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 03/16 RESEND] rbtree: move some implementation details from rbtree.h to rbtree.c
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
  2017-11-21 15:19 ` [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase() Praveen Kumar
  2017-11-21 15:19 ` [PATCH v6 02/16 RESEND] rbtree: empty nodes have no color Praveen Kumar
@ 2017-11-21 15:19 ` Praveen Kumar
  2017-12-20 16:46   ` Jan Beulich
  2017-11-21 15:19 ` [PATCH v6 04/16 RESEND] rbtree: break out of rb_insert_color loop after tree rotation Praveen Kumar
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

rbtree users must use the documented APIs to manipulate the tree
structure.  Low-level helpers to manipulate node colors and parenthood are
not part of that API, so move them to lib/rbtree.c

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit bf7ad8eeab995710c766df49c9c69a8592ca0216]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c      | 20 +++++++++++++++++++-
 xen/include/xen/rbtree.h | 34 +++++++++-------------------------
 2 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 76f009f5a9..a75b336ba2 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -23,6 +23,24 @@
 #include <xen/types.h>
 #include <xen/rbtree.h>
 
+#define		RB_RED		0
+#define		RB_BLACK	1
+
+#define rb_color(r)   ((r)->__rb_parent_color & 1)
+#define rb_is_red(r)   (!rb_color(r))
+#define rb_is_black(r) rb_color(r)
+#define rb_set_red(r)  do { (r)->__rb_parent_color &= ~1; } while (0)
+#define rb_set_black(r)  do { (r)->__rb_parent_color |= 1; } while (0)
+
+static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
+}
+static inline void rb_set_color(struct rb_node *rb, int color)
+{
+	rb->__rb_parent_color = (rb->__rb_parent_color & ~1) | color;
+}
+
 static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
 {
 	struct rb_node *right = node->rb_right;
@@ -255,7 +273,7 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 			rb_set_parent(old->rb_right, node);
 		}
 
-		node->rb_parent_color = old->rb_parent_color;
+		node->__rb_parent_color = old->__rb_parent_color;
 		node->rb_left = old->rb_left;
 		rb_set_parent(old->rb_left, node);
 
diff --git a/xen/include/xen/rbtree.h b/xen/include/xen/rbtree.h
index e947e3800f..1b72590e4e 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -94,36 +94,18 @@ static inline struct page * rb_insert_page_cache(struct inode * inode,
 #ifndef __RBTREE_H__
 #define __RBTREE_H__
 
-struct rb_node
-{
-	unsigned long  rb_parent_color;
-#define	RB_RED		0
-#define	RB_BLACK	1
+struct rb_node {
+	unsigned long  __rb_parent_color;
 	struct rb_node *rb_right;
 	struct rb_node *rb_left;
 } __attribute__((aligned(sizeof(long))));
     /* The alignment might seem pointless, but allegedly CRIS needs it */
 
-struct rb_root
-{
+struct rb_root {
 	struct rb_node *rb_node;
 };
 
-#define rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
-#define rb_color(r)   ((r)->rb_parent_color & 1)
-#define rb_is_red(r)   (!rb_color(r))
-#define rb_is_black(r) rb_color(r)
-#define rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
-#define rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
-
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
-	rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
-}
-static inline void rb_set_color(struct rb_node *rb, int color)
-{
-	rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
-}
+#define rb_parent(r)	((struct rb_node *)((r)->__rb_parent_color & ~3))
 
 #define RB_ROOT	(struct rb_root) { NULL, }
 #define	rb_entry(ptr, type, member) container_of(ptr, type, member)
@@ -131,8 +113,10 @@ static inline void rb_set_color(struct rb_node *rb, int color)
 #define RB_EMPTY_ROOT(root)  ((root)->rb_node == NULL)
 
 /* 'empty' nodes are nodes that are known not to be inserted in an rbree */
-#define RB_EMPTY_NODE(node)  ((node)->rb_parent_color == (unsigned long)(node))
-#define RB_CLEAR_NODE(node)  ((node)->rb_parent_color = (unsigned long)(node))
+#define RB_EMPTY_NODE(node)  \
+	((node)->__rb_parent_color == (unsigned long)(node))
+#define RB_CLEAR_NODE(node)  \
+	((node)->__rb_parent_color = (unsigned long)(node))
 
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
@@ -150,7 +134,7 @@ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
 static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
 				struct rb_node ** rb_link)
 {
-	node->rb_parent_color = (unsigned long )parent;
+	node->__rb_parent_color = (unsigned long )parent;
 	node->rb_left = node->rb_right = NULL;
 
 	*rb_link = node;
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 04/16 RESEND] rbtree: break out of rb_insert_color loop after tree rotation
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (2 preceding siblings ...)
  2017-11-21 15:19 ` [PATCH v6 03/16 RESEND] rbtree: move some implementation details from rbtree.h to rbtree.c Praveen Kumar
@ 2017-11-21 15:19 ` Praveen Kumar
  2017-12-20 16:49   ` Jan Beulich
  2017-11-21 15:19 ` [PATCH v6 05/16 RESEND] rbtree: adjust root color in rb_insert_color() only when necessary Praveen Kumar
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

It is a well known property of rbtrees that insertion never requires more
than two tree rotations.  In our implementation, after one loop iteration
identified one or two necessary tree rotations, we would iterate and look
for more.  However at that point the node's parent would always be black,
which would cause us to exit the loop.

We can make the code flow more obvious by just adding a break statement
after the tree rotations, where we know we are done.  Additionally, in the
cases where two tree rotations are necessary, we don't have to update the
'node' pointer as it wouldn't be used until the next loop iteration, which
we now avoid due to this break statement.

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 1f0528653e41ec230c60f5738820e8a544731399]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index a75b336ba2..9dc296e0d8 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -109,18 +109,15 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 				}
 			}
 
-			if (parent->rb_right == node)
-			{
-				register struct rb_node *tmp;
+			if (parent->rb_right == node) {
 				__rb_rotate_left(parent, root);
-				tmp = parent;
 				parent = node;
-				node = tmp;
 			}
 
 			rb_set_black(parent);
 			rb_set_red(gparent);
 			__rb_rotate_right(gparent, root);
+			break;
 		} else {
 			{
 				register struct rb_node *uncle = gparent->rb_left;
@@ -134,18 +131,15 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 				}
 			}
 
-			if (parent->rb_left == node)
-			{
-				register struct rb_node *tmp;
+			if (parent->rb_left == node) {
 				__rb_rotate_right(parent, root);
-				tmp = parent;
 				parent = node;
-				node = tmp;
 			}
 
 			rb_set_black(parent);
 			rb_set_red(gparent);
 			__rb_rotate_left(gparent, root);
+			break;
 		}
 	}
 
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 05/16 RESEND] rbtree: adjust root color in rb_insert_color() only when necessary
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (3 preceding siblings ...)
  2017-11-21 15:19 ` [PATCH v6 04/16 RESEND] rbtree: break out of rb_insert_color loop after tree rotation Praveen Kumar
@ 2017-11-21 15:19 ` Praveen Kumar
  2017-12-20 16:51   ` Jan Beulich
  2017-11-21 15:19 ` [PATCH v6 06/16 RESEND] rbtree: low level optimizations in rb_insert_color() Praveen Kumar
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

The root node of an rbtree must always be black.  However,
rb_insert_color() only needs to maintain this invariant when it has been
broken - that is, when it exits the loop due to the current (red) node
being the root.  In all other cases (exiting after tree rotations, or
exiting due to an existing black parent) the invariant is already
satisfied, so there is no need to adjust the root node color.

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 6d58452dc066db61acdff7b84671db1b11a3de1c]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 9dc296e0d8..244f1d8818 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -91,8 +91,21 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 {
 	struct rb_node *parent, *gparent;
 
-	while ((parent = rb_parent(node)) && rb_is_red(parent))
-	{
+	while (true) {
+		/*
+		 * Loop invariant: node is red
+		 *
+		 * If there is a black parent, we are done.
+		 * Otherwise, take some corrective action as we don't
+		 * want a red root or two consecutive red nodes.
+		 */
+		parent = rb_parent(node);
+		if (!parent) {
+			rb_set_black(node);
+			break;
+		} else if (rb_is_black(parent))
+			break;
+
 		gparent = rb_parent(parent);
 
 		if (parent == gparent->rb_left)
@@ -142,8 +155,6 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 			break;
 		}
 	}
-
-	rb_set_black(root->rb_node);
 }
 EXPORT_SYMBOL(rb_insert_color);
 
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 06/16 RESEND] rbtree: low level optimizations in rb_insert_color()
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (4 preceding siblings ...)
  2017-11-21 15:19 ` [PATCH v6 05/16 RESEND] rbtree: adjust root color in rb_insert_color() only when necessary Praveen Kumar
@ 2017-11-21 15:19 ` Praveen Kumar
  2017-12-20 16:52   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 07/16 RESEND] rbtree: adjust node color in __rb_erase_color() only when necessary Praveen Kumar
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

- Use the newly introduced rb_set_parent_color() function to flip the color
  of nodes whose parent is already known.
- Optimize rb_parent() when the node is known to be red - there is no need
  to mask out the color in that case.
- Flipping gparent's color to red requires us to fetch its rb_parent_color
  field, so we can reuse it as the parent value for the next loop iteration.
- Do not use __rb_rotate_left() and __rb_rotate_right() to handle tree
  rotations: we already have pointers to all relevant nodes, and know their
  colors (either because we want to adjust it, or because we've tested it,
  or we can deduce it as black due to the node proximity to a known red node).
  So we can generate more efficient code by making use of the node pointers
  we already have, and setting both the parent and color attributes for
  nodes all at once. Also in Case 2, some node attributes don't have to
  be set because we know another tree rotation (Case 3) will always follow
  and override them.

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 5bc9188aa207dafd47eab57df7c4fe5b3d3f636a]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 166 +++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 131 insertions(+), 35 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 244f1d8818..72dfcf9acb 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -23,6 +23,25 @@
 #include <xen/types.h>
 #include <xen/rbtree.h>
 
+/*
+ * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
+ *
+ *  1) A node is either red or black
+ *  2) The root is black
+ *  3) All leaves (NULL) are black
+ *  4) Both children of every red node are black
+ *  5) Every simple path from root to leaves contains the same number
+ *     of black nodes.
+ *
+ *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
+ *  consecutive red nodes in a path and every red node is therefore followed by
+ *  a black. So if B is the number of black nodes on every simple path (as per
+ *  5), then the longest possible path due to 4 is 2B.
+ *
+ *  We shall indicate color with case, where black nodes are uppercase and red
+ *  nodes will be lowercase.
+ */
+
 #define		RB_RED		0
 #define		RB_BLACK	1
 
@@ -41,6 +60,17 @@ static inline void rb_set_color(struct rb_node *rb, int color)
 	rb->__rb_parent_color = (rb->__rb_parent_color & ~1) | color;
 }
 
+static inline void rb_set_parent_color(struct rb_node *rb,
+				      struct rb_node *p, int color)
+{
+	rb->__rb_parent_color = (unsigned long)p | color;
+}
+
+static inline struct rb_node *rb_red_parent(struct rb_node *red)
+{
+	return (struct rb_node *)red->__rb_parent_color;
+}
+
 static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
 {
 	struct rb_node *right = node->rb_right;
@@ -87,9 +117,30 @@ static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
 	rb_set_parent(node, left);
 }
 
+/*
+ * Helper function for rotations:
+ * - old's parent and color get assigned to new
+ * - old gets assigned new as a parent and 'color' as a color.
+ */
+static inline void
+__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
+			struct rb_root *root, int color)
+{
+	struct rb_node *parent = rb_parent(old);
+	new->__rb_parent_color = old->__rb_parent_color;
+	rb_set_parent_color(old, new, color);
+	if (parent) {
+		if (parent->rb_left == old)
+			parent->rb_left = new;
+		else
+			parent->rb_right = new;
+	} else
+		root->rb_node = new;
+}
+
 void rb_insert_color(struct rb_node *node, struct rb_root *root)
 {
-	struct rb_node *parent, *gparent;
+	struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
 
 	while (true) {
 		/*
@@ -99,59 +150,104 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 		 * Otherwise, take some corrective action as we don't
 		 * want a red root or two consecutive red nodes.
 		 */
-		parent = rb_parent(node);
 		if (!parent) {
-			rb_set_black(node);
+			rb_set_parent_color(node, NULL, RB_BLACK);
 			break;
 		} else if (rb_is_black(parent))
 			break;
 
-		gparent = rb_parent(parent);
-
-		if (parent == gparent->rb_left)
-		{
-			{
-				register struct rb_node *uncle = gparent->rb_right;
-				if (uncle && rb_is_red(uncle))
-				{
-					rb_set_black(uncle);
-					rb_set_black(parent);
-					rb_set_red(gparent);
-					node = gparent;
-					continue;
-				}
+		gparent = rb_red_parent(parent);
+
+		if (parent == gparent->rb_left) {
+			tmp = gparent->rb_right;
+			if (tmp && rb_is_red(tmp)) {
+				/*
+				 * Case 1 - color flips
+				 *
+				 *       G            g
+				 *      / \          / \
+				 *     p   u  -->   P   U
+				 *    /            /
+				 *   n            N
+				 *
+				 * However, since g's parent might be red, and
+				 * 4) does not allow this, we need to recurse
+				 * at g.
+				 */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
 			}
 
 			if (parent->rb_right == node) {
-				__rb_rotate_left(parent, root);
+				/*
+				 * Case 2 - left rotate at parent
+				 *
+				 *      G             G
+				 *     / \           / \
+				 *    p   U  -->    n   U
+				 *     \           /
+				 *      n         p
+				 *
+				 * This still leaves us in violation of 4), the
+				 * continuation into Case 3 will fix that.
+				 */
+				parent->rb_right = tmp = node->rb_left;
+				node->rb_left = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
 				parent = node;
 			}
 
-			rb_set_black(parent);
-			rb_set_red(gparent);
-			__rb_rotate_right(gparent, root);
+			/*
+			 * Case 3 - right rotate at gparent
+			 *
+			 *        G           P
+			 *       / \         / \
+			 *      p   U  -->  n   g
+			 *     /                 \
+			 *    n                   U
+			 */
+			gparent->rb_left = tmp = parent->rb_right;
+			parent->rb_right = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
 			break;
 		} else {
-			{
-				register struct rb_node *uncle = gparent->rb_left;
-				if (uncle && rb_is_red(uncle))
-				{
-					rb_set_black(uncle);
-					rb_set_black(parent);
-					rb_set_red(gparent);
-					node = gparent;
-					continue;
-				}
+			tmp = gparent->rb_left;
+			if (tmp && rb_is_red(tmp)) {
+				/* Case 1 - color flips */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
 			}
 
 			if (parent->rb_left == node) {
-				__rb_rotate_right(parent, root);
+				/* Case 2 - right rotate at parent */
+				parent->rb_left = tmp = node->rb_right;
+				node->rb_right = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
 				parent = node;
 			}
 
-			rb_set_black(parent);
-			rb_set_red(gparent);
-			__rb_rotate_left(gparent, root);
+			/* Case 3 - left rotate at gparent */
+			gparent->rb_right = tmp = parent->rb_left;
+			parent->rb_left = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
 			break;
 		}
 	}
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 07/16 RESEND] rbtree: adjust node color in __rb_erase_color() only when necessary
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (5 preceding siblings ...)
  2017-11-21 15:19 ` [PATCH v6 06/16 RESEND] rbtree: low level optimizations in rb_insert_color() Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2017-12-20 16:55   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 08/16 RESEND] rbtree: optimize case selection logic in __rb_erase_color() Praveen Kumar
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

In __rb_erase_color(), we were always setting a node to black after
exiting the main loop.  And in one case, after fixing up the tree to
satisfy all rbtree invariants, we were setting the current node to root
just to guarantee a loop exit, at which point the root would be set to
black.  However this is not necessary, as the root of an rbtree is already
known to be black.  The only case where the color flip is required is when
we exit the loop due to the current node being red, and it's easiest to
just do the flip at that point instead of doing it after the loop.

[adrian.hunter@intel.com: perf tools: fix build for another rbtree.c change]
Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit d6ff1273928ebf15466a85b7e1810cd00e72998b]

Ported only rbtree.c to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 72dfcf9acb..5d44533f57 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -259,10 +259,22 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 {
 	struct rb_node *other;
 
-	while ((!node || rb_is_black(node)) && node != root->rb_node)
-	{
-		if (parent->rb_left == node)
-		{
+	while (true) {
+		/*
+		 * Loop invariant: all leaf paths going through node have a
+		 * black node count that is 1 lower than other leaf paths.
+		 *
+		 * If node is red, we can flip it to black to adjust.
+		 * If node is the root, all leaf paths go through it.
+		 * Otherwise, we need to adjust the tree through color flips
+		 * and tree rotations as per one of the 4 cases below.
+		 */
+		if (node && rb_is_red(node)) {
+			rb_set_black(node);
+			break;
+		} else if (!parent) {
+			break;
+		} else if (parent->rb_left == node) {
 			other = parent->rb_right;
 			if (rb_is_red(other))
 			{
@@ -291,12 +303,9 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 				rb_set_black(parent);
 				rb_set_black(other->rb_right);
 				__rb_rotate_left(parent, root);
-				node = root->rb_node;
 				break;
 			}
-		}
-		else
-		{
+		} else {
 			other = parent->rb_left;
 			if (rb_is_red(other))
 			{
@@ -325,13 +334,10 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 				rb_set_black(parent);
 				rb_set_black(other->rb_left);
 				__rb_rotate_right(parent, root);
-				node = root->rb_node;
 				break;
 			}
 		}
 	}
-	if (node)
-		rb_set_black(node);
 }
 
 void rb_erase(struct rb_node *node, struct rb_root *root)
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 08/16 RESEND] rbtree: optimize case selection logic in __rb_erase_color()
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (6 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 07/16 RESEND] rbtree: adjust node color in __rb_erase_color() only when necessary Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2017-12-20 16:57   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 09/16 RESEND] rbtree: low level optimizations " Praveen Kumar
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

In __rb_erase_color(), we have to select one of 3 cases depending on the
color on the 'other' node children.  If both children are black, we flip a
few node colors and iterate.  Otherwise, we do either one or two tree
rotations, depending on the color of the 'other' child opposite to 'node',
and then we are done.

The corresponding logic had duplicate checks for the color of the 'other'
child opposite to 'node'.  It was checking it first to determine if both
children are black, and then to determine how many tree rotations are
required.  Rearrange the logic to avoid that extra check.

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit e125d1471a4f8f1bf7ea9a83deb8d23cb40bd712]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 68 +++++++++++++++++++++++------------------------------
 1 file changed, 30 insertions(+), 38 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 5d44533f57..462662886a 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -283,28 +283,24 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 				__rb_rotate_left(parent, root);
 				other = parent->rb_right;
 			}
-			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
-			    (!other->rb_right || rb_is_black(other->rb_right)))
-			{
-				rb_set_red(other);
-				node = parent;
-				parent = rb_parent(node);
-			}
-			else
-			{
-				if (!other->rb_right || rb_is_black(other->rb_right))
-				{
-					rb_set_black(other->rb_left);
+			if (!other->rb_right || rb_is_black(other->rb_right)) {
+				if (!other->rb_left ||
+				    rb_is_black(other->rb_left)) {
 					rb_set_red(other);
-					__rb_rotate_right(other, root);
-					other = parent->rb_right;
+					node = parent;
+					parent = rb_parent(node);
+					continue;
 				}
-				rb_set_color(other, rb_color(parent));
-				rb_set_black(parent);
-				rb_set_black(other->rb_right);
-				__rb_rotate_left(parent, root);
-				break;
+				rb_set_black(other->rb_left);
+				rb_set_red(other);
+				__rb_rotate_right(other, root);
+				other = parent->rb_right;
 			}
+			rb_set_color(other, rb_color(parent));
+			rb_set_black(parent);
+			rb_set_black(other->rb_right);
+			__rb_rotate_left(parent, root);
+			break;
 		} else {
 			other = parent->rb_left;
 			if (rb_is_red(other))
@@ -314,28 +310,24 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 				__rb_rotate_right(parent, root);
 				other = parent->rb_left;
 			}
-			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
-			    (!other->rb_right || rb_is_black(other->rb_right)))
-			{
-				rb_set_red(other);
-				node = parent;
-				parent = rb_parent(node);
-			}
-			else
-			{
-				if (!other->rb_left || rb_is_black(other->rb_left))
-				{
-					rb_set_black(other->rb_right);
+			if (!other->rb_left || rb_is_black(other->rb_left)) {
+				if (!other->rb_right ||
+				    rb_is_black(other->rb_right)) {
 					rb_set_red(other);
-					__rb_rotate_left(other, root);
-					other = parent->rb_left;
+					node = parent;
+					parent = rb_parent(node);
+					continue;
 				}
-				rb_set_color(other, rb_color(parent));
-				rb_set_black(parent);
-				rb_set_black(other->rb_left);
-				__rb_rotate_right(parent, root);
-				break;
+				rb_set_black(other->rb_right);
+				rb_set_red(other);
+				__rb_rotate_left(other, root);
+				other = parent->rb_left;
 			}
+			rb_set_color(other, rb_color(parent));
+			rb_set_black(parent);
+			rb_set_black(other->rb_left);
+			__rb_rotate_right(parent, root);
+			break;
 		}
 	}
 }
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 09/16 RESEND] rbtree: low level optimizations in __rb_erase_color()
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (7 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 08/16 RESEND] rbtree: optimize case selection logic in __rb_erase_color() Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2017-12-20 16:59   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 10/16 RESEND] rbtree: coding style adjustments Praveen Kumar
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

In __rb_erase_color(), we often already have pointers to the nodes being
rotated and/or know what their colors must be, so we can generate more
efficient code than the generic __rb_rotate_left() and __rb_rotate_right()
functions.

Also when the current node is red or when flipping the sibling's color,
the parent is already known so we can use the more efficient
rb_set_parent_color() function to set the desired color.

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 6280d2356fd8ad0936a63c10dc1e6accf48d0c61]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 208 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 115 insertions(+), 93 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 462662886a..0ad1a1455d 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -39,7 +39,8 @@
  *  5), then the longest possible path due to 4 is 2B.
  *
  *  We shall indicate color with case, where black nodes are uppercase and red
- *  nodes will be lowercase.
+ *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
+ *  parentheses and have some accompanying text comment.
  */
 
 #define		RB_RED		0
@@ -48,17 +49,11 @@
 #define rb_color(r)   ((r)->__rb_parent_color & 1)
 #define rb_is_red(r)   (!rb_color(r))
 #define rb_is_black(r) rb_color(r)
-#define rb_set_red(r)  do { (r)->__rb_parent_color &= ~1; } while (0)
-#define rb_set_black(r)  do { (r)->__rb_parent_color |= 1; } while (0)
 
 static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
 {
 	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
 }
-static inline void rb_set_color(struct rb_node *rb, int color)
-{
-	rb->__rb_parent_color = (rb->__rb_parent_color & ~1) | color;
-}
 
 static inline void rb_set_parent_color(struct rb_node *rb,
 				      struct rb_node *p, int color)
@@ -71,52 +66,6 @@ static inline struct rb_node *rb_red_parent(struct rb_node *red)
 	return (struct rb_node *)red->__rb_parent_color;
 }
 
-static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
-{
-	struct rb_node *right = node->rb_right;
-	struct rb_node *parent = rb_parent(node);
-
-	if ((node->rb_right = right->rb_left))
-		rb_set_parent(right->rb_left, node);
-	right->rb_left = node;
-
-	rb_set_parent(right, parent);
-
-	if (parent)
-	{
-		if (node == parent->rb_left)
-			parent->rb_left = right;
-		else
-			parent->rb_right = right;
-	}
-	else
-		root->rb_node = right;
-	rb_set_parent(node, right);
-}
-
-static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
-{
-	struct rb_node *left = node->rb_left;
-	struct rb_node *parent = rb_parent(node);
-
-	if ((node->rb_left = left->rb_right))
-		rb_set_parent(left->rb_right, node);
-	left->rb_right = node;
-
-	rb_set_parent(left, parent);
-
-	if (parent)
-	{
-		if (node == parent->rb_right)
-			parent->rb_right = left;
-		else
-			parent->rb_left = left;
-	}
-	else
-		root->rb_node = left;
-	rb_set_parent(node, left);
-}
-
 /*
  * Helper function for rotations:
  * - old's parent and color get assigned to new
@@ -257,7 +206,7 @@ EXPORT_SYMBOL(rb_insert_color);
 static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 			     struct rb_root *root)
 {
-	struct rb_node *other;
+	struct rb_node *sibling, *tmp1, *tmp2;
 
 	while (true) {
 		/*
@@ -270,63 +219,136 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 		 * and tree rotations as per one of the 4 cases below.
 		 */
 		if (node && rb_is_red(node)) {
-			rb_set_black(node);
+			rb_set_parent_color(node, parent, RB_BLACK);
 			break;
 		} else if (!parent) {
 			break;
 		} else if (parent->rb_left == node) {
-			other = parent->rb_right;
-			if (rb_is_red(other))
-			{
-				rb_set_black(other);
-				rb_set_red(parent);
-				__rb_rotate_left(parent, root);
-				other = parent->rb_right;
+			sibling = parent->rb_right;
+			if (rb_is_red(sibling)) {
+				/*
+				 * Case 1 - left rotate at parent
+				 *
+				 *     P               S
+				 *    / \             / \
+				 *   N   s    -->    p   Sr
+				 *      / \         / \
+				 *     Sl  Sr      N   Sl
+				 */
+				parent->rb_right = tmp1 = sibling->rb_left;
+				sibling->rb_left = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				sibling = tmp1;
 			}
-			if (!other->rb_right || rb_is_black(other->rb_right)) {
-				if (!other->rb_left ||
-				    rb_is_black(other->rb_left)) {
-					rb_set_red(other);
+			tmp1 = sibling->rb_right;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_left;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/*
+					* Case 2 - sibling color flip
+					* (p could be either color here)
+					*
+					*    (p)           (p)
+					*    / \           / \
+					*   N   S    -->  N   s
+					*      / \           / \
+					*     Sl  Sr        Sl  Sr
+					*
+					* This leaves us violating 5), so
+					* recurse at p. If p is red, the
+					* recursion will just flip it to black
+					* and exit. If coming from Case 1,
+					* p is known to be red.
+					*/
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
 					node = parent;
 					parent = rb_parent(node);
 					continue;
 				}
-				rb_set_black(other->rb_left);
-				rb_set_red(other);
-				__rb_rotate_right(other, root);
-				other = parent->rb_right;
+				/*
+				 * Case 3 - right rotate at sibling
+				 * (p could be either color here)
+				 *
+				 *   (p)           (p)
+				 *   / \           / \
+				 *  N   S    -->  N   Sl
+				 *     / \             \
+				 *    sl  Sr            s
+				 *                       \
+				 *                        Sr
+				 */
+				sibling->rb_left = tmp1 = tmp2->rb_right;
+				tmp2->rb_right = sibling;
+				parent->rb_right = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				tmp1 = sibling;
+				sibling = tmp2;
 			}
-			rb_set_color(other, rb_color(parent));
-			rb_set_black(parent);
-			rb_set_black(other->rb_right);
-			__rb_rotate_left(parent, root);
+			/*
+			 * Case 4 - left rotate at parent + color flips
+			 * (p and sl could be either color here.
+			 *  After rotation, p becomes black, s acquires
+			 *  p's color, and sl keeps its color)
+			 *
+			 *      (p)             (s)
+			 *      / \             / \
+			 *     N   S     -->   P   Sr
+			 *        / \         / \
+			 *      (sl) sr      N  (sl)
+			 */
+			parent->rb_right = tmp2 = sibling->rb_left;
+			sibling->rb_left = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
 			break;
 		} else {
-			other = parent->rb_left;
-			if (rb_is_red(other))
-			{
-				rb_set_black(other);
-				rb_set_red(parent);
-				__rb_rotate_right(parent, root);
-				other = parent->rb_left;
+			sibling = parent->rb_left;
+			if (rb_is_red(sibling)) {
+				/* Case 1 - right rotate at parent */
+				parent->rb_left = tmp1 = sibling->rb_right;
+				sibling->rb_right = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				sibling = tmp1;
 			}
-			if (!other->rb_left || rb_is_black(other->rb_left)) {
-				if (!other->rb_right ||
-				    rb_is_black(other->rb_right)) {
-					rb_set_red(other);
+			tmp1 = sibling->rb_left;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_right;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/* Case 2 - sibling color flip */
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
 					node = parent;
 					parent = rb_parent(node);
 					continue;
 				}
-				rb_set_black(other->rb_right);
-				rb_set_red(other);
-				__rb_rotate_left(other, root);
-				other = parent->rb_left;
+				/* Case 3 - right rotate at sibling */
+				sibling->rb_right = tmp1 = tmp2->rb_left;
+				tmp2->rb_left = sibling;
+				parent->rb_left = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				tmp1 = sibling;
+				sibling = tmp2;
 			}
-			rb_set_color(other, rb_color(parent));
-			rb_set_black(parent);
-			rb_set_black(other->rb_left);
-			__rb_rotate_right(parent, root);
+			/* Case 4 - left rotate at parent + color flips */
+			parent->rb_left = tmp2 = sibling->rb_right;
+			sibling->rb_right = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
 			break;
 		}
 	}
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 10/16 RESEND] rbtree: coding style adjustments
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (8 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 09/16 RESEND] rbtree: low level optimizations " Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2018-01-03 11:26   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 11/16 RESEND] rbtree: optimize fetching of sibling node Praveen Kumar
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

Set comment and indentation style to be consistent with linux coding style
and the rest of the file, as suggested by Peter Zijlstra

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 0ad1a1455d..b964171bee 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -363,8 +363,7 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 		child = node->rb_right;
 	else if (!node->rb_right)
 		child = node->rb_left;
-	else
-	{
+	else {
 		struct rb_node *old = node, *left;
 
 		node = node->rb_right;
@@ -406,17 +405,15 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 
 	if (child)
 		rb_set_parent(child, parent);
-	if (parent)
-	{
+	if (parent) {
 		if (parent->rb_left == node)
 			parent->rb_left = child;
 		else
 			parent->rb_right = child;
-	}
-	else
+	} else
 		root->rb_node = child;
 
- color:
+color:
 	if (color == RB_BLACK)
 		__rb_erase_color(child, parent, root);
 }
@@ -458,8 +455,10 @@ struct rb_node *rb_next(const struct rb_node *node)
 	if (RB_EMPTY_NODE(node))
 		return NULL;
 
-	/* If we have a right-hand child, go down and then left as far
-	   as we can. */
+	/*
+	 * If we have a right-hand child, go down and then left as far
+	 * as we can.
+	 */
 	if (node->rb_right) {
 		node = node->rb_right;
 		while (node->rb_left)
@@ -467,12 +466,13 @@ struct rb_node *rb_next(const struct rb_node *node)
 		return (struct rb_node *)node;
 	}
 
-	/* No right-hand children.  Everything down and left is
-	   smaller than us, so any 'next' node must be in the general
-	   direction of our parent. Go up the tree; any time the
-	   ancestor is a right-hand child of its parent, keep going
-	   up. First time it's a left-hand child of its parent, said
-	   parent is our 'next' node. */
+	/*
+	 * No right-hand children. Everything down and left is smaller than us,
+	 * so any 'next' node must be in the general direction of our parent.
+	 * Go up the tree; any time the ancestor is a right-hand child of its
+	 * parent, keep going up. First time it's a left-hand child of its
+	 * parent, said parent is our 'next' node.
+	 */
 	while ((parent = rb_parent(node)) && node == parent->rb_right)
 		node = parent;
 
@@ -487,8 +487,10 @@ struct rb_node *rb_prev(const struct rb_node *node)
 	if (RB_EMPTY_NODE(node))
 		return NULL;
 
-	/* If we have a left-hand child, go down and then right as far
-	   as we can. */
+	/*
+	 * If we have a left-hand child, go down and then right as far
+	 * as we can.
+	 */
 	if (node->rb_left) {
 		node = node->rb_left;
 		while (node->rb_right)
@@ -496,8 +498,10 @@ struct rb_node *rb_prev(const struct rb_node *node)
 		return (struct rb_node *)node;
 	}
 
-	/* No left-hand children. Go up till we find an ancestor which
-	   is a right-hand child of its parent */
+	/*
+	 * No left-hand children. Go up till we find an ancestor which
+	 * is a right-hand child of its parent
+	 */
 	while ((parent = rb_parent(node)) && node == parent->rb_left)
 		node = parent;
 
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 11/16 RESEND] rbtree: optimize fetching of sibling node
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (9 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 10/16 RESEND] rbtree: coding style adjustments Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2018-01-03 11:29   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 12/16 RESEND] rbtree: add __rb_change_child() helper function Praveen Kumar
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

When looking to fetch a node's sibling, we went through a sequence of:
- check if node is the parent's left child
- if it is, then fetch the parent's right child

This can be replaced with:
- fetch the parent's right child as an assumed sibling
- check that node is NOT the fetched child

This avoids fetching the parent's left child when node is actually
that child. Saves a bit on code size, though it doesn't seem to make
a large difference in speed.

Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 59633abf34e2f44b8e772a2c12a92132aa7c2220]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index b964171bee..07b0875227 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -107,8 +107,8 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 
 		gparent = rb_red_parent(parent);
 
-		if (parent == gparent->rb_left) {
-			tmp = gparent->rb_right;
+		tmp = gparent->rb_right;
+		if (parent != tmp) {    /* parent == gparent->rb_left */
 			if (tmp && rb_is_red(tmp)) {
 				/*
 				 * Case 1 - color flips
@@ -131,7 +131,8 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 				continue;
 			}
 
-			if (parent->rb_right == node) {
+			tmp = parent->rb_right;
+			if (node == tmp) {
 				/*
 				 * Case 2 - left rotate at parent
 				 *
@@ -151,6 +152,7 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 							    RB_BLACK);
 				rb_set_parent_color(parent, node, RB_RED);
 				parent = node;
+				tmp = node->rb_right;
 			}
 
 			/*
@@ -162,7 +164,7 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 			 *     /                 \
 			 *    n                   U
 			 */
-			gparent->rb_left = tmp = parent->rb_right;
+			gparent->rb_left = tmp;  /* == parent->rb_right */
 			parent->rb_right = gparent;
 			if (tmp)
 				rb_set_parent_color(tmp, gparent, RB_BLACK);
@@ -180,7 +182,8 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 				continue;
 			}
 
-			if (parent->rb_left == node) {
+			tmp = parent->rb_left;
+			if (node == tmp) {
 				/* Case 2 - right rotate at parent */
 				parent->rb_left = tmp = node->rb_right;
 				node->rb_right = parent;
@@ -189,10 +192,11 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 							    RB_BLACK);
 				rb_set_parent_color(parent, node, RB_RED);
 				parent = node;
+				tmp = node->rb_left;
 			}
 
 			/* Case 3 - left rotate at gparent */
-			gparent->rb_right = tmp = parent->rb_left;
+			gparent->rb_right = tmp;  /* == parent->rb_left */
 			parent->rb_left = gparent;
 			if (tmp)
 				rb_set_parent_color(tmp, gparent, RB_BLACK);
@@ -223,8 +227,9 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 			break;
 		} else if (!parent) {
 			break;
-		} else if (parent->rb_left == node) {
-			sibling = parent->rb_right;
+		}
+		sibling = parent->rb_right;
+		if (node != sibling) {  /* node == parent->rb_left */
 			if (rb_is_red(sibling)) {
 				/*
 				 * Case 1 - left rotate at parent
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 12/16 RESEND] rbtree: add __rb_change_child() helper function
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (10 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 11/16 RESEND] rbtree: optimize fetching of sibling node Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2018-01-03 11:30   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 13/16 RESEND] rbtree: place easiest case first in rb_erase() Praveen Kumar
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

Add __rb_change_child() as an inline helper function to replace code that
would otherwise be duplicated 4 times in the source.

No changes to binary size or speed.

Signed-off-by: Michel Lespinasse <walken@google.com>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 7abc704ae399fcb9c51ca200b0456f8a975a8011]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 46 +++++++++++++++++-----------------------------
 1 file changed, 17 insertions(+), 29 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 07b0875227..8d836cef81 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -66,6 +66,19 @@ static inline struct rb_node *rb_red_parent(struct rb_node *red)
 	return (struct rb_node *)red->__rb_parent_color;
 }
 
+static inline void
+__rb_change_child(struct rb_node *old, struct rb_node *new,
+		  struct rb_node *parent, struct rb_root *root)
+{
+	if (parent) {
+		if (parent->rb_left == old)
+			parent->rb_left = new;
+		else
+			parent->rb_right = new;
+	} else
+		root->rb_node = new;
+}
+
 /*
  * Helper function for rotations:
  * - old's parent and color get assigned to new
@@ -78,13 +91,7 @@ __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
 	struct rb_node *parent = rb_parent(old);
 	new->__rb_parent_color = old->__rb_parent_color;
 	rb_set_parent_color(old, new, color);
-	if (parent) {
-		if (parent->rb_left == old)
-			parent->rb_left = new;
-		else
-			parent->rb_right = new;
-	} else
-		root->rb_node = new;
+	__rb_change_child(old, new, parent, root);
 }
 
 void rb_insert_color(struct rb_node *node, struct rb_root *root)
@@ -375,13 +382,7 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 		while ((left = node->rb_left) != NULL)
 			node = left;
 
-		if (rb_parent(old)) {
-			if (rb_parent(old)->rb_left == old)
-				rb_parent(old)->rb_left = node;
-			else
-				rb_parent(old)->rb_right = node;
-		} else
-			root->rb_node = node;
+		__rb_change_child(old, node, rb_parent(old), root);
 
 		child = node->rb_right;
 		parent = rb_parent(node);
@@ -410,13 +411,7 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 
 	if (child)
 		rb_set_parent(child, parent);
-	if (parent) {
-		if (parent->rb_left == node)
-			parent->rb_left = child;
-		else
-			parent->rb_right = child;
-	} else
-		root->rb_node = child;
+	__rb_change_child(node, child, parent, root);
 
 color:
 	if (color == RB_BLACK)
@@ -520,14 +515,7 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new,
 	struct rb_node *parent = rb_parent(victim);
 
 	/* Set the surrounding nodes to point to the replacement */
-	if (parent) {
-		if (victim == parent->rb_left)
-			parent->rb_left = new;
-		else
-			parent->rb_right = new;
-	} else {
-		root->rb_node = new;
-	}
+	__rb_change_child(victim, new, parent, root);
 	if (victim->rb_left)
 		rb_set_parent(victim->rb_left, new);
 	if (victim->rb_right)
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 13/16 RESEND] rbtree: place easiest case first in rb_erase()
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (11 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 12/16 RESEND] rbtree: add __rb_change_child() helper function Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2018-01-03 11:32   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 14/16] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color() Praveen Kumar
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

In rb_erase, move the easy case (node to erase has no more than
1 child) first. I feel the code reads easier that way.

Signed-off-by: Michel Lespinasse <walken@google.com>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 60670b8034d6e2ba860af79c9379b7788d09db73]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 35 ++++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 8d836cef81..13a622326d 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -368,17 +368,28 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 
 void rb_erase(struct rb_node *node, struct rb_root *root)
 {
-	struct rb_node *child, *parent;
+	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
+	struct rb_node *parent;
 	int color;
 
-	if (!node->rb_left)
-		child = node->rb_right;
-	else if (!node->rb_right)
-		child = node->rb_left;
-	else {
+	if (!tmp) {
+	case1:
+		/* Case 1: node to erase has no more than 1 child (easy!) */
+
+		parent = rb_parent(node);
+		color = rb_color(node);
+
+		if (child)
+			rb_set_parent(child, parent);
+		__rb_change_child(node, child, parent, root);
+	} else if (!child) {
+		/* Still case 1, but this time the child is node->rb_left */
+		child = tmp;
+		goto case1;
+	} else {
 		struct rb_node *old = node, *left;
 
-		node = node->rb_right;
+		node = child;
 		while ((left = node->rb_left) != NULL)
 			node = left;
 
@@ -402,18 +413,8 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 		node->__rb_parent_color = old->__rb_parent_color;
 		node->rb_left = old->rb_left;
 		rb_set_parent(old->rb_left, node);
-
-		goto color;
 	}
 
-	parent = rb_parent(node);
-	color = rb_color(node);
-
-	if (child)
-		rb_set_parent(child, parent);
-	__rb_change_child(node, child, parent, root);
-
-color:
 	if (color == RB_BLACK)
 		__rb_erase_color(child, parent, root);
 }
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 14/16] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color()
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (12 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 13/16 RESEND] rbtree: place easiest case first in rb_erase() Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2018-01-03 11:35   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 15/16 RESEND] rbtree: low level optimizations in rb_erase() Praveen Kumar
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

An interesting observation for rb_erase() is that when a node has
exactly one child, the node must be black and the child must be red.
An interesting consequence is that removing such a node can be done by
simply replacing it with its child and making the child black,
which we can do efficiently in rb_erase(). __rb_erase_color() then
only needs to handle the no-childs case and can be modified accordingly.

Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 46b6135a7402ac23c5b25f2bd79b03bab8f98278]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
Removed new line from previous patch to make inline with Linux code base
---
 xen/common/rbtree.c | 105 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 62 insertions(+), 43 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 13a622326d..e7df273800 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -2,7 +2,8 @@
   Red Black Trees
   (C) 1999  Andrea Arcangeli <andrea@suse.de>
   (C) 2002  David Woodhouse <dwmw2@infradead.org>
-  
+  (C) 2012  Michel Lespinasse <walken@google.com>
+
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
@@ -50,6 +51,11 @@
 #define rb_is_red(r)   (!rb_color(r))
 #define rb_is_black(r) rb_color(r)
 
+static inline void rb_set_black(struct rb_node *rb)
+{
+	rb->__rb_parent_color |= RB_BLACK;
+}
+
 static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
 {
 	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
@@ -214,27 +220,18 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 }
 EXPORT_SYMBOL(rb_insert_color);
 
-static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
-			     struct rb_root *root)
+static void __rb_erase_color(struct rb_node *parent, struct rb_root *root)
 {
-	struct rb_node *sibling, *tmp1, *tmp2;
+	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
 
 	while (true) {
 		/*
-		 * Loop invariant: all leaf paths going through node have a
-		 * black node count that is 1 lower than other leaf paths.
-		 *
-		 * If node is red, we can flip it to black to adjust.
-		 * If node is the root, all leaf paths go through it.
-		 * Otherwise, we need to adjust the tree through color flips
-		 * and tree rotations as per one of the 4 cases below.
+		 * Loop invariants:
+		 * - node is black (or NULL on first iteration)
+		 * - node is not the root (parent is not NULL)
+		 * - All leaf paths going through parent and node have a
+		 *   black node count that is 1 lower than other leaf paths.
 		 */
-		if (node && rb_is_red(node)) {
-			rb_set_parent_color(node, parent, RB_BLACK);
-			break;
-		} else if (!parent) {
-			break;
-		}
 		sibling = parent->rb_right;
 		if (node != sibling) {  /* node == parent->rb_left */
 			if (rb_is_red(sibling)) {
@@ -268,17 +265,22 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 					*      / \           / \
 					*     Sl  Sr        Sl  Sr
 					*
-					* This leaves us violating 5), so
-					* recurse at p. If p is red, the
-					* recursion will just flip it to black
-					* and exit. If coming from Case 1,
-					* p is known to be red.
+					* This leaves us violating 5) which
+					* can be fixed by flipping p to black
+					* if it was red, or by recursing at p.
+					* p is red when coming from Case 1.
 					*/
 					rb_set_parent_color(sibling, parent,
 							    RB_RED);
-					node = parent;
-					parent = rb_parent(node);
-					continue;
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
 				}
 				/*
 				 * Case 3 - right rotate at sibling
@@ -339,9 +341,15 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 					/* Case 2 - sibling color flip */
 					rb_set_parent_color(sibling, parent,
 							    RB_RED);
-					node = parent;
-					parent = rb_parent(node);
-					continue;
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
 				}
 				/* Case 3 - right rotate at sibling */
 				sibling->rb_right = tmp1 = tmp2->rb_left;
@@ -369,23 +377,31 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 void rb_erase(struct rb_node *node, struct rb_root *root)
 {
 	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
-	struct rb_node *parent;
-	int color;
+	struct rb_node *parent, *rebalance;
 
 	if (!tmp) {
-	case1:
-		/* Case 1: node to erase has no more than 1 child (easy!) */
+		/*
+		 * Case 1: node to erase has no more than 1 child (easy!)
+		 *
+		 * Note that if there is one child it must be red due to 5)
+		 * and node must be black due to 4). We adjust colors locally
+		 * so as to bypass __rb_erase_color() later on.
+		 */
 
 		parent = rb_parent(node);
-		color = rb_color(node);
-
-		if (child)
-			rb_set_parent(child, parent);
 		__rb_change_child(node, child, parent, root);
+		if (child) {
+			rb_set_parent_color(child, parent, RB_BLACK);
+			rebalance = NULL;
+		} else {
+			rebalance = rb_is_black(node) ? parent : NULL;
+		}
 	} else if (!child) {
 		/* Still case 1, but this time the child is node->rb_left */
-		child = tmp;
-		goto case1;
+		parent = rb_parent(node);
+		__rb_change_child(node, tmp, parent, root);
+		rb_set_parent_color(tmp, parent, RB_BLACK);
+		rebalance = NULL;
 	} else {
 		struct rb_node *old = node, *left;
 
@@ -397,26 +413,29 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 
 		child = node->rb_right;
 		parent = rb_parent(node);
-		color = rb_color(node);
 
 		if (parent == old) {
 			parent = node;
 		} else {
-			if (child)
-				rb_set_parent(child, parent);
 			parent->rb_left = child;
 
 			node->rb_right = old->rb_right;
 			rb_set_parent(old->rb_right, node);
 		}
 
+		if (child) {
+			rb_set_parent_color(child, parent, RB_BLACK);
+			rebalance = NULL;
+		} else {
+			rebalance = rb_is_black(node) ? parent : NULL;
+		}
 		node->__rb_parent_color = old->__rb_parent_color;
 		node->rb_left = old->rb_left;
 		rb_set_parent(old->rb_left, node);
 	}
 
-	if (color == RB_BLACK)
-		__rb_erase_color(child, parent, root);
+	if (rebalance)
+		__rb_erase_color(rebalance, root);
 }
 EXPORT_SYMBOL(rb_erase);
 
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 15/16 RESEND] rbtree: low level optimizations in rb_erase()
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (13 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 14/16] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color() Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2018-01-03 11:37   ` Jan Beulich
  2017-11-21 15:20 ` [PATCH v6 16/16 RESEND] rbtree: fix typo in comment of rb_insert_color Praveen Kumar
  2017-12-05 16:19 ` [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Michel Lespinasse <walken@google.com>

Various minor optimizations in rb_erase():
- Avoid multiple loading of node->__rb_parent_color when computing parent
  and color information (possibly not in close sequence, as there might
  be further branches in the algorithm)
- In the 1-child subcase of case 1, copy the __rb_parent_color field from
  the erased node to the child instead of recomputing it from the desired
  parent and color
- When searching for the erased node's successor, differentiate between
  cases 2 and 3 based on whether any left links were followed. This avoids
  a condition later down.
- In case 3, keep a pointer to the erased node's right child so we don't
  have to refetch it later to adjust its parent.
- In the no-childs subcase of cases 2 and 3, place the rebalance assigment
  last so that the compiler can remove the following if(rebalance) test.

Also, added some comments to illustrate cases 2 and 3.

Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 4f035ad67f4633c233cb3642711d49b4efc9c82d]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 98 ++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 64 insertions(+), 34 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index e7df273800..5c4e239c24 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -47,9 +47,14 @@
 #define		RB_RED		0
 #define		RB_BLACK	1
 
-#define rb_color(r)   ((r)->__rb_parent_color & 1)
-#define rb_is_red(r)   (!rb_color(r))
-#define rb_is_black(r) rb_color(r)
+#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
+
+#define __rb_color(pc)     ((pc) & 1)
+#define __rb_is_black(pc)  __rb_color(pc)
+#define __rb_is_red(pc)    (!__rb_color(pc))
+#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
+#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
+#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
 
 static inline void rb_set_black(struct rb_node *rb)
 {
@@ -378,6 +383,7 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 {
 	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
 	struct rb_node *parent, *rebalance;
+	unsigned long pc;
 
 	if (!tmp) {
 		/*
@@ -387,51 +393,75 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 		 * and node must be black due to 4). We adjust colors locally
 		 * so as to bypass __rb_erase_color() later on.
 		 */
-
-		parent = rb_parent(node);
+		pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
 		__rb_change_child(node, child, parent, root);
 		if (child) {
-			rb_set_parent_color(child, parent, RB_BLACK);
+			child->__rb_parent_color = pc;
 			rebalance = NULL;
-		} else {
-			rebalance = rb_is_black(node) ? parent : NULL;
-		}
+		} else
+			rebalance = __rb_is_black(pc) ? parent : NULL;
 	} else if (!child) {
 		/* Still case 1, but this time the child is node->rb_left */
-		parent = rb_parent(node);
+		tmp->__rb_parent_color = pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
 		__rb_change_child(node, tmp, parent, root);
-		rb_set_parent_color(tmp, parent, RB_BLACK);
 		rebalance = NULL;
 	} else {
-		struct rb_node *old = node, *left;
-
-		node = child;
-		while ((left = node->rb_left) != NULL)
-			node = left;
-
-		__rb_change_child(old, node, rb_parent(old), root);
-
-		child = node->rb_right;
-		parent = rb_parent(node);
-
-		if (parent == old) {
-			parent = node;
+		struct rb_node *successor = child, *child2;
+		tmp = child->rb_left;
+		if (!tmp) {
+			/*
+			 * Case 2: node's successor is its right child
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (s)  ->  (x) (c)
+			 *        \
+			 *        (c)
+			 */
+			parent = child;
+			child2 = child->rb_right;
 		} else {
-			parent->rb_left = child;
-
-			node->rb_right = old->rb_right;
-			rb_set_parent(old->rb_right, node);
+			/*
+			 * Case 3: node's successor is leftmost under
+			 * node's right child subtree
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (y)  ->  (x) (y)
+			 *      /            /
+			 *    (p)          (p)
+			 *    /            /
+			 *  (s)          (c)
+			 *    \
+			 *    (c)
+			 */
+			do {
+				parent = successor;
+				successor = tmp;
+				tmp = tmp->rb_left;
+			} while (tmp);
+			parent->rb_left = child2 = successor->rb_right;
+			successor->rb_right = child;
+			rb_set_parent(child, successor);
 		}
 
-		if (child) {
-			rb_set_parent_color(child, parent, RB_BLACK);
+		successor->rb_left = tmp = node->rb_left;
+		rb_set_parent(tmp, successor);
+
+		pc = node->__rb_parent_color;
+		tmp = __rb_parent(pc);
+		__rb_change_child(node, successor, tmp, root);
+		if (child2) {
+			successor->__rb_parent_color = pc;
+			rb_set_parent_color(child2, parent, RB_BLACK);
 			rebalance = NULL;
 		} else {
-			rebalance = rb_is_black(node) ? parent : NULL;
+			unsigned long pc2 = successor->__rb_parent_color;
+			successor->__rb_parent_color = pc;
+			rebalance = __rb_is_black(pc2) ? parent : NULL;
 		}
-		node->__rb_parent_color = old->__rb_parent_color;
-		node->rb_left = old->rb_left;
-		rb_set_parent(old->rb_left, node);
 	}
 
 	if (rebalance)
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 16/16 RESEND] rbtree: fix typo in comment of rb_insert_color
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (14 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 15/16 RESEND] rbtree: low level optimizations in rb_erase() Praveen Kumar
@ 2017-11-21 15:20 ` Praveen Kumar
  2018-01-03 11:38   ` Jan Beulich
  2017-12-05 16:19 ` [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-11-21 15:20 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, konrad.wilk, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, tim, kpraveen.lkml, jbeulich

From: Wei Yang <weiyang@linux.vnet.ibm.com>

In case 1, it passes down the BLACK color from G to p and u, and maintains
the color of n.  By doing so, it maintains the black height of the sub-tree.

While in the comment, it marks the color of n to BLACK.  This is a typo
and not consistents with the code.

This patch fixs this typo in comment.

Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Acked-by: Michel Lespinasse <walken@google.com>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Linux commit 1b9c53e849aa65776d4f611d99aa09f856518dad]

Ported to Xen for rb_insert_color API.

Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>
---
 xen/common/rbtree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 5c4e239c24..8977aea487 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -135,7 +135,7 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 				 *      / \          / \
 				 *     p   u  -->   P   U
 				 *    /            /
-				 *   n            N
+				 *   n            n
 				 *
 				 * However, since g's parent might be red, and
 				 * 4) does not allow this, we need to recurse
-- 
2.13.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree
  2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
                   ` (15 preceding siblings ...)
  2017-11-21 15:20 ` [PATCH v6 16/16 RESEND] rbtree: fix typo in comment of rb_insert_color Praveen Kumar
@ 2017-12-05 16:19 ` Praveen Kumar
  2017-12-07 15:32   ` Dario Faggioli
  16 siblings, 1 reply; 35+ messages in thread
From: Praveen Kumar @ 2017-12-05 16:19 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, wei.liu2, George Dunlap, Andrew Cooper,
	Dario Faggioli, ian.jackson, tim, Praveen Kumar, Jan Beulich

Hi All,

Can you please provide your comments over the changes shared. Thanks in advance.

Regards,

~Praveen.

On Tue, Nov 21, 2017 at 8:49 PM, Praveen Kumar <kpraveen.lkml@gmail.com> wrote:
> Hi All,
>
> The patch imports the changes and updates of the rbtree implementaiton
> from Linux tree. But since, the only current implementation is with tmem.c,
> which am not much aware off much and therefore, was unable to test the changes
> thoroughly. Having said that, I do have plans of adding futher code changes
> which will be using rb-tree more in credit2 scheduler and that will help in
> further testing the same.
>
> I have not imported augmented, rcu and patches which added new rbtree
> functionality, as there was no specific requirement for current planned
> implementation.
>
> Below are the categorized Linux commit versions which are not imported :
>
> Augmented rbtree :
> 14b94af0b251a2c80885b60538166fb7d04a642e
> 9d9e6f9703bbd642f3f2f807e6aaa642a4cbcec9
> 9c079add0d0f45220f4bb37febf0621137ec2d38
> 3cb7a56344ca45ee56d71c5f8fe9f922306bff1f
> f231aebfc4cae2f6ed27a46a31e2630909513d77
>
>
> Add postorder iteration functions:
> 9dee5c51516d2c3fff22633c1272c5652e68075a
>
> RCU related implementation :
> d72da4a4d973d8a0a0d3c97e7cdebf287fbe3a99
> c1adf20052d80f776849fa2c1acb472cdeb7786c
> ce093a04543c403d52c1a5788d8cb92e47453aba
>
> Please share your inputs. Thanks in advance.
>
> Regards,
>
> ~Praveen.
>
> Praveen Kumar (16):
>   rbtree: remove redundant if()-condition in rb_erase()
>   rbtree: empty nodes have no color
>   rbtree: move some implementation details from rbtree.h to rbtree.c
>   rbtree: break out of rb_insert_color loop after tree rotation
>   rbtree: adjust root color in rb_insert_color() only when necessary
>   rbtree: low level optimizations in rb_insert_color()
>   rbtree: adjust node color in __rb_erase_color() only when necessary
>   rbtree: optimize case selection logic in __rb_erase_color()
>   rbtree: low level optimizations in __rb_erase_color()
>   rbtree: coding style adjustments
>   rbtree: optimize fetching of sibling node
>   rbtree: add __rb_change_child() helper function
>   rbtree: place easiest case first in rb_erase()
>   rbtree: handle 1-child recoloring in rb_erase() instead of
>     rb_erase_color()
>   rbtree: low level optimizations in rb_erase()
>   rbtree: fix typo in comment of rb_insert_color
>
>  xen/common/rbtree.c      | 646 ++++++++++++++++++++++++++++++-----------------
>  xen/include/xen/rbtree.h |  38 +--
>  2 files changed, 428 insertions(+), 256 deletions(-)
>
> ---
> Updated set of changes catering the comments provided.
> 2.13.1
>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree
  2017-12-05 16:19 ` [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
@ 2017-12-07 15:32   ` Dario Faggioli
  0 siblings, 0 replies; 35+ messages in thread
From: Dario Faggioli @ 2017-12-07 15:32 UTC (permalink / raw)
  To: Praveen Kumar, xen-devel
  Cc: sstabellini, wei.liu2, George Dunlap, Andrew Cooper,
	Dario Faggioli, ian.jackson, tim, Jan Beulich


[-- Attachment #1.1: Type: text/plain, Size: 565 bytes --]

On Tue, 2017-12-05 at 21:49 +0530, Praveen Kumar wrote:
> Hi All,
> 
Hi,

> Can you please provide your comments over the changes shared. Thanks
> in advance.
> 
Sorry, I noticed this series only a few days ago, and was busy. FWIW,
I'll try to have a look at the patches next week.

BTW, can you update my email address to raistlin@linux.it ?

Regards,
Dario
-- 
<<This happens because I choose it to happen!>> (Raistlin Majere)
-----------------------------------------------------------------
Dario Faggioli, Ph.D, http://about.me/dario.faggioli

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase()
  2017-11-21 15:19 ` [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase() Praveen Kumar
@ 2017-12-20 16:39   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:39 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:19, <kpraveen.lkml@gmail.com> wrote:
> From: Wolfram Strepp <wstrepp@gmx.de>
> 
> Furthermore, notice that the initial checks:
> 
>             if (!node->rb_left)
>                     child = node->rb_right;
>             else if (!node->rb_right)
>                     child = node->rb_left;
>             else
>             {
>                     ...
>             }
> guarantee that old->rb_right is set in the final else branch, therefore
> we can omit checking that again.
> 
> Signed-off-by: Wolfram Strepp <wstrepp@gmx.de>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 4b324126e0c6c3a5080ca3ec0981e8766ed6f1ee]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 02/16 RESEND] rbtree: empty nodes have no color
  2017-11-21 15:19 ` [PATCH v6 02/16 RESEND] rbtree: empty nodes have no color Praveen Kumar
@ 2017-12-20 16:43   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:43 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:19, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> Empty nodes have no color.  We can make use of this property to simplify
> the code emitted by the RB_EMPTY_NODE and RB_CLEAR_NODE macros.  Also,
> we can get rid of the rb_init_node function which had been introduced by
> commit 88d19cf37952 ("timers: Add rb_init_node() to allow for stack
> allocated rb nodes") to avoid some issue with the empty node's color not
> being initialized.
> 
> I'm not sure what the RB_EMPTY_NODE checks in rb_prev() / rb_next() are
> doing there, though.  axboe introduced them in commit 10fd48f2376d
> ("rbtree: fixed reversed RB_EMPTY_NODE and rb_next/prev").  The way I
> see it, the 'empty node' abstraction is only used by rbtree users to
> flag nodes that they haven't inserted in any rbtree, so asking the
> predecessor or successor of such nodes doesn't make any sense.
> 
> One final rb_init_node() caller was recently added in sysctl code to
> implement faster sysctl name lookups.  This code doesn't make use of
> RB_EMPTY_NODE at all, and from what I could see it only called
> rb_init_node() under the mistaken assumption that such initialization was
> required before node insertion.
> 
> [sfr@canb.auug.org.au: fix net/ceph/osd_client.c build]
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: John Stultz <john.stultz@linaro.org>
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 4c199a93a2d36b277a9fd209a0f2793f8460a215]
> 
> Ported rbtree.h and rbtree.c changes which are relevant to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 03/16 RESEND] rbtree: move some implementation details from rbtree.h to rbtree.c
  2017-11-21 15:19 ` [PATCH v6 03/16 RESEND] rbtree: move some implementation details from rbtree.h to rbtree.c Praveen Kumar
@ 2017-12-20 16:46   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:46 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:19, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> rbtree users must use the documented APIs to manipulate the tree
> structure.  Low-level helpers to manipulate node colors and parenthood are
> not part of that API, so move them to lib/rbtree.c
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit bf7ad8eeab995710c766df49c9c69a8592ca0216]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 04/16 RESEND] rbtree: break out of rb_insert_color loop after tree rotation
  2017-11-21 15:19 ` [PATCH v6 04/16 RESEND] rbtree: break out of rb_insert_color loop after tree rotation Praveen Kumar
@ 2017-12-20 16:49   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:49 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:19, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> It is a well known property of rbtrees that insertion never requires more
> than two tree rotations.  In our implementation, after one loop iteration
> identified one or two necessary tree rotations, we would iterate and look
> for more.  However at that point the node's parent would always be black,
> which would cause us to exit the loop.
> 
> We can make the code flow more obvious by just adding a break statement
> after the tree rotations, where we know we are done.  Additionally, in the
> cases where two tree rotations are necessary, we don't have to update the
> 'node' pointer as it wouldn't be used until the next loop iteration, which
> we now avoid due to this break statement.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 1f0528653e41ec230c60f5738820e8a544731399]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 05/16 RESEND] rbtree: adjust root color in rb_insert_color() only when necessary
  2017-11-21 15:19 ` [PATCH v6 05/16 RESEND] rbtree: adjust root color in rb_insert_color() only when necessary Praveen Kumar
@ 2017-12-20 16:51   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:51 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:19, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> The root node of an rbtree must always be black.  However,
> rb_insert_color() only needs to maintain this invariant when it has been
> broken - that is, when it exits the loop due to the current (red) node
> being the root.  In all other cases (exiting after tree rotations, or
> exiting due to an existing black parent) the invariant is already
> satisfied, so there is no need to adjust the root node color.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 6d58452dc066db61acdff7b84671db1b11a3de1c]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 06/16 RESEND] rbtree: low level optimizations in rb_insert_color()
  2017-11-21 15:19 ` [PATCH v6 06/16 RESEND] rbtree: low level optimizations in rb_insert_color() Praveen Kumar
@ 2017-12-20 16:52   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:52 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:19, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> - Use the newly introduced rb_set_parent_color() function to flip the color
>   of nodes whose parent is already known.
> - Optimize rb_parent() when the node is known to be red - there is no need
>   to mask out the color in that case.
> - Flipping gparent's color to red requires us to fetch its rb_parent_color
>   field, so we can reuse it as the parent value for the next loop iteration.
> - Do not use __rb_rotate_left() and __rb_rotate_right() to handle tree
>   rotations: we already have pointers to all relevant nodes, and know their
>   colors (either because we want to adjust it, or because we've tested it,
>   or we can deduce it as black due to the node proximity to a known red 
> node).
>   So we can generate more efficient code by making use of the node pointers
>   we already have, and setting both the parent and color attributes for
>   nodes all at once. Also in Case 2, some node attributes don't have to
>   be set because we know another tree rotation (Case 3) will always follow
>   and override them.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 5bc9188aa207dafd47eab57df7c4fe5b3d3f636a]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 07/16 RESEND] rbtree: adjust node color in __rb_erase_color() only when necessary
  2017-11-21 15:20 ` [PATCH v6 07/16 RESEND] rbtree: adjust node color in __rb_erase_color() only when necessary Praveen Kumar
@ 2017-12-20 16:55   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:55 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> In __rb_erase_color(), we were always setting a node to black after
> exiting the main loop.  And in one case, after fixing up the tree to
> satisfy all rbtree invariants, we were setting the current node to root
> just to guarantee a loop exit, at which point the root would be set to
> black.  However this is not necessary, as the root of an rbtree is already
> known to be black.  The only case where the color flip is required is when
> we exit the loop due to the current node being red, and it's easiest to
> just do the flip at that point instead of doing it after the loop.
> 
> [adrian.hunter@intel.com: perf tools: fix build for another rbtree.c change]
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Alexander Shishkin <alexander.shishkin@intel.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit d6ff1273928ebf15466a85b7e1810cd00e72998b]
> 
> Ported only rbtree.c to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 08/16 RESEND] rbtree: optimize case selection logic in __rb_erase_color()
  2017-11-21 15:20 ` [PATCH v6 08/16 RESEND] rbtree: optimize case selection logic in __rb_erase_color() Praveen Kumar
@ 2017-12-20 16:57   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:57 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> In __rb_erase_color(), we have to select one of 3 cases depending on the
> color on the 'other' node children.  If both children are black, we flip a
> few node colors and iterate.  Otherwise, we do either one or two tree
> rotations, depending on the color of the 'other' child opposite to 'node',
> and then we are done.
> 
> The corresponding logic had duplicate checks for the color of the 'other'
> child opposite to 'node'.  It was checking it first to determine if both
> children are black, and then to determine how many tree rotations are
> required.  Rearrange the logic to avoid that extra check.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit e125d1471a4f8f1bf7ea9a83deb8d23cb40bd712]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 09/16 RESEND] rbtree: low level optimizations in __rb_erase_color()
  2017-11-21 15:20 ` [PATCH v6 09/16 RESEND] rbtree: low level optimizations " Praveen Kumar
@ 2017-12-20 16:59   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-12-20 16:59 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> In __rb_erase_color(), we often already have pointers to the nodes being
> rotated and/or know what their colors must be, so we can generate more
> efficient code than the generic __rb_rotate_left() and __rb_rotate_right()
> functions.
> 
> Also when the current node is red or when flipping the sibling's color,
> the parent is already known so we can use the more efficient
> rb_set_parent_color() function to set the desired color.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 6280d2356fd8ad0936a63c10dc1e6accf48d0c61]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 10/16 RESEND] rbtree: coding style adjustments
  2017-11-21 15:20 ` [PATCH v6 10/16 RESEND] rbtree: coding style adjustments Praveen Kumar
@ 2018-01-03 11:26   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2018-01-03 11:26 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> Set comment and indentation style to be consistent with linux coding style
> and the rest of the file, as suggested by Peter Zijlstra
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Acked-by: David Woodhouse <David.Woodhouse@intel.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 11/16 RESEND] rbtree: optimize fetching of sibling node
  2017-11-21 15:20 ` [PATCH v6 11/16 RESEND] rbtree: optimize fetching of sibling node Praveen Kumar
@ 2018-01-03 11:29   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2018-01-03 11:29 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> When looking to fetch a node's sibling, we went through a sequence of:
> - check if node is the parent's left child
> - if it is, then fetch the parent's right child
> 
> This can be replaced with:
> - fetch the parent's right child as an assumed sibling
> - check that node is NOT the fetched child
> 
> This avoids fetching the parent's left child when node is actually
> that child. Saves a bit on code size, though it doesn't seem to make
> a large difference in speed.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: David Woodhouse <David.Woodhouse@intel.com>
> Acked-by: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Daniel Santos <daniel.santos@pobox.com>
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 59633abf34e2f44b8e772a2c12a92132aa7c2220]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 12/16 RESEND] rbtree: add __rb_change_child() helper function
  2017-11-21 15:20 ` [PATCH v6 12/16 RESEND] rbtree: add __rb_change_child() helper function Praveen Kumar
@ 2018-01-03 11:30   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2018-01-03 11:30 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> Add __rb_change_child() as an inline helper function to replace code that
> would otherwise be duplicated 4 times in the source.
> 
> No changes to binary size or speed.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Reviewed-by: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 7abc704ae399fcb9c51ca200b0456f8a975a8011]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 13/16 RESEND] rbtree: place easiest case first in rb_erase()
  2017-11-21 15:20 ` [PATCH v6 13/16 RESEND] rbtree: place easiest case first in rb_erase() Praveen Kumar
@ 2018-01-03 11:32   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2018-01-03 11:32 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> In rb_erase, move the easy case (node to erase has no more than
> 1 child) first. I feel the code reads easier that way.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Reviewed-by: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 60670b8034d6e2ba860af79c9379b7788d09db73]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 14/16] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color()
  2017-11-21 15:20 ` [PATCH v6 14/16] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color() Praveen Kumar
@ 2018-01-03 11:35   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2018-01-03 11:35 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> An interesting observation for rb_erase() is that when a node has
> exactly one child, the node must be black and the child must be red.
> An interesting consequence is that removing such a node can be done by
> simply replacing it with its child and making the child black,
> which we can do efficiently in rb_erase(). __rb_erase_color() then
> only needs to handle the no-childs case and can be modified accordingly.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Acked-by: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 46b6135a7402ac23c5b25f2bd79b03bab8f98278]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 15/16 RESEND] rbtree: low level optimizations in rb_erase()
  2017-11-21 15:20 ` [PATCH v6 15/16 RESEND] rbtree: low level optimizations in rb_erase() Praveen Kumar
@ 2018-01-03 11:37   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2018-01-03 11:37 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Michel Lespinasse <walken@google.com>
> 
> Various minor optimizations in rb_erase():
> - Avoid multiple loading of node->__rb_parent_color when computing parent
>   and color information (possibly not in close sequence, as there might
>   be further branches in the algorithm)
> - In the 1-child subcase of case 1, copy the __rb_parent_color field from
>   the erased node to the child instead of recomputing it from the desired
>   parent and color
> - When searching for the erased node's successor, differentiate between
>   cases 2 and 3 based on whether any left links were followed. This avoids
>   a condition later down.
> - In case 3, keep a pointer to the erased node's right child so we don't
>   have to refetch it later to adjust its parent.
> - In the no-childs subcase of cases 2 and 3, place the rebalance assigment
>   last so that the compiler can remove the following if(rebalance) test.
> 
> Also, added some comments to illustrate cases 2 and 3.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> Acked-by: Rik van Riel <riel@redhat.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 4f035ad67f4633c233cb3642711d49b4efc9c82d]
> 
> Ported to Xen.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 16/16 RESEND] rbtree: fix typo in comment of rb_insert_color
  2017-11-21 15:20 ` [PATCH v6 16/16 RESEND] rbtree: fix typo in comment of rb_insert_color Praveen Kumar
@ 2018-01-03 11:38   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2018-01-03 11:38 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: tim, sstabellini, wei.liu2, George.Dunlap, andrew.cooper3,
	dario.faggioli, ian.jackson, xen-devel

>>> On 21.11.17 at 16:20, <kpraveen.lkml@gmail.com> wrote:
> From: Wei Yang <weiyang@linux.vnet.ibm.com>
> 
> In case 1, it passes down the BLACK color from G to p and u, and maintains
> the color of n.  By doing so, it maintains the black height of the sub-tree.
> 
> While in the comment, it marks the color of n to BLACK.  This is a typo
> and not consistents with the code.
> 
> This patch fixs this typo in comment.
> 
> Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
> Acked-by: Michel Lespinasse <walken@google.com>
> Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> [Linux commit 1b9c53e849aa65776d4f611d99aa09f856518dad]
> 
> Ported to Xen for rb_insert_color API.
> 
> Signed-off-by: Praveen Kumar <kpraveen.lkml@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2018-01-03 11:38 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-21 15:19 [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
2017-11-21 15:19 ` [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase() Praveen Kumar
2017-12-20 16:39   ` Jan Beulich
2017-11-21 15:19 ` [PATCH v6 02/16 RESEND] rbtree: empty nodes have no color Praveen Kumar
2017-12-20 16:43   ` Jan Beulich
2017-11-21 15:19 ` [PATCH v6 03/16 RESEND] rbtree: move some implementation details from rbtree.h to rbtree.c Praveen Kumar
2017-12-20 16:46   ` Jan Beulich
2017-11-21 15:19 ` [PATCH v6 04/16 RESEND] rbtree: break out of rb_insert_color loop after tree rotation Praveen Kumar
2017-12-20 16:49   ` Jan Beulich
2017-11-21 15:19 ` [PATCH v6 05/16 RESEND] rbtree: adjust root color in rb_insert_color() only when necessary Praveen Kumar
2017-12-20 16:51   ` Jan Beulich
2017-11-21 15:19 ` [PATCH v6 06/16 RESEND] rbtree: low level optimizations in rb_insert_color() Praveen Kumar
2017-12-20 16:52   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 07/16 RESEND] rbtree: adjust node color in __rb_erase_color() only when necessary Praveen Kumar
2017-12-20 16:55   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 08/16 RESEND] rbtree: optimize case selection logic in __rb_erase_color() Praveen Kumar
2017-12-20 16:57   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 09/16 RESEND] rbtree: low level optimizations " Praveen Kumar
2017-12-20 16:59   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 10/16 RESEND] rbtree: coding style adjustments Praveen Kumar
2018-01-03 11:26   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 11/16 RESEND] rbtree: optimize fetching of sibling node Praveen Kumar
2018-01-03 11:29   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 12/16 RESEND] rbtree: add __rb_change_child() helper function Praveen Kumar
2018-01-03 11:30   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 13/16 RESEND] rbtree: place easiest case first in rb_erase() Praveen Kumar
2018-01-03 11:32   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 14/16] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color() Praveen Kumar
2018-01-03 11:35   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 15/16 RESEND] rbtree: low level optimizations in rb_erase() Praveen Kumar
2018-01-03 11:37   ` Jan Beulich
2017-11-21 15:20 ` [PATCH v6 16/16 RESEND] rbtree: fix typo in comment of rb_insert_color Praveen Kumar
2018-01-03 11:38   ` Jan Beulich
2017-12-05 16:19 ` [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree Praveen Kumar
2017-12-07 15:32   ` Dario Faggioli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).