diff options
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r-- | kernel/softirq.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c index b5197dcb0dad..ca25e6e704a2 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -127,8 +127,7 @@ static inline void __local_bh_disable(unsigned long ip, unsigned int cnt) | |||
127 | 127 | ||
128 | void local_bh_disable(void) | 128 | void local_bh_disable(void) |
129 | { | 129 | { |
130 | __local_bh_disable((unsigned long)__builtin_return_address(0), | 130 | __local_bh_disable(_RET_IP_, SOFTIRQ_DISABLE_OFFSET); |
131 | SOFTIRQ_DISABLE_OFFSET); | ||
132 | } | 131 | } |
133 | 132 | ||
134 | EXPORT_SYMBOL(local_bh_disable); | 133 | EXPORT_SYMBOL(local_bh_disable); |
@@ -139,7 +138,7 @@ static void __local_bh_enable(unsigned int cnt) | |||
139 | WARN_ON_ONCE(!irqs_disabled()); | 138 | WARN_ON_ONCE(!irqs_disabled()); |
140 | 139 | ||
141 | if (softirq_count() == cnt) | 140 | if (softirq_count() == cnt) |
142 | trace_softirqs_on((unsigned long)__builtin_return_address(0)); | 141 | trace_softirqs_on(_RET_IP_); |
143 | sub_preempt_count(cnt); | 142 | sub_preempt_count(cnt); |
144 | } | 143 | } |
145 | 144 | ||
@@ -184,7 +183,7 @@ static inline void _local_bh_enable_ip(unsigned long ip) | |||
184 | 183 | ||
185 | void local_bh_enable(void) | 184 | void local_bh_enable(void) |
186 | { | 185 | { |
187 | _local_bh_enable_ip((unsigned long)__builtin_return_address(0)); | 186 | _local_bh_enable_ip(_RET_IP_); |
188 | } | 187 | } |
189 | EXPORT_SYMBOL(local_bh_enable); | 188 | EXPORT_SYMBOL(local_bh_enable); |
190 | 189 | ||
@@ -195,8 +194,12 @@ void local_bh_enable_ip(unsigned long ip) | |||
195 | EXPORT_SYMBOL(local_bh_enable_ip); | 194 | EXPORT_SYMBOL(local_bh_enable_ip); |
196 | 195 | ||
197 | /* | 196 | /* |
198 | * We restart softirq processing for at most 2 ms, | 197 | * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times, |
199 | * and if need_resched() is not set. | 198 | * but break the loop if need_resched() is set or after 2 ms. |
199 | * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in | ||
200 | * certain cases, such as stop_machine(), jiffies may cease to | ||
201 | * increment and so we need the MAX_SOFTIRQ_RESTART limit as | ||
202 | * well to make sure we eventually return from this method. | ||
200 | * | 203 | * |
201 | * These limits have been established via experimentation. | 204 | * These limits have been established via experimentation. |
202 | * The two things to balance is latency against fairness - | 205 | * The two things to balance is latency against fairness - |
@@ -204,6 +207,7 @@ EXPORT_SYMBOL(local_bh_enable_ip); | |||
204 | * should not be able to lock up the box. | 207 | * should not be able to lock up the box. |
205 | */ | 208 | */ |
206 | #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) | 209 | #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) |
210 | #define MAX_SOFTIRQ_RESTART 10 | ||
207 | 211 | ||
208 | asmlinkage void __do_softirq(void) | 212 | asmlinkage void __do_softirq(void) |
209 | { | 213 | { |
@@ -212,6 +216,7 @@ asmlinkage void __do_softirq(void) | |||
212 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; | 216 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; |
213 | int cpu; | 217 | int cpu; |
214 | unsigned long old_flags = current->flags; | 218 | unsigned long old_flags = current->flags; |
219 | int max_restart = MAX_SOFTIRQ_RESTART; | ||
215 | 220 | ||
216 | /* | 221 | /* |
217 | * Mask out PF_MEMALLOC s current task context is borrowed for the | 222 | * Mask out PF_MEMALLOC s current task context is borrowed for the |
@@ -223,8 +228,7 @@ asmlinkage void __do_softirq(void) | |||
223 | pending = local_softirq_pending(); | 228 | pending = local_softirq_pending(); |
224 | account_irq_enter_time(current); | 229 | account_irq_enter_time(current); |
225 | 230 | ||
226 | __local_bh_disable((unsigned long)__builtin_return_address(0), | 231 | __local_bh_disable(_RET_IP_, SOFTIRQ_OFFSET); |
227 | SOFTIRQ_OFFSET); | ||
228 | lockdep_softirq_enter(); | 232 | lockdep_softirq_enter(); |
229 | 233 | ||
230 | cpu = smp_processor_id(); | 234 | cpu = smp_processor_id(); |
@@ -265,7 +269,8 @@ restart: | |||
265 | 269 | ||
266 | pending = local_softirq_pending(); | 270 | pending = local_softirq_pending(); |
267 | if (pending) { | 271 | if (pending) { |
268 | if (time_before(jiffies, end) && !need_resched()) | 272 | if (time_before(jiffies, end) && !need_resched() && |
273 | --max_restart) | ||
269 | goto restart; | 274 | goto restart; |
270 | 275 | ||
271 | wakeup_softirqd(); | 276 | wakeup_softirqd(); |