[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86, irq: No synamic memory allocation with IRQs disabled.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1224594834 -3600 # Node ID de6af72f7b5cef2902063f2898d8238ab4697a1e # Parent 3b99705155c156dca3e139c83830261cb7c07f6d x86, irq: No synamic memory allocation with IRQs disabled. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/irq.c | 55 +++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 39 insertions(+), 16 deletions(-) diff -r 3b99705155c1 -r de6af72f7b5c xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Tue Oct 21 11:44:39 2008 +0100 +++ b/xen/arch/x86/irq.c Tue Oct 21 14:13:54 2008 +0100 @@ -510,7 +510,7 @@ int pirq_guest_bind(struct vcpu *v, int { unsigned int vector; irq_desc_t *desc; - irq_guest_action_t *action; + irq_guest_action_t *action, *newaction = NULL; int rc = 0; cpumask_t cpumask = CPU_MASK_NONE; @@ -520,7 +520,10 @@ int pirq_guest_bind(struct vcpu *v, int retry: desc = domain_spin_lock_irq_desc(v->domain, irq, NULL); if ( desc == NULL ) - return -EINVAL; + { + rc = -EINVAL; + goto out; + } action = (irq_guest_action_t *)desc->action; vector = desc - irq_desc; @@ -533,18 +536,24 @@ int pirq_guest_bind(struct vcpu *v, int "Cannot bind IRQ %d to guest. In use by '%s'.\n", irq, desc->action->name); rc = -EBUSY; - goto out; + goto unlock_out; } - action = xmalloc(irq_guest_action_t); - if ( (desc->action = (struct irqaction *)action) == NULL ) + if ( newaction == NULL ) { + spin_unlock_irq(&desc->lock); + if ( (newaction = xmalloc(irq_guest_action_t)) != NULL ) + goto retry; gdprintk(XENLOG_INFO, - "Cannot bind IRQ %d to guest. Out of memory.\n", - irq); + "Cannot bind IRQ %d to guest. Out of memory.\n", + irq); rc = -ENOMEM; goto out; } + + action = newaction; + desc->action = (struct irqaction *)action; + newaction = NULL; action->nr_guests = 0; action->in_flight = 0; @@ -568,7 +577,7 @@ int pirq_guest_bind(struct vcpu *v, int "Will not share with others.\n", irq); rc = -EBUSY; - goto out; + goto unlock_out; } else if ( action->nr_guests == 0 ) { @@ -588,17 +597,21 @@ int pirq_guest_bind(struct vcpu *v, int gdprintk(XENLOG_INFO, "Cannot bind IRQ %d to guest. " "Already at max share.\n", irq); rc = -EBUSY; - goto out; + goto unlock_out; } action->guest[action->nr_guests++] = v->domain; + unlock_out: + spin_unlock_irq(&desc->lock); out: - spin_unlock_irq(&desc->lock); + if ( newaction != NULL ) + xfree(newaction); return rc; } -static void __pirq_guest_unbind(struct domain *d, int irq, irq_desc_t *desc) +static irq_guest_action_t *__pirq_guest_unbind( + struct domain *d, int irq, irq_desc_t *desc) { unsigned int vector; irq_guest_action_t *action; @@ -644,7 +657,7 @@ static void __pirq_guest_unbind(struct d BUG_ON(test_bit(irq, d->pirq_mask)); if ( action->nr_guests != 0 ) - return; + return NULL; BUG_ON(action->in_flight != 0); @@ -672,15 +685,18 @@ static void __pirq_guest_unbind(struct d BUG_ON(!cpus_empty(action->cpu_eoi_map)); desc->action = NULL; - xfree(action); desc->status &= ~IRQ_GUEST; desc->status &= ~IRQ_INPROGRESS; kill_timer(&irq_guest_eoi_timer[vector]); desc->handler->shutdown(vector); + + /* Caller frees the old guest descriptor block. */ + return action; } void pirq_guest_unbind(struct domain *d, int irq) { + irq_guest_action_t *oldaction = NULL; irq_desc_t *desc; int vector; @@ -699,16 +715,19 @@ void pirq_guest_unbind(struct domain *d, } else { - __pirq_guest_unbind(d, irq, desc); + oldaction = __pirq_guest_unbind(d, irq, desc); } spin_unlock_irq(&desc->lock); + + if ( oldaction != NULL ) + xfree(oldaction); } int pirq_guest_force_unbind(struct domain *d, int irq) { irq_desc_t *desc; - irq_guest_action_t *action; + irq_guest_action_t *action, *oldaction = NULL; int i, bound = 0; WARN_ON(!spin_is_locked(&d->event_lock)); @@ -727,10 +746,14 @@ int pirq_guest_force_unbind(struct domai goto out; bound = 1; - __pirq_guest_unbind(d, irq, desc); + oldaction = __pirq_guest_unbind(d, irq, desc); out: spin_unlock_irq(&desc->lock); + + if ( oldaction != NULL ) + xfree(oldaction); + return bound; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |