diff options
| -rw-r--r-- | kernel/softirq.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c index b5197dcb0dad..3d6833f125d3 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
| @@ -195,8 +195,12 @@ void local_bh_enable_ip(unsigned long ip) | |||
| 195 | EXPORT_SYMBOL(local_bh_enable_ip); | 195 | EXPORT_SYMBOL(local_bh_enable_ip); |
| 196 | 196 | ||
| 197 | /* | 197 | /* |
| 198 | * We restart softirq processing for at most 2 ms, | 198 | * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times, |
| 199 | * and if need_resched() is not set. | 199 | * but break the loop if need_resched() is set or after 2 ms. |
| 200 | * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in | ||
| 201 | * certain cases, such as stop_machine(), jiffies may cease to | ||
| 202 | * increment and so we need the MAX_SOFTIRQ_RESTART limit as | ||
| 203 | * well to make sure we eventually return from this method. | ||
| 200 | * | 204 | * |
| 201 | * These limits have been established via experimentation. | 205 | * These limits have been established via experimentation. |
| 202 | * The two things to balance is latency against fairness - | 206 | * The two things to balance is latency against fairness - |
| @@ -204,6 +208,7 @@ EXPORT_SYMBOL(local_bh_enable_ip); | |||
| 204 | * should not be able to lock up the box. | 208 | * should not be able to lock up the box. |
| 205 | */ | 209 | */ |
| 206 | #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) | 210 | #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) |
| 211 | #define MAX_SOFTIRQ_RESTART 10 | ||
| 207 | 212 | ||
| 208 | asmlinkage void __do_softirq(void) | 213 | asmlinkage void __do_softirq(void) |
| 209 | { | 214 | { |
| @@ -212,6 +217,7 @@ asmlinkage void __do_softirq(void) | |||
| 212 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; | 217 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; |
| 213 | int cpu; | 218 | int cpu; |
| 214 | unsigned long old_flags = current->flags; | 219 | unsigned long old_flags = current->flags; |
| 220 | int max_restart = MAX_SOFTIRQ_RESTART; | ||
| 215 | 221 | ||
| 216 | /* | 222 | /* |
| 217 | * Mask out PF_MEMALLOC s current task context is borrowed for the | 223 | * Mask out PF_MEMALLOC s current task context is borrowed for the |
| @@ -265,7 +271,8 @@ restart: | |||
| 265 | 271 | ||
| 266 | pending = local_softirq_pending(); | 272 | pending = local_softirq_pending(); |
| 267 | if (pending) { | 273 | if (pending) { |
| 268 | if (time_before(jiffies, end) && !need_resched()) | 274 | if (time_before(jiffies, end) && !need_resched() && |
| 275 | --max_restart) | ||
| 269 | goto restart; | 276 | goto restart; |
| 270 | 277 | ||
| 271 | wakeup_softirqd(); | 278 | wakeup_softirqd(); |
