[Xen-devel] [PATCH v6 13/16 RESEND] rbtree: place easiest case first in rb_erase()

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 60670b8034d6e2ba860af79c9379b7788d09db73]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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


[Xen-devel] [PATCH v6 16/16 RESEND] rbtree: fix typo in comment of rb_insert_color

2017-11-21 Thread Praveen Kumar
From: Wei Yang <weiy...@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 <weiy...@linux.vnet.ibm.com>
Acked-by: Michel Lespinasse <wal...@google.com>
Cc: Xiao Guangrong <xiaoguangr...@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1b9c53e849aa65776d4f611d99aa09f856518dad]

Ported to Xen for rb_insert_color API.

Signed-off-by: Praveen Kumar <kpraveen.l...@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
 *//
-*   nN
+*   nn
 *
 * 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


[Xen-devel] [PATCH v6 12/16 RESEND] rbtree: add __rb_change_child() helper function

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7abc704ae399fcb9c51ca200b0456f8a975a8011]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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


[Xen-devel] [PATCH v6 06/16 RESEND] rbtree: low level optimizations in rb_insert_color()

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 5bc9188aa207dafd47eab57df7c4fe5b3d3f636a]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 
 #include 
 
+/*
+ * 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.
+ */
+
 #defineRB_RED  0
 #defineRB_BLACK1
 
@@ -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, 

[Xen-devel] [PATCH v6 14/16] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color()

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 46b6135a7402ac23c5b25f2bd79b03bab8f98278]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 <and...@suse.de>
   (C) 2002  David Woodhouse <dw...@infradead.org>
-  
+  (C) 2012  Michel Lespinasse <wal...@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  SrSl  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);
- 

[Xen-devel] [PATCH v6 15/16 RESEND] rbtree: low level optimizations in rb_erase()

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4f035ad67f4633c233cb3642711d49b4efc9c82d]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 @@
 #defineRB_RED  0
 #defineRB_BLACK1
 
-#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-&

[Xen-devel] [PATCH v6 08/16 RESEND] rbtree: optimize case selection logic in __rb_erase_color()

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit e125d1471a4f8f1bf7ea9a83deb8d23cb40bd712]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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);
+

[Xen-devel] [PATCH v6 10/16 RESEND] rbtree: coding style adjustments

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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


[Xen-devel] [PATCH v6 11/16 RESEND] rbtree: optimize fetching of sibling node

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <david.woodho...@intel.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 59633abf34e2f44b8e772a2c12a92132aa7c2220]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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) {  /*

[Xen-devel] [PATCH v6 05/16 RESEND] rbtree: adjust root color in rb_insert_color() only when necessary

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6d58452dc066db61acdff7b84671db1b11a3de1c]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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


[Xen-devel] [PATCH v6 09/16 RESEND] rbtree: low level optimizations in __rb_erase_color()

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6280d2356fd8ad0936a63c10dc1e6accf48d0c61]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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.
  */
 
 #defineRB_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->r

[Xen-devel] [PATCH v6 07/16 RESEND] rbtree: adjust node color in __rb_erase_color() only when necessary

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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.hun...@intel.com: perf tools: fix build for another rbtree.c change]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
Cc: Alexander Shishkin <alexander.shish...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit d6ff1273928ebf15466a85b7e1810cd00e72998b]

Ported only rbtree.c to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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


[Xen-devel] [PATCH v6 04/16 RESEND] rbtree: break out of rb_insert_color loop after tree rotation

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1f0528653e41ec230c60f5738820e8a544731399]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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


[Xen-devel] [PATCH v6 03/16 RESEND] rbtree: move some implementation details from rbtree.h to rbtree.c

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: David Woodhouse <david.woodho...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit bf7ad8eeab995710c766df49c9c69a8592ca0216]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 
 #include 
 
+#defineRB_RED  0
+#defineRB_BLACK1
+
+#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;
-#defineRB_RED  0
-#defineRB_BLACK1
+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, }
 #definerb_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,

[Xen-devel] [PATCH v6 02/16 RESEND] rbtree: empty nodes have no color

2017-11-21 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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.

[s...@canb.auug.org.au: fix net/ceph/osd_client.c build]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Cc: John Stultz <john.stu...@linaro.org>
Signed-off-by: Stephen Rothwell <s...@canb.auug.org.au>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4c199a93a2d36b277a9fd209a0f2793f8460a215]

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

Signed-off-by: Praveen Kumar <kpraveen.l...@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, }
 #definerb_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


[Xen-devel] [PATCH v6 00/16] xen: common: rbtree: ported updates from Linux tree

2017-11-21 Thread Praveen Kumar
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


[Xen-devel] [PATCH v6 01/16] rbtree: remove redundant if()-condition in rb_erase()

2017-11-21 Thread Praveen Kumar
From: Wolfram Strepp <wstr...@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 <wstr...@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4b324126e0c6c3a5080ca3ec0981e8766ed6f1ee]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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


Re: [Xen-devel] [PATCH v5 01/17] rbtree: changes to align the coding conventions with Linux tree

2017-08-04 Thread Praveen Kumar
I tried applying the patches generated from Linux tree and updating
the file location ( as per the Xen tree location ); some of the
places, I was facing issues.
Adding comment to the file, resolved some of the patching issues. So,
this is my understanding ( could be completely wrong ) that, with the
change in location and difference in code statements, the patch
application have failed. Please suggest if I can perform this is a
better way. Thanks in advance.

On Fri, Aug 4, 2017 at 10:34 PM, Jan Beulich <jbeul...@suse.com> wrote:
>>>> Praveen Kumar <kpraveen.l...@gmail.com> 08/04/17 7:00 PM >>>
>>There will be issue while directly applying the patch from Linux tree
>>( having changed the file name ) as the line number changes.
>
> How do line numbers matter?
>
> Jan
>

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


Re: [Xen-devel] [PATCH v5 01/17] rbtree: changes to align the coding conventions with Linux tree

2017-08-04 Thread Praveen Kumar
Hi Dario,

On Thu, Aug 3, 2017 at 4:07 PM, Dario Faggioli
 wrote:
> On Fri, 2017-07-14 at 07:05 -0600, Jan Beulich wrote:
>> > > > On 14.07.17 at 14:51,  wrote:
>> >
>> > Agreed, I shouldn't have added.
>> > rbtree.h file does include incline functions which are actually
>> > commented, and in order to have complete similarity I did include
>> > the
>> > same here.
>> >
>> > Also, rbtree.c does have comment in header note being modified, for
>> > the
>> > same reason.
>> >
>> > Further, do you suggest to keep the old ones, but that may cause
>> > porting issue and it won't be exact replica from Linux base. Please
>> > suggest.
>>
>> I'm fine with comment updates, _as long as you say so_ in the
>> commit message. If you say "only style changes", then there
>> ought to be no additions whatsoever.
>>
> I fully agree with Jan.
>
> And, as him, I also think you can update the header comments at the
> beginning of both rbtree.c and rbtree.h files, as soon as you mention
> that in the changelog.
>

Sure, will try to update with each patch individually in the header
comments ( if there are any version change ).

> *HOWEVER*, about this change, in both .c and .h:
>
> @@ -14,7 +14,8 @@
>GNU General Public License for more details.
>
>You should have received a copy of the GNU General Public License
> -  along with this program; If not, see .
> +  along with this program; if not, write to the Free Software
> +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>
>linux/lib/rbtree.c
>  */
>
> This comes from 443701ef "Replace FSF street address with canonical
> URL" (check with `git blame xen/common/rbtree.c'), and I think we
> should leave this alone (i.e., keep the url, and not change back to the
> physical address).
>
> I understand it then will be a difference between our rbtree.{c,h} and
> Linux's ones, but I think it's one difference it's worth living with
> (and, honestly, I really don't expect this specific thing to cause much
> issues in future 'backports' from Linux).
>
> If others agree on this too, that would mean you basically would let
> the header comment of rbtree.c alone, while in rbtree.h, you "just" add
> the commented API usage example functions.
>

There will be issue while directly applying the patch from Linux tree
( having changed the file name ) as the line number changes. Because
of which I included the commented code. Further to this, for some of
the patches shared, I was also facing porting issue with and has been
manually ported. So, I am thinking if maintaining complete accuracy /
replica with Linux tree will give any benefit ?

> Regards,
> Dario
> --
> <> (Raistlin Majere)
> -
> Dario Faggioli, Ph.D, http://about.me/dario.faggioli
> Senior Software Engineer, Citrix Systems R Ltd., Cambridge (UK)

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


[Xen-devel] [PATCH v7 01/17] rbtree: changes to align the code with Linux tree

2017-07-14 Thread Praveen Kumar
The patch aligns the code of rbtree related files with Linux tree.
This will minimize the conflicts during any future porting from Linux tree.

Linux commit till f4b477c47332367d35686bd2b808c2156b96d7c7 for rbtree.h
This includes addition of commented inline functions in rbtree.h, to have
complete replica from Linux tree.

Linux commit till 4c60117811171d867d4f27f17ea07d7419d45dae for rbtree.c
This includes updates in comments in header note in rbtree.c.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c  | 633 ---
 xen/include/xen/rbtree.h | 116 +++--
 2 files changed, 413 insertions(+), 336 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index d91d651d77..167ebfdc4d 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -14,7 +14,8 @@
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
-  along with this program; If not, see <http://www.gnu.org/licenses/>.
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
   linux/lib/rbtree.c
 */
@@ -24,261 +25,261 @@
 
 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);
+   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);
+   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);
 }
 
 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))
-{
-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;
-}
-}
-
-if (parent->rb_right == node)
-{
-register struct rb_node *tmp;
-__rb_rotate_left(parent, root);
-tmp = parent;
-parent = node;
-node = tmp;
-}
-
-rb_set_black(parent);
-rb_set_red(gparent);
-__rb_rotate_right(gparent, root);
-} 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_re

[Xen-devel] [PATCH v6 01/17] rbtree: changes to align the coding conventions with Linux tree

