aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/radix-tree.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2011-05-01 13:16:30 +0100
committerJan Beulich <jbeulich@novell.com>2011-05-01 13:16:30 +0100
commitf22f2fe48d144141fffd42a380383f45efbea8e3 (patch)
tree8e0d2c4787f66363688bc649a9c19a39a41379b2 /xen/common/radix-tree.c
parent4c7909939b059cd366426acaf9988cc7c5f4c00b (diff)
downloadxen-f22f2fe48d144141fffd42a380383f45efbea8e3.tar.gz
xen-f22f2fe48d144141fffd42a380383f45efbea8e3.tar.bz2
xen-f22f2fe48d144141fffd42a380383f45efbea8e3.zip
x86: replace nr_irqs sized per-domain arrays with radix trees
It would seem possible to fold the two trees into one (making e.g. the emuirq bits stored in the upper half of the pointer), but I'm not certain that's worth it as it would make deletion of entries more cumbersome. Unless pirq-s and emuirq-s were mutually exclusive... Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/common/radix-tree.c')
-rw-r--r--xen/common/radix-tree.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/xen/common/radix-tree.c b/xen/common/radix-tree.c
index e6e213c0a0..1763fe7555 100644
--- a/xen/common/radix-tree.c
+++ b/xen/common/radix-tree.c
@@ -26,7 +26,6 @@
* o tagging code removed
* o radix_tree_insert has func parameter for dynamic data struct allocation
* o radix_tree_destroy added (including recursive helper function)
- * o __init functions must be called explicitly
* o other include files adapted to Xen
*/
@@ -35,6 +34,7 @@
#include <xen/lib.h>
#include <xen/types.h>
#include <xen/errno.h>
+#include <xen/xmalloc.h>
#include <xen/radix-tree.h>
#include <asm/cache.h>
@@ -49,6 +49,18 @@ static inline unsigned long radix_tree_maxindex(unsigned int height)
return height_to_maxindex[height];
}
+static struct radix_tree_node *_node_alloc(void *unused)
+{
+ struct radix_tree_node *node = xmalloc(struct radix_tree_node);
+
+ return node ? memset(node, 0, sizeof(*node)) : node;
+}
+
+static void _node_free(struct radix_tree_node *node)
+{
+ xfree(node);
+}
+
/*
* Extend a radix tree so it can store key @index.
*/
@@ -100,6 +112,9 @@ int radix_tree_insert(struct radix_tree_root *root, unsigned long index,
int offset;
int error;
+ if (!node_alloc)
+ node_alloc = _node_alloc;
+
/* Make sure the tree is high enough. */
if (index > radix_tree_maxindex(root->height)) {
error = radix_tree_extend(root, index, node_alloc, arg);
@@ -336,6 +351,9 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index,
unsigned int height, shift;
int offset;
+ if (!node_free)
+ node_free = _node_free;
+
height = root->height;
if (index > radix_tree_maxindex(height))
goto out;
@@ -420,6 +438,8 @@ void radix_tree_destroy(struct radix_tree_root *root,
if (root->height == 0)
slot_free(root->rnode);
else {
+ if (!node_free)
+ node_free = _node_free;
radix_tree_node_destroy(root->rnode, root->height,
slot_free, node_free);
node_free(root->rnode);
@@ -440,10 +460,14 @@ static unsigned long __init __maxindex(unsigned int height)
return index;
}
-void __init radix_tree_init(void)
+static int __init radix_tree_init(void)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(height_to_maxindex); i++)
height_to_maxindex[i] = __maxindex(i);
+
+ return 0;
}
+/* pre-SMP just so it runs before 'normal' initcalls */
+presmp_initcall(radix_tree_init);