1 From: jbeulich@novell.com
2 Subject: fold IPIs onto a single IRQ each
3 Patch-mainline: obsolete
5 Index: head-2008-12-01/arch/x86/kernel/genapic_xen_64.c
6 ===================================================================
7 --- head-2008-12-01.orig/arch/x86/kernel/genapic_xen_64.c 2008-11-25 13:12:11.000000000 +0100
8 +++ head-2008-12-01/arch/x86/kernel/genapic_xen_64.c 2008-12-01 12:07:34.000000000 +0100
10 #include <asm/genapic.h>
11 #include <xen/evtchn.h>
13 -DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
15 static inline void __send_IPI_one(unsigned int cpu, int vector)
17 - int irq = per_cpu(ipi_to_irq, cpu)[vector];
19 - notify_remote_via_irq(irq);
20 + notify_remote_via_ipi(vector, cpu);
23 static void xen_send_IPI_shortcut(unsigned int shortcut,
24 Index: head-2008-12-01/arch/x86/kernel/ipi-xen.c
25 ===================================================================
26 --- head-2008-12-01.orig/arch/x86/kernel/ipi-xen.c 2008-11-25 13:12:11.000000000 +0100
27 +++ head-2008-12-01/arch/x86/kernel/ipi-xen.c 2008-12-01 12:07:34.000000000 +0100
28 @@ -48,15 +48,6 @@ static inline int __prepare_ICR2(unsigne
31 #include <xen/evtchn.h>
33 -DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
35 -static inline void __send_IPI_one(unsigned int cpu, int vector)
37 - int irq = per_cpu(ipi_to_irq, cpu)[vector];
39 - notify_remote_via_irq(irq);
43 void __send_IPI_shortcut(unsigned int shortcut, int vector)
44 @@ -90,12 +81,12 @@ void __send_IPI_shortcut(unsigned int sh
48 - __send_IPI_one(smp_processor_id(), vector);
49 + notify_remote_via_ipi(vector, smp_processor_id());
51 case APIC_DEST_ALLBUT:
52 for_each_online_cpu(cpu)
53 if (cpu != smp_processor_id())
54 - __send_IPI_one(cpu, vector);
55 + notify_remote_via_ipi(vector, cpu);
58 printk("XXXXXX __send_IPI_shortcut %08x vector %d\n", shortcut,
59 @@ -165,7 +156,7 @@ void send_IPI_mask_bitmask(const cpumask
60 WARN_ON(!cpus_empty(mask));
61 for_each_online_cpu(cpu)
62 if (cpu_isset(cpu, cpumask))
63 - __send_IPI_one(cpu, vector);
64 + notify_remote_via_ipi(vector, cpu);
66 local_irq_restore(flags);
68 Index: head-2008-12-01/arch/x86/kernel/irq_32-xen.c
69 ===================================================================
70 --- head-2008-12-01.orig/arch/x86/kernel/irq_32-xen.c 2008-12-01 11:49:07.000000000 +0100
71 +++ head-2008-12-01/arch/x86/kernel/irq_32-xen.c 2008-12-01 12:07:34.000000000 +0100
72 @@ -404,6 +404,9 @@ void fixup_irqs(cpumask_t map)
76 + if (irq_desc[irq].status & IRQ_PER_CPU)
79 cpus_and(mask, irq_desc[irq].affinity, map);
80 if (any_online_cpu(mask) == NR_CPUS) {
81 /*printk("Breaking affinity for irq %i\n", irq);*/
82 Index: head-2008-12-01/arch/x86/kernel/irq_64-xen.c
83 ===================================================================
84 --- head-2008-12-01.orig/arch/x86/kernel/irq_64-xen.c 2008-12-01 11:49:07.000000000 +0100
85 +++ head-2008-12-01/arch/x86/kernel/irq_64-xen.c 2008-12-01 12:07:34.000000000 +0100
86 @@ -245,6 +245,7 @@ void fixup_irqs(cpumask_t map)
87 spin_lock(&irq_desc[irq].lock);
89 if (!irq_has_action(irq) ||
90 + (irq_desc[irq].status & IRQ_PER_CPU) ||
91 cpus_equal(irq_desc[irq].affinity, map)) {
92 spin_unlock(&irq_desc[irq].lock);
94 Index: head-2008-12-01/drivers/xen/Kconfig
95 ===================================================================
96 --- head-2008-12-01.orig/drivers/xen/Kconfig 2008-10-24 10:52:17.000000000 +0200
97 +++ head-2008-12-01/drivers/xen/Kconfig 2008-12-01 12:07:34.000000000 +0100
102 + select IRQ_PER_CPU if SMP
105 config XEN_INTERFACE_VERSION
106 @@ -292,6 +293,9 @@ config HAVE_IRQ_IGNORE_UNHANDLED
107 config GENERIC_HARDIRQS_NO__DO_IRQ
116 Index: head-2008-12-01/drivers/xen/core/evtchn.c
117 ===================================================================
118 --- head-2008-12-01.orig/drivers/xen/core/evtchn.c 2008-12-02 09:14:14.000000000 +0100
119 +++ head-2008-12-01/drivers/xen/core/evtchn.c 2008-12-02 09:14:29.000000000 +0100
120 @@ -57,6 +57,22 @@ static DEFINE_SPINLOCK(irq_mapping_updat
121 static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
122 [0 ... NR_EVENT_CHANNELS-1] = -1 };
124 +/* IRQ <-> IPI mapping. */
128 +#if defined(CONFIG_SMP) && defined(CONFIG_X86)
129 +static int ipi_to_irq[NR_IPIS] __read_mostly = {[0 ... NR_IPIS-1] = -1};
130 +static DEFINE_PER_CPU(int[NR_IPIS], ipi_to_evtchn) = {[0 ... NR_IPIS-1] = -1};
132 +#define PER_CPU_IPI_IRQ
134 +#if !defined(CONFIG_SMP) || !defined(PER_CPU_IPI_IRQ)
135 +#define BUG_IF_IPI(irq) BUG_ON(type_from_irq(irq) == IRQT_IPI)
137 +#define BUG_IF_IPI(irq) ((void)(irq))
140 /* Packed IRQ information: binding type, sub-type index, and event channel. */
141 static u32 irq_info[NR_IRQS];
143 @@ -97,10 +113,12 @@ static inline u32 mk_irq_info(u32 type,
144 * Accessors for packed IRQ information.
147 +#ifdef PER_CPU_IPI_IRQ
148 static inline unsigned int evtchn_from_irq(int irq)
150 return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
154 static inline unsigned int index_from_irq(int irq)
156 @@ -112,14 +130,28 @@ static inline unsigned int type_from_irq
157 return irq_info[irq] >> (32 - _IRQT_BITS);
160 +#ifndef PER_CPU_IPI_IRQ
161 +static inline unsigned int evtchn_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
163 + BUG_ON(type_from_irq(irq) != IRQT_IPI);
164 + return per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)];
167 +static inline unsigned int evtchn_from_irq(unsigned int irq)
169 + if (type_from_irq(irq) != IRQT_IPI)
170 + return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
171 + return evtchn_from_per_cpu_irq(irq, smp_processor_id());
175 /* IRQ <-> VIRQ mapping. */
176 DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
178 +#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
179 /* IRQ <-> IPI mapping. */
183 DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]) = {[0 ... NR_IPIS-1] = -1};
186 /* Reference counts for bindings to IRQs. */
187 static int irq_bindcount[NR_IRQS];
188 @@ -144,8 +176,14 @@ static void bind_evtchn_to_cpu(unsigned
190 BUG_ON(!test_bit(chn, s->evtchn_mask));
193 - irq_desc[irq].affinity = cpumask_of_cpu(cpu);
195 + struct irq_desc *desc = irq_desc + irq;
197 + if (!(desc->status & IRQ_PER_CPU))
198 + desc->affinity = cpumask_of_cpu(cpu);
200 + cpu_set(cpu, desc->affinity);
203 clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
204 set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
205 @@ -439,6 +477,7 @@ static int bind_virq_to_irq(unsigned int
209 +#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
210 static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
212 struct evtchn_bind_ipi bind_ipi;
213 @@ -470,6 +509,7 @@ static int bind_ipi_to_irq(unsigned int
214 spin_unlock(&irq_mapping_update_lock);
219 static void unbind_from_irq(unsigned int irq)
221 @@ -477,6 +517,7 @@ static void unbind_from_irq(unsigned int
223 int evtchn = evtchn_from_irq(irq);
226 spin_lock(&irq_mapping_update_lock);
228 if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
229 @@ -490,10 +531,12 @@ static void unbind_from_irq(unsigned int
230 per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
231 [index_from_irq(irq)] = -1;
233 +#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
235 per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
236 [index_from_irq(irq)] = -1;
242 @@ -512,6 +555,46 @@ static void unbind_from_irq(unsigned int
243 spin_unlock(&irq_mapping_update_lock);
246 +#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
247 +void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
249 + struct evtchn_close close;
250 + int evtchn = evtchn_from_per_cpu_irq(irq, cpu);
252 + spin_lock(&irq_mapping_update_lock);
254 + if (VALID_EVTCHN(evtchn)) {
255 + struct irq_desc *desc = irq_desc + irq;
257 + mask_evtchn(evtchn);
259 + BUG_ON(irq_bindcount[irq] <= 1);
260 + irq_bindcount[irq]--;
261 + cpu_clear(cpu, desc->affinity);
263 + close.port = evtchn;
264 + if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
267 + switch (type_from_irq(irq)) {
269 + per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)] = -1;
276 + /* Closed ports are implicitly re-bound to VCPU0. */
277 + bind_evtchn_to_cpu(evtchn, 0);
279 + evtchn_to_irq[evtchn] = -1;
282 + spin_unlock(&irq_mapping_update_lock);
284 +#endif /* CONFIG_SMP && !PER_CPU_IPI_IRQ */
286 int bind_caller_port_to_irqhandler(
287 unsigned int caller_port,
288 irq_handler_t handler,
289 @@ -606,6 +689,8 @@ int bind_virq_to_irqhandler(
291 EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
294 +#ifdef PER_CPU_IPI_IRQ
295 int bind_ipi_to_irqhandler(
298 @@ -628,7 +713,72 @@ int bind_ipi_to_irqhandler(
302 -EXPORT_SYMBOL_GPL(bind_ipi_to_irqhandler);
304 +int __cpuinit bind_ipi_to_irqaction(
307 + struct irqaction *action)
309 + struct evtchn_bind_ipi bind_ipi;
310 + int evtchn, irq, retval = 0;
312 + spin_lock(&irq_mapping_update_lock);
314 + if (per_cpu(ipi_to_evtchn, cpu)[ipi] != -1) {
315 + spin_unlock(&irq_mapping_update_lock);
319 + if ((irq = ipi_to_irq[ipi]) == -1) {
320 + if ((irq = find_unbound_irq()) < 0) {
321 + spin_unlock(&irq_mapping_update_lock);
325 + /* Extra reference so count will never drop to zero. */
326 + irq_bindcount[irq]++;
328 + ipi_to_irq[ipi] = irq;
329 + irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, 0);
330 + irq_desc[irq].handle_irq = handle_percpu_irq;
334 + bind_ipi.vcpu = cpu;
335 + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
339 + evtchn = bind_ipi.port;
340 + evtchn_to_irq[evtchn] = irq;
341 + per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
343 + bind_evtchn_to_cpu(evtchn, cpu);
345 + irq_bindcount[irq]++;
347 + spin_unlock(&irq_mapping_update_lock);
350 + unsigned long flags;
352 + local_irq_save(flags);
353 + unmask_evtchn(evtchn);
354 + local_irq_restore(flags);
356 + action->flags |= IRQF_PERCPU;
357 + retval = setup_irq(irq, action);
359 + unbind_from_per_cpu_irq(irq, cpu);
360 + BUG_ON(retval > 0);
367 +#endif /* PER_CPU_IPI_IRQ */
368 +#endif /* CONFIG_SMP */
370 void unbind_from_irqhandler(unsigned int irq, void *dev_id)
372 @@ -654,6 +804,7 @@ static void rebind_irq_to_cpu(unsigned i
374 int evtchn = evtchn_from_irq(irq);
377 if (VALID_EVTCHN(evtchn))
378 rebind_evtchn_to_cpu(evtchn, tcpu);
380 @@ -737,6 +888,7 @@ static struct irq_chip dynirq_chip = {
381 .unmask = unmask_dynirq,
382 .mask_ack = ack_dynirq,
387 .set_affinity = set_affinity_irq,
388 @@ -909,10 +1061,21 @@ int irq_ignore_unhandled(unsigned int ir
389 return !!(irq_status.flags & XENIRQSTAT_shared);
392 +#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
393 +void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu)
395 + int evtchn = evtchn_from_per_cpu_irq(ipi_to_irq[ipi], cpu);
397 + if (VALID_EVTCHN(evtchn))
398 + notify_remote_via_evtchn(evtchn);
402 void notify_remote_via_irq(int irq)
404 int evtchn = evtchn_from_irq(irq);
407 if (VALID_EVTCHN(evtchn))
408 notify_remote_via_evtchn(evtchn);
410 @@ -920,6 +1083,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
412 int irq_to_evtchn_port(int irq)
415 return evtchn_from_irq(irq);
417 EXPORT_SYMBOL_GPL(irq_to_evtchn_port);
418 @@ -1035,11 +1199,16 @@ static void restore_cpu_virqs(unsigned i
420 static void restore_cpu_ipis(unsigned int cpu)
423 struct evtchn_bind_ipi bind_ipi;
424 int ipi, irq, evtchn;
426 for (ipi = 0; ipi < NR_IPIS; ipi++) {
427 +#ifdef PER_CPU_IPI_IRQ
428 if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1)
430 + if ((irq = ipi_to_irq[ipi]) == -1)
434 BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
435 @@ -1053,13 +1222,17 @@ static void restore_cpu_ipis(unsigned in
437 /* Record the new mapping. */
438 evtchn_to_irq[evtchn] = irq;
439 +#ifdef PER_CPU_IPI_IRQ
440 irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
442 + per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
444 bind_evtchn_to_cpu(evtchn, cpu);
447 unmask_evtchn(evtchn);
453 static int evtchn_resume(struct sys_device *dev)
454 @@ -1103,8 +1276,17 @@ static int evtchn_resume(struct sys_devi
456 for_each_possible_cpu(cpu) {
457 restore_cpu_virqs(cpu);
458 +#ifdef PER_CPU_IPI_IRQ
459 restore_cpu_ipis(cpu);
461 + /* No IPI <-> event-channel mappings. */
462 + for (irq = 0; irq < NR_IPIS; ++irq)
463 + per_cpu(ipi_to_evtchn, cpu)[irq] = -1;
466 +#ifndef PER_CPU_IPI_IRQ
467 + restore_cpu_ipis(smp_processor_id());
472 Index: head-2008-12-01/drivers/xen/core/smpboot.c
473 ===================================================================
474 --- head-2008-12-01.orig/drivers/xen/core/smpboot.c 2008-12-01 12:07:15.000000000 +0100
475 +++ head-2008-12-01/drivers/xen/core/smpboot.c 2008-12-01 12:07:34.000000000 +0100
476 @@ -53,12 +53,9 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
477 DEFINE_PER_CPU(int, cpu_state) = { 0 };
480 -static DEFINE_PER_CPU(int, resched_irq);
481 -static DEFINE_PER_CPU(int, callfunc_irq);
482 -static DEFINE_PER_CPU(int, call1func_irq);
483 -static char resched_name[NR_CPUS][15];
484 -static char callfunc_name[NR_CPUS][15];
485 -static char call1func_name[NR_CPUS][15];
486 +static int __read_mostly resched_irq = -1;
487 +static int __read_mostly callfunc_irq = -1;
488 +static int __read_mostly call1func_irq = -1;
490 #ifdef CONFIG_X86_LOCAL_APIC
491 #define set_cpu_to_apicid(cpu, apicid) (per_cpu(x86_cpu_to_apicid, cpu) = (apicid))
492 @@ -117,43 +114,50 @@ remove_siblinginfo(unsigned int cpu)
494 static int __cpuinit xen_smp_intr_init(unsigned int cpu)
496 + static struct irqaction resched_action = {
497 + .handler = smp_reschedule_interrupt,
498 + .flags = IRQF_DISABLED,
500 + }, callfunc_action = {
501 + .handler = smp_call_function_interrupt,
502 + .flags = IRQF_DISABLED,
504 + }, call1func_action = {
505 + .handler = smp_call_function_single_interrupt,
506 + .flags = IRQF_DISABLED,
507 + .name = "call1func"
511 - per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) =
512 - per_cpu(call1func_irq, cpu) = -1;
514 - sprintf(resched_name[cpu], "resched%u", cpu);
515 - rc = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR,
517 - smp_reschedule_interrupt,
518 - IRQF_DISABLED|IRQF_NOBALANCING,
521 + rc = bind_ipi_to_irqaction(RESCHEDULE_VECTOR,
526 - per_cpu(resched_irq, cpu) = rc;
528 - sprintf(callfunc_name[cpu], "callfunc%u", cpu);
529 - rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR,
531 - smp_call_function_interrupt,
532 - IRQF_DISABLED|IRQF_NOBALANCING,
533 - callfunc_name[cpu],
535 + if (resched_irq < 0)
538 + BUG_ON(resched_irq != rc);
540 + rc = bind_ipi_to_irqaction(CALL_FUNCTION_VECTOR,
545 - per_cpu(callfunc_irq, cpu) = rc;
547 - sprintf(call1func_name[cpu], "call1func%u", cpu);
548 - rc = bind_ipi_to_irqhandler(CALL_FUNC_SINGLE_VECTOR,
550 - smp_call_function_single_interrupt,
551 - IRQF_DISABLED|IRQF_NOBALANCING,
552 - call1func_name[cpu],
554 + if (callfunc_irq < 0)
557 + BUG_ON(callfunc_irq != rc);
559 + rc = bind_ipi_to_irqaction(CALL_FUNC_SINGLE_VECTOR,
561 + &call1func_action);
564 - per_cpu(call1func_irq, cpu) = rc;
565 + if (call1func_irq < 0)
566 + call1func_irq = rc;
568 + BUG_ON(call1func_irq != rc);
570 rc = xen_spinlock_init(cpu);
572 @@ -165,12 +169,12 @@ static int __cpuinit xen_smp_intr_init(u
576 - if (per_cpu(resched_irq, cpu) >= 0)
577 - unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
578 - if (per_cpu(callfunc_irq, cpu) >= 0)
579 - unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
580 - if (per_cpu(call1func_irq, cpu) >= 0)
581 - unbind_from_irqhandler(per_cpu(call1func_irq, cpu), NULL);
582 + if (resched_irq >= 0)
583 + unbind_from_per_cpu_irq(resched_irq, cpu);
584 + if (callfunc_irq >= 0)
585 + unbind_from_per_cpu_irq(callfunc_irq, cpu);
586 + if (call1func_irq >= 0)
587 + unbind_from_per_cpu_irq(call1func_irq, cpu);
588 xen_spinlock_cleanup(cpu);
591 @@ -181,9 +185,9 @@ static void __cpuinit xen_smp_intr_exit(
593 local_teardown_timer(cpu);
595 - unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
596 - unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
597 - unbind_from_irqhandler(per_cpu(call1func_irq, cpu), NULL);
598 + unbind_from_per_cpu_irq(resched_irq, cpu);
599 + unbind_from_per_cpu_irq(callfunc_irq, cpu);
600 + unbind_from_per_cpu_irq(call1func_irq, cpu);
601 xen_spinlock_cleanup(cpu);
604 Index: head-2008-12-01/drivers/xen/core/spinlock.c
605 ===================================================================
606 --- head-2008-12-01.orig/drivers/xen/core/spinlock.c 2008-12-01 11:51:53.000000000 +0100
607 +++ head-2008-12-01/drivers/xen/core/spinlock.c 2008-12-01 12:07:34.000000000 +0100
610 extern irqreturn_t smp_reschedule_interrupt(int, void *);
612 -static DEFINE_PER_CPU(int, spinlock_irq) = -1;
613 -static char spinlock_name[NR_CPUS][15];
614 +static int __read_mostly spinlock_irq = -1;
617 raw_spinlock_t *lock;
618 @@ -32,34 +31,37 @@ static DEFINE_PER_CPU(raw_rwlock_t, spin
620 int __cpuinit xen_spinlock_init(unsigned int cpu)
622 + static struct irqaction spinlock_action = {
623 + .handler = smp_reschedule_interrupt,
624 + .flags = IRQF_DISABLED,
629 - sprintf(spinlock_name[cpu], "spinlock%u", cpu);
630 - rc = bind_ipi_to_irqhandler(SPIN_UNLOCK_VECTOR,
632 - smp_reschedule_interrupt,
633 - IRQF_DISABLED|IRQF_NOBALANCING,
634 - spinlock_name[cpu],
636 + rc = bind_ipi_to_irqaction(SPIN_UNLOCK_VECTOR,
642 - disable_irq(rc); /* make sure it's never delivered */
643 - per_cpu(spinlock_irq, cpu) = rc;
644 + if (spinlock_irq < 0) {
645 + disable_irq(rc); /* make sure it's never delivered */
648 + BUG_ON(spinlock_irq != rc);
653 void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
655 - if (per_cpu(spinlock_irq, cpu) >= 0)
656 - unbind_from_irqhandler(per_cpu(spinlock_irq, cpu), NULL);
657 - per_cpu(spinlock_irq, cpu) = -1;
658 + if (spinlock_irq >= 0)
659 + unbind_from_per_cpu_irq(spinlock_irq, cpu);
662 int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
664 - int rc = 0, irq = __get_cpu_var(spinlock_irq);
665 + int rc = 0, irq = spinlock_irq;
666 raw_rwlock_t *rm_lock;
668 struct spinning spinning;
669 @@ -153,7 +155,7 @@ void xen_spin_kick(raw_spinlock_t *lock,
670 raw_local_irq_restore(flags);
672 if (unlikely(spinning)) {
673 - notify_remote_via_irq(per_cpu(spinlock_irq, cpu));
674 + notify_remote_via_ipi(SPIN_UNLOCK_VECTOR, cpu);
678 Index: head-2008-12-01/include/xen/evtchn.h
679 ===================================================================
680 --- head-2008-12-01.orig/include/xen/evtchn.h 2008-12-01 12:07:30.000000000 +0100
681 +++ head-2008-12-01/include/xen/evtchn.h 2008-12-01 12:07:34.000000000 +0100
682 @@ -78,6 +78,8 @@ int bind_virq_to_irqhandler(
683 unsigned long irqflags,
686 +#if defined(CONFIG_SMP) && !defined(MODULE)
688 int bind_ipi_to_irqhandler(
691 @@ -85,6 +87,13 @@ int bind_ipi_to_irqhandler(
692 unsigned long irqflags,
696 +int bind_ipi_to_irqaction(
699 + struct irqaction *action);
704 * Common unbind function for all event sources. Takes IRQ to unbind from.
705 @@ -93,6 +102,11 @@ int bind_ipi_to_irqhandler(
707 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
709 +#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
710 +/* Specialized unbind function for per-CPU IRQs. */
711 +void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu);
715 void irq_resume(void);
717 @@ -184,4 +198,8 @@ int clear_pirq_hw_action(int pirq);
721 +#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
722 +void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu);
725 #endif /* __ASM_EVTCHN_H__ */