Makes IRQ allocation for new devices thread-safe.
Signed-off-by: Sasha Levin <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html