1 From: jbeulich@novell.com
2 Subject: fold IPIs onto a single IRQ each
3 Patch-mainline: obsolete
5 --- sle11-2009-06-04.orig/arch/x86/kernel/genapic_xen_64.c 2009-06-04 10:46:34.000000000 +0200
6 +++ sle11-2009-06-04/arch/x86/kernel/genapic_xen_64.c 2009-06-04 10:47:21.000000000 +0200
8 #include <asm/genapic.h>
9 #include <xen/evtchn.h>
11 -DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
13 static inline void __send_IPI_one(unsigned int cpu, int vector)
15 - int irq = per_cpu(ipi_to_irq, cpu)[vector];
17 - notify_remote_via_irq(irq);
19 + notify_remote_via_ipi(vector, cpu);
25 static void xen_send_IPI_shortcut(unsigned int shortcut,
26 --- sle11-2009-06-04.orig/arch/x86/kernel/ipi-xen.c 2009-06-04 10:46:34.000000000 +0200
27 +++ sle11-2009-06-04/arch/x86/kernel/ipi-xen.c 2009-06-04 10:47:21.000000000 +0200
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_subset(*cpumask, cpu_online_map));
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 --- sle11-2009-06-04.orig/arch/x86/kernel/irq_32-xen.c 2009-06-04 10:21:39.000000000 +0200
69 +++ sle11-2009-06-04/arch/x86/kernel/irq_32-xen.c 2009-06-04 10:47:21.000000000 +0200
70 @@ -404,6 +404,9 @@ void fixup_irqs(cpumask_t map)
74 + if (irq_desc[irq].status & IRQ_PER_CPU)
77 cpus_and(mask, irq_desc[irq].affinity, map);
78 if (any_online_cpu(mask) == NR_CPUS) {
79 /*printk("Breaking affinity for irq %i\n", irq);*/
80 --- sle11-2009-06-04.orig/arch/x86/kernel/irq_64-xen.c 2009-06-04 10:21:39.000000000 +0200
81 +++ sle11-2009-06-04/arch/x86/kernel/irq_64-xen.c 2009-06-04 10:47:21.000000000 +0200
82 @@ -245,6 +245,7 @@ void fixup_irqs(cpumask_t map)
83 spin_lock(&irq_desc[irq].lock);
85 if (!irq_has_action(irq) ||
86 + (irq_desc[irq].status & IRQ_PER_CPU) ||
87 cpus_equal(irq_desc[irq].affinity, map)) {
88 spin_unlock(&irq_desc[irq].lock);
90 --- sle11-2009-06-04.orig/drivers/xen/Kconfig 2009-06-04 10:47:17.000000000 +0200
91 +++ sle11-2009-06-04/drivers/xen/Kconfig 2009-06-04 10:47:21.000000000 +0200
96 + select IRQ_PER_CPU if SMP
99 config XEN_INTERFACE_VERSION
100 @@ -292,6 +293,9 @@ config HAVE_IRQ_IGNORE_UNHANDLED
101 config GENERIC_HARDIRQS_NO__DO_IRQ
110 --- sle11-2009-06-04.orig/drivers/xen/core/evtchn.c 2009-06-04 10:47:20.000000000 +0200
111 +++ sle11-2009-06-04/drivers/xen/core/evtchn.c 2009-06-04 10:47:21.000000000 +0200
112 @@ -58,6 +58,22 @@ static DEFINE_SPINLOCK(irq_mapping_updat
113 static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
114 [0 ... NR_EVENT_CHANNELS-1] = -1 };
116 +/* IRQ <-> IPI mapping. */
120 +#if defined(CONFIG_SMP) && defined(CONFIG_X86)
121 +static int ipi_to_irq[NR_IPIS] __read_mostly = {[0 ... NR_IPIS-1] = -1};
122 +static DEFINE_PER_CPU(int[NR_IPIS], ipi_to_evtchn);
124 +#define PER_CPU_IPI_IRQ
126 +#if !defined(CONFIG_SMP) || !defined(PER_CPU_IPI_IRQ)
127 +#define BUG_IF_IPI(irq) BUG_ON(type_from_irq(irq) == IRQT_IPI)
129 +#define BUG_IF_IPI(irq) ((void)(irq))
132 /* Packed IRQ information: binding type, sub-type index, and event channel. */
133 static u32 irq_info[NR_IRQS];
135 @@ -98,10 +114,12 @@ static inline u32 mk_irq_info(u32 type,
136 * Accessors for packed IRQ information.
139 +#ifdef PER_CPU_IPI_IRQ
140 static inline unsigned int evtchn_from_irq(int irq)
142 return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
146 static inline unsigned int index_from_irq(int irq)
148 @@ -113,14 +131,28 @@ static inline unsigned int type_from_irq
149 return irq_info[irq] >> (32 - _IRQT_BITS);
152 +#ifndef PER_CPU_IPI_IRQ
153 +static inline unsigned int evtchn_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
155 + BUG_ON(type_from_irq(irq) != IRQT_IPI);
156 + return per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)];
159 +static inline unsigned int evtchn_from_irq(unsigned int irq)
161 + if (type_from_irq(irq) != IRQT_IPI)
162 + return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
163 + return evtchn_from_per_cpu_irq(irq, smp_processor_id());
167 /* IRQ <-> VIRQ mapping. */
168 DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
170 +#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
171 /* IRQ <-> IPI mapping. */
175 DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]) = {[0 ... NR_IPIS-1] = -1};
178 /* Reference counts for bindings to IRQs. */
179 static int irq_bindcount[NR_IRQS];
180 @@ -145,8 +177,14 @@ static void bind_evtchn_to_cpu(unsigned
182 BUG_ON(!test_bit(chn, s->evtchn_mask));
185 - irq_desc[irq].affinity = cpumask_of_cpu(cpu);
187 + struct irq_desc *desc = irq_desc + irq;
189 + if (!(desc->status & IRQ_PER_CPU))
190 + desc->affinity = cpumask_of_cpu(cpu);
192 + cpu_set(cpu, desc->affinity);
195 clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
196 set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
197 @@ -315,14 +353,29 @@ asmlinkage void evtchn_do_upcall(struct
201 -static int find_unbound_irq(void)
202 +static struct irq_chip dynirq_chip;
204 +static int find_unbound_irq(bool percpu)
209 for (irq = DYNIRQ_BASE; irq < (DYNIRQ_BASE + NR_DYNIRQS); irq++)
210 - if (irq_bindcount[irq] == 0)
211 + if (irq_bindcount[irq] == 0) {
212 + irq_flow_handler_t handle;
216 + handle = handle_level_irq;
219 + handle = handle_percpu_irq;
222 + set_irq_chip_and_handler_name(irq, &dynirq_chip,
229 @@ -340,7 +393,7 @@ static int bind_caller_port_to_irq(unsig
230 spin_lock(&irq_mapping_update_lock);
232 if ((irq = evtchn_to_irq[caller_port]) == -1) {
233 - if ((irq = find_unbound_irq()) < 0)
234 + if ((irq = find_unbound_irq(false)) < 0)
237 evtchn_to_irq[caller_port] = irq;
238 @@ -362,7 +415,7 @@ static int bind_local_port_to_irq(unsign
240 BUG_ON(evtchn_to_irq[local_port] != -1);
242 - if ((irq = find_unbound_irq()) < 0) {
243 + if ((irq = find_unbound_irq(false)) < 0) {
244 struct evtchn_close close = { .port = local_port };
245 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
247 @@ -415,7 +468,7 @@ static int bind_virq_to_irq(unsigned int
248 spin_lock(&irq_mapping_update_lock);
250 if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
251 - if ((irq = find_unbound_irq()) < 0)
252 + if ((irq = find_unbound_irq(false)) < 0)
255 bind_virq.virq = virq;
256 @@ -440,6 +493,7 @@ static int bind_virq_to_irq(unsigned int
260 +#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
261 static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
263 struct evtchn_bind_ipi bind_ipi;
264 @@ -448,7 +502,7 @@ static int bind_ipi_to_irq(unsigned int
265 spin_lock(&irq_mapping_update_lock);
267 if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
268 - if ((irq = find_unbound_irq()) < 0)
269 + if ((irq = find_unbound_irq(false)) < 0)
273 @@ -471,6 +525,7 @@ static int bind_ipi_to_irq(unsigned int
274 spin_unlock(&irq_mapping_update_lock);
279 static void unbind_from_irq(unsigned int irq)
281 @@ -478,6 +533,7 @@ static void unbind_from_irq(unsigned int
283 int evtchn = evtchn_from_irq(irq);
286 spin_lock(&irq_mapping_update_lock);
288 if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
289 @@ -491,10 +547,12 @@ static void unbind_from_irq(unsigned int
290 per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
291 [index_from_irq(irq)] = -1;
293 +#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
295 per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
296 [index_from_irq(irq)] = -1;
302 @@ -513,6 +571,46 @@ static void unbind_from_irq(unsigned int
303 spin_unlock(&irq_mapping_update_lock);
306 +#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
307 +void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
309 + struct evtchn_close close;
310 + int evtchn = evtchn_from_per_cpu_irq(irq, cpu);
312 + spin_lock(&irq_mapping_update_lock);
314 + if (VALID_EVTCHN(evtchn)) {
315 + struct irq_desc *desc = irq_desc + irq;
317 + mask_evtchn(evtchn);
319 + BUG_ON(irq_bindcount[irq] <= 1);
320 + irq_bindcount[irq]--;
321 + cpu_clear(cpu, desc->affinity);
323 + close.port = evtchn;
324 + if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
327 + switch (type_from_irq(irq)) {
329 + per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)] = 0;
336 + /* Closed ports are implicitly re-bound to VCPU0. */
337 + bind_evtchn_to_cpu(evtchn, 0);
339 + evtchn_to_irq[evtchn] = -1;
342 + spin_unlock(&irq_mapping_update_lock);
344 +#endif /* CONFIG_SMP && !PER_CPU_IPI_IRQ */
346 int bind_caller_port_to_irqhandler(
347 unsigned int caller_port,
348 irq_handler_t handler,
349 @@ -607,6 +705,8 @@ int bind_virq_to_irqhandler(
351 EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
354 +#ifdef PER_CPU_IPI_IRQ
355 int bind_ipi_to_irqhandler(
358 @@ -629,7 +729,71 @@ int bind_ipi_to_irqhandler(
362 -EXPORT_SYMBOL_GPL(bind_ipi_to_irqhandler);
364 +int __cpuinit bind_ipi_to_irqaction(
367 + struct irqaction *action)
369 + struct evtchn_bind_ipi bind_ipi;
370 + int evtchn, irq, retval = 0;
372 + spin_lock(&irq_mapping_update_lock);
374 + if (VALID_EVTCHN(per_cpu(ipi_to_evtchn, cpu)[ipi])) {
375 + spin_unlock(&irq_mapping_update_lock);
379 + if ((irq = ipi_to_irq[ipi]) == -1) {
380 + if ((irq = find_unbound_irq(true)) < 0) {
381 + spin_unlock(&irq_mapping_update_lock);
385 + /* Extra reference so count will never drop to zero. */
386 + irq_bindcount[irq]++;
388 + ipi_to_irq[ipi] = irq;
389 + irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, 0);
393 + bind_ipi.vcpu = cpu;
394 + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
398 + evtchn = bind_ipi.port;
399 + evtchn_to_irq[evtchn] = irq;
400 + per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
402 + bind_evtchn_to_cpu(evtchn, cpu);
404 + irq_bindcount[irq]++;
406 + spin_unlock(&irq_mapping_update_lock);
409 + unsigned long flags;
411 + local_irq_save(flags);
412 + unmask_evtchn(evtchn);
413 + local_irq_restore(flags);
415 + action->flags |= IRQF_PERCPU;
416 + retval = setup_irq(irq, action);
418 + unbind_from_per_cpu_irq(irq, cpu);
419 + BUG_ON(retval > 0);
426 +#endif /* PER_CPU_IPI_IRQ */
427 +#endif /* CONFIG_SMP */
429 void unbind_from_irqhandler(unsigned int irq, void *dev_id)
431 @@ -655,6 +819,7 @@ static void rebind_irq_to_cpu(unsigned i
433 int evtchn = evtchn_from_irq(irq);
436 if (VALID_EVTCHN(evtchn))
437 rebind_evtchn_to_cpu(evtchn, tcpu);
439 @@ -739,6 +904,7 @@ static struct irq_chip dynirq_chip = {
440 .unmask = unmask_dynirq,
441 .mask_ack = ack_dynirq,
446 .set_affinity = set_affinity_irq,
447 @@ -918,10 +1084,21 @@ int irq_ignore_unhandled(unsigned int ir
448 return !!(irq_status.flags & XENIRQSTAT_shared);
451 +#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
452 +void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu)
454 + int evtchn = evtchn_from_per_cpu_irq(ipi_to_irq[ipi], cpu);
456 + if (VALID_EVTCHN(evtchn))
457 + notify_remote_via_evtchn(evtchn);
461 void notify_remote_via_irq(int irq)
463 int evtchn = evtchn_from_irq(irq);
466 if (VALID_EVTCHN(evtchn))
467 notify_remote_via_evtchn(evtchn);
469 @@ -929,6 +1106,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
471 int irq_to_evtchn_port(int irq)
474 return evtchn_from_irq(irq);
476 EXPORT_SYMBOL_GPL(irq_to_evtchn_port);
477 @@ -1044,11 +1222,17 @@ static void restore_cpu_virqs(unsigned i
479 static void restore_cpu_ipis(unsigned int cpu)
482 struct evtchn_bind_ipi bind_ipi;
483 int ipi, irq, evtchn;
485 for (ipi = 0; ipi < NR_IPIS; ipi++) {
486 +#ifdef PER_CPU_IPI_IRQ
487 if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1)
489 + if ((irq = ipi_to_irq[ipi]) == -1
490 + || !VALID_EVTCHN(per_cpu(ipi_to_evtchn, cpu)[ipi]))
494 BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
495 @@ -1062,13 +1246,18 @@ static void restore_cpu_ipis(unsigned in
497 /* Record the new mapping. */
498 evtchn_to_irq[evtchn] = irq;
499 +#ifdef PER_CPU_IPI_IRQ
500 irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
502 + per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
504 bind_evtchn_to_cpu(evtchn, cpu);
507 if (!(irq_desc[irq].status & IRQ_DISABLED))
508 unmask_evtchn(evtchn);
513 static int evtchn_resume(struct sys_device *dev)
514 @@ -1239,8 +1428,6 @@ void __init xen_init_IRQ(void)
515 irq_bindcount[i] = 0;
517 irq_desc[i].status |= IRQ_NOPROBE;
518 - set_irq_chip_and_handler_name(i, &dynirq_chip,
519 - handle_level_irq, "level");
522 /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
523 --- sle11-2009-06-04.orig/drivers/xen/core/smpboot.c 2009-06-04 10:47:07.000000000 +0200
524 +++ sle11-2009-06-04/drivers/xen/core/smpboot.c 2009-06-04 10:47:21.000000000 +0200
525 @@ -49,12 +49,9 @@ cpumask_t cpu_initialized_map;
526 DEFINE_PER_CPU(struct cpuinfo_x86, cpu_info);
527 EXPORT_PER_CPU_SYMBOL(cpu_info);
529 -static DEFINE_PER_CPU(int, resched_irq);
530 -static DEFINE_PER_CPU(int, callfunc_irq);
531 -static DEFINE_PER_CPU(int, call1func_irq);
532 -static char resched_name[NR_CPUS][15];
533 -static char callfunc_name[NR_CPUS][15];
534 -static char call1func_name[NR_CPUS][15];
535 +static int __read_mostly resched_irq = -1;
536 +static int __read_mostly callfunc_irq = -1;
537 +static int __read_mostly call1func_irq = -1;
539 #ifdef CONFIG_X86_LOCAL_APIC
540 #define set_cpu_to_apicid(cpu, apicid) (per_cpu(x86_cpu_to_apicid, cpu) = (apicid))
541 @@ -109,47 +106,54 @@ remove_siblinginfo(unsigned int cpu)
543 static int __cpuinit xen_smp_intr_init(unsigned int cpu)
545 + static struct irqaction resched_action = {
546 + .handler = smp_reschedule_interrupt,
547 + .flags = IRQF_DISABLED,
549 + }, callfunc_action = {
550 + .handler = smp_call_function_interrupt,
551 + .flags = IRQF_DISABLED,
553 + }, call1func_action = {
554 + .handler = smp_call_function_single_interrupt,
555 + .flags = IRQF_DISABLED,
556 + .name = "call1func"
560 - per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) =
561 - per_cpu(call1func_irq, cpu) = -1;
563 - sprintf(resched_name[cpu], "resched%u", cpu);
564 - rc = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR,
566 - smp_reschedule_interrupt,
567 - IRQF_DISABLED|IRQF_NOBALANCING,
570 + rc = bind_ipi_to_irqaction(RESCHEDULE_VECTOR,
575 - per_cpu(resched_irq, cpu) = rc;
577 - sprintf(callfunc_name[cpu], "callfunc%u", cpu);
578 - rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR,
580 - smp_call_function_interrupt,
581 - IRQF_DISABLED|IRQF_NOBALANCING,
582 - callfunc_name[cpu],
585 + if (resched_irq < 0)
588 + BUG_ON(resched_irq != rc);
590 + rc = bind_ipi_to_irqaction(CALL_FUNCTION_VECTOR,
595 - per_cpu(callfunc_irq, cpu) = rc;
597 - sprintf(call1func_name[cpu], "call1func%u", cpu);
598 - rc = bind_ipi_to_irqhandler(CALL_FUNC_SINGLE_VECTOR,
600 - smp_call_function_single_interrupt,
601 - IRQF_DISABLED|IRQF_NOBALANCING,
602 - call1func_name[cpu],
604 + goto unbind_resched;
605 + if (callfunc_irq < 0)
608 + BUG_ON(callfunc_irq != rc);
610 + rc = bind_ipi_to_irqaction(CALL_FUNC_SINGLE_VECTOR,
612 + &call1func_action);
615 - per_cpu(call1func_irq, cpu) = rc;
617 + if (call1func_irq < 0)
618 + call1func_irq = rc;
620 + BUG_ON(call1func_irq != rc);
622 rc = xen_spinlock_init(cpu);
627 if ((cpu != 0) && ((rc = local_setup_timer(cpu)) != 0))
629 @@ -157,13 +161,13 @@ static int __cpuinit xen_smp_intr_init(u
633 - if (per_cpu(resched_irq, cpu) >= 0)
634 - unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
635 - if (per_cpu(callfunc_irq, cpu) >= 0)
636 - unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
637 - if (per_cpu(call1func_irq, cpu) >= 0)
638 - unbind_from_irqhandler(per_cpu(call1func_irq, cpu), NULL);
639 xen_spinlock_cleanup(cpu);
641 + unbind_from_per_cpu_irq(call1func_irq, cpu);
643 + unbind_from_per_cpu_irq(callfunc_irq, cpu);
645 + unbind_from_per_cpu_irq(resched_irq, cpu);
649 @@ -173,9 +177,9 @@ static void __cpuinit xen_smp_intr_exit(
651 local_teardown_timer(cpu);
653 - unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
654 - unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
655 - unbind_from_irqhandler(per_cpu(call1func_irq, cpu), NULL);
656 + unbind_from_per_cpu_irq(resched_irq, cpu);
657 + unbind_from_per_cpu_irq(callfunc_irq, cpu);
658 + unbind_from_per_cpu_irq(call1func_irq, cpu);
659 xen_spinlock_cleanup(cpu);
662 --- sle11-2009-06-04.orig/drivers/xen/core/spinlock.c 2009-06-04 10:36:24.000000000 +0200
663 +++ sle11-2009-06-04/drivers/xen/core/spinlock.c 2009-06-04 10:47:21.000000000 +0200
666 extern irqreturn_t smp_reschedule_interrupt(int, void *);
668 -static DEFINE_PER_CPU(int, spinlock_irq) = -1;
669 -static char spinlock_name[NR_CPUS][15];
670 +static int __read_mostly spinlock_irq = -1;
673 raw_spinlock_t *lock;
674 @@ -34,34 +33,36 @@ static DEFINE_PER_CPU(raw_rwlock_t, spin
676 int __cpuinit xen_spinlock_init(unsigned int cpu)
678 + static struct irqaction spinlock_action = {
679 + .handler = smp_reschedule_interrupt,
680 + .flags = IRQF_DISABLED,
685 - sprintf(spinlock_name[cpu], "spinlock%u", cpu);
686 - rc = bind_ipi_to_irqhandler(SPIN_UNLOCK_VECTOR,
688 - smp_reschedule_interrupt,
689 - IRQF_DISABLED|IRQF_NOBALANCING,
690 - spinlock_name[cpu],
692 + rc = bind_ipi_to_irqaction(SPIN_UNLOCK_VECTOR,
698 - disable_irq(rc); /* make sure it's never delivered */
699 - per_cpu(spinlock_irq, cpu) = rc;
700 + if (spinlock_irq < 0) {
701 + disable_irq(rc); /* make sure it's never delivered */
704 + BUG_ON(spinlock_irq != rc);
709 void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
711 - if (per_cpu(spinlock_irq, cpu) >= 0)
712 - unbind_from_irqhandler(per_cpu(spinlock_irq, cpu), NULL);
713 - per_cpu(spinlock_irq, cpu) = -1;
714 + unbind_from_per_cpu_irq(spinlock_irq, cpu);
717 int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
719 - int rc = 0, irq = __get_cpu_var(spinlock_irq);
720 + int rc = 0, irq = spinlock_irq;
721 raw_rwlock_t *rm_lock;
723 struct spinning spinning;
724 @@ -155,7 +156,7 @@ void xen_spin_kick(raw_spinlock_t *lock,
725 raw_local_irq_restore(flags);
727 if (unlikely(spinning)) {
728 - notify_remote_via_irq(per_cpu(spinlock_irq, cpu));
729 + notify_remote_via_ipi(SPIN_UNLOCK_VECTOR, cpu);
733 --- sle11-2009-06-04.orig/include/xen/evtchn.h 2009-06-04 10:47:20.000000000 +0200
734 +++ sle11-2009-06-04/include/xen/evtchn.h 2009-06-04 10:47:21.000000000 +0200
735 @@ -78,6 +78,8 @@ int bind_virq_to_irqhandler(
736 unsigned long irqflags,
739 +#if defined(CONFIG_SMP) && !defined(MODULE)
741 int bind_ipi_to_irqhandler(
744 @@ -85,6 +87,13 @@ int bind_ipi_to_irqhandler(
745 unsigned long irqflags,
749 +int bind_ipi_to_irqaction(
752 + struct irqaction *action);
757 * Common unbind function for all event sources. Takes IRQ to unbind from.
758 @@ -93,6 +102,11 @@ int bind_ipi_to_irqhandler(
760 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
762 +#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
763 +/* Specialized unbind function for per-CPU IRQs. */
764 +void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu);
768 void irq_resume(void);
770 @@ -184,4 +198,8 @@ int clear_pirq_hw_action(int pirq);
774 +#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
775 +void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu);
778 #endif /* __ASM_EVTCHN_H__ */