2017-07-14 Thread Praveen Kumar
The patch aligns the coding style of rbtree related files to Linux coding
conventions to have limited conflicts in future while porting from Linux tree.

Linux commit till f4b477c47332367d35686bd2b808c2156b96d7c7 for rbtree.h
rbtree.h file includes commented inline functions in order to have complete
replica from Linux tree.

Linux commit till 4c60117811171d867d4f27f17ea07d7419d45dae for rbtree.c
rbtree.c has comment changes in header note for the same reason.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c  | 633 ---
 xen/include/xen/rbtree.h | 116 +++--
 2 files changed, 413 insertions(+), 336 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index d91d651d77..167ebfdc4d 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -14,7 +14,8 @@
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
-  along with this program; If not, see <http://www.gnu.org/licenses/>.
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
   linux/lib/rbtree.c
 */
@@ -24,261 +25,261 @@
 
 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);
+   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);
+   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);
 }
 
 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))
-{
-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;
-}
-}
-
-if (parent->rb_right == node)
-{
-register struct rb_node *tmp;
-__rb_rotate_left(parent, root);
-tmp = parent;
-parent = node;
-node = tmp;
-}
-
-rb_set_black(parent);
-rb_set_red(gparent);
-__rb_rotate_right(gparent, root);
-} 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_re

Re: [Xen-devel] [PATCH v5 01/17] rbtree: changes to align the coding conventions with Linux tree

2017-07-14 Thread Praveen Kumar
On Fri, 2017-07-14 at 06:28 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > On 14.07.17 at 10:26,  wrote:
> > The patch aligns the coding style of rbtree related files to Linux
> > coding
> > conventions to have limited conflicts in future while porting from
> > Linux 
> > tree.
> > 
> > This patch includes only the style changes.
> 
> Certainly not: In the header you introduce at least 3 new inline
> functions. Please be _really_ careful with such statements.
> 
> Jan
> 
Agreed, I shouldn't have added.
rbtree.h file does include incline functions which are actually
commented, and in order to have complete similarity I did include the
same here.

Also, rbtree.c does have comment in header note being modified, for the
same reason.

Further, do you suggest to keep the old ones, but that may cause
porting issue and it won't be exact replica from Linux base. Please
suggest.

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


[Xen-devel] [PATCH v5 11/17] rbtree: coding style adjustments

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 e58336bd26..215d4f3613 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;
@@ -407,17 +406,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);
 }
@@ -459,8 +456,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)
@@ -468,12 +467,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;
 
@@ -488,8 +488,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)
@@ -497,8 +499,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.12.0


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


[Xen-devel] [PATCH v5 15/17] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color()

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 46b6135a7402ac23c5b25f2bd79b03bab8f98278]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 102 +++-
 1 file changed, 61 insertions(+), 41 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 9aead2f892..43319b8f3b 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -2,6 +2,7 @@
   Red Black Trees
   (C) 1999  Andrea Arcangeli <and...@suse.de>
   (C) 2002  David Woodhouse <dw...@infradead.org>
+  (C) 2012  Michel Lespinasse <wal...@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
@@ -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  SrSl  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;
+ 

[Xen-devel] [PATCH v5 17/17] rbtree: fix typo in comment of rb_insert_color

2017-07-14 Thread Praveen Kumar
From: Wei Yang <weiy...@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 <weiy...@linux.vnet.ibm.com>
Acked-by: Michel Lespinasse <wal...@google.com>
Cc: Xiao Guangrong <xiaoguangr...@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1b9c53e849aa65776d4f611d99aa09f856518dad]

Ported to Xen for rb_insert_color API.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 8e1dd2c56e..7147481480 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
 *//
-*   nN
+*   nn
 *
 * However, since g's parent might be red, and
 * 4) does not allow this, we need to recurse
-- 
2.12.0


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


[Xen-devel] [PATCH v5 14/17] rbtree: place easiest case first in rb_erase()

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 60670b8034d6e2ba860af79c9379b7788d09db73]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 9182544417..9aead2f892 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;
 
@@ -403,18 +414,8 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
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.12.0


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


[Xen-devel] [PATCH v5 13/17] rbtree: add __rb_change_child() helper function

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7abc704ae399fcb9c51ca200b0456f8a975a8011]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 d8f1194e20..9182544417 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);
@@ -411,13 +412,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)
@@ -521,14 +516,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.12.0


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


[Xen-devel] [PATCH v5 08/17] rbtree: adjust node color in __rb_erase_color() only when necessary

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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.hun...@intel.com: perf tools: fix build for another rbtree.c change]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
Cc: Alexander Shishkin <alexander.shish...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit d6ff1273928ebf15466a85b7e1810cd00e72998b]

Ported only rbtree.c to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 c3a8575ec0..249035c923 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.12.0


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


[Xen-devel] [PATCH v5 05/17] rbtree: break out of rb_insert_color loop after tree rotation

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1f0528653e41ec230c60f5738820e8a544731399]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 ecebd2746c..1e74ec0f65 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.12.0


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


[Xen-devel] [PATCH v5 16/17] rbtree: low level optimizations in rb_erase()

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4f035ad67f4633c233cb3642711d49b4efc9c82d]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 43319b8f3b..8e1dd2c56e 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -47,9 +47,14 @@
 #defineRB_RED  0
 #defineRB_BLACK1
 
-#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,53 +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-&

[Xen-devel] [PATCH v5 02/17] rbtree: remove redundant if()-condition in rb_erase()

2017-07-14 Thread Praveen Kumar
From: Wolfram Strepp <wstr...@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 <wstr...@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4b324126e0c6c3a5080ca3ec0981e8766ed6f1ee]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 167ebfdc4d..acfd34a62d 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -250,15 +250,16 @@ 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.12.0


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


[Xen-devel] [PATCH v5 07/17] rbtree: low level optimizations in rb_insert_color()

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 5bc9188aa207dafd47eab57df7c4fe5b3d3f636a]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 16a1a97193..c3a8575ec0 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -23,6 +23,25 @@
 #include 
 #include 
 
+/*
+ * 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.
+ */
+
 #defineRB_RED  0
 #defineRB_BLACK1
 
@@ -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, 

[Xen-devel] [PATCH v5 04/17] rbtree: move some implementation details from rbtree.h to rbtree.c

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: David Woodhouse <david.woodho...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit bf7ad8eeab995710c766df49c9c69a8592ca0216]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 ce69000879..ecebd2746c 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -23,6 +23,24 @@
 #include 
 #include 
 
+#defineRB_RED  0
+#defineRB_BLACK1
+
+#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;
-#defineRB_RED  0
-#defineRB_BLACK1
+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, }
 #definerb_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,

[Xen-devel] [PATCH v5 12/17] rbtree: optimize fetching of sibling node

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <david.woodho...@intel.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 59633abf34e2f44b8e772a2c12a92132aa7c2220]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 215d4f3613..d8f1194e20 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) {  /*

[Xen-devel] [PATCH v5 09/17] rbtree: optimize case selection logic in __rb_erase_color()

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit e125d1471a4f8f1bf7ea9a83deb8d23cb40bd712]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 249035c923..a6491e5610 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);
+

[Xen-devel] [PATCH v5 00/17] xen: common: rbtree: ported updates from Linux tree

2017-07-14 Thread Praveen Kumar
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 (17):
  rbtree: changes to align the coding conventions with Linux tree
  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  | 829 +--
 xen/include/xen/rbtree.h | 132 ++--
 2 files changed, 605 insertions(+), 356 deletions(-)

-- 
2.12.0


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


[Xen-devel] [PATCH v5 10/17] rbtree: low level optimizations in __rb_erase_color()

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6280d2356fd8ad0936a63c10dc1e6accf48d0c61]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 a6491e5610..e58336bd26 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.
  */
 
 #defineRB_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->r

[Xen-devel] [PATCH v5 03/17] rbtree: empty nodes have no color

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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.

[s...@canb.auug.org.au: fix net/ceph/osd_client.c build]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Cc: John Stultz <john.stu...@linaro.org>
Signed-off-by: Stephen Rothwell <s...@canb.auug.org.au>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4c199a93a2d36b277a9fd209a0f2793f8460a215]

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

Signed-off-by: Praveen Kumar <kpraveen.l...@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 acfd34a62d..ce69000879 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -317,7 +317,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
@@ -346,7 +346,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, }
 #definerb_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.12.0


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


[Xen-devel] [PATCH v5 01/17] rbtree: changes to align the coding conventions with Linux tree

2017-07-14 Thread Praveen Kumar
The patch aligns the coding style of rbtree related files to Linux coding
conventions to have limited conflicts in future while porting from Linux tree.

This patch includes only the style changes.

Linux commit till 4c60117811171d867d4f27f17ea07d7419d45dae for rbtree.c
Linux commit till f4b477c47332367d35686bd2b808c2156b96d7c7 for rbtree.h

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c  | 633 ---
 xen/include/xen/rbtree.h | 116 +++--
 2 files changed, 413 insertions(+), 336 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index d91d651d77..167ebfdc4d 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -14,7 +14,8 @@
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
-  along with this program; If not, see <http://www.gnu.org/licenses/>.
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
   linux/lib/rbtree.c
 */
@@ -24,261 +25,261 @@
 
 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);
+   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);
+   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);
 }
 
 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))
-{
-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;
-}
-}
-
-if (parent->rb_right == node)
-{
-register struct rb_node *tmp;
-__rb_rotate_left(parent, root);
-tmp = parent;
-parent = node;
-node = tmp;
-}
-
-rb_set_black(parent);
-rb_set_red(gparent);
-__rb_rotate_right(gparent, root);
-} 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;
-}
-}
-
-if (parent->

[Xen-devel] [PATCH v5 06/17] rbtree: adjust root color in rb_insert_color() only when necessary

2017-07-14 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6d58452dc066db61acdff7b84671db1b11a3de1c]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 1e74ec0f65..16a1a97193 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.12.0


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


Re: [Xen-devel] [PATCH v4 01/17] rbtree: changes to inline coding conventions with Linux tree

