diff options
author | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2010-08-20 21:57:53 -0400 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2010-08-24 14:13:28 -0400 |
commit | aaca49642b92c8a57d3ca5029a5a94019c7af69f (patch) | |
tree | a86a88c11addd689a2903d21f1bb948f461c1a1d /drivers/xen | |
parent | 76be97c1fc945db08aae1f1b746012662d643e97 (diff) |
xen: use percpu interrupts for IPIs and VIRQs
IPIs and VIRQs are inherently per-cpu event types, so treat them as such:
- use a specific percpu irq_chip implementation, and
- handle them with handle_percpu_irq
This makes the path for delivering these interrupts more efficient
(no masking/unmasking, no locks), and it avoid problems with attempts
to migrate them.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: Stable Kernel <stable@kernel.org>
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/events.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 72f91bff29c7..0923ccb26121 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -112,6 +112,7 @@ static inline unsigned long *cpu_evtchn_mask(int cpu) | |||
112 | #define VALID_EVTCHN(chn) ((chn) != 0) | 112 | #define VALID_EVTCHN(chn) ((chn) != 0) |
113 | 113 | ||
114 | static struct irq_chip xen_dynamic_chip; | 114 | static struct irq_chip xen_dynamic_chip; |
115 | static struct irq_chip xen_percpu_chip; | ||
115 | 116 | ||
116 | /* Constructor for packed IRQ information. */ | 117 | /* Constructor for packed IRQ information. */ |
117 | static struct irq_info mk_unbound_info(void) | 118 | static struct irq_info mk_unbound_info(void) |
@@ -403,8 +404,8 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) | |||
403 | if (irq < 0) | 404 | if (irq < 0) |
404 | goto out; | 405 | goto out; |
405 | 406 | ||
406 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 407 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
407 | handle_level_irq, "ipi"); | 408 | handle_percpu_irq, "ipi"); |
408 | 409 | ||
409 | bind_ipi.vcpu = cpu; | 410 | bind_ipi.vcpu = cpu; |
410 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, | 411 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, |
@@ -444,8 +445,8 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
444 | 445 | ||
445 | irq = find_unbound_irq(); | 446 | irq = find_unbound_irq(); |
446 | 447 | ||
447 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 448 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
448 | handle_level_irq, "virq"); | 449 | handle_percpu_irq, "virq"); |
449 | 450 | ||
450 | evtchn_to_irq[evtchn] = irq; | 451 | evtchn_to_irq[evtchn] = irq; |
451 | irq_info[irq] = mk_virq_info(evtchn, virq); | 452 | irq_info[irq] = mk_virq_info(evtchn, virq); |
@@ -964,6 +965,16 @@ static struct irq_chip xen_dynamic_chip __read_mostly = { | |||
964 | .retrigger = retrigger_dynirq, | 965 | .retrigger = retrigger_dynirq, |
965 | }; | 966 | }; |
966 | 967 | ||
968 | static struct irq_chip xen_percpu_chip __read_mostly = { | ||
969 | .name = "xen-percpu", | ||
970 | |||
971 | .disable = disable_dynirq, | ||
972 | .mask = disable_dynirq, | ||
973 | .unmask = enable_dynirq, | ||
974 | |||
975 | .ack = ack_dynirq, | ||
976 | }; | ||
977 | |||
967 | int xen_set_callback_via(uint64_t via) | 978 | int xen_set_callback_via(uint64_t via) |
968 | { | 979 | { |
969 | struct xen_hvm_param a; | 980 | struct xen_hvm_param a; |