]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.xen/xen-ipi-per-cpu-irq
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.xen / xen-ipi-per-cpu-irq
CommitLineData
cc90b958
BS
1From: jbeulich@novell.com
2Subject: fold IPIs onto a single IRQ each
3Patch-mainline: obsolete
4
00e5a55c
BS
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
7@@ -25,13 +25,13 @@
cc90b958
BS
8 #include <asm/genapic.h>
9 #include <xen/evtchn.h>
10
11-DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
12-
13 static inline void __send_IPI_one(unsigned int cpu, int vector)
14 {
15- int irq = per_cpu(ipi_to_irq, cpu)[vector];
16- BUG_ON(irq < 0);
17- notify_remote_via_irq(irq);
00e5a55c 18+#ifdef CONFIG_SMP
cc90b958 19+ notify_remote_via_ipi(vector, cpu);
00e5a55c
BS
20+#else
21+ BUG();
22+#endif
cc90b958
BS
23 }
24
25 static void xen_send_IPI_shortcut(unsigned int shortcut,
00e5a55c
BS
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
cc90b958
BS
28@@ -48,15 +48,6 @@ static inline int __prepare_ICR2(unsigne
29 }
30 #else
31 #include <xen/evtchn.h>
32-
33-DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
34-
35-static inline void __send_IPI_one(unsigned int cpu, int vector)
36-{
37- int irq = per_cpu(ipi_to_irq, cpu)[vector];
38- BUG_ON(irq < 0);
39- notify_remote_via_irq(irq);
40-}
41 #endif
42
43 void __send_IPI_shortcut(unsigned int shortcut, int vector)
44@@ -90,12 +81,12 @@ void __send_IPI_shortcut(unsigned int sh
45
46 switch (shortcut) {
47 case APIC_DEST_SELF:
48- __send_IPI_one(smp_processor_id(), vector);
49+ notify_remote_via_ipi(vector, smp_processor_id());
50 break;
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);
56 break;
57 default:
58 printk("XXXXXX __send_IPI_shortcut %08x vector %d\n", shortcut,
59@@ -165,7 +156,7 @@ void send_IPI_mask_bitmask(const cpumask
00e5a55c 60 WARN_ON(!cpus_subset(*cpumask, cpu_online_map));
cc90b958 61 for_each_online_cpu(cpu)
00e5a55c 62 if (cpu_isset(cpu, *cpumask))
cc90b958
BS
63- __send_IPI_one(cpu, vector);
64+ notify_remote_via_ipi(vector, cpu);
65 #endif
66 local_irq_restore(flags);
67 }
00e5a55c
BS
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
cc90b958
BS
70@@ -404,6 +404,9 @@ void fixup_irqs(cpumask_t map)
71 if (irq == 2)
72 continue;
73
74+ if (irq_desc[irq].status & IRQ_PER_CPU)
75+ continue;
76+
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);*/
00e5a55c
BS
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
cc90b958
BS
82@@ -245,6 +245,7 @@ void fixup_irqs(cpumask_t map)
83 spin_lock(&irq_desc[irq].lock);
84
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);
89 continue;
00e5a55c
BS
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
cc90b958
BS
92@@ -4,6 +4,7 @@
93
94 config XEN
95 bool
96+ select IRQ_PER_CPU if SMP
97
98 if XEN
99 config XEN_INTERFACE_VERSION
100@@ -292,6 +293,9 @@ config HAVE_IRQ_IGNORE_UNHANDLED
101 config GENERIC_HARDIRQS_NO__DO_IRQ
102 def_bool y
103
104+config IRQ_PER_CPU
105+ bool
106+
107 config NO_IDLE_HZ
108 def_bool y
109
00e5a55c
BS
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
cc90b958
BS
113 static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
114 [0 ... NR_EVENT_CHANNELS-1] = -1 };
115
116+/* IRQ <-> IPI mapping. */
117+#ifndef NR_IPIS
118+#define NR_IPIS 1
119+#endif
120+#if defined(CONFIG_SMP) && defined(CONFIG_X86)
121+static int ipi_to_irq[NR_IPIS] __read_mostly = {[0 ... NR_IPIS-1] = -1};
00e5a55c 122+static DEFINE_PER_CPU(int[NR_IPIS], ipi_to_evtchn);
cc90b958
BS
123+#else
124+#define PER_CPU_IPI_IRQ
125+#endif
126+#if !defined(CONFIG_SMP) || !defined(PER_CPU_IPI_IRQ)
127+#define BUG_IF_IPI(irq) BUG_ON(type_from_irq(irq) == IRQT_IPI)
128+#else
129+#define BUG_IF_IPI(irq) ((void)(irq))
130+#endif
131+
132 /* Packed IRQ information: binding type, sub-type index, and event channel. */
133 static u32 irq_info[NR_IRQS];
134
00e5a55c 135@@ -98,10 +114,12 @@ static inline u32 mk_irq_info(u32 type,
cc90b958
BS
136 * Accessors for packed IRQ information.
137 */
138
139+#ifdef PER_CPU_IPI_IRQ
140 static inline unsigned int evtchn_from_irq(int irq)
141 {
142 return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
143 }
144+#endif
145
146 static inline unsigned int index_from_irq(int irq)
147 {
00e5a55c 148@@ -113,14 +131,28 @@ static inline unsigned int type_from_irq
cc90b958
BS
149 return irq_info[irq] >> (32 - _IRQT_BITS);
150 }
151
152+#ifndef PER_CPU_IPI_IRQ
153+static inline unsigned int evtchn_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
154+{
155+ BUG_ON(type_from_irq(irq) != IRQT_IPI);
156+ return per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)];
157+}
158+
159+static inline unsigned int evtchn_from_irq(unsigned int irq)
160+{
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());
164+}
165+#endif
166+
167 /* IRQ <-> VIRQ mapping. */
168 DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
169
170+#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
171 /* IRQ <-> IPI mapping. */
172-#ifndef NR_IPIS
173-#define NR_IPIS 1
174-#endif
175 DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]) = {[0 ... NR_IPIS-1] = -1};
176+#endif
177
178 /* Reference counts for bindings to IRQs. */
179 static int irq_bindcount[NR_IRQS];
00e5a55c 180@@ -145,8 +177,14 @@ static void bind_evtchn_to_cpu(unsigned
cc90b958
BS
181
182 BUG_ON(!test_bit(chn, s->evtchn_mask));
183
184- if (irq != -1)
185- irq_desc[irq].affinity = cpumask_of_cpu(cpu);
186+ if (irq != -1) {
187+ struct irq_desc *desc = irq_desc + irq;
188+
189+ if (!(desc->status & IRQ_PER_CPU))
190+ desc->affinity = cpumask_of_cpu(cpu);
191+ else
192+ cpu_set(cpu, desc->affinity);
193+ }
194
195 clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
196 set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
00e5a55c
BS
197@@ -315,14 +353,29 @@ asmlinkage void evtchn_do_upcall(struct
198 irq_exit();
199 }
200
201-static int find_unbound_irq(void)
202+static struct irq_chip dynirq_chip;
203+
204+static int find_unbound_irq(bool percpu)
205 {
206 static int warned;
207 int irq;
208
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;
213+ const char *name;
214+
215+ if (!percpu) {
216+ handle = handle_level_irq;
217+ name = "level";
218+ } else {
219+ handle = handle_percpu_irq;
220+ name = "percpu";
221+ }
222+ set_irq_chip_and_handler_name(irq, &dynirq_chip,
223+ handle, name);
224 return irq;
225+ }
226
227 if (!warned) {
228 warned = 1;
229@@ -340,7 +393,7 @@ static int bind_caller_port_to_irq(unsig
230 spin_lock(&irq_mapping_update_lock);
231
232 if ((irq = evtchn_to_irq[caller_port]) == -1) {
233- if ((irq = find_unbound_irq()) < 0)
234+ if ((irq = find_unbound_irq(false)) < 0)
235 goto out;
236
237 evtchn_to_irq[caller_port] = irq;
238@@ -362,7 +415,7 @@ static int bind_local_port_to_irq(unsign
239
240 BUG_ON(evtchn_to_irq[local_port] != -1);
241
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))
246 BUG();
247@@ -415,7 +468,7 @@ static int bind_virq_to_irq(unsigned int
248 spin_lock(&irq_mapping_update_lock);
249
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)
253 goto out;
254
255 bind_virq.virq = virq;
256@@ -440,6 +493,7 @@ static int bind_virq_to_irq(unsigned int
cc90b958
BS
257 return irq;
258 }
259
260+#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
261 static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
262 {
263 struct evtchn_bind_ipi bind_ipi;
00e5a55c
BS
264@@ -448,7 +502,7 @@ static int bind_ipi_to_irq(unsigned int
265 spin_lock(&irq_mapping_update_lock);
266
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)
270 goto out;
271
272 bind_ipi.vcpu = cpu;
273@@ -471,6 +525,7 @@ static int bind_ipi_to_irq(unsigned int
cc90b958
BS
274 spin_unlock(&irq_mapping_update_lock);
275 return irq;
276 }
277+#endif
278
279 static void unbind_from_irq(unsigned int irq)
280 {
00e5a55c 281@@ -478,6 +533,7 @@ static void unbind_from_irq(unsigned int
cc90b958
BS
282 unsigned int cpu;
283 int evtchn = evtchn_from_irq(irq);
284
285+ BUG_IF_IPI(irq);
286 spin_lock(&irq_mapping_update_lock);
287
288 if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
00e5a55c 289@@ -491,10 +547,12 @@ static void unbind_from_irq(unsigned int
cc90b958
BS
290 per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
291 [index_from_irq(irq)] = -1;
292 break;
293+#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
294 case IRQT_IPI:
295 per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
296 [index_from_irq(irq)] = -1;
297 break;
298+#endif
299 default:
300 break;
301 }
00e5a55c 302@@ -513,6 +571,46 @@ static void unbind_from_irq(unsigned int
cc90b958
BS
303 spin_unlock(&irq_mapping_update_lock);
304 }
305
306+#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
307+void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
308+{
309+ struct evtchn_close close;
310+ int evtchn = evtchn_from_per_cpu_irq(irq, cpu);
311+
312+ spin_lock(&irq_mapping_update_lock);
313+
314+ if (VALID_EVTCHN(evtchn)) {
315+ struct irq_desc *desc = irq_desc + irq;
316+
317+ mask_evtchn(evtchn);
318+
319+ BUG_ON(irq_bindcount[irq] <= 1);
320+ irq_bindcount[irq]--;
321+ cpu_clear(cpu, desc->affinity);
322+
323+ close.port = evtchn;
324+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
325+ BUG();
326+
327+ switch (type_from_irq(irq)) {
328+ case IRQT_IPI:
00e5a55c 329+ per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)] = 0;
cc90b958
BS
330+ break;
331+ default:
332+ BUG();
333+ break;
334+ }
335+
336+ /* Closed ports are implicitly re-bound to VCPU0. */
337+ bind_evtchn_to_cpu(evtchn, 0);
338+
339+ evtchn_to_irq[evtchn] = -1;
340+ }
341+
342+ spin_unlock(&irq_mapping_update_lock);
343+}
344+#endif /* CONFIG_SMP && !PER_CPU_IPI_IRQ */
345+
346 int bind_caller_port_to_irqhandler(
347 unsigned int caller_port,
348 irq_handler_t handler,
00e5a55c 349@@ -607,6 +705,8 @@ int bind_virq_to_irqhandler(
cc90b958
BS
350 }
351 EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
352
353+#ifdef CONFIG_SMP
354+#ifdef PER_CPU_IPI_IRQ
355 int bind_ipi_to_irqhandler(
356 unsigned int ipi,
357 unsigned int cpu,
00e5a55c 358@@ -629,7 +729,71 @@ int bind_ipi_to_irqhandler(
cc90b958
BS
359
360 return irq;
361 }
362-EXPORT_SYMBOL_GPL(bind_ipi_to_irqhandler);
363+#else
364+int __cpuinit bind_ipi_to_irqaction(
365+ unsigned int ipi,
366+ unsigned int cpu,
367+ struct irqaction *action)
368+{
369+ struct evtchn_bind_ipi bind_ipi;
370+ int evtchn, irq, retval = 0;
371+
372+ spin_lock(&irq_mapping_update_lock);
373+
00e5a55c 374+ if (VALID_EVTCHN(per_cpu(ipi_to_evtchn, cpu)[ipi])) {
cc90b958
BS
375+ spin_unlock(&irq_mapping_update_lock);
376+ return -EBUSY;
377+ }
378+
379+ if ((irq = ipi_to_irq[ipi]) == -1) {
00e5a55c 380+ if ((irq = find_unbound_irq(true)) < 0) {
cc90b958
BS
381+ spin_unlock(&irq_mapping_update_lock);
382+ return irq;
383+ }
384+
385+ /* Extra reference so count will never drop to zero. */
386+ irq_bindcount[irq]++;
387+
388+ ipi_to_irq[ipi] = irq;
389+ irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, 0);
cc90b958
BS
390+ retval = 1;
391+ }
392+
393+ bind_ipi.vcpu = cpu;
394+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
395+ &bind_ipi) != 0)
396+ BUG();
397+
398+ evtchn = bind_ipi.port;
399+ evtchn_to_irq[evtchn] = irq;
400+ per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
401+
402+ bind_evtchn_to_cpu(evtchn, cpu);
403+
404+ irq_bindcount[irq]++;
405+
406+ spin_unlock(&irq_mapping_update_lock);
407+
408+ if (retval == 0) {
409+ unsigned long flags;
410+
411+ local_irq_save(flags);
412+ unmask_evtchn(evtchn);
413+ local_irq_restore(flags);
414+ } else {
415+ action->flags |= IRQF_PERCPU;
416+ retval = setup_irq(irq, action);
417+ if (retval) {
418+ unbind_from_per_cpu_irq(irq, cpu);
419+ BUG_ON(retval > 0);
420+ irq = retval;
421+ }
422+ }
423+
424+ return irq;
425+}
426+#endif /* PER_CPU_IPI_IRQ */
427+#endif /* CONFIG_SMP */
428
429 void unbind_from_irqhandler(unsigned int irq, void *dev_id)
430 {
00e5a55c 431@@ -655,6 +819,7 @@ static void rebind_irq_to_cpu(unsigned i
cc90b958
BS
432 {
433 int evtchn = evtchn_from_irq(irq);
434
435+ BUG_IF_IPI(irq);
436 if (VALID_EVTCHN(evtchn))
437 rebind_evtchn_to_cpu(evtchn, tcpu);
438 }
00e5a55c 439@@ -739,6 +904,7 @@ static struct irq_chip dynirq_chip = {
cc90b958
BS
440 .unmask = unmask_dynirq,
441 .mask_ack = ack_dynirq,
442 .ack = ack_dynirq,
443+ .eoi = end_dynirq,
444 .end = end_dynirq,
445 #ifdef CONFIG_SMP
446 .set_affinity = set_affinity_irq,
00e5a55c 447@@ -918,10 +1084,21 @@ int irq_ignore_unhandled(unsigned int ir
cc90b958
BS
448 return !!(irq_status.flags & XENIRQSTAT_shared);
449 }
450
451+#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
452+void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu)
453+{
454+ int evtchn = evtchn_from_per_cpu_irq(ipi_to_irq[ipi], cpu);
455+
456+ if (VALID_EVTCHN(evtchn))
457+ notify_remote_via_evtchn(evtchn);
458+}
459+#endif
460+
461 void notify_remote_via_irq(int irq)
462 {
463 int evtchn = evtchn_from_irq(irq);
464
465+ BUG_IF_IPI(irq);
466 if (VALID_EVTCHN(evtchn))
467 notify_remote_via_evtchn(evtchn);
468 }
00e5a55c 469@@ -929,6 +1106,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
cc90b958
BS
470
471 int irq_to_evtchn_port(int irq)
472 {
473+ BUG_IF_IPI(irq);
474 return evtchn_from_irq(irq);
475 }
476 EXPORT_SYMBOL_GPL(irq_to_evtchn_port);
00e5a55c 477@@ -1044,11 +1222,17 @@ static void restore_cpu_virqs(unsigned i
cc90b958
BS
478
479 static void restore_cpu_ipis(unsigned int cpu)
480 {
481+#ifdef CONFIG_SMP
482 struct evtchn_bind_ipi bind_ipi;
483 int ipi, irq, evtchn;
484
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)
488+#else
00e5a55c
BS
489+ if ((irq = ipi_to_irq[ipi]) == -1
490+ || !VALID_EVTCHN(per_cpu(ipi_to_evtchn, cpu)[ipi]))
cc90b958
BS
491+#endif
492 continue;
493
494 BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
00e5a55c 495@@ -1062,13 +1246,18 @@ static void restore_cpu_ipis(unsigned in
cc90b958
BS
496
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);
501+#else
502+ per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
503+#endif
504 bind_evtchn_to_cpu(evtchn, cpu);
505
506 /* Ready for use. */
00e5a55c
BS
507 if (!(irq_desc[irq].status & IRQ_DISABLED))
508 unmask_evtchn(evtchn);
cc90b958
BS
509 }
510+#endif
511 }
512
513 static int evtchn_resume(struct sys_device *dev)
00e5a55c
BS
514@@ -1239,8 +1428,6 @@ void __init xen_init_IRQ(void)
515 irq_bindcount[i] = 0;
cc90b958 516
00e5a55c
BS
517 irq_desc[i].status |= IRQ_NOPROBE;
518- set_irq_chip_and_handler_name(i, &dynirq_chip,
519- handle_level_irq, "level");
cc90b958 520 }
cc90b958 521
00e5a55c
BS
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);
cc90b958
BS
528
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;
538
539 #ifdef CONFIG_X86_LOCAL_APIC
540 #define set_cpu_to_apicid(cpu, apicid) (per_cpu(x86_cpu_to_apicid, cpu) = (apicid))
00e5a55c 541@@ -109,47 +106,54 @@ remove_siblinginfo(unsigned int cpu)
cc90b958
BS
542
543 static int __cpuinit xen_smp_intr_init(unsigned int cpu)
544 {
545+ static struct irqaction resched_action = {
546+ .handler = smp_reschedule_interrupt,
547+ .flags = IRQF_DISABLED,
548+ .name = "resched"
549+ }, callfunc_action = {
550+ .handler = smp_call_function_interrupt,
551+ .flags = IRQF_DISABLED,
552+ .name = "callfunc"
553+ }, call1func_action = {
554+ .handler = smp_call_function_single_interrupt,
555+ .flags = IRQF_DISABLED,
556+ .name = "call1func"
557+ };
558 int rc;
559
560- per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) =
561- per_cpu(call1func_irq, cpu) = -1;
562-
563- sprintf(resched_name[cpu], "resched%u", cpu);
564- rc = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR,
565- cpu,
566- smp_reschedule_interrupt,
567- IRQF_DISABLED|IRQF_NOBALANCING,
568- resched_name[cpu],
569- NULL);
570+ rc = bind_ipi_to_irqaction(RESCHEDULE_VECTOR,
571+ cpu,
572+ &resched_action);
573 if (rc < 0)
00e5a55c 574- goto fail;
cc90b958
BS
575- per_cpu(resched_irq, cpu) = rc;
576-
577- sprintf(callfunc_name[cpu], "callfunc%u", cpu);
578- rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR,
579- cpu,
580- smp_call_function_interrupt,
581- IRQF_DISABLED|IRQF_NOBALANCING,
582- callfunc_name[cpu],
583- NULL);
00e5a55c 584+ return rc;
cc90b958
BS
585+ if (resched_irq < 0)
586+ resched_irq = rc;
587+ else
588+ BUG_ON(resched_irq != rc);
589+
590+ rc = bind_ipi_to_irqaction(CALL_FUNCTION_VECTOR,
591+ cpu,
592+ &callfunc_action);
593 if (rc < 0)
00e5a55c 594- goto fail;
cc90b958
BS
595- per_cpu(callfunc_irq, cpu) = rc;
596-
597- sprintf(call1func_name[cpu], "call1func%u", cpu);
598- rc = bind_ipi_to_irqhandler(CALL_FUNC_SINGLE_VECTOR,
599- cpu,
600- smp_call_function_single_interrupt,
601- IRQF_DISABLED|IRQF_NOBALANCING,
602- call1func_name[cpu],
603- NULL);
00e5a55c 604+ goto unbind_resched;
cc90b958
BS
605+ if (callfunc_irq < 0)
606+ callfunc_irq = rc;
607+ else
608+ BUG_ON(callfunc_irq != rc);
609+
610+ rc = bind_ipi_to_irqaction(CALL_FUNC_SINGLE_VECTOR,
611+ cpu,
612+ &call1func_action);
613 if (rc < 0)
00e5a55c 614- goto fail;
cc90b958 615- per_cpu(call1func_irq, cpu) = rc;
00e5a55c 616+ goto unbind_call;
cc90b958
BS
617+ if (call1func_irq < 0)
618+ call1func_irq = rc;
619+ else
620+ BUG_ON(call1func_irq != rc);
621
622 rc = xen_spinlock_init(cpu);
623 if (rc < 0)
00e5a55c
BS
624- goto fail;
625+ goto unbind_call1;
626
627 if ((cpu != 0) && ((rc = local_setup_timer(cpu)) != 0))
628 goto fail;
629@@ -157,13 +161,13 @@ static int __cpuinit xen_smp_intr_init(u
cc90b958
BS
630 return 0;
631
632 fail:
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);
cc90b958 639 xen_spinlock_cleanup(cpu);
00e5a55c
BS
640+ unbind_call1:
641+ unbind_from_per_cpu_irq(call1func_irq, cpu);
642+ unbind_call:
643+ unbind_from_per_cpu_irq(callfunc_irq, cpu);
644+ unbind_resched:
645+ unbind_from_per_cpu_irq(resched_irq, cpu);
cc90b958
BS
646 return rc;
647 }
00e5a55c
BS
648
649@@ -173,9 +177,9 @@ static void __cpuinit xen_smp_intr_exit(
cc90b958
BS
650 if (cpu != 0)
651 local_teardown_timer(cpu);
652
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);
660 }
661 #endif
00e5a55c
BS
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
664@@ -16,8 +16,7 @@
cc90b958
BS
665
666 extern irqreturn_t smp_reschedule_interrupt(int, void *);
667
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;
671
672 struct spinning {
673 raw_spinlock_t *lock;
00e5a55c 674@@ -34,34 +33,36 @@ static DEFINE_PER_CPU(raw_rwlock_t, spin
cc90b958
BS
675
676 int __cpuinit xen_spinlock_init(unsigned int cpu)
677 {
678+ static struct irqaction spinlock_action = {
679+ .handler = smp_reschedule_interrupt,
680+ .flags = IRQF_DISABLED,
681+ .name = "spinlock"
682+ };
683 int rc;
684
685- sprintf(spinlock_name[cpu], "spinlock%u", cpu);
686- rc = bind_ipi_to_irqhandler(SPIN_UNLOCK_VECTOR,
687- cpu,
688- smp_reschedule_interrupt,
689- IRQF_DISABLED|IRQF_NOBALANCING,
690- spinlock_name[cpu],
691- NULL);
692+ rc = bind_ipi_to_irqaction(SPIN_UNLOCK_VECTOR,
693+ cpu,
694+ &spinlock_action);
695 if (rc < 0)
696 return rc;
697
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 */
702+ spinlock_irq = rc;
703+ } else
704+ BUG_ON(spinlock_irq != rc);
705
706 return 0;
707 }
708
709 void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
710 {
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;
00e5a55c 714+ unbind_from_per_cpu_irq(spinlock_irq, cpu);
cc90b958
BS
715 }
716
717 int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
718 {
719- int rc = 0, irq = __get_cpu_var(spinlock_irq);
720+ int rc = 0, irq = spinlock_irq;
721 raw_rwlock_t *rm_lock;
722 unsigned long flags;
723 struct spinning spinning;
00e5a55c 724@@ -155,7 +156,7 @@ void xen_spin_kick(raw_spinlock_t *lock,
cc90b958
BS
725 raw_local_irq_restore(flags);
726
727 if (unlikely(spinning)) {
728- notify_remote_via_irq(per_cpu(spinlock_irq, cpu));
729+ notify_remote_via_ipi(SPIN_UNLOCK_VECTOR, cpu);
730 return;
731 }
732 }
00e5a55c
BS
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
cc90b958
BS
735@@ -78,6 +78,8 @@ int bind_virq_to_irqhandler(
736 unsigned long irqflags,
737 const char *devname,
738 void *dev_id);
739+#if defined(CONFIG_SMP) && !defined(MODULE)
740+#ifndef CONFIG_X86
741 int bind_ipi_to_irqhandler(
742 unsigned int ipi,
743 unsigned int cpu,
744@@ -85,6 +87,13 @@ int bind_ipi_to_irqhandler(
745 unsigned long irqflags,
746 const char *devname,
747 void *dev_id);
748+#else
749+int bind_ipi_to_irqaction(
750+ unsigned int ipi,
751+ unsigned int cpu,
752+ struct irqaction *action);
753+#endif
754+#endif
755
756 /*
757 * Common unbind function for all event sources. Takes IRQ to unbind from.
758@@ -93,6 +102,11 @@ int bind_ipi_to_irqhandler(
759 */
760 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
761
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);
765+#endif
766+
767 #ifndef CONFIG_XEN
768 void irq_resume(void);
769 #endif
770@@ -184,4 +198,8 @@ int clear_pirq_hw_action(int pirq);
771 #define PIRQ_END 5
772 #define PIRQ_ACK 6
773
774+#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
775+void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu);
776+#endif
777+
778 #endif /* __ASM_EVTCHN_H__ */