aboutsummaryrefslogtreecommitdiff
path: root/kernel/softirq.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2013-07-02 08:31:48 +0200
committerJens Axboe <axboe@kernel.dk>2013-07-02 08:31:48 +0200
commit5f0e5afa0de4522abb3ea7d1369039b94e740ec5 (patch)
tree6a5be3db9ecfed8ef2150c6146f6d1e0d658ac8b /kernel/softirq.c
parentd752b2696072ed52fd5afab08b601e2220a3b87e (diff)
parent9e895ace5d82df8929b16f58e9f515f6d54ab82d (diff)
Merge tag 'v3.10-rc7' into for-3.11/drivers
Linux 3.10-rc7 Pull this in early to avoid doing it with the bcache merge, since there are a number of changes to bcache between my old base (3.10-rc1) and the new pull request.
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r--kernel/softirq.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c
index b5197dcb0da..3d6833f125d 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -195,8 +195,12 @@ void local_bh_enable_ip(unsigned long ip)
EXPORT_SYMBOL(local_bh_enable_ip);
/*
- * We restart softirq processing for at most 2 ms,
- * and if need_resched() is not set.
+ * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times,
+ * but break the loop if need_resched() is set or after 2 ms.
+ * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in
+ * certain cases, such as stop_machine(), jiffies may cease to
+ * increment and so we need the MAX_SOFTIRQ_RESTART limit as
+ * well to make sure we eventually return from this method.
*
* These limits have been established via experimentation.
* The two things to balance is latency against fairness -
@@ -204,6 +208,7 @@ EXPORT_SYMBOL(local_bh_enable_ip);
* should not be able to lock up the box.
*/
#define MAX_SOFTIRQ_TIME msecs_to_jiffies(2)
+#define MAX_SOFTIRQ_RESTART 10
asmlinkage void __do_softirq(void)
{
@@ -212,6 +217,7 @@ asmlinkage void __do_softirq(void)
unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
int cpu;
unsigned long old_flags = current->flags;
+ int max_restart = MAX_SOFTIRQ_RESTART;
/*
* Mask out PF_MEMALLOC s current task context is borrowed for the
@@ -265,7 +271,8 @@ restart:
pending = local_softirq_pending();
if (pending) {
- if (time_before(jiffies, end) && !need_resched())
+ if (time_before(jiffies, end) && !need_resched() &&
+ --max_restart)
goto restart;
wakeup_softirqd();