mlx4: Enable QP destruction
authorKanoj Sarcar' via Akaros <akaros@googlegroups.com>
Wed, 10 Feb 2016 23:18:17 +0000 (15:18 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 10 Feb 2016 23:26:46 +0000 (18:26 -0500)
QP destruction panics because radix_tree_delete() is panic-stubbed. Implement
a version using linked lists that allows deletion.

Signed-off-by: Kanoj Sarcar <kanoj@google.com>
[ tagged commit with mlx4: ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/linux/compat_todo.h

index a99e575..bcd0809 100644 (file)
@@ -163,55 +163,73 @@ static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
 
 /* XXX This is not a tree. */
 struct radix_tree_node {
+       struct list_head        linkage;
        unsigned long           index;
        void                    *item;
-       struct radix_tree_node  *next;
 };
 
 struct radix_tree_root {
-       struct radix_tree_node  *rnode;
+       struct list_head        hlinks;
 };
 
-#define INIT_RADIX_TREE(root, mask) \
-do { \
-       (root)->rnode = NULL; \
-} while (0)
+static inline void INIT_RADIX_TREE(struct radix_tree_root *rp, int mask)
+{
+       INIT_LIST_HEAD(&rp->hlinks);
+}
 
 static inline int radix_tree_insert(struct radix_tree_root *root,
                                    unsigned long index, void *item)
 {
+       struct list_head *lp = root->hlinks.next;
        struct radix_tree_node *p;
 
-       for (p = root->rnode; p; p = p->next) {
+       while (lp != &root->hlinks) {
+               p = (struct radix_tree_node *)lp;
                if (p->index == index)
                        return -EEXIST;
+               lp = lp->next;
        }
+
        p = kmalloc(sizeof(*p), KMALLOC_WAIT);
        if (!p)
                return -ENOMEM;
        p->index = index;
        p->item = item;
-       p->next = root->rnode;
-       root->rnode = p;
+       list_add(&p->linkage, &root->hlinks);
        return 0;
 }
 
 static inline void *radix_tree_lookup(struct radix_tree_root *root,
                                      unsigned long index)
 {
+       struct list_head *lp = root->hlinks.next;
        struct radix_tree_node *p;
 
-       for (p = root->rnode; p; p = p->next) {
+       while (lp != &root->hlinks) {
+               p = (struct radix_tree_node *)lp;
                if (p->index == index)
                        return p->item;
+               lp = lp->next;
        }
+
        return NULL;
 }
 
-static inline void *radix_tree_delete(struct radix_tree_root *root,
+static inline void radix_tree_delete(struct radix_tree_root *root,
                                      unsigned long index)
 {
-       panic("todo");
+       struct list_head *lp = root->hlinks.next;
+       struct radix_tree_node *p;
+
+       while (lp != &root->hlinks) {
+               p = (struct radix_tree_node *)lp;
+               if (p->index == index) {
+                       list_del(lp);
+                       return;
+               }
+               lp = lp->next;
+       }
+       panic("Node not found\n");
 }
 
 #define INIT_DEFERRABLE_WORK(_work, _func) \