]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.xen/xen-virq-per-cpu-irq
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.xen / xen-virq-per-cpu-irq
CommitLineData
cc90b958
BS
1From: jbeulich@novell.com
2Subject: fold per-CPU VIRQs onto a single IRQ each
3Patch-mainline: obsolete
4
00e5a55c
BS
5--- sle11-2009-06-04.orig/arch/x86/kernel/time_32-xen.c 2009-06-04 10:47:20.000000000 +0200
6+++ sle11-2009-06-04/arch/x86/kernel/time_32-xen.c 2009-06-04 10:47:28.000000000 +0200
7@@ -725,19 +725,17 @@ int xen_update_persistent_clock(void)
cc90b958
BS
8 }
9
10 /* Dynamically-mapped IRQ. */
11-DEFINE_PER_CPU(int, timer_irq);
12+static int __read_mostly timer_irq = -1;
13+static struct irqaction timer_action = {
14+ .handler = timer_interrupt,
15+ .flags = IRQF_DISABLED,
16+ .name = "timer"
17+};
18
19 static void __init setup_cpu0_timer_irq(void)
20 {
21- per_cpu(timer_irq, 0) =
22- bind_virq_to_irqhandler(
23- VIRQ_TIMER,
24- 0,
25- timer_interrupt,
26- IRQF_DISABLED|IRQF_NOBALANCING,
27- "timer0",
28- NULL);
29- BUG_ON(per_cpu(timer_irq, 0) < 0);
30+ timer_irq = bind_virq_to_irqaction(VIRQ_TIMER, 0, &timer_action);
31+ BUG_ON(timer_irq < 0);
32 }
33
34 void __init time_init(void)
00e5a55c 35@@ -864,8 +862,6 @@ void xen_halt(void)
cc90b958
BS
36 EXPORT_SYMBOL(xen_halt);
37
38 #ifdef CONFIG_SMP
39-static char timer_name[NR_CPUS][15];
40-
41 int __cpuinit local_setup_timer(unsigned int cpu)
42 {
43 int seq, irq;
00e5a55c 44@@ -891,16 +887,10 @@ int __cpuinit local_setup_timer(unsigned
cc90b958
BS
45 init_missing_ticks_accounting(cpu);
46 } while (read_seqretry(&xtime_lock, seq));
47
48- sprintf(timer_name[cpu], "timer%u", cpu);
49- irq = bind_virq_to_irqhandler(VIRQ_TIMER,
50- cpu,
51- timer_interrupt,
52- IRQF_DISABLED|IRQF_NOBALANCING,
53- timer_name[cpu],
54- NULL);
55+ irq = bind_virq_to_irqaction(VIRQ_TIMER, cpu, &timer_action);
56 if (irq < 0)
57 return irq;
58- per_cpu(timer_irq, cpu) = irq;
59+ BUG_ON(timer_irq != irq);
60
61 return 0;
62 }
00e5a55c 63@@ -908,7 +898,7 @@ int __cpuinit local_setup_timer(unsigned
cc90b958
BS
64 void __cpuinit local_teardown_timer(unsigned int cpu)
65 {
66 BUG_ON(cpu == 0);
67- unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
68+ unbind_from_per_cpu_irq(timer_irq, cpu, &timer_action);
69 }
70 #endif
71
00e5a55c
BS
72--- sle11-2009-06-04.orig/drivers/xen/core/evtchn.c 2009-06-04 10:47:21.000000000 +0200
73+++ sle11-2009-06-04/drivers/xen/core/evtchn.c 2009-06-04 10:47:28.000000000 +0200
74@@ -58,6 +58,23 @@ static DEFINE_SPINLOCK(irq_mapping_updat
cc90b958
BS
75 static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
76 [0 ... NR_EVENT_CHANNELS-1] = -1 };
77
78+#if defined(CONFIG_SMP) && defined(CONFIG_X86)
79+static struct per_cpu_irqaction {
80+ struct irqaction action; /* must be first */
81+ struct per_cpu_irqaction *next;
82+ cpumask_t cpus;
83+} *virq_actions[NR_VIRQS];
84+/* IRQ <-> VIRQ mapping. */
85+static DECLARE_BITMAP(virq_per_cpu, NR_VIRQS) __read_mostly;
00e5a55c 86+static DEFINE_PER_CPU(int[NR_VIRQS], virq_to_evtchn);
cc90b958
BS
87+#define BUG_IF_VIRQ_PER_CPU(irq) \
88+ BUG_ON(type_from_irq(irq) == IRQT_VIRQ \
89+ && test_bit(index_from_irq(irq), virq_per_cpu))
90+#else
91+#define BUG_IF_VIRQ_PER_CPU(irq) ((void)(irq))
92+#define PER_CPU_VIRQ_IRQ
93+#endif
94+
95 /* IRQ <-> IPI mapping. */
96 #ifndef NR_IPIS
97 #define NR_IPIS 1
00e5a55c 98@@ -114,13 +131,6 @@ static inline u32 mk_irq_info(u32 type,
cc90b958
BS
99 * Accessors for packed IRQ information.
100 */
101
102-#ifdef PER_CPU_IPI_IRQ
103-static inline unsigned int evtchn_from_irq(int irq)
104-{
105- return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
106-}
107-#endif
108-
109 static inline unsigned int index_from_irq(int irq)
110 {
111 return (irq_info[irq] >> _EVTCHN_BITS) & ((1U << _INDEX_BITS) - 1);
00e5a55c 112@@ -131,20 +141,35 @@ static inline unsigned int type_from_irq
cc90b958
BS
113 return irq_info[irq] >> (32 - _IRQT_BITS);
114 }
115
116-#ifndef PER_CPU_IPI_IRQ
117 static inline unsigned int evtchn_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
118 {
119- BUG_ON(type_from_irq(irq) != IRQT_IPI);
120- return per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)];
121+ switch (type_from_irq(irq)) {
122+#ifndef PER_CPU_VIRQ_IRQ
123+ case IRQT_VIRQ:
124+ return per_cpu(virq_to_evtchn, cpu)[index_from_irq(irq)];
125+#endif
126+#ifndef PER_CPU_IPI_IRQ
127+ case IRQT_IPI:
128+ return per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)];
129+#endif
130+ }
131+ BUG();
00e5a55c 132+ return 0;
cc90b958
BS
133 }
134
135 static inline unsigned int evtchn_from_irq(unsigned int irq)
136 {
137- if (type_from_irq(irq) != IRQT_IPI)
138- return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
139- return evtchn_from_per_cpu_irq(irq, smp_processor_id());
140-}
141+ switch (type_from_irq(irq)) {
142+#ifndef PER_CPU_VIRQ_IRQ
143+ case IRQT_VIRQ:
144+#endif
145+#ifndef PER_CPU_IPI_IRQ
146+ case IRQT_IPI:
147 #endif
148+ return evtchn_from_per_cpu_irq(irq, smp_processor_id());
149+ }
150+ return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
151+}
152
153 /* IRQ <-> VIRQ mapping. */
154 DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
00e5a55c 155@@ -479,6 +504,14 @@ static int bind_virq_to_irq(unsigned int
cc90b958
BS
156 evtchn = bind_virq.port;
157
158 evtchn_to_irq[evtchn] = irq;
159+#ifndef PER_CPU_VIRQ_IRQ
160+ {
161+ unsigned int cpu;
162+
163+ for_each_possible_cpu(cpu)
164+ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
165+ }
166+#endif
167 irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
168
169 per_cpu(virq_to_irq, cpu)[virq] = irq;
00e5a55c 170@@ -533,7 +566,9 @@ static void unbind_from_irq(unsigned int
cc90b958
BS
171 unsigned int cpu;
172 int evtchn = evtchn_from_irq(irq);
173
174+ BUG_IF_VIRQ_PER_CPU(irq);
175 BUG_IF_IPI(irq);
176+
177 spin_lock(&irq_mapping_update_lock);
178
179 if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
00e5a55c 180@@ -546,6 +581,11 @@ static void unbind_from_irq(unsigned int
cc90b958
BS
181 case IRQT_VIRQ:
182 per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
183 [index_from_irq(irq)] = -1;
184+#ifndef PER_CPU_VIRQ_IRQ
185+ for_each_possible_cpu(cpu)
186+ per_cpu(virq_to_evtchn, cpu)
00e5a55c 187+ [index_from_irq(irq)] = 0;
cc90b958
BS
188+#endif
189 break;
190 #if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
191 case IRQT_IPI:
00e5a55c 192@@ -571,11 +611,13 @@ static void unbind_from_irq(unsigned int
cc90b958
BS
193 spin_unlock(&irq_mapping_update_lock);
194 }
195
196-#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
197-void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
198+#if defined(CONFIG_SMP) && (!defined(PER_CPU_IPI_IRQ) || !defined(PER_CPU_VIRQ_IRQ))
199+void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu,
200+ struct irqaction *action)
201 {
202 struct evtchn_close close;
203 int evtchn = evtchn_from_per_cpu_irq(irq, cpu);
204+ struct irqaction *free_action = NULL;
205
206 spin_lock(&irq_mapping_update_lock);
207
00e5a55c 208@@ -586,6 +628,32 @@ void unbind_from_per_cpu_irq(unsigned in
cc90b958
BS
209
210 BUG_ON(irq_bindcount[irq] <= 1);
211 irq_bindcount[irq]--;
212+
213+#ifndef PER_CPU_VIRQ_IRQ
214+ if (type_from_irq(irq) == IRQT_VIRQ) {
215+ unsigned int virq = index_from_irq(irq);
216+ struct per_cpu_irqaction *cur, *prev = NULL;
217+
218+ cur = virq_actions[virq];
219+ while (cur) {
220+ if (cur->action.dev_id == action) {
221+ cpu_clear(cpu, cur->cpus);
222+ if (cpus_empty(cur->cpus)) {
223+ if (prev)
224+ prev->next = cur->next;
225+ else
226+ virq_actions[virq] = cur->next;
227+ free_action = action;
228+ }
229+ } else if (cpu_isset(cpu, cur->cpus))
230+ evtchn = 0;
231+ cur = (prev = cur)->next;
232+ }
233+ if (!VALID_EVTCHN(evtchn))
234+ goto done;
235+ }
236+#endif
237+
238 cpu_clear(cpu, desc->affinity);
239
240 close.port = evtchn;
00e5a55c 241@@ -593,9 +661,16 @@ void unbind_from_per_cpu_irq(unsigned in
cc90b958
BS
242 BUG();
243
244 switch (type_from_irq(irq)) {
245+#ifndef PER_CPU_VIRQ_IRQ
246+ case IRQT_VIRQ:
00e5a55c 247+ per_cpu(virq_to_evtchn, cpu)[index_from_irq(irq)] = 0;
cc90b958
BS
248+ break;
249+#endif
250+#ifndef PER_CPU_IPI_IRQ
251 case IRQT_IPI:
00e5a55c 252 per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)] = 0;
cc90b958
BS
253 break;
254+#endif
255 default:
256 BUG();
257 break;
00e5a55c 258@@ -607,9 +682,16 @@ void unbind_from_per_cpu_irq(unsigned in
cc90b958
BS
259 evtchn_to_irq[evtchn] = -1;
260 }
261
262+#ifndef PER_CPU_VIRQ_IRQ
263+done:
264+#endif
265 spin_unlock(&irq_mapping_update_lock);
266+
267+ if (free_action)
268+ free_irq(irq, free_action);
269 }
270-#endif /* CONFIG_SMP && !PER_CPU_IPI_IRQ */
271+EXPORT_SYMBOL_GPL(unbind_from_per_cpu_irq);
272+#endif /* CONFIG_SMP && (!PER_CPU_IPI_IRQ || !PER_CPU_VIRQ_IRQ) */
273
274 int bind_caller_port_to_irqhandler(
275 unsigned int caller_port,
00e5a55c 276@@ -691,6 +773,8 @@ int bind_virq_to_irqhandler(
cc90b958
BS
277 {
278 int irq, retval;
279
280+ BUG_IF_VIRQ_PER_CPU(virq);
281+
282 irq = bind_virq_to_irq(virq, cpu);
283 if (irq < 0)
284 return irq;
00e5a55c 285@@ -706,6 +790,108 @@ int bind_virq_to_irqhandler(
cc90b958
BS
286 EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
287
288 #ifdef CONFIG_SMP
289+#ifndef PER_CPU_VIRQ_IRQ
290+int bind_virq_to_irqaction(
291+ unsigned int virq,
292+ unsigned int cpu,
293+ struct irqaction *action)
294+{
295+ struct evtchn_bind_virq bind_virq;
296+ int evtchn, irq, retval = 0;
297+ struct per_cpu_irqaction *cur = NULL, *new;
298+
299+ BUG_ON(!test_bit(virq, virq_per_cpu));
300+
301+ if (action->dev_id)
302+ return -EINVAL;
303+
304+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
305+ if (new) {
306+ new->action = *action;
307+ new->action.dev_id = action;
308+ }
309+
310+ spin_lock(&irq_mapping_update_lock);
311+
312+ for (cur = virq_actions[virq]; cur; cur = cur->next)
313+ if (cur->action.dev_id == action)
314+ break;
315+ if (!cur) {
316+ if (!new) {
317+ spin_unlock(&irq_mapping_update_lock);
318+ return -ENOMEM;
319+ }
320+ new->next = virq_actions[virq];
321+ virq_actions[virq] = cur = new;
322+ retval = 1;
323+ }
324+ cpu_set(cpu, cur->cpus);
325+ action = &cur->action;
326+
327+ if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
328+ unsigned int cpu;
329+
330+ BUG_ON(!retval);
331+
00e5a55c 332+ if ((irq = find_unbound_irq(true)) < 0) {
cc90b958
BS
333+ if (cur)
334+ virq_actions[virq] = cur->next;
335+ spin_unlock(&irq_mapping_update_lock);
336+ if (cur != new)
337+ kfree(new);
338+ return irq;
339+ }
340+
341+ /* Extra reference so count will never drop to zero. */
342+ irq_bindcount[irq]++;
343+
344+ for_each_possible_cpu(cpu)
345+ per_cpu(virq_to_irq, cpu)[virq] = irq;
346+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, 0);
cc90b958
BS
347+ }
348+
00e5a55c
BS
349+ evtchn = per_cpu(virq_to_evtchn, cpu)[virq];
350+ if (!VALID_EVTCHN(evtchn)) {
cc90b958
BS
351+ bind_virq.virq = virq;
352+ bind_virq.vcpu = cpu;
353+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
354+ &bind_virq) != 0)
355+ BUG();
356+ evtchn = bind_virq.port;
357+ evtchn_to_irq[evtchn] = irq;
358+ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
359+
360+ bind_evtchn_to_cpu(evtchn, cpu);
361+ }
362+
363+ irq_bindcount[irq]++;
364+
365+ spin_unlock(&irq_mapping_update_lock);
366+
367+ if (cur != new)
368+ kfree(new);
369+
370+ if (retval == 0) {
371+ unsigned long flags;
372+
373+ local_irq_save(flags);
374+ unmask_evtchn(evtchn);
375+ local_irq_restore(flags);
376+ } else {
377+ action->flags |= IRQF_PERCPU;
378+ retval = setup_irq(irq, action);
379+ if (retval) {
380+ unbind_from_per_cpu_irq(irq, cpu, cur->action.dev_id);
381+ BUG_ON(retval > 0);
382+ irq = retval;
383+ }
384+ }
385+
386+ return irq;
387+}
388+EXPORT_SYMBOL_GPL(bind_virq_to_irqaction);
389+#endif
390+
391 #ifdef PER_CPU_IPI_IRQ
392 int bind_ipi_to_irqhandler(
393 unsigned int ipi,
00e5a55c 394@@ -784,7 +970,7 @@ int __cpuinit bind_ipi_to_irqaction(
cc90b958
BS
395 action->flags |= IRQF_PERCPU;
396 retval = setup_irq(irq, action);
397 if (retval) {
398- unbind_from_per_cpu_irq(irq, cpu);
399+ unbind_from_per_cpu_irq(irq, cpu, NULL);
400 BUG_ON(retval > 0);
401 irq = retval;
402 }
00e5a55c 403@@ -819,7 +1005,9 @@ static void rebind_irq_to_cpu(unsigned i
cc90b958
BS
404 {
405 int evtchn = evtchn_from_irq(irq);
406
407+ BUG_IF_VIRQ_PER_CPU(irq);
408 BUG_IF_IPI(irq);
409+
410 if (VALID_EVTCHN(evtchn))
411 rebind_evtchn_to_cpu(evtchn, tcpu);
412 }
00e5a55c 413@@ -1098,7 +1286,9 @@ void notify_remote_via_irq(int irq)
cc90b958
BS
414 {
415 int evtchn = evtchn_from_irq(irq);
416
417+ BUG_ON(type_from_irq(irq) == IRQT_VIRQ);
418 BUG_IF_IPI(irq);
419+
420 if (VALID_EVTCHN(evtchn))
421 notify_remote_via_evtchn(evtchn);
422 }
00e5a55c 423@@ -1106,6 +1296,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
cc90b958
BS
424
425 int irq_to_evtchn_port(int irq)
426 {
427+ BUG_IF_VIRQ_PER_CPU(irq);
428 BUG_IF_IPI(irq);
429 return evtchn_from_irq(irq);
430 }
00e5a55c 431@@ -1200,6 +1391,12 @@ static void restore_cpu_virqs(unsigned i
cc90b958
BS
432 if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
433 continue;
434
435+#ifndef PER_CPU_VIRQ_IRQ
00e5a55c
BS
436+ if (test_bit(virq, virq_per_cpu)
437+ && !VALID_EVTCHN(per_cpu(virq_to_evtchn, cpu)[virq]))
438+ continue;
cc90b958
BS
439+#endif
440+
441 BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
442
443 /* Get a new binding from Xen. */
00e5a55c 444@@ -1212,7 +1409,19 @@ static void restore_cpu_virqs(unsigned i
cc90b958
BS
445
446 /* Record the new mapping. */
447 evtchn_to_irq[evtchn] = irq;
00e5a55c
BS
448+#ifdef PER_CPU_VIRQ_IRQ
449 irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
450+#else
cc90b958
BS
451+ if (test_bit(virq, virq_per_cpu))
452+ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
453+ else {
454+ unsigned int cpu;
455+
456+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
457+ for_each_possible_cpu(cpu)
458+ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
459+ }
cc90b958
BS
460+#endif
461 bind_evtchn_to_cpu(evtchn, cpu);
462
463 /* Ready for use. */
00e5a55c 464@@ -1267,7 +1476,11 @@ static int evtchn_resume(struct sys_devi
cc90b958
BS
465
466 /* Avoid doing anything in the 'suspend cancelled' case. */
467 status.dom = DOMID_SELF;
468+#ifdef PER_CPU_VIRQ_IRQ
469 status.port = evtchn_from_irq(__get_cpu_var(virq_to_irq)[VIRQ_TIMER]);
470+#else
471+ status.port = __get_cpu_var(virq_to_evtchn)[VIRQ_TIMER];
472+#endif
473 if (HYPERVISOR_event_channel_op(EVTCHNOP_status, &status))
474 BUG();
475 if (status.status == EVTCHNSTAT_virq
00e5a55c 476@@ -1407,6 +1620,15 @@ void __init xen_init_IRQ(void)
cc90b958 477 unsigned int i;
00e5a55c 478 struct physdev_pirq_eoi_gmfn eoi_gmfn;
cc90b958
BS
479
480+#ifndef PER_CPU_VIRQ_IRQ
481+ __set_bit(VIRQ_TIMER, virq_per_cpu);
482+ __set_bit(VIRQ_DEBUG, virq_per_cpu);
483+ __set_bit(VIRQ_XENOPROF, virq_per_cpu);
484+#ifdef CONFIG_IA64
485+ __set_bit(VIRQ_ITC, virq_per_cpu);
486+#endif
487+#endif
488+
489 init_evtchn_cpu_bindings();
490
00e5a55c
BS
491 pirq_needs_eoi = alloc_bootmem_pages(sizeof(unsigned long)
492--- sle11-2009-06-04.orig/drivers/xen/core/smpboot.c 2009-06-04 10:47:21.000000000 +0200
493+++ sle11-2009-06-04/drivers/xen/core/smpboot.c 2009-06-04 10:47:28.000000000 +0200
494@@ -163,11 +163,11 @@ static int __cpuinit xen_smp_intr_init(u
cc90b958 495 fail:
cc90b958 496 xen_spinlock_cleanup(cpu);
00e5a55c
BS
497 unbind_call1:
498- unbind_from_per_cpu_irq(call1func_irq, cpu);
499+ unbind_from_per_cpu_irq(call1func_irq, cpu, NULL);
500 unbind_call:
501- unbind_from_per_cpu_irq(callfunc_irq, cpu);
502+ unbind_from_per_cpu_irq(callfunc_irq, cpu, NULL);
503 unbind_resched:
504- unbind_from_per_cpu_irq(resched_irq, cpu);
505+ unbind_from_per_cpu_irq(resched_irq, cpu, NULL);
cc90b958
BS
506 return rc;
507 }
00e5a55c
BS
508
509@@ -177,9 +177,9 @@ static void __cpuinit xen_smp_intr_exit(
cc90b958
BS
510 if (cpu != 0)
511 local_teardown_timer(cpu);
512
513- unbind_from_per_cpu_irq(resched_irq, cpu);
514- unbind_from_per_cpu_irq(callfunc_irq, cpu);
515- unbind_from_per_cpu_irq(call1func_irq, cpu);
516+ unbind_from_per_cpu_irq(resched_irq, cpu, NULL);
517+ unbind_from_per_cpu_irq(callfunc_irq, cpu, NULL);
518+ unbind_from_per_cpu_irq(call1func_irq, cpu, NULL);
519 xen_spinlock_cleanup(cpu);
520 }
521 #endif
00e5a55c
BS
522--- sle11-2009-06-04.orig/drivers/xen/core/spinlock.c 2009-06-04 10:47:21.000000000 +0200
523+++ sle11-2009-06-04/drivers/xen/core/spinlock.c 2009-06-04 10:47:28.000000000 +0200
524@@ -57,7 +57,7 @@ int __cpuinit xen_spinlock_init(unsigned
525
cc90b958
BS
526 void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
527 {
00e5a55c
BS
528- unbind_from_per_cpu_irq(spinlock_irq, cpu);
529+ unbind_from_per_cpu_irq(spinlock_irq, cpu, NULL);
cc90b958
BS
530 }
531
532 int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
00e5a55c
BS
533--- sle11-2009-06-04.orig/drivers/xen/netback/netback.c 2009-06-04 10:20:21.000000000 +0200
534+++ sle11-2009-06-04/drivers/xen/netback/netback.c 2009-06-04 10:47:28.000000000 +0200
535@@ -1561,6 +1561,12 @@ static irqreturn_t netif_be_dbg(int irq,
cc90b958
BS
536
537 return IRQ_HANDLED;
538 }
539+
540+static struct irqaction netif_be_dbg_action = {
541+ .handler = netif_be_dbg,
542+ .flags = IRQF_SHARED,
543+ .name = "net-be-dbg"
544+};
545 #endif
546
547 static int __init netback_init(void)
00e5a55c 548@@ -1620,12 +1626,9 @@ static int __init netback_init(void)
cc90b958
BS
549 netif_xenbus_init();
550
551 #ifdef NETBE_DEBUG_INTERRUPT
552- (void)bind_virq_to_irqhandler(VIRQ_DEBUG,
553- 0,
554- netif_be_dbg,
555- IRQF_SHARED,
556- "net-be-dbg",
557- &netif_be_dbg);
558+ (void)bind_virq_to_irqaction(VIRQ_DEBUG,
559+ 0,
560+ &netif_be_dbg_action);
561 #endif
562
563 return 0;
00e5a55c
BS
564--- sle11-2009-06-04.orig/drivers/xen/xenoprof/xenoprofile.c 2009-06-04 10:20:39.000000000 +0200
565+++ sle11-2009-06-04/drivers/xen/xenoprof/xenoprofile.c 2009-06-04 10:47:28.000000000 +0200
566@@ -210,6 +210,11 @@ static irqreturn_t xenoprof_ovf_interrup
cc90b958
BS
567 return IRQ_HANDLED;
568 }
569
570+static struct irqaction ovf_action = {
571+ .handler = xenoprof_ovf_interrupt,
572+ .flags = IRQF_DISABLED,
573+ .name = "xenoprof"
574+};
575
576 static void unbind_virq(void)
577 {
00e5a55c 578@@ -217,7 +222,7 @@ static void unbind_virq(void)
cc90b958
BS
579
580 for_each_online_cpu(i) {
581 if (ovf_irq[i] >= 0) {
582- unbind_from_irqhandler(ovf_irq[i], NULL);
583+ unbind_from_per_cpu_irq(ovf_irq[i], i, &ovf_action);
584 ovf_irq[i] = -1;
585 }
586 }
00e5a55c 587@@ -230,12 +235,7 @@ static int bind_virq(void)
cc90b958
BS
588 int result;
589
590 for_each_online_cpu(i) {
591- result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
592- i,
593- xenoprof_ovf_interrupt,
594- IRQF_DISABLED|IRQF_NOBALANCING,
595- "xenoprof",
596- NULL);
597+ result = bind_virq_to_irqaction(VIRQ_XENOPROF, i, &ovf_action);
598
599 if (result < 0) {
600 unbind_virq();
00e5a55c
BS
601--- sle11-2009-06-04.orig/include/xen/evtchn.h 2009-06-04 10:47:21.000000000 +0200
602+++ sle11-2009-06-04/include/xen/evtchn.h 2009-06-04 10:47:28.000000000 +0200
cc90b958
BS
603@@ -78,6 +78,17 @@ int bind_virq_to_irqhandler(
604 unsigned long irqflags,
605 const char *devname,
606 void *dev_id);
607+#if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
608+int bind_virq_to_irqaction(
609+ unsigned int virq,
610+ unsigned int cpu,
611+ struct irqaction *action);
612+#else
613+#define bind_virq_to_irqaction(virq, cpu, action) \
614+ bind_virq_to_irqhandler(virq, cpu, (action)->handler, \
615+ (action)->flags | IRQF_NOBALANCING, \
616+ (action)->name, action)
617+#endif
618 #if defined(CONFIG_SMP) && !defined(MODULE)
619 #ifndef CONFIG_X86
620 int bind_ipi_to_irqhandler(
621@@ -102,9 +113,13 @@ int bind_ipi_to_irqaction(
622 */
623 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
624
625-#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
626+#if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
627 /* Specialized unbind function for per-CPU IRQs. */
628-void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu);
629+void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu,
630+ struct irqaction *);
631+#else
632+#define unbind_from_per_cpu_irq(irq, cpu, action) \
633+ unbind_from_irqhandler(irq, action)
634 #endif
635
636 #ifndef CONFIG_XEN