Makes IRQ allocation for new devices thread-safe.

Signed-off-by: Sasha Levin <levinsasha...@gmail.com>
---
 tools/kvm/irq.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c
index 15f4702..f92123d 100644
--- a/tools/kvm/irq.c
+++ b/tools/kvm/irq.c
@@ -1,4 +1,5 @@
 #include "kvm/irq.h"
+#include "kvm/mutex.h"
 
 #include <linux/types.h>
 #include <linux/rbtree.h>
@@ -10,6 +11,7 @@
 static u8              next_line       = 3;
 static u8              next_dev        = 1;
 static struct rb_root  pci_tree        = RB_ROOT;
+static DEFINE_MUTEX(irq_lock);
 
 static struct pci_dev *search(struct rb_root *root, u32 id)
 {
@@ -58,7 +60,9 @@ static int insert(struct rb_root *root, struct pci_dev *data)
 
 int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line)
 {
-       struct pci_dev *node;
+       struct pci_dev *node = NULL;
+
+       mutex_lock(&irq_lock);
 
        node = search(&pci_tree, dev);
 
@@ -66,7 +70,7 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line)
                /* We haven't found a node - First device of it's kind */
                node = malloc(sizeof(*node));
                if (node == NULL)
-                       return -1;
+                       goto exit_fail;
 
                *node = (struct pci_dev) {
                        .id     = dev,
@@ -81,17 +85,15 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 
*line)
 
                INIT_LIST_HEAD(&node->lines);
 
-               if (insert(&pci_tree, node) != 1) {
-                       free(node);
-                       return -1;
-               }
+               if (insert(&pci_tree, node) != 1)
+                       goto exit_fail;
        }
 
        if (node) {
                /* This device already has a pin assigned, give out a new line 
and device id */
                struct irq_line *new = malloc(sizeof(*new));
                if (new == NULL)
-                       return -1;
+                       goto exit_fail;
 
                new->line       = next_line++;
                *line           = new->line;
@@ -100,9 +102,13 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 
*line)
 
                list_add(&new->node, &node->lines);
 
+               mutex_unlock(&irq_lock);
                return 0;
        }
 
+exit_fail:
+       free(node);
+       mutex_unlock(&irq_lock);
        return -1;
 }
 
-- 
1.7.5.rc3

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to