diff mbox

[1/3] kvm tools: Introduce IRQ registry

Message ID 1304681052-30992-1-git-send-email-levinsasha928@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sasha Levin May 6, 2011, 11:24 a.m. UTC
Instead of having static definitions of devices, Use a
dynamic registry of pci devices.

The structure is a rbtree which holds device types (net,
blk, etc). Each device entry holds a list of IRQ lines
associated with that device (pin).

Devices dynamically register upon initialization, and receive
a set of: device id, irq pin and irq line.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/Makefile               |    2 +
 tools/kvm/include/kvm/irq.h      |   24 +++++++++
 tools/kvm/include/linux/module.h |    6 ++
 tools/kvm/irq.c                  |  107 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 139 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/include/kvm/irq.h
 create mode 100644 tools/kvm/include/linux/module.h
 create mode 100644 tools/kvm/irq.c

Comments

Pekka Enberg May 7, 2011, 9:13 a.m. UTC | #1
On Fri, 6 May 2011, Sasha Levin wrote:
> +int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line)
> +{
> +	struct pci_dev *node;
> +
> +	node = search(&pci_tree, dev);
> +
> +	if (!node) {
> +		/* We haven't found a node - First device of it's kind */
> +		node = malloc(sizeof(*node));
> +		if (node == NULL)
> +			return -1;
> +

This is never free'd:

   # KVM session ended normally.
==29360==
==29360== HEAP SUMMARY:
==29360==     in use at exit: 1,008 bytes in 8 blocks
==29360==   total heap usage: 23 allocs, 15 frees, 33,565,229 bytes 
allocated
==29360==
==29360== 24 bytes in 1 blocks are possibly lost in loss record 2 of 7
==29360==    at 0x4C275D8: malloc (vg_replace_malloc.c:236)
==29360==    by 0x40849F: irq__register_device (irq.c:87)
==29360==    by 0x404E4A: virtio_blk__init (blk.c:298)
==29360==    by 0x40766E: kvm_cmd_run (kvm-run.c:388)
==29360==    by 0x404636: main (main.c:16)
==29360==
==29360== 576 bytes in 2 blocks are possibly lost in loss record 7 of 7
==29360==    at 0x4C268FC: calloc (vg_replace_malloc.c:467)
==29360==    by 0x4012455: _dl_allocate_tls (dl-tls.c:300)
==29360==    by 0x503D728: pthread_create@@GLIBC_2.2.5 
(allocatestack.c:561)
==29360==    by 0x4082A1: thread_pool__init (threadpool.c:121)
==29360==    by 0x407827: kvm_cmd_run (kvm-run.c:447)
==29360==    by 0x404636: main (main.c:16)
==29360==
==29360== LEAK SUMMARY:
==29360==    definitely lost: 0 bytes in 0 blocks
==29360==    indirectly lost: 0 bytes in 0 blocks
==29360==      possibly lost: 600 bytes in 3 blocks
==29360==    still reachable: 408 bytes in 5 blocks
==29360==         suppressed: 0 bytes in 0 blocks
==29360== Reachable blocks (those to which a pointer was found) are not 
shown.
==29360== To see them, rerun with: --leak-check=full --show-reachable=yes
==29360==
==29360== For counts of detected and suppressed errors, rerun with: -v
==29360== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)

While it's not an error per se, I'd really like to keep things clean when 
running under valgrind.

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

Patch

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 89c7e3d..fb839fc 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -39,6 +39,8 @@  OBJS    += kvm-run.o
 OBJS    += qcow.o
 OBJS    += mptable.o
 OBJS    += threadpool.o
+OBJS    += irq.o
+OBJS    += ../../lib/rbtree.o
 
 DEPS	:= $(patsubst %.o,%.d,$(OBJS))
 
diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h
new file mode 100644
index 0000000..7a75a0c
--- /dev/null
+++ b/tools/kvm/include/kvm/irq.h
@@ -0,0 +1,24 @@ 
+#ifndef KVM__IRQ_H
+#define KVM__IRQ_H
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+
+struct irq_line {
+	u8			line;
+	struct list_head	node;
+};
+
+struct pci_dev {
+	struct rb_node		node;
+	u32			id;
+	u8			pin;
+	struct list_head	lines;
+};
+
+int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line);
+
+struct rb_node *irq__get_pci_tree(void);
+
+#endif
diff --git a/tools/kvm/include/linux/module.h b/tools/kvm/include/linux/module.h
new file mode 100644
index 0000000..0e4c6a3
--- /dev/null
+++ b/tools/kvm/include/linux/module.h
@@ -0,0 +1,6 @@ 
+#ifndef KVM__LINUX_MODULE_H
+#define KVM__LINUX_MODULE_H
+
+#define EXPORT_SYMBOL(name)
+
+#endif
diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c
new file mode 100644
index 0000000..4f4305f
--- /dev/null
+++ b/tools/kvm/irq.c
@@ -0,0 +1,107 @@ 
+#include "kvm/irq.h"
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+
+static u8		next_pin	= 1;
+static u8		next_line	= 3;
+static u8		next_dev	= 1;
+static struct rb_root	pci_tree	= RB_ROOT;
+
+static struct pci_dev *search(struct rb_root *root, u32 id)
+{
+	struct rb_node *node = root->rb_node;
+
+	while (node) {
+		struct pci_dev *data = container_of(node, struct pci_dev, node);
+		int result;
+
+		result = id - data->id;
+
+		if (result < 0)
+			node = node->rb_left;
+		else if (result > 0)
+			node = node->rb_right;
+		else
+			return data;
+	}
+	return NULL;
+}
+
+static int insert(struct rb_root *root, struct pci_dev *data)
+{
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+
+	/* Figure out where to put new node */
+	while (*new) {
+		struct pci_dev *this	= container_of(*new, struct pci_dev, node);
+		int result		= data->id - this->id;
+
+		parent = *new;
+		if (result < 0)
+			new = &((*new)->rb_left);
+		else if (result > 0)
+			new = &((*new)->rb_right);
+		else
+			return 0;
+	}
+
+	/* Add new node and rebalance tree. */
+	rb_link_node(&data->node, parent, new);
+	rb_insert_color(&data->node, root);
+
+	return 1;
+}
+
+int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line)
+{
+	struct pci_dev *node;
+
+	node = search(&pci_tree, dev);
+
+	if (!node) {
+		/* We haven't found a node - First device of it's kind */
+		node = malloc(sizeof(*node));
+		if (node == NULL)
+			return -1;
+
+		*node = (struct pci_dev) {
+			.id	= dev,
+			.pin	= next_pin++,
+		};
+
+		INIT_LIST_HEAD(&node->lines);
+
+		if (insert(&pci_tree, node) != 1) {
+			free(node);
+			return -1;
+		}
+	}
+
+	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;
+
+		new->line	= next_line++;
+		*line		= new->line;
+		*pin		= node->pin;
+		*num		= next_dev++;
+
+		list_add(&new->node, &node->lines);
+
+		return 0;
+	}
+
+	return -1;
+}
+
+struct rb_node *irq__get_pci_tree(void)
+{
+	return rb_first(&pci_tree);
+}