]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/make-note_interrupt-fast.diff
Add a patch to fix Intel E100 wake-on-lan problems.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / make-note_interrupt-fast.diff
1 From: Bernhard Walle <bwalle@suse.de>
2 Subject: [PATCH] Fix performance regression on large IA64 systems
3 References: bnc #469589
4
5 This patch tries to address a performance regression discovered by SGI.
6
7 Patch b60c1f6ffd88850079ae419aa933ab0eddbd5535 removes the call
8 to note_interrupt() in __do_IRQ(). Patch d85a60d85ea5b7c597508c1510c88e657773d378
9 adds it again. Because it's needed for irqpoll.
10
11 That patch now introduces a new parameter 'only_fixup' for note_interrupt().
12 This parameter determines two cases:
13
14 TRUE => The function should be only executed when irqfixup is set.
15 Either 'irqpoll' or 'irqfixup' directly set that.
16
17 FALSE => Just the behaviour as note_interrupt() always had.
18
19 Now the patch converts all calls of note_interrupt() to only_fixup=FALSE,
20 except the call that has been removed by b60c1f6ffd88850079ae419aa933ab0eddbd5535.
21 So that call is always done, but the body is only executed when either
22 'irqpoll' or 'irqfixup' are specified.
23
24 This patch is not meant for mainline inclusion in the first run!
25
26
27 Signed-off-by: Bernhard Walle <bwalle@suse.de>
28
29 ---
30 arch/arm/mach-ns9xxx/irq.c | 2 +-
31 arch/powerpc/platforms/cell/interrupt.c | 2 +-
32 include/linux/irq.h | 2 +-
33 kernel/irq/chip.c | 10 +++++-----
34 kernel/irq/handle.c | 4 ++--
35 kernel/irq/spurious.c | 13 ++++++++++++-
36 6 files changed, 22 insertions(+), 11 deletions(-)
37
38 --- a/arch/arm/mach-ns9xxx/irq.c
39 +++ b/arch/arm/mach-ns9xxx/irq.c
40 @@ -86,7 +86,7 @@ static void handle_prio_irq(unsigned int
41 /* XXX: There is no direct way to access noirqdebug, so check
42 * unconditionally for spurious irqs...
43 * Maybe this function should go to kernel/irq/chip.c? */
44 - note_interrupt(irq, desc, action_ret);
45 + note_interrupt(irq, desc, action_ret, 0);
46
47 spin_lock(&desc->lock);
48 desc->status &= ~IRQ_INPROGRESS;
49 --- a/arch/powerpc/platforms/cell/interrupt.c
50 +++ b/arch/powerpc/platforms/cell/interrupt.c
51 @@ -270,7 +270,7 @@ static void handle_iic_irq(unsigned int
52 spin_unlock(&desc->lock);
53 action_ret = handle_IRQ_event(irq, action);
54 if (!noirqdebug)
55 - note_interrupt(irq, desc, action_ret);
56 + note_interrupt(irq, desc, action_ret, 0);
57 spin_lock(&desc->lock);
58
59 } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
60 --- a/include/linux/irq.h
61 +++ b/include/linux/irq.h
62 @@ -296,7 +296,7 @@ static inline void generic_handle_irq(un
63
64 /* Handling of unhandled and spurious interrupts: */
65 extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
66 - int action_ret);
67 + int action_ret, int only_fixup);
68
69 /* Resending of interrupts :*/
70 void check_irq_resend(struct irq_desc *desc, unsigned int irq);
71 --- a/kernel/irq/chip.c
72 +++ b/kernel/irq/chip.c
73 @@ -324,7 +324,7 @@ handle_simple_irq(unsigned int irq, stru
74
75 action_ret = handle_IRQ_event(irq, action);
76 if (!noirqdebug)
77 - note_interrupt(irq, desc, action_ret);
78 + note_interrupt(irq, desc, action_ret, 0);
79
80 spin_lock(&desc->lock);
81 desc->status &= ~IRQ_INPROGRESS;
82 @@ -370,7 +370,7 @@ handle_level_irq(unsigned int irq, struc
83
84 action_ret = handle_IRQ_event(irq, action);
85 if (!noirqdebug)
86 - note_interrupt(irq, desc, action_ret);
87 + note_interrupt(irq, desc, action_ret, 0);
88
89 spin_lock(&desc->lock);
90 desc->status &= ~IRQ_INPROGRESS;
91 @@ -423,7 +423,7 @@ handle_fasteoi_irq(unsigned int irq, str
92
93 action_ret = handle_IRQ_event(irq, action);
94 if (!noirqdebug)
95 - note_interrupt(irq, desc, action_ret);
96 + note_interrupt(irq, desc, action_ret, 0);
97
98 spin_lock(&desc->lock);
99 desc->status &= ~IRQ_INPROGRESS;
100 @@ -503,7 +503,7 @@ handle_edge_irq(unsigned int irq, struct
101 spin_unlock(&desc->lock);
102 action_ret = handle_IRQ_event(irq, action);
103 if (!noirqdebug)
104 - note_interrupt(irq, desc, action_ret);
105 + note_interrupt(irq, desc, action_ret, 0);
106 spin_lock(&desc->lock);
107
108 } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
109 @@ -532,7 +532,7 @@ handle_percpu_irq(unsigned int irq, stru
110
111 action_ret = handle_IRQ_event(irq, desc->action);
112 if (!noirqdebug)
113 - note_interrupt(irq, desc, action_ret);
114 + note_interrupt(irq, desc, action_ret, 0);
115
116 if (desc->chip->eoi)
117 desc->chip->eoi(irq);
118 --- a/kernel/irq/handle.c
119 +++ b/kernel/irq/handle.c
120 @@ -187,7 +187,7 @@ unsigned int __do_IRQ(unsigned int irq)
121 if (likely(!(desc->status & IRQ_DISABLED))) {
122 action_ret = handle_IRQ_event(irq, desc->action);
123 if (!noirqdebug)
124 - note_interrupt(irq, desc, action_ret);
125 + note_interrupt(irq, desc, action_ret, 1);
126 }
127 desc->chip->end(irq);
128 return 1;
129 @@ -241,7 +241,7 @@ unsigned int __do_IRQ(unsigned int irq)
130
131 action_ret = handle_IRQ_event(irq, action);
132 if (!noirqdebug)
133 - note_interrupt(irq, desc, action_ret);
134 + note_interrupt(irq, desc, action_ret, 0);
135
136 spin_lock(&desc->lock);
137 if (likely(!(desc->status & IRQ_PENDING)))
138 --- a/kernel/irq/spurious.c
139 +++ b/kernel/irq/spurious.c
140 @@ -171,8 +171,19 @@ static inline int try_misrouted_irq(unsi
141 }
142
143 void note_interrupt(unsigned int irq, struct irq_desc *desc,
144 - irqreturn_t action_ret)
145 + irqreturn_t action_ret, int only_fixup)
146 {
147 + /*
148 + * The parameter "only_fixup" means that the function should be only
149 + * executed if this parameter is set to 1 and the function should
150 + * not be executed if the parameter is 0.
151 + *
152 + * We need that because irqfixup is static to the function but
153 + * this function is called from kernel/irq/handle.c.
154 + */
155 + if (only_fixup && irqfixup == 0)
156 + return;
157 +
158 if (unlikely(action_ret != IRQ_HANDLED)) {
159 /*
160 * If we are seeing only the odd spurious IRQ caused by