Commit aaca49642b92c8a57d3ca5029a5a94019c7af69f

Authored by Jeremy Fitzhardinge
1 parent 76be97c1fc

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>

Showing 1 changed file with 15 additions and 4 deletions Side-by-side Diff

drivers/xen/events.c
... ... @@ -112,6 +112,7 @@
112 112 #define VALID_EVTCHN(chn) ((chn) != 0)
113 113  
114 114 static struct irq_chip xen_dynamic_chip;
  115 +static struct irq_chip xen_percpu_chip;
115 116  
116 117 /* Constructor for packed IRQ information. */
117 118 static struct irq_info mk_unbound_info(void)
... ... @@ -403,8 +404,8 @@
403 404 if (irq < 0)
404 405 goto out;
405 406  
406   - set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
407   - handle_level_irq, "ipi");
  407 + set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
  408 + handle_percpu_irq, "ipi");
408 409  
409 410 bind_ipi.vcpu = cpu;
410 411 if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
... ... @@ -444,8 +445,8 @@
444 445  
445 446 irq = find_unbound_irq();
446 447  
447   - set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
448   - handle_level_irq, "virq");
  448 + set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
  449 + handle_percpu_irq, "virq");
449 450  
450 451 evtchn_to_irq[evtchn] = irq;
451 452 irq_info[irq] = mk_virq_info(evtchn, virq);
... ... @@ -962,6 +963,16 @@
962 963 .ack = ack_dynirq,
963 964 .set_affinity = set_affinity_irq,
964 965 .retrigger = retrigger_dynirq,
  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,
965 976 };
966 977  
967 978 int xen_set_callback_via(uint64_t via)