2017-07-13 Thread Praveen Kumar
On Tue, 2017-07-04 at 02:24 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > On 03.07.17 at 21:58,  wrote:
> > The patch inlines the rbtree related files to Linux coding
> > conventions to have
> > limited conflicts in future while porting from Linux tree.
> 
> "inlines" has a different meaning most of the time - how about
> "brings in line" (but I'll be happy to be corrected by a native
> speaker)? This would then also call for a change to the subject.
> 
> What I'm missing though is a reference to the Linux version to
> compare with - this is especially relevant because the format
> the patch brings the code into is not normal Linux style (but I
> do see that e.g. in 3.0 such oddities indeed existed).
> 
Jan,

Is it ok to add the last reference from Linux tree, which has already
been ported to Xen code base till date, so that we can diff from start
and verify that its only coding style changed and not anything else ?

> Also please state explicitly whether what you do are _only_
> style changes, making quite a bit of a difference to the level
> of review needed.

Sure, will update the same. Thanks.
> 
> Jan
> 

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


Re: [Xen-devel] [PATCH v4 00/17] xen: common: rbtree: ported updates from Linux tree

2017-07-13 Thread Praveen Kumar
On Tue, 2017-07-04 at 10:45 +0200, Dario Faggioli wrote:
> On Tue, 2017-07-04 at 02:27 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > > 
> > > > > On 03.07.17 at 21:58,  wrote:
> > > 
> > > Use of designated initializers :
> > > f231aebfc4cae2f6ed27a46a31e2630909513d77
> > 
> > Unless none of the changes actually apply to our code, I can't see
> > why we wouldn't want to take something like this. I do note though
> > that only augmenting callbacks are being affected, in which case
> > grouping the commit there would have been better for people to
> > understand why you exclude it.
> > 
> I agree.
> 
> It's actually ok to keep this out, but it should be listed in the
> first
>  group of excluded commits ("Augmented rbtree").
> 
> Dario

Yes, this should be part of "Augmented rbtree" list. Will send the
updated patches soon. Thanks.

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


Re: [Xen-devel] [PATCH v4 00/17] xen: common: rbtree: ported updates from Linux tree

2017-07-13 Thread Praveen Kumar
On Tue, 2017-07-04 at 14:44 +0530, Praveen Kumar wrote:
> On Tue, 2017-07-04 at 10:49 +0200, Dario Faggioli wrote:
> > 
> > On Tue, 2017-07-04 at 01:28 +0530, Praveen Kumar wrote:
> > > 
> > > 
> > > Below are the categorized Linux commit versions which are not
> > > imported :
> > > 
> > > Augmented rbtree :
> > > 14b94af0b251a2c80885b60538166fb7d04a642e
> > > 9d9e6f9703bbd642f3f2f807e6aaa642a4cbcec9
> > > 9c079add0d0f45220f4bb37febf0621137ec2d38
> > > 3cb7a56344ca45ee56d71c5f8fe9f922306bff1f
> > > 
> > > Add postorder iteration functions:
> > > 9dee5c51516d2c3fff22633c1272c5652e68075a
> > > 
> > > RCU related implementation :
> > > 
> > What about "Lockless access improvements"
> > 
Dario,

Did you mean to import Lockless improvement with the updated patch ?
Can you please provide more clarity on this. Thanks in advance.

> > > 
> > > 
> > > ce093a04543c403d52c1a5788d8cb92e47453aba
> > > 
> > Mmm... this last one is "lib/rbtree.c: fix typo in comment of
> > rb_erase_color". Did we agree together of excluding it? If yes,
> > can
> > you state here why? If not, why are we excluding it? :-)
> > 
> >  
> The respective patch has subsequent changes done on top of augmented
> and other features, which we excluded. So, I think, its not
> applicable
> for now.
> 
> Regards,
> 
> ~Praveen.

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


Re: [Xen-devel] [PATCH v4 00/17] xen: common: rbtree: ported updates from Linux tree

2017-07-04 Thread Praveen Kumar
On Tue, 2017-07-04 at 10:49 +0200, Dario Faggioli wrote:
> On Tue, 2017-07-04 at 01:28 +0530, Praveen Kumar wrote:
> > 
> > Below are the categorized Linux commit versions which are not
> > imported :
> > 
> > Augmented rbtree :
> > 14b94af0b251a2c80885b60538166fb7d04a642e
> > 9d9e6f9703bbd642f3f2f807e6aaa642a4cbcec9
> > 9c079add0d0f45220f4bb37febf0621137ec2d38
> > 3cb7a56344ca45ee56d71c5f8fe9f922306bff1f
> > 
> > Add postorder iteration functions:
> > 9dee5c51516d2c3fff22633c1272c5652e68075a
> > 
> > RCU related implementation :
> > 
> What about "Lockless access improvements"
> 
> > 
> > ce093a04543c403d52c1a5788d8cb92e47453aba
> > 
> Mmm... this last one is "lib/rbtree.c: fix typo in comment of
> rb_erase_color". Did we agree together of excluding it? If yes,
> can
> you state here why? If not, why are we excluding it? :-)
> 
> 
The respective patch has subsequent changes done on top of augmented
and other features, which we excluded. So, I think, its not applicable
for now.

Regards,

~Praveen.

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


[Xen-devel] [PATCH v4 13/17] rbtree: add __rb_change_child() helper function

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7abc704ae399fcb9c51ca200b0456f8a975a8011]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 56c815b4a5..d438d50761 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -65,6 +65,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
@@ -77,13 +90,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)
@@ -374,13 +381,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.12.0


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


[Xen-devel] [PATCH v4 14/17] rbtree: place easiest case first in rb_erase()

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 60670b8034d6e2ba860af79c9379b7788d09db73]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 d438d50761..891f04e919 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -367,17 +367,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_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.12.0


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


[Xen-devel] [PATCH v4 15/17] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color()

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 46b6135a7402ac23c5b25f2bd79b03bab8f98278]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 102 +++-
 1 file changed, 61 insertions(+), 41 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 891f04e919..e506e0451d 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -2,6 +2,7 @@
   Red Black Trees
   (C) 1999  Andrea Arcangeli <and...@suse.de>
   (C) 2002  David Woodhouse <dw...@infradead.org>
+  (C) 2012  Michel Lespinasse <wal...@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
@@ -49,6 +50,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;
@@ -213,27 +219,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)) {
@@ -267,17 +264,22 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
*  / \   / \
* Sl  SrSl  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;
+ 

[Xen-devel] [PATCH v4 17/17] rbtree: fix typo in comment of rb_insert_color

2017-07-03 Thread Praveen Kumar
From: Wei Yang <weiy...@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 <weiy...@linux.vnet.ibm.com>
Acked-by: Michel Lespinasse <wal...@google.com>
Cc: Xiao Guangrong <xiaoguangr...@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1b9c53e849aa65776d4f611d99aa09f856518dad]

Ported to Xen for rb_insert_color API.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 678adf5aa3..837fc4895f 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -134,7 +134,7 @@ void rb_insert_color(struct rb_node *node, struct rb_root 
*root)
 *  / \  / \
 * p   u  -->   P   U
 *//
-*   nN
+*   nn
 *
 * However, since g's parent might be red, and
 * 4) does not allow this, we need to recurse
-- 
2.12.0


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


[Xen-devel] [PATCH v4 16/17] rbtree: low level optimizations in rb_erase()

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4f035ad67f4633c233cb3642711d49b4efc9c82d]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index e506e0451d..678adf5aa3 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -46,9 +46,14 @@
 #defineRB_RED  0
 #defineRB_BLACK1
 
