diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2011-03-10 16:08:15 +0000 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-03-10 14:48:45 -0500 |
commit | 7bee976822a78bbb278790c2cd64293568592cdb (patch) | |
tree | 85cf33e4ccf140cbf5848b515b761c69880ab7e0 /drivers/xen | |
parent | 6cb9bf3aaffcdd175574a9d66af4ad69156d0070 (diff) | |
download | linux-3.10-7bee976822a78bbb278790c2cd64293568592cdb.tar.gz linux-3.10-7bee976822a78bbb278790c2cd64293568592cdb.tar.bz2 linux-3.10-7bee976822a78bbb278790c2cd64293568592cdb.zip |
xen: events: propagate irq allocation failure instead of panicking
Running out of IRQs need not be fatal to the machine as a whole.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/events.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 7c3668960c7..3566c00e1e3 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -406,7 +406,7 @@ static void xen_irq_init(unsigned irq) list_add_tail(&info->list, &xen_irq_list_head); } -static int xen_allocate_irq_dynamic(void) +static int __must_check xen_allocate_irq_dynamic(void) { int first = 0; int irq; @@ -425,15 +425,12 @@ static int xen_allocate_irq_dynamic(void) irq = irq_alloc_desc_from(first, -1); - if (irq < 0) - panic("No available IRQ to bind to: increase nr_irqs!\n"); - xen_irq_init(irq); return irq; } -static int xen_allocate_irq_gsi(unsigned gsi) +static int __must_check xen_allocate_irq_gsi(unsigned gsi) { int irq; @@ -452,9 +449,6 @@ static int xen_allocate_irq_gsi(unsigned gsi) else irq = irq_alloc_desc_at(gsi, -1); - if (irq < 0) - panic("Unable to allocate to IRQ%d (%d)\n", gsi, irq); - xen_irq_init(irq); return irq; @@ -640,6 +634,8 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi, } irq = xen_allocate_irq_gsi(gsi); + if (irq < 0) + goto out; set_irq_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, name); @@ -771,6 +767,8 @@ int bind_evtchn_to_irq(unsigned int evtchn) if (irq == -1) { irq = xen_allocate_irq_dynamic(); + if (irq == -1) + goto out; set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, handle_fasteoi_irq, "event"); @@ -778,6 +776,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) xen_irq_info_evtchn_init(irq, evtchn); } +out: spin_unlock(&irq_mapping_update_lock); return irq; @@ -829,6 +828,8 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) if (irq == -1) { irq = xen_allocate_irq_dynamic(); + if (irq == -1) + goto out; set_irq_chip_and_handler_name(irq, &xen_percpu_chip, handle_percpu_irq, "virq"); @@ -845,6 +846,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) bind_evtchn_to_cpu(evtchn, cpu); } +out: spin_unlock(&irq_mapping_update_lock); return irq; @@ -897,6 +899,8 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, int retval; irq = bind_evtchn_to_irq(evtchn); + if (irq < 0) + return irq; retval = request_irq(irq, handler, irqflags, devname, dev_id); if (retval != 0) { unbind_from_irq(irq); @@ -915,6 +919,8 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, int retval; irq = bind_virq_to_irq(virq, cpu); + if (irq < 0) + return irq; retval = request_irq(irq, handler, irqflags, devname, dev_id); if (retval != 0) { unbind_from_irq(irq); |