diff options
author | Jan Beulich <jbeulich@novell.com> | 2011-06-23 11:32:43 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@novell.com> | 2011-06-23 11:32:43 +0100 |
commit | c24536b636f23e4d3202968fcad129d979881e2c (patch) | |
tree | e3e188d484b371f8770714bc0453f6395d6da241 /xen/common/domain.c | |
parent | eebfd58f212c5fb75e602ac1aa126863452375da (diff) | |
download | xen-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.c | 43 |
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; |