-#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)
 {
@@ -377,6 +382,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) {
/*
@@ -386,53 +392,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-&

[Xen-devel] [PATCH v4 11/17] rbtree: coding style adjustments

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 ba0c483903..e24f4c4d39 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -362,8 +362,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.12.0


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


[Xen-devel] [PATCH v4 12/17] rbtree: optimize fetching of sibling node

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <david.woodho...@intel.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 59633abf34e2f44b8e772a2c12a92132aa7c2220]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 e24f4c4d39..56c815b4a5 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -106,8 +106,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
@@ -130,7 +130,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
 *
@@ -150,6 +151,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;
}
 
/*
@@ -161,7 +163,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);
@@ -179,7 +181,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;
@@ -188,10 +191,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);
@@ -222,8 +226,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) {  /*

[Xen-devel] [PATCH v4 09/17] rbtree: optimize case selection logic in __rb_erase_color()

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit e125d1471a4f8f1bf7ea9a83deb8d23cb40bd712]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 e6ec186be3..9f0e283765 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -282,28 +282,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))
@@ -313,28 +309,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);
+

[Xen-devel] [PATCH v4 10/17] rbtree: low level optimizations in __rb_erase_color()

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6280d2356fd8ad0936a63c10dc1e6accf48d0c61]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 9f0e283765..ba0c483903 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -38,7 +38,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.
  */
 
 #defineRB_RED  0
@@ -47,17 +48,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)
@@ -70,52 +65,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
@@ -256,7 +205,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) {
/*
@@ -269,63 +218,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->r

[Xen-devel] [PATCH v4 08/17] rbtree: adjust node color in __rb_erase_color() only when necessary

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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.hun...@intel.com: perf tools: fix build for another rbtree.c change]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
Cc: Alexander Shishkin <alexander.shish...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit d6ff1273928ebf15466a85b7e1810cd00e72998b]

Ported only rbtree.c to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 162b2d67b2..e6ec186be3 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -258,10 +258,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))
{
@@ -290,12 +302,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))
{
@@ -324,13 +333,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.12.0


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


[Xen-devel] [PATCH v4 07/17] rbtree: low level optimizations in rb_insert_color()

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 5bc9188aa207dafd47eab57df7c4fe5b3d3f636a]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 b5d2a025d1..162b2d67b2 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -22,6 +22,25 @@
 #include 
 #include 
 
+/*
+ * 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.
+ */
+
 #defineRB_RED  0
 #defineRB_BLACK1
 
@@ -40,6 +59,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;
@@ -86,9 +116,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) {
/*
@@ -98,59 +149,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, 

[Xen-devel] [PATCH v4 05/17] rbtree: break out of rb_insert_color loop after tree rotation

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1f0528653e41ec230c60f5738820e8a544731399]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 1ed5943c5a..5bf25c4ad8 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -108,18 +108,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;
@@ -133,18 +130,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.12.0


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


[Xen-devel] [PATCH v4 06/17] rbtree: adjust root color in rb_insert_color() only when necessary

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6d58452dc066db61acdff7b84671db1b11a3de1c]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 5bf25c4ad8..b5d2a025d1 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -90,8 +90,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)
@@ -141,8 +154,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.12.0


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


[Xen-devel] [PATCH v4 04/17] rbtree: move some implementation details from rbtree.h to rbtree.c

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: David Woodhouse <david.woodho...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit bf7ad8eeab995710c766df49c9c69a8592ca0216]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 e2a665118b..1ed5943c5a 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -22,6 +22,24 @@
 #include 
 #include 
 
+#defineRB_RED  0
+#defineRB_BLACK1
+
+#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;
@@ -254,7 +272,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 4249752dcb..c3af3db5d0 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -19,36 +19,18 @@
 #ifndef __RBTREE_H__
 #define __RBTREE_H__
 
-struct rb_node
-{
-   unsigned long  rb_parent_color;
-#defineRB_RED  0
-#defineRB_BLACK1
+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, }
 #definerb_entry(ptr, type, member) container_of(ptr, type, member)
@@ -56,8 +38,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 *);
@@ -75,7 +59,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 * p

[Xen-devel] [PATCH v4 02/17] rbtree: remove redundant if()-condition in rb_erase()

2017-07-03 Thread Praveen Kumar
From: Wolfram Strepp <wstr...@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 <wstr...@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4b324126e0c6c3a5080ca3ec0981e8766ed6f1ee]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index d5e3d06b80..3a19b44a2f 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -249,15 +249,16 @@ 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.12.0


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


[Xen-devel] [PATCH v4 01/17] rbtree: changes to inline coding conventions with Linux tree

2017-07-03 Thread Praveen Kumar
The patch inlines the rbtree related files to Linux coding conventions to have
limited conflicts in future while porting from Linux tree.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
New in v4.
---
 xen/common/rbtree.c  | 630 +++
 xen/include/xen/rbtree.h |  39 +--
 2 files changed, 335 insertions(+), 334 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index d91d651d77..d5e3d06b80 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -24,261 +24,261 @@
 
 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);
+   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);
+   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);
 }
 
 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))
-{
-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;
-}
-}
-
-if (parent->rb_right == node)
-{
-register struct rb_node *tmp;
-__rb_rotate_left(parent, root);
-tmp = parent;
-parent = node;
-node = tmp;
-}
-
-rb_set_black(parent);
-rb_set_red(gparent);
-__rb_rotate_right(gparent, root);
-} 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;
-}
-}
-
-if (parent->rb_left == node)
-{
-register struct rb_node *tmp;
-__rb_rotate_right(parent, root);
-tmp = parent;
-parent = node;
-node = tmp;
-}
-
-rb_set_black(parent);
-rb_set_red(gparent);
-__rb_rotate_left(gparent, root);
-}
-}
-
-rb_set_black(root->rb_node);
+   struct rb_node *parent, *gparent;
+
+   while ((parent = rb_parent(node)) && rb_is_red(parent))
+   {
+   gparent = rb_parent(parent);
+
+

[Xen-devel] [PATCH v4 03/17] rbtree: empty nodes have no color

2017-07-03 Thread Praveen Kumar
From: Michel Lespinasse <wal...@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.

[s...@canb.auug.org.au: fix net/ceph/osd_client.c build]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Cc: John Stultz <john.stu...@linaro.org>
Signed-off-by: Stephen Rothwell <s...@canb.auug.org.au>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4c199a93a2d36b277a9fd209a0f2793f8460a215]

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

Signed-off-by: Praveen Kumar <kpraveen.l...@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 3a19b44a2f..e2a665118b 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 1a13ea66fa..4249752dcb 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -53,9 +53,11 @@ static inline void rb_set_color(struct rb_node *rb, int 
color)
 #define RB_ROOT(struct rb_root) { NULL, }
 #definerb_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.12.0


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


[Xen-devel] [PATCH v4 00/17] xen: common: rbtree: ported updates from Linux tree

2017-07-03 Thread Praveen Kumar
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

Add postorder iteration functions:
9dee5c51516d2c3fff22633c1272c5652e68075a

RCU related implementation :
d72da4a4d973d8a0a0d3c97e7cdebf287fbe3a99
c1adf20052d80f776849fa2c1acb472cdeb7786c
ce093a04543c403d52c1a5788d8cb92e47453aba

Use of designated initializers :
f231aebfc4cae2f6ed27a46a31e2630909513d77

Please share your inputs. Thanks in advance.

Regards,

~Praveen.

Praveen Kumar (17):
  rbtree: changes to inline coding conventions with Linux tree
  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  | 826 +--
 xen/include/xen/rbtree.h |  57 ++--
 2 files changed, 528 insertions(+), 355 deletions(-)

-- 
2.12.0


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


Re: [Xen-devel] [PATCH v2 09/20] rbtree: adjust root color in rb_insert_color() only when necessary

2017-06-27 Thread Praveen Kumar
Hi Dario and Jan,

Sorry, I missed this update.

On Tue, Jun 20, 2017 at 7:24 PM, Dario Faggioli  wrote:
> 
> On Tue, 2017-06-20 at 01:26 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > > 
> > > > > On 19.06.17 at 19:13,  wrote:
> > > And here we are again. (I.e., in the cited Linux's commit, this
> > > is
> > > being turned into 'while (true) {`.
> > > 
> > > So, I think we should gather others' opinion about how to deal
> > > with
> > > these aspects of this series. So, I'll stop my review for now,
> > > and
> > > chase feedback.
> > 
> > I fully second your opinion here. I even wonder whether we
> > shouldn't convert the file back to be fully Linux style first
> > thing,
> > so that Linux changes can be applied (mostly) as is, specifically
> > without having to convert tabs to spaces.
> > 
> That indeed would be good!
> 
> Praveen, this would mean having a patch, at the beginning of the
> series, which converts the coding style of the files to Linux one.
> 
> Basically, that would mean using tabs for indentation, and undoing
> any
> style change that may have been done in our tree, to make the file
> adopt the Xen style.
> 
> In practise, the idea is ending up with something that is basically
> identical to what was in Linux, before all the patches you are
> porting
> were committed (and without the additional parts and features that we
> don't need, of course).
> 
> At this point, even generating and applying the patches that you are
> porting, in this very series, would be really easy, and less error
> prone (as it can be almost entirely automated).
> 
> Are you up for this?

Sounds good. Let me work on the same. Will re-send the updated patch
series having first indentation changes followed by series of changes
in Linux code base ( as sent already )

> 
> 
> Thanks and Regards,
> Dario
> --
> <> (Raistlin Majere)
> -
> Dario Faggioli, Ph.D, http://about.me/dario.faggioli
> Senior Software Engineer, Citrix Systems R Ltd., Cambridge (UK)

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


Re: [Xen-devel] [PATCH 01/20] rbtree: add const qualifier to some functions

2017-06-19 Thread Praveen Kumar
Hi Jan,

On Mon, Jun 19, 2017 at 7:19 PM, Jan Beulich <jbeul...@suse.com> wrote:
>>>> On 17.06.17 at 11:32, <kpraveen.l...@gmail.com> wrote:
>> The 'rb_first()', 'rb_last()', 'rb_next()' and 'rb_prev()' calls
>> take a pointer to an RB node or RB root. They do not change the
>> pointed objects, so add a 'const' qualifier in order to make life
>> of the users of these functions easier.
>>
>> Indeed, if I have my own constant pointer  struct my_type *p,
>> and I call 'rb_next(>rb)', I get a GCC warning:
>>
>> warning: passing argument 1 of ‘rb_next’ discards qualifiers from pointer 
>> target
>> type
>>
>> Signed-off-by: Artem Bityutskiy <artem.bityuts...@nokia.com>
>> Signed-off-by: David Woodhouse <david.woodho...@intel.com>
>> Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
>> [Linux commit f4b477c47332367d35686bd2b808c2156b96d7c7]
>>
>> Ported to Xen.
>>
>> Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
>
> This looks okay now from a content pov, but I still have a question
> and a remark.
>
> Question: Who's the original author? According to the Linux commit,
> it's Artem, but without an explicit From: tag I think anyone trying to
> "git am" you mail would put you in as the author. With this taken
> care of (which the committer may be willing to do)
> Acked-by: Jan Beulich <jbeul...@suse.com>
>

Thanks for your input.
Pardon me, I am new to the forum. The Ack you added is only for this patch.

Also, do you want me to add 'From' and resend ?
To be precise in below order  :

Signed-off-by: Artem Bityutskiy <artem.bityuts...@nokia.com>
Signed-off-by: David Woodhouse <david.woodho...@intel.com>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit f4b477c47332367d35686bd2b808c2156b96d7c7]

Ported to Xen.

From: Artem Bityutskiy <artem.bityuts...@nokia.com>
Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>

Please do correct me if my understanding is wrong. Thanks.

> Remark: You've sent v3 of the series. This patch has no version
> indicator at all, and most other patches say v2. This is all quite
> inconsistent, and prevents easily identifying the various pieces
> belonging together when not using a threaded view. If you add
> new patches to a series, don't start them at v1. Instead in the
> brief revision info (after the first --- marker) simply say "New in
> v3."
>

Sure, my mistake. I was not aware of the same. I will take care in
future patches.
Thanks for your input.

Regards,

~Praveen.

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


[Xen-devel] [PATCH v2 06/20] rbtree: empty nodes have no color

2017-06-17 Thread Praveen Kumar
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.

[s...@canb.auug.org.au: fix net/ceph/osd_client.c build]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Cc: John Stultz <john.stu...@linaro.org>
Signed-off-by: Stephen Rothwell <s...@canb.auug.org.au>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4c199a93a2d36b277a9fd209a0f2793f8460a215]

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

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 9d3c5fab95..2561dbc7d9 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -317,7 +317,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
@@ -346,7 +346,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 3eb527eb37..f74b68ce62 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -52,9 +52,12 @@ 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.12.0


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


[Xen-devel] [PATCH 20/20] lib/rbtree.c: fix typo in comment of __rb_insert()

2017-06-17 Thread Praveen Kumar
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 <weiy...@linux.vnet.ibm.com>
Acked-by: Michel Lespinasse <wal...@google.com>
Cc: Xiao Guangrong <xiaoguangr...@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1b9c53e849aa65776d4f611d99aa09f856518dad]

Ported to Xen for rb_insert_color API.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 68e505bede..4fe5354785 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -138,7 +138,7 @@ void rb_insert_color(struct rb_node *node, struct rb_root 
*root)
  *  / \  / \
  * p   u  -->   P   U
  *//
- *   nN
+ *   nn
  *
  * However, since g's parent might be red, and
  * 4) does not allow this, we need to recurse
