]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Tony Ernst <tee@sgi.com> |
2 | Subject: sn2: preserve irq affinity set in PROM | |
3 | Patch-mainline: No, this is a one-off from the mainline fix | |
4 | References: bnc#457679 | |
5 | ||
6 | The latest SLES11 has numerous changes in the | |
7 | request_irq() path, the one of issue is irq_select_affinity(), | |
8 | which reassigns an IRQ to a CPU. And, in the case of SN2 Altix, | |
9 | it assigns every IRQ to the same CPU; CPU0 in most cases, except | |
10 | on systems like rappel where it's CPU1, due to the Shub1.1 restrictions. | |
11 | ||
12 | This is a problem. Unlike most platforms, on Altix, the assignment | |
13 | of an IRQ to a CPU is determined and setup in the PROM, and the kernel | |
14 | is not expected to change this, except in the case of a manual | |
15 | redirect/migration. | |
16 | ||
17 | Acked-by: Jeff Mahoney <jeffm@suse.com> | |
18 | --- | |
19 | arch/ia64/sn/kernel/irq.c | 5 +++++ | |
20 | include/linux/irq.h | 1 + | |
21 | kernel/irq/manage.c | 11 +++++++++++ | |
22 | 3 files changed, 17 insertions(+) | |
23 | ||
24 | --- a/arch/ia64/sn/kernel/irq.c 2008-10-09 17:13:53.000000000 -0500 | |
25 | +++ b/arch/ia64/sn/kernel/irq.c 2008-12-18 13:34:46.822283902 -0600 | |
26 | @@ -391,6 +391,11 @@ | |
27 | #ifdef CONFIG_SMP | |
28 | cpuphys = cpu_physical_id(cpu); | |
29 | set_irq_affinity_info(sn_irq_info->irq_irq, cpuphys, 0); | |
30 | + /* | |
31 | + * Affinity was set by the PROM, prevent it from | |
32 | + * being reset by the request_irq() path. | |
33 | + */ | |
34 | + irq_desc[sn_irq_info->irq_irq].status |= IRQ_AFFINITY_SET; | |
35 | #endif | |
36 | } | |
37 | ||
38 | --- a/include/linux/irq.h 2008-12-16 11:27:10.000000000 -0600 | |
39 | +++ b/include/linux/irq.h 2008-12-18 13:49:23.519706754 -0600 | |
40 | @@ -63,6 +63,7 @@ | |
41 | #define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */ | |
42 | #define IRQ_SPURIOUS_DISABLED 0x00800000 /* IRQ was disabled by the spurious trap */ | |
43 | #define IRQ_MOVE_PCNTXT 0x01000000 /* IRQ migration from process context */ | |
44 | +#define IRQ_AFFINITY_SET 0x02000000 /* IRQ affinity was previously set */ | |
45 | ||
46 | #ifdef CONFIG_IRQ_PER_CPU | |
47 | # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) | |
48 | --- a/kernel/irq/manage.c 2008-12-16 11:27:10.000000000 -0600 | |
49 | +++ b/kernel/irq/manage.c 2008-12-18 13:36:15.693395542 -0600 | |
50 | @@ -117,6 +117,17 @@ | |
51 | ||
52 | cpus_and(mask, cpu_online_map, irq_default_affinity); | |
53 | ||
54 | + /* | |
55 | + * Preserve the affinity that was previously set, but make | |
56 | + * sure one of the targets is online. | |
57 | + */ | |
58 | + if (irq_desc[irq].status & IRQ_AFFINITY_SET) { | |
59 | + if (cpus_intersects(irq_desc[irq].affinity, cpu_online_map)) | |
60 | + mask = irq_desc[irq].affinity; | |
61 | + else | |
62 | + irq_desc[irq].status &= ~IRQ_AFFINITY_SET; | |
63 | + } | |
64 | + | |
65 | irq_desc[irq].affinity = mask; | |
66 | irq_desc[irq].chip->set_affinity(irq, mask); | |
67 |