diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2011-03-10 11:08:15 -0500 |
---|---|---|
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) |
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 7c3668960c75..3566c00e1e3d 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -406,7 +406,7 @@ static void xen_irq_init(unsigned irq) | |||
406 | list_add_tail(&info->list, &xen_irq_list_head); | 406 | list_add_tail(&info->list, &xen_irq_list_head); |
407 | } | 407 | } |
408 | 408 | ||
409 | static int xen_allocate_irq_dynamic(void) | 409 | static int __must_check xen_allocate_irq_dynamic(void) |
410 | { | 410 | { |
411 | int first = 0; | 411 | int first = 0; |
412 | int irq; | 412 | int irq; |
@@ -425,15 +425,12 @@ static int xen_allocate_irq_dynamic(void) | |||
425 | 425 | ||
426 | irq = irq_alloc_desc_from(first, -1); | 426 | irq = irq_alloc_desc_from(first, -1); |
427 | 427 | ||
428 | if (irq < 0) | ||
429 | panic("No available IRQ to bind to: increase nr_irqs!\n"); | ||
430 | |||
431 | xen_irq_init(irq); | 428 | xen_irq_init(irq); |
432 | 429 | ||
433 | return irq; | 430 | return irq; |
434 | } | 431 | } |
435 | 432 | ||
436 | static int xen_allocate_irq_gsi(unsigned gsi) | 433 | static int __must_check xen_allocate_irq_gsi(unsigned gsi) |
437 | { | 434 | { |
438 | int irq; | 435 | int irq; |
439 | 436 | ||
@@ -452,9 +449,6 @@ static int xen_allocate_irq_gsi(unsigned gsi) | |||
452 | else | 449 | else |
453 | irq = irq_alloc_desc_at(gsi, -1); | 450 | irq = irq_alloc_desc_at(gsi, -1); |
454 | 451 | ||
455 | if (irq < 0) | ||
456 | panic("Unable to allocate to IRQ%d (%d)\n", gsi, irq); | ||
457 | |||
458 | xen_irq_init(irq); | 452 | xen_irq_init(irq); |
459 | 453 | ||
460 | return irq; | 454 | return irq; |
@@ -640,6 +634,8 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi, | |||
640 | } | 634 | } |
641 | 635 | ||
642 | irq = xen_allocate_irq_gsi(gsi); | 636 | irq = xen_allocate_irq_gsi(gsi); |
637 | if (irq < 0) | ||
638 | goto out; | ||
643 | 639 | ||
644 | set_irq_chip_and_handler_name(irq, &xen_pirq_chip, | 640 | set_irq_chip_and_handler_name(irq, &xen_pirq_chip, |
645 | handle_level_irq, name); | 641 | handle_level_irq, name); |
@@ -771,6 +767,8 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
771 | 767 | ||
772 | if (irq == -1) { | 768 | if (irq == -1) { |
773 | irq = xen_allocate_irq_dynamic(); | 769 | irq = xen_allocate_irq_dynamic(); |
770 | if (irq == -1) | ||
771 | goto out; | ||
774 | 772 | ||
775 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 773 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, |
776 | handle_fasteoi_irq, "event"); | 774 | handle_fasteoi_irq, "event"); |
@@ -778,6 +776,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
778 | xen_irq_info_evtchn_init(irq, evtchn); | 776 | xen_irq_info_evtchn_init(irq, evtchn); |
779 | } | 777 | } |
780 | 778 | ||
779 | out: | ||
781 | spin_unlock(&irq_mapping_update_lock); | 780 | spin_unlock(&irq_mapping_update_lock); |
782 | 781 | ||
783 | return irq; | 782 | return irq; |
@@ -829,6 +828,8 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
829 | 828 | ||
830 | if (irq == -1) { | 829 | if (irq == -1) { |
831 | irq = xen_allocate_irq_dynamic(); | 830 | irq = xen_allocate_irq_dynamic(); |
831 | if (irq == -1) | ||
832 | goto out; | ||
832 | 833 | ||
833 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, | 834 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
834 | handle_percpu_irq, "virq"); | 835 | handle_percpu_irq, "virq"); |
@@ -845,6 +846,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
845 | bind_evtchn_to_cpu(evtchn, cpu); | 846 | bind_evtchn_to_cpu(evtchn, cpu); |
846 | } | 847 | } |
847 | 848 | ||
849 | out: | ||
848 | spin_unlock(&irq_mapping_update_lock); | 850 | spin_unlock(&irq_mapping_update_lock); |
849 | 851 | ||
850 | return irq; | 852 | return irq; |
@@ -897,6 +899,8 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, | |||
897 | int retval; | 899 | int retval; |
898 | 900 | ||
899 | irq = bind_evtchn_to_irq(evtchn); | 901 | irq = bind_evtchn_to_irq(evtchn); |
902 | if (irq < 0) | ||
903 | return irq; | ||
900 | retval = request_irq(irq, handler, irqflags, devname, dev_id); | 904 | retval = request_irq(irq, handler, irqflags, devname, dev_id); |
901 | if (retval != 0) { | 905 | if (retval != 0) { |
902 | unbind_from_irq(irq); | 906 | unbind_from_irq(irq); |
@@ -915,6 +919,8 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, | |||
915 | int retval; | 919 | int retval; |
916 | 920 | ||
917 | irq = bind_virq_to_irq(virq, cpu); | 921 | irq = bind_virq_to_irq(virq, cpu); |
922 | if (irq < 0) | ||
923 | return irq; | ||
918 | retval = request_irq(irq, handler, irqflags, devname, dev_id); | 924 | retval = request_irq(irq, handler, irqflags, devname, dev_id); |
919 | if (retval != 0) { | 925 | if (retval != 0) { |
920 | unbind_from_irq(irq); | 926 | unbind_from_irq(irq); |