-- 
2.12.0


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


[Xen-devel] [PATCH v2 07/20] rbtree: move some implementation details from rbtree.h to rbtree.c

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: David Woodhouse <david.woodho...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit bf7ad8eeab995710c766df49c9c69a8592ca0216]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 2561dbc7d9..49f73e2461 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -22,6 +22,24 @@
 #include 
 #include 
 
+#defineRB_RED0
+#defineRB_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 f74b68ce62..89df40afd0 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -21,9 +21,7 @@
 
 struct rb_node
 {
-unsigned long  rb_parent_color;
-#define RB_RED  0
-#define RB_BLACK 1
+unsigned long  __rb_parent_color;
 struct rb_node *rb_right;
 struct rb_node *rb_left;
 };
@@ -33,21 +31,7 @@ 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)
@@ -55,9 +39,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 *);
@@ -75,7 +60,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.12.0


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


[Xen-devel] [PATCH v2 12/20] rbtree: optimize case selection logic in __rb_erase_color()

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit e125d1471a4f8f1bf7ea9a83deb8d23cb40bd712]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 2d5da9ea28..a365670369 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -287,28 +287,25 @@ 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)))
+if (!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))
+if (!other->rb_left || rb_is_black(other->rb_left))
 {
-rb_set_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
 {
@@ -320,28 +317,25 @@ 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)))
+if (!other->rb_left || rb_is_black(other->rb_left))
 {
-rb_set_red(other);
-node = parent;
-parent = rb_parent(node);
-}
-else
-{
-if (!other->rb_left || rb_is_black(other->rb_left))
+if (!other->rb_right || rb_is_black(other->rb_right))
 {
-rb_set_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_r

[Xen-devel] [PATCH v2 15/20] rbtree: optimize fetching of sibling node

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <david.woodho...@intel.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 59633abf34e2f44b8e772a2c12a92132aa7c2220]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 1cbe9a53d7..8c28ab1967 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -108,9 +108,9 @@ 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;
+if (parent != tmp)/* parent == gparent->rb_left */
 {
-tmp = gparent->rb_right;
 if (tmp && rb_is_red(tmp))
 {
 /*
@@ -134,7 +134,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
@@ -164,7 +165,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);
@@ -227,8 +228,10 @@ 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))
 {
 /*
-- 
2.12.0


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


[Xen-devel] [PATCH v2 10/20] rbtree: low level optimizations in rb_insert_color()

2017-06-17 Thread Praveen Kumar
- 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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 5bc9188aa207dafd47eab57df7c4fe5b3d3f636a]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 159 +---
 1 file changed, 127 insertions(+), 32 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index fff8e22526..d44fa22df5 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -22,6 +22,25 @@
 #include 
 #include 
 
+/*
+ * 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.
+ */
+
 #defineRB_RED0
 #defineRB_BLACK  1
 
@@ -40,6 +59,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;
@@ -86,9 +116,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,62 +150,106 @@ 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);
+gparent = rb_red_parent(parent);
 
 if (p

[Xen-devel] [PATCH v2 18/20] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color()

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 46b6135a7402ac23c5b25f2bd79b03bab8f98278]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 110 +++-
 1 file changed, 66 insertions(+), 44 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 149c861ac6..dfe566a5af 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -2,6 +2,7 @@
   Red Black Trees
   (C) 1999  Andrea Arcangeli <and...@suse.de>
   (C) 2002  David Woodhouse <dw...@infradead.org>
+  (C) 2012  Michel Lespinasse <wal...@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
@@ -49,6 +50,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;
@@ -213,29 +219,19 @@ 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 */
 {
@@ -272,16 +268,22 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
  *  / \   / \
  * Sl  SrSl  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
@@ -343,9 +345,16 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
 {
 /* Case 2 - sibling color flip */
 rb_set_parent_color(sib

[Xen-devel] [PATCH v2 17/20] rbtree: place easiest case first in rb_erase()

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 60670b8034d6e2ba860af79c9379b7788d09db73]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 2063536548..149c861ac6 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -370,17 +370,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;
 __rb_change_child(old, node, rb_parent(old), root);
@@ -403,17 +414,8 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 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.12.0


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


[Xen-devel] [PATCH v2 13/20] rbtree: low level optimizations in __rb_erase_color()

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6280d2356fd8ad0936a63c10dc1e6accf48d0c61]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 196 
 1 file changed, 107 insertions(+), 89 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index a365670369..1fe059a568 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -38,7 +38,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.
  */
 
 #defineRB_RED0
@@ -47,17 +48,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)
@@ -70,52 +65,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
@@ -259,7 +208,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)
 {
@@ -274,67 +223,136 @@ static void __rb_erase_color(struct rb_node *node, 
struct rb_node *parent,
  */
 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))
+sibling = parent->rb_right;
+if (rb_is_red(sibling))
 {
-rb_set_black(other);
-rb_set_red(parent);
-__rb_rotate_left(parent, root);
-other = parent->rb_right;
+/*
+

[Xen-devel] [PATCH v2 19/20] rbtree: low level optimizations in rb_erase()

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Acked-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4f035ad67f4633c233cb3642711d49b4efc9c82d]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 100 +++-
 1 file changed, 67 insertions(+), 33 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index dfe566a5af..68e505bede 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -46,9 +46,14 @@
 #defineRB_RED0
 #defineRB_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)
 {
@@ -381,6 +386,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) {
 /*
@@ -391,51 +397,79 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
  * 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)   

[Xen-devel] [PATCH v2 16/20] rbtree: add __rb_change_child() helper function

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Reviewed-by: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: David Woodhouse <dw...@infradead.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7abc704ae399fcb9c51ca200b0456f8a975a8011]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 8c28ab1967..2063536548 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -65,6 +65,13 @@ 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)
+{
+__rb_change_child(old, new, parent, root);
+}
+
 /*
  * Helper function for rotations:
  * - old's parent and color get assigned to new
@@ -376,15 +383,7 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 node = node->rb_right;
 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);
 color = rb_color(node);
@@ -413,15 +412,8 @@ 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;
-
- color:
+__rb_change_child(node, child, parent, root);
+color:
 if (color == RB_BLACK)
 __rb_erase_color(child, parent, root);
 }
@@ -524,14 +516,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.12.0


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


[Xen-devel] [PATCH v2 14/20] rbtree: coding style adjustments

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 44 
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 1fe059a568..1cbe9a53d7 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -367,16 +367,14 @@ 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;
 while ((left = node->rb_left) != NULL)
 node = left;
 
-if (rb_parent(old))
-{
+if (rb_parent(old)) {
 if (rb_parent(old)->rb_left == old)
 rb_parent(old)->rb_left = node;
 else
@@ -412,14 +410,12 @@ 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:
@@ -464,8 +460,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)
@@ -473,12 +471,14 @@ 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;
 
@@ -493,8 +493,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)
@@ -502,8 +504,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.12.0


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


[Xen-devel] [PATCH v2 11/20] rbtree: adjust node color in __rb_erase_color() only when necessary

2017-06-17 Thread Praveen Kumar
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.hun...@intel.com: perf tools: fix build for another rbtree.c change]
Signed-off-by: Michel Lespinasse <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
Cc: Alexander Shishkin <alexander.shish...@intel.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit d6ff1273928ebf15466a85b7e1810cd00e72998b]

Ported only rbtree.c to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index d44fa22df5..2d5da9ea28 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -261,10 +261,24 @@ 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)
+while (true)
 {
-if (parent->rb_left == node)
+/*
+ * 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))
 {
@@ -293,7 +307,6 @@ 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;
 }
 }
@@ -327,13 +340,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.12.0


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


[Xen-devel] [PATCH v2 09/20] rbtree: adjust root color in rb_insert_color() only when necessary

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 6d58452dc066db61acdff7b84671db1b11a3de1c]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 25902c0659..fff8e22526 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -90,8 +90,23 @@ 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)
@@ -143,8 +158,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.12.0


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


[Xen-devel] [PATCH v2 08/20] rbtree: break out of rb_insert_color loop after tree rotation

2017-06-17 Thread Praveen Kumar
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 <wal...@google.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Acked-by: David Woodhouse <david.woodho...@intel.com>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Daniel Santos <daniel.san...@pobox.com>
Cc: Jens Axboe <ax...@kernel.dk>
Cc: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 1f0528653e41ec230c60f5738820e8a544731399]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 49f73e2461..25902c0659 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -110,16 +110,14 @@ void rb_insert_color(struct rb_node *node, struct rb_root 
*root)
 
 if (parent->rb_right == node)
 {
-register struct rb_node *tmp;
 __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;
@@ -135,16 +133,14 @@ void rb_insert_color(struct rb_node *node, struct rb_root 
*root)
 
 if (parent->rb_left == node)
 {
-register struct rb_node *tmp;
 __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.12.0


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


[Xen-devel] [PATCH 01/20] rbtree: add const qualifier to some functions

2017-06-17 Thread Praveen Kumar
The 'rb_first()', 'rb_last()', 'rb_next()' and 'rb_prev()' calls
take a pointer to an RB node or RB root. They do not change the
pointed objects, so add a 'const' qualifier in order to make life
of the users of these functions easier.

Indeed, if I have my own constant pointer  struct my_type *p,
and I call 'rb_next(>rb)', I get a GCC warning:

warning: passing argument 1 of ‘rb_next’ discards qualifiers from pointer target
type

Signed-off-by: Artem Bityutskiy <artem.bityuts...@nokia.com>
Signed-off-by: David Woodhouse <david.woodho...@intel.com>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit f4b477c47332367d35686bd2b808c2156b96d7c7]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 3328960d56..d86b5f25c0 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -291,7 +291,7 @@ EXPORT_SYMBOL(rb_erase);
 /*
  * This function returns the first node (in sort order) of the tree.
  */
-struct rb_node *rb_first(struct rb_root *root)
+struct rb_node *rb_first(const struct rb_root *root)
 {
 struct rb_node *n;
 
@@ -304,7 +304,7 @@ struct rb_node *rb_first(struct rb_root *root)
 }
 EXPORT_SYMBOL(rb_first);
 
-struct rb_node *rb_last(struct rb_root *root)
+struct rb_node *rb_last(const struct rb_root *root)
 {
 struct rb_node *n;
 
@@ -317,7 +317,7 @@ struct rb_node *rb_last(struct rb_root *root)
 }
 EXPORT_SYMBOL(rb_last);
 
-struct rb_node *rb_next(struct rb_node *node)
+struct rb_node *rb_next(const struct rb_node *node)
 {
 struct rb_node *parent;
 
@@ -330,7 +330,7 @@ struct rb_node *rb_next(struct rb_node *node)
 node = node->rb_right; 
 while (node->rb_left)
 node=node->rb_left;
-return node;
+return (struct rb_node *)node;
 }
 
 /* No right-hand children.  Everything down and left is
@@ -346,7 +346,7 @@ struct rb_node *rb_next(struct rb_node *node)
 }
 EXPORT_SYMBOL(rb_next);
 
-struct rb_node *rb_prev(struct rb_node *node)
+struct rb_node *rb_prev(const struct rb_node *node)
 {
 struct rb_node *parent;
 
@@ -359,7 +359,7 @@ struct rb_node *rb_prev(struct rb_node *node)
 node = node->rb_left; 
 while (node->rb_right)
 node=node->rb_right;
-return node;
+return (struct rb_node *)node;
 }
 
 /* No left-hand children. Go up till we find an ancestor which
diff --git a/xen/include/xen/rbtree.h b/xen/include/xen/rbtree.h
index f93c4d5823..3eb527eb37 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -60,10 +60,10 @@ extern void rb_insert_color(struct rb_node *, struct 
rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
 
 /* Find logical next and previous nodes in a tree */
-extern struct rb_node *rb_next(struct rb_node *);
-extern struct rb_node *rb_prev(struct rb_node *);
-extern struct rb_node *rb_first(struct rb_root *);
-extern struct rb_node *rb_last(struct rb_root *);
+extern struct rb_node *rb_next(const struct rb_node *);
+extern struct rb_node *rb_prev(const struct rb_node *);
+extern struct rb_node *rb_first(const struct rb_root *);
+extern struct rb_node *rb_last(const struct rb_root *);
 
 /* Fast replacement of a single node without remove/rebalance/add/rebalance */
 extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, 
-- 
2.12.0


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


[Xen-devel] [PATCH v2 03/20] rb_tree: reorganize code in rb_erase() for additional changes

2017-06-17 Thread Praveen Kumar
First, move some code around in order to make the next change more obvious.

[a...@linux-foundation.org: coding-style fixes]
Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl>
Signed-off-by: Wolfram Strepp <wstr...@gmx.de>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 16c047add3ceaf0ab882e3e094d1ec904d02312d]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 70cb15f1fe..4b85fd492b 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -230,6 +230,16 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 node = node->rb_right;
 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;
+
 child = node->rb_right;
 parent = rb_parent(node);
 color = rb_color(node);
@@ -246,15 +256,6 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 node->rb_right = old->rb_right;
 node->rb_left = old->rb_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_set_parent(old->rb_left, node);
 if (old->rb_right)
 rb_set_parent(old->rb_right, node);
-- 
2.12.0


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


[Xen-devel] [PATCH v2 05/20] rb_tree: remove redundant if()-condition in rb_erase()

2017-06-17 Thread Praveen Kumar
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 <wstr...@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4b324126e0c6c3a5080ca3ec0981e8766ed6f1ee]

