aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/domain.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2011-06-23 11:32:43 +0100
committerJan Beulich <jbeulich@novell.com>2011-06-23 11:32:43 +0100
commitc24536b636f23e4d3202968fcad129d979881e2c (patch)
treee3e188d484b371f8770714bc0453f6395d6da241 /xen/common/domain.c
parenteebfd58f212c5fb75e602ac1aa126863452375da (diff)
downloadxen-c24536b636f23e4d3202968fcad129d979881e2c.tar.gz
xen-c24536b636f23e4d3202968fcad129d979881e2c.tar.bz2
xen-c24536b636f23e4d3202968fcad129d979881e2c.zip
replace d->nr_pirqs sized arrays with radix tree
With this it is questionable whether retaining struct domain's nr_pirqs is actually necessary - the value now only serves for bounds checking, and this boundary could easily be nr_irqs. Note that ia64, the build of which is broken currently anyway, is only being partially fixed up. v2: adjustments for split setup/teardown of translation data v3: re-sync with radix tree implementation changes Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/common/domain.c')
-rw-r--r--xen/common/domain.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 5323c83bae..793990e7b6 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -293,13 +293,7 @@ struct domain *domain_create(
if ( d->nr_pirqs > nr_irqs )
d->nr_pirqs = nr_irqs;
- d->pirq_to_evtchn = xmalloc_array(u16, d->nr_pirqs);
- d->pirq_mask = xmalloc_array(
- unsigned long, BITS_TO_LONGS(d->nr_pirqs));
- if ( (d->pirq_to_evtchn == NULL) || (d->pirq_mask == NULL) )
- goto fail;
- memset(d->pirq_to_evtchn, 0, d->nr_pirqs * sizeof(*d->pirq_to_evtchn));
- bitmap_zero(d->pirq_mask, d->nr_pirqs);
+ radix_tree_init(&d->pirq_tree);
if ( evtchn_init(d) != 0 )
goto fail;
@@ -349,6 +343,7 @@ struct domain *domain_create(
{
evtchn_destroy(d);
evtchn_destroy_final(d);
+ radix_tree_destroy(&d->pirq_tree, free_pirq_struct);
}
if ( init_status & INIT_rangeset )
rangeset_domain_destroy(d);
@@ -356,8 +351,6 @@ struct domain *domain_create(
watchdog_domain_destroy(d);
if ( init_status & INIT_xsm )
xsm_free_security_domain(d);
- xfree(d->pirq_mask);
- xfree(d->pirq_to_evtchn);
free_cpumask_var(d->domain_dirty_cpumask);
free_domain_struct(d);
return NULL;
@@ -683,8 +676,7 @@ static void complete_domain_destroy(struct rcu_head *head)
evtchn_destroy_final(d);
- xfree(d->pirq_mask);
- xfree(d->pirq_to_evtchn);
+ radix_tree_destroy(&d->pirq_tree, free_pirq_struct);
xsm_free_security_domain(d);
free_cpumask_var(d->domain_dirty_cpumask);
@@ -966,6 +958,35 @@ long vm_assist(struct domain *p, unsigned int cmd, unsigned int type)
return -ENOSYS;
}
+struct pirq *pirq_get_info(struct domain *d, int pirq)
+{
+ struct pirq *info = pirq_info(d, pirq);
+
+ if ( !info && (info = alloc_pirq_struct(d)) != NULL )
+ {
+ info->pirq = pirq;
+ if ( radix_tree_insert(&d->pirq_tree, pirq, info) )
+ {
+ free_pirq_struct(info);
+ info = NULL;
+ }
+ }
+
+ return info;
+}
+
+static void _free_pirq_struct(struct rcu_head *head)
+{
+ xfree(container_of(head, struct pirq, rcu_head));
+}
+
+void free_pirq_struct(void *ptr)
+{
+ struct pirq *pirq = ptr;
+
+ call_rcu(&pirq->rcu_head, _free_pirq_struct);
+}
+
struct migrate_info {
long (*func)(void *data);
void *data;