iommu/iova: Consolidate code for adding new node to iovad domain rbtree
authorMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 24 Feb 2017 11:13:37 +0000 (12:13 +0100)
committerJoerg Roedel <jroedel@suse.de>
Tue, 21 Mar 2017 13:58:18 +0000 (14:58 +0100)
This patch consolidates almost the same code used in iova_insert_rbtree()
and __alloc_and_insert_iova_range() functions. While touching this code,
replace BUG() with WARN_ON(1) to avoid taking down the whole system in
case of corrupted iova tree or incorrect calls.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/iova.c

index b7268a14184f220bef244f38bfcc2d13900c443a..e80a4105ac2abe55d365a9a5f03220f97417c9ac 100644 (file)
@@ -100,6 +100,34 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
        }
 }
 
+/* Insert the iova into domain rbtree by holding writer lock */
+static void
+iova_insert_rbtree(struct rb_root *root, struct iova *iova,
+                  struct rb_node *start)
+{
+       struct rb_node **new, *parent = NULL;
+
+       new = (start) ? &start : &(root->rb_node);
+       /* Figure out where to put new node */
+       while (*new) {
+               struct iova *this = rb_entry(*new, struct iova, node);
+
+               parent = *new;
+
+               if (iova->pfn_lo < this->pfn_lo)
+                       new = &((*new)->rb_left);
+               else if (iova->pfn_lo > this->pfn_lo)
+                       new = &((*new)->rb_right);
+               else {
+                       WARN_ON(1); /* this should not happen */
+                       return;
+               }
+       }
+       /* Add new node and rebalance tree. */
+       rb_link_node(&iova->node, parent, new);
+       rb_insert_color(&iova->node, root);
+}
+
 /*
  * Computes the padding size required, to make the start address
  * naturally aligned on the power-of-two order of its size
@@ -157,35 +185,8 @@ move_left:
        new->pfn_lo = limit_pfn - (size + pad_size) + 1;
        new->pfn_hi = new->pfn_lo + size - 1;
 
-       /* Insert the new_iova into domain rbtree by holding writer lock */
-       /* Add new node and rebalance tree. */
-       {
-               struct rb_node **entry, *parent = NULL;
-
-               /* If we have 'prev', it's a valid place to start the
-                  insertion. Otherwise, start from the root. */
-               if (prev)
-                       entry = &prev;
-               else
-                       entry = &iovad->rbroot.rb_node;
-
-               /* Figure out where to put new node */
-               while (*entry) {
-                       struct iova *this = rb_entry(*entry, struct iova, node);
-                       parent = *entry;
-
-                       if (new->pfn_lo < this->pfn_lo)
-                               entry = &((*entry)->rb_left);
-                       else if (new->pfn_lo > this->pfn_lo)
-                               entry = &((*entry)->rb_right);
-                       else
-                               BUG(); /* this should not happen */
-               }
-
-               /* Add new node and rebalance tree. */
-               rb_link_node(&new->node, parent, entry);
-               rb_insert_color(&new->node, &iovad->rbroot);
-       }
+       /* If we have 'prev', it's a valid place to start the insertion. */
+       iova_insert_rbtree(&iovad->rbroot, new, prev);
        __cached_rbnode_insert_update(iovad, saved_pfn, new);
 
        spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
@@ -194,28 +195,6 @@ move_left:
        return 0;
 }
 
-static void
-iova_insert_rbtree(struct rb_root *root, struct iova *iova)
-{
-       struct rb_node **new = &(root->rb_node), *parent = NULL;
-       /* Figure out where to put new node */
-       while (*new) {
-               struct iova *this = rb_entry(*new, struct iova, node);
-
-               parent = *new;
-
-               if (iova->pfn_lo < this->pfn_lo)
-                       new = &((*new)->rb_left);
-               else if (iova->pfn_lo > this->pfn_lo)
-                       new = &((*new)->rb_right);
-               else
-                       BUG(); /* this should not happen */
-       }
-       /* Add new node and rebalance tree. */
-       rb_link_node(&iova->node, parent, new);
-       rb_insert_color(&iova->node, root);
-}
-
 static struct kmem_cache *iova_cache;
 static unsigned int iova_cache_users;
 static DEFINE_MUTEX(iova_cache_mutex);
@@ -505,7 +484,7 @@ __insert_new_range(struct iova_domain *iovad,
 
        iova = alloc_and_init_iova(pfn_lo, pfn_hi);
        if (iova)
-               iova_insert_rbtree(&iovad->rbroot, iova);
+               iova_insert_rbtree(&iovad->rbroot, iova, NULL);
 
        return iova;
 }
@@ -612,11 +591,11 @@ split_and_remove_iova(struct iova_domain *iovad, struct iova *iova,
        rb_erase(&iova->node, &iovad->rbroot);
 
        if (prev) {
-               iova_insert_rbtree(&iovad->rbroot, prev);
+               iova_insert_rbtree(&iovad->rbroot, prev, NULL);
                iova->pfn_lo = pfn_lo;
        }
        if (next) {
-               iova_insert_rbtree(&iovad->rbroot, next);
+               iova_insert_rbtree(&iovad->rbroot, next, NULL);
                iova->pfn_hi = pfn_hi;
        }
        spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);