Ported to Xen.

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 90db00a5e8..9d3c5fab95 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -250,15 +250,16 @@ 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.12.0


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


[Xen-devel] [PATCH 02/20] lib/rbtree.c: optimize rb_erase()

2017-06-17 Thread Praveen Kumar
Tfour 4 redundant if-conditions in function __rb_erase_color() in
lib/rbtree.c are removed.

In pseudo-source-code, the structure of the code is as follows:

if ((!A || B) && (!C || D)) {
.
.
.
} else {
if (!C || D) {//if this is true, it implies: (A == true) && (B 
== false)
if (A) {//hence this always evaluates to 
'true'...
.
}
.
//at this point, C always becomes true, because 
of:
__rb_rotate_right/left();
//and:
other = parent->rb_right/left;
}
.
.
if (C) {//...and this too !
.
}
}

Signed-off-by: Wolfram Strepp <wstr...@gmx.de>
Acked-by: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Andrea Arcangeli <and...@qumranet.com>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 55a63998b8967615a15e2211ba0ff3a84a565824]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@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 d86b5f25c0..70cb15f1fe 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -162,17 +162,14 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
 {
 if (!other->rb_right || rb_is_black(other->rb_right))
 {
-struct rb_node *o_left;
-if ((o_left = other->rb_left))
-rb_set_black(o_left);
+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);
-if (other->rb_right)
-rb_set_black(other->rb_right);
+rb_set_black(other->rb_right);
 __rb_rotate_left(parent, root);
 node = root->rb_node;
 break;
@@ -199,17 +196,14 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
 {
 if (!other->rb_left || rb_is_black(other->rb_left))
 {
-register struct rb_node *o_right;
-if ((o_right = other->rb_right))
-rb_set_black(o_right);
+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);
-if (other->rb_left)
-rb_set_black(other->rb_left);
+rb_set_black(other->rb_left);
 __rb_rotate_right(parent, root);
 node = root->rb_node;
 break;
-- 
2.12.0


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


[Xen-devel] [PATCH v3] xen: common: rbtree: ported updates from

2017-06-17 Thread Praveen Kumar
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

Add postorder iteration functions:
9dee5c51516d2c3fff22633c1272c5652e68075a

RCU related implementation :
d72da4a4d973d8a0a0d3c97e7cdebf287fbe3a99
c1adf20052d80f776849fa2c1acb472cdeb7786c
ce093a04543c403d52c1a5788d8cb92e47453aba

Use of designated initializers :
f231aebfc4cae2f6ed27a46a31e2630909513d77

Please share your inputs. Thanks in advance.

Regards,

~Praveen.



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


[Xen-devel] [PATCH v2 04/20] rb_tree: make clear distinction between two different cases in rb_erase()

2017-06-17 Thread Praveen Kumar
There are two cases when a node, having 2 childs, is erased:
'normal case': the successor is not the right-hand-child of the node to be
erased
'special case': the successor is the right-hand child of the node to be erased

Here some ascii-art, with following symbols (referring to the code):
O: node to be deleted
N: the successor of O
P: parent of N
C: child of N
L: some other node

normal case:

   O N
  / \   / \
 /   \ /   \
L \   L \
   / \ P  >  / \ P
  / \   / \
 / /
N C
 \   / \
  \
   C
  / \

special case:
  O|PN
  / \   / \
 /   \ /   \
L \   L \
   / \ N  >  /   C
\   / \
 \
  C
 / \

Notice that for the special case we don't have to reconnect C to N.

Signed-off-by: Wolfram Strepp <wstr...@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
[Linux commit 4c60117811171d867d4f27f17ea07d7419d45dae]

Ported to Xen.

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 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 4b85fd492b..90db00a5e8 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -244,13 +244,13 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 parent = rb_parent(node);
 color = rb_color(node);
 
-if (child)
-rb_set_parent(child, parent);
 if (parent == old) {
-parent->rb_right = child;
 parent = node;
-} else
+} else {
+if (child)
+rb_set_parent(child, parent);
 parent->rb_left = child;
+}
 
 node->rb_parent_color = old->rb_parent_color;
 node->rb_right = old->rb_right;
-- 
2.12.0


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


Re: [Xen-devel] [RFC PATCH v4] xen: credit2: provide custom option to create runqueue

2017-06-02 Thread Praveen Kumar
Hi,

Can you please provide comments on the shared patch.
Thanks in advance.

Regards,

~Praveen.

On Wed, 2017-04-19 at 23:15 +0530, Praveen Kumar wrote:
> The patch introduces a new, very flexible way of arranging runqueues
> in Credit2.
> It allows to specify, explicitly and precisely, what pCPUs should
> belong to
> which runqueue.
> 
> Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
> ---
>  docs/misc/xen-command-line.markdown |  10 ++-
>  xen/common/sched_credit2.c  | 167
> +++-
>  2 files changed, 174 insertions(+), 3 deletions(-)
> 
> diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-
> command-line.markdown
> index 33e54aef63..f2ee4ad972 100644
> --- a/docs/misc/xen-command-line.markdown
> +++ b/docs/misc/xen-command-line.markdown
> @@ -525,7 +525,7 @@ also slow in responding to load changes.
>  The default value of `1 sec` is rather long.
>  
>  ### credit2\_runqueue
> -> `= cpu | core | socket | node | all`
> +> `= cpu | core | socket | node | all | `
>  
>  > Default: `socket`
>  
> @@ -543,6 +543,14 @@ Available alternatives, with their meaning, are:
>  * `node`: one runqueue per each NUMA node of the host;
>  * `all`: just one runqueue shared by all the logical pCPUs of
>   the host
> +* ``: one runqueue per mentioned subset. The subset can be
> defined as
> +  as shown in below example:
> +  credit2_runqueue=[[0,1,][2,6][3,5][4,7]] , or
> 0,1\;2,6\;3,5\;4,7
> +  which means :
> +  - pCPUs 0 and 1 belong to runqueue 0
> +  - pCPUs 2 and 6 belong to runqueue 1
> +  - pCPUs 3 and 5 belong to runqueue 2
> +  - pCPUs 4 and 7 belong to runqueue 3
>  
>  ### dbgp
>  > `= ehci[  | @pci:. ]`
> diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
> index b9b928347f..ebec33f450 100644
> --- a/xen/common/sched_credit2.c
> +++ b/xen/common/sched_credit2.c
> @@ -321,6 +321,16 @@ integer_param("credit2_balance_over",
> opt_overload_balance_tolerance);
>   *   (logical) processors of the host belong. This will
> happen if
>   *   the opt_runqueue parameter is set to 'all'.
>   *
> + * - custom: meaning that there will be one runqueue per subset
> being passed as
> + *   parameter to credit2_runqueue as shown in below
> example.
> + *   Example:
> + *   credit2_runqueue=[[cpu0,cpu1][cpu3][cpu4,cpu5]] or
> + *   credit2_runqueue=0,1\;3\;4,5
> + *   The example mentioned states :
> + *   cpu0 and cpu1 belongs to runqueue 0
> + *   cpu3 belongs to runqueue 1
> + *   cpu4 and cpu5 belongs to runqueue 2
> + *
>   * Depending on the value of opt_runqueue, therefore, cpus that are
> part of
>   * either the same physical core, the same physical socket, the same
> NUMA
>   * node, or just all of them, will be put together to form
> runqueues.
> @@ -330,15 +340,138 @@ integer_param("credit2_balance_over",
> opt_overload_balance_tolerance);
>  #define OPT_RUNQUEUE_SOCKET 2
>  #define OPT_RUNQUEUE_NODE   3
>  #define OPT_RUNQUEUE_ALL4
> +#define OPT_RUNQUEUE_CUSTOM 5
>  static const char *const opt_runqueue_str[] = {
>  [OPT_RUNQUEUE_CPU] = "cpu",
>  [OPT_RUNQUEUE_CORE] = "core",
>  [OPT_RUNQUEUE_SOCKET] = "socket",
>  [OPT_RUNQUEUE_NODE] = "node",
> -[OPT_RUNQUEUE_ALL] = "all"
> +[OPT_RUNQUEUE_ALL] = "all",
> +[OPT_RUNQUEUE_CUSTOM] = "custom"
>  };
>  static int __read_mostly opt_runqueue = OPT_RUNQUEUE_SOCKET;
>  
> +static unsigned long __read_mostly custom_cpu_runqueue[NR_CPUS];
> +
> +static inline int getlen(const char *start, const char *end)
> +{
> +if ( ( start ) && ( end ) && ( end > start ) )
> +return end-start;
> +else
> +return -1;
> +}
> +
> +static int parse_custom_runqueue_option(const char *s)
> +{
> +const char *parse = NULL, *s_end = NULL;
> +const char *start = NULL, *end = NULL;
> +char delimiter[2] = {0};
> +int cpu_added_to_runqueue = 0;
> +int runqueue = 0;
> +
> +/* Format supported :
> + * [[0,1,4,5][2,3,6,7][8,9,12,13][10,11,14,15]]
> + *  or
> + * 0,1,4,5\;2,3,6,7\;8,9,12,13\;10,11,14,15
> + */
> +parse = s;
> +s_end = s + strlen(s);
> +/* The start and should always be in format of '[..]' */
> +if ( ( '[' == *parse ) && ( ']' == *(s_end-1)) )
> +{
> +delimiter[0] 

Re: [Xen-devel] [Xen-devel[PATCH Resend v2] xen: common: rbtree: ported updates from linux tree

2017-06-02 Thread Praveen Kumar
On Thu, 2017-06-01 at 09:43 +0200, Dario Faggioli wrote:
> On Thu, 2017-06-01 at 01:26 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > > 
> > > > > On 31.05.17 at 23:20,  wrote:
> > > I have not imported augmented and rcu rbtree functionality to the
> > > xen tree,
> > > as there was no specific requirement for current planned
> > > implementation.
> > > 
> > Bug fixes and improvements to existing code are clearly welcome
> > and need no further rationale provided here. Having looked only
> > over the titles so far I see two patches which look to add new
> > functionality (13 and 17). 
> > 
> I also have only quickly skimmed through the series for now.
> 
> Indeed 17 adds stuff which I suspect we may not need, and in any
> case,
> I don't think it belongs in this series.
> 
> If you really need those iterators when actually using rb-tree,
> you'll
> add the patch at that time.
> 
> 13, despite its own (poor, I agree) subject line, is actually doing
> some decent refactoring of the code, so I'd keep it:
> < code 
> that would otherwise be duplicated 4 times in the source.>>
> 

Dario,

For the commits not ported from Linux tree, I will share the
information in updated patch ( in similar way what I did by adding a
cover letter ).

Also, as suggested Will remove the patch 17 for now, and validate
others too.

Thanks once again for providing your comment.

Regards,

~Praveen.

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


Re: [Xen-devel] [Xen-devel[PATCH Resend v2] xen: common: rbtree: ported updates from linux tree

2017-06-02 Thread Praveen Kumar
On Thu, 2017-06-01 at 01:26 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > On 31.05.17 at 23:20,  wrote:
> > 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 and rcu rbtree functionality to the
> > xen tree,
> > as there was no specific requirement for current planned
> > implementation.
> > 
> > Please share your inputs. Thanks in advance.
> 
> Bug fixes and improvements to existing code are clearly welcome
> and need no further rationale provided here. Having looked only
> over the titles so far I see two patches which look to add new
> functionality (13 and 17). As I hope you've left the original patch
> descriptions intact, a reason for why we want/need these should
> likely be provided here.
> 

Sure Jan, I will take care of the same in my updated patch. Thanks for
your comment.
> 

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


Re: [Xen-devel] [Resend][PATCH 01/17] rb_tree: reorganize code in rb_erase() for additional changes

2017-06-02 Thread Praveen Kumar
On Thu, 2017-06-01 at 10:01 +0200, Dario Faggioli wrote:
> On Wed, 2017-05-31 at 23:56 +0100, Andrew Cooper wrote:
> > 
> > As an example, see
> > 
> > http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=b01c2fb5834
> > ae
> > a0328db55c310caa34173021d3d
> > 
> Nice, I especially like how the changelog looks, i.e.:
>  - original Linux patch description description
>  - Linux's Signed-off-by, Reviewed-by, Acked-by, etc.
>  - ref to Linux commit id
>  - a line with "Ported to Xen."
>  - author of the port's Signed-off-by
>  - (Reviewed-by, Acked-by, etc. coming from xen-devel)
> 
> Praveen, I suggest using the same pattern (if you also like it, of
> course :-D).
> 
Thanks Andrew for sharing the information.

Yes, liked it too. Will incorporate the changes and share updated
patch. Will try to do dry-run as suggested.

> Using patch 1 as an example, that would mean the following:
> 
>   Subject: [PATCH 01/17] rb_tree: reorganize code in rb_erase()
> for additional changes
> 
>   First, move some code around in order to make the next change more 
>   obvious.
> 
>   [a...@linux-foundation.org: coding-style fixes]
>   Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl>
>   Signed-off-by: Wolfram Strepp <wstr...@gmx.de>
>   Signed-off-by: Andrew Morton <a...@linux-foundation.org>
>   Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
>   [Linux commit 16c047add3ceaf0ab882e3e094d1ec904d02312d]
> 
>   Ported to Xen.
> 
>   Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
>   ---
> 
> > 
> > The way I prepare series like this for email is to use `git format-
> > patch
> > staging --cover-letter` to render the entire series as patch files
> > in
> > the local directory,  edit each patch to put suitable Cc: lines
> > beside
> > the From: header, then `git send-email --dry-run *.patch
> > --suppress-cc=all` to check what it will actually send.  The Cc's
> > in
> > the
> > header section are included, but no automatic Cc's are generated
> > from
> > content in the body.
> > 
> Cool to know, thanks.
> 
Sure, I too was bit confused by replacing Signed-off-by. As suggested
by Andrew, I will rework on the patches. Thanks again.

Regards,

~Praveen.

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


[Xen-devel] [Resend][PATCH 15/17] rbtree: handle 1-child recoloring in rb_erase() instead of rb_erase_color()

2017-05-31 Thread Praveen Kumar
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.

commit 46b6135a7402ac23c5b25f2bd79b03bab8f98278 from Linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 110 +++-
 1 file changed, 66 insertions(+), 44 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 69c7496c65..6e37e960ab 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -2,6 +2,7 @@
   Red Black Trees
   (C) 1999  Andrea Arcangeli <and...@suse.de>
   (C) 2002  David Woodhouse <dw...@infradead.org>
+  (C) 2012  Michel Lespinasse <wal...@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
@@ -49,6 +50,12 @@
 #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;
@@ -219,29 +226,19 @@ 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 */
 {
@@ -277,17 +274,22 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
  *  / \   / \
  * Sl  SrSl  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
@@ -349,9 +351,16 @@ 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_paren

[Xen-devel] [Resend][PATCH 14/17] rbtree: place easiest case first in rb_erase()

2017-05-31 Thread Praveen Kumar
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.

commit 60670b8034d6e2ba860af79c9379b7788d09db73 from Linux tree

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 3b54c04bea..69c7496c65 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -376,18 +376,29 @@ 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;
 
@@ -412,19 +423,8 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 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.12.0


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


[Xen-devel] [Resend][PATCH 16/17] rbtree: low level optimizations in rb_erase()

2017-05-31 Thread Praveen Kumar
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.

commit 4f035ad67f4633c233cb3642711d49b4efc9c82d from Linux tree

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 6e37e960ab..83b4892f54 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -46,9 +46,14 @@
 #defineRB_RED0
 #defineRB_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)
 {
@@ -387,6 +392,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)
 {
@@ -398,53 +404,79 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
  * 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, success

[Xen-devel] [Resend][PATCH 17/17] rbtree: add postorder iteration functions

2017-05-31 Thread Praveen Kumar
Postorder iteration yields all of a node's children prior to yielding the
node itself, and this particular implementation also avoids examining the
leaf links in a node after that node has been yielded.

In what I expect will be its most common usage, postorder iteration allows
the deletion of every node in an rbtree without modifying the rbtree nodes
(no _requirement_ that they be nulled) while avoiding referencing child
nodes after they have been "deleted" (most commonly, freed).

I have only updated zswap to use this functionality at this point, but
numerous bits of code (most notably in the filesystem drivers) use a hand
rolled postorder iteration that NULLs child links as it traverses the
tree.  Each of those instances could be replaced with this common
implementation.

1 & 2 add rbtree postorder iteration functions.
3 adds testing of the iteration to the rbtree runtime tests
4 allows building the rbtree runtime tests as builtins
5 updates zswap.

This patch:

Add postorder iteration functions for rbtree.  These are useful for safely
freeing an entire rbtree without modifying the tree at all.

commit 9dee5c51516d2c3fff22633c1272c5652e68075a from Linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c  | 45 +
 xen/include/xen/rbtree.h |  4 
 2 files changed, 49 insertions(+)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 83b4892f54..3c994dcc0c 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -584,3 +584,48 @@ void rb_replace_node(struct rb_node *victim, struct 
rb_node *new,
 *new = *victim;
 }
 EXPORT_SYMBOL(rb_replace_node);
+
+static struct rb_node *rb_left_deepest_node(const struct rb_node *node)
+{
+for (;;)
+{ 
+if (node->rb_left)
+node = node->rb_left;
+else if (node->rb_right)
+node = node->rb_right;
+else
+return (struct rb_node *)node;
+}
+}
+
+struct rb_node *rb_next_postorder(const struct rb_node *node)
+{
+const struct rb_node *parent;
+if (!node)
+return NULL;
+parent = rb_parent(node);
+
+/* If we're sitting on node, we've already seen our children */
+if (parent && node == parent->rb_left && parent->rb_right)
+{
+/* If we are the parent's left node, go to the parent's right
+ * node then all the way down to the left
+ */
+return rb_left_deepest_node(parent->rb_right);
+} else
+/* Otherwise we are the parent's right node, and the parent
+ * should be next
+ */
+return (struct rb_node *)parent;
+}
+EXPORT_SYMBOL(rb_next_postorder);
+
+struct rb_node *rb_first_postorder(const struct rb_root *root)
+{
+if (!root->rb_node)
+return NULL;
+
+return rb_left_deepest_node(root->rb_node);
+}
+EXPORT_SYMBOL(rb_first_postorder);
+
diff --git a/xen/include/xen/rbtree.h b/xen/include/xen/rbtree.h
index 107f1b12f2..24650a5cd8 100644
--- a/xen/include/xen/rbtree.h
+++ b/xen/include/xen/rbtree.h
@@ -66,4 +66,8 @@ static inline void rb_link_node(struct rb_node * node, struct 
rb_node * parent,
 *rb_link = node;
 }
 
+/* Postorder iteration - always visit the parent after its children */
+extern struct rb_node *rb_first_postorder(const struct rb_root *);
+extern struct rb_node *rb_next_postorder(const struct rb_node *);
+
 #endif /* __RBTREE_H__ */
-- 
2.12.0


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


[Xen-devel] [Resend][PATCH 11/17] rbtree: low level optimizations in __rb_erase_color()

2017-05-31 Thread Praveen Kumar
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.

commit 6280d2356fd8ad0936a63c10dc1e6accf48d0c61 from linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 197 
 1 file changed, 107 insertions(+), 90 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 1e4cb1ed2c..253861d889 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -38,7 +38,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.
  */
 
 #defineRB_RED0
@@ -47,17 +48,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)
@@ -70,52 +65,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
@@ -260,7 +209,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)
 {
@@ -275,68 +224,136 @@ static void __rb_erase_color(struct rb_node *node, 
struct rb_node *parent,
  */
 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

[Xen-devel] [Resend][PATCH 13/17] rbtree: add __rb_change_child() helper function

2017-05-31 Thread Praveen Kumar
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.

commit 7abc704ae399fcb9c51ca200b0456f8a975a8011 from Linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 54 ++---
 1 file changed, 22 insertions(+), 32 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index b65f00ca1f..3b54c04bea 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -65,6 +65,22 @@ 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
@@ -77,13 +93,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)
@@ -381,14 +391,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);
@@ -418,15 +421,8 @@ 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)
@@ -523,14 +519,8 @@ 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.12.0


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


[Xen-devel] [Resend][PATCH 12/17] rbtree: optimize fetching of sibling node

2017-05-31 Thread Praveen Kumar
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.

commit 59633abf34e2f44b8e772a2c12a92132aa7c2220 from Linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@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 253861d889..b65f00ca1f 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -108,9 +108,9 @@ 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;
+if (parent != tmp)/* parent == gparent->rb_left */
 {
-tmp = gparent->rb_right;
 if (tmp && rb_is_red(tmp))
 {
 /*
@@ -134,7 +134,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
@@ -164,7 +165,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);
@@ -183,7 +184,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;
@@ -192,10 +194,11 @@ void rb_insert_color(struct rb_node *node, struct rb_root 
*root)
 rb_set_parent_color(tmp, parent, 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);
@@ -228,8 +231,10 @@ 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.12.0


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


[Xen-devel] [Resend][PATCH 09/17] rbtree: adjust node color in __rb_erase_color() only when necessary

2017-05-31 Thread Praveen Kumar
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.

commit d6ff1273928ebf15466a85b7e1810cd00e72998b from linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 8db7a5b4ca..736e2a55aa 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -262,10 +262,24 @@ 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)
+while (true)
 {
-if (parent->rb_left == node)
+/*
+ * 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))
 {
@@ -297,7 +311,6 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
 if (other->rb_right)
 rb_set_black(other->rb_right);
 __rb_rotate_left(parent, root);
-node = root->rb_node;
 break;
 }
 }
@@ -334,13 +347,10 @@ static void __rb_erase_color(struct rb_node *node, struct 
rb_node *parent,
 if (other->rb_left)
 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.12.0


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


[Xen-devel] [Resend][PATCH 10/17] rbtree: optimize case selection logic in __rb_erase_color()

2017-05-31 Thread Praveen Kumar
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.

commit e125d1471a4f8f1bf7ea9a83deb8d23cb40bd712 from linux tree

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

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index 736e2a55aa..1e4cb1ed2c 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -288,31 +288,26 @@ 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)))
+if (!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))
+if (!other->rb_left || rb_is_black(other->rb_left))
 {
-struct rb_node *o_left;
-if ((o_left = other->rb_left))
-rb_set_black(o_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);
-if (other->rb_right)
-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
 {
@@ -324,31 +319,25 @@ 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)))
+if (!other->rb_left || rb_is_black(other->rb_left))
 {
-rb_set_red(other);
-node = parent;
-parent = rb_parent(node);
-}
-else
-{
-if (!other->rb_left || rb_is_black(other->rb_left))
+if (!other->rb_right || rb_is_black(other->rb_right))
 {
-register struct rb_node *o_right;
-if ((o_right = other->rb_right))
-rb_set_black(o_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);
-if (other->rb_left)
-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.12.0


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


[Xen-devel] [Resend][PATCH 08/17] rbtree: low level optimizations in rb_insert_color()

2017-05-31 Thread Praveen Kumar
- 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.

commit 5bc9188aa207dafd47eab57df7c4fe5b3d3f636a from linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 xen/common/rbtree.c | 160 ++--
 1 file changed, 129 insertions(+), 31 deletions(-)

diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
index ccf905e35c..8db7a5b4ca 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -22,6 +22,25 @@
 #include 
 #include 
 
+/*
+ * 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.
+ */
+
 #defineRB_RED0
 #defineRB_BLACK  1
 
@@ -40,6 +59,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;
@@ -86,9 +116,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,61 +150,108 @@ 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);
+gparent = rb_red_parent(parent);
 
 if (parent == gparent->rb_left)
 {
+tmp = gparent->rb_right;
+if (tmp && rb_is_red(tmp))
 {
-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;
-}
+/*
+ * Case 1 - colo

[Xen-devel] [Resend][PATCH 02/17] rb_tree: make clear distinction between two different cases in rb_erase()

2017-05-31 Thread Praveen Kumar
There are two cases when a node, having 2 childs, is erased:
'normal case': the successor is not the right-hand-child of the node to be
erased
'special case': the successor is the right-hand child of the node to be
erased

Here some ascii-art, with following symbols (referring to the code):
O: node to be deleted
N: the successor of O
P: parent of N
C: child of N
L: some other node

normal case:

   O N
  / \   / \
 /   \ /   \
L \   L \
   / \ P  >  / \ P
  / \   / \
 / /
N C
 \   / \
  \
   C
  / \

special case:
  O|PN
  / \   / \
 /   \ /   \
L \   L \
   / \ N  >  /   C
\   / \
 \
  C
 / \

Notice that for the special case we don't have to reconnect C to N.

commit 4c60117811171d867d4f27f17ea07d7419d45dae from linux tree

Signed-off-by: Praveen Kumar <kpraveen.l...@gmail.com>
---
 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 9826909a2a..3df599c3cb 100644
--- a/xen/common/rbtree.c
+++ b/xen/common/rbtree.c
@@ -250,13 +250,13 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 parent = rb_parent(node);
 color = rb_color(node);
 
-if (child)
-rb_set_parent(child, parent);
 if (parent == old) {
-parent->rb_right = child;
 parent = node;
-} else
+} else {
+if (child)
+rb_set_parent(child, parent);
 parent->rb_left = child;
+}
 
 node->rb_parent_color = old->rb_parent_color;
 node->rb_right = old->rb_right;
-- 
2.12.0


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


  1   2   >