summaryrefslogtreecommitdiffstats
path: root/kernel/hung_task.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hung_task.c')
-rw-r--r--kernel/hung_task.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index cb8e3e8ac7b9..4a9191617076 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -34,7 +34,7 @@ int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT;
34 * is disabled during the critical section. It also controls the size of 34 * is disabled during the critical section. It also controls the size of
35 * the RCU grace period. So it needs to be upper-bound. 35 * the RCU grace period. So it needs to be upper-bound.
36 */ 36 */
37#define HUNG_TASK_BATCHING 1024 37#define HUNG_TASK_LOCK_BREAK (HZ / 10)
38 38
39/* 39/*
40 * Zero means infinite timeout - no checking done: 40 * Zero means infinite timeout - no checking done:
@@ -112,8 +112,11 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
112 112
113 trace_sched_process_hang(t); 113 trace_sched_process_hang(t);
114 114
115 if (!sysctl_hung_task_warnings && !sysctl_hung_task_panic) 115 if (sysctl_hung_task_panic) {
116 return; 116 console_verbose();
117 hung_task_show_lock = true;
118 hung_task_call_panic = true;
119 }
117 120
118 /* 121 /*
119 * Ok, the task did not get scheduled for more than 2 minutes, 122 * Ok, the task did not get scheduled for more than 2 minutes,
@@ -135,11 +138,6 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
135 } 138 }
136 139
137 touch_nmi_watchdog(); 140 touch_nmi_watchdog();
138
139 if (sysctl_hung_task_panic) {
140 hung_task_show_lock = true;
141 hung_task_call_panic = true;
142 }
143} 141}
144 142
145/* 143/*
@@ -173,7 +171,7 @@ static bool rcu_lock_break(struct task_struct *g, struct task_struct *t)
173static void check_hung_uninterruptible_tasks(unsigned long timeout) 171static void check_hung_uninterruptible_tasks(unsigned long timeout)
174{ 172{
175 int max_count = sysctl_hung_task_check_count; 173 int max_count = sysctl_hung_task_check_count;
176 int batch_count = HUNG_TASK_BATCHING; 174 unsigned long last_break = jiffies;
177 struct task_struct *g, *t; 175 struct task_struct *g, *t;
178 176
179 /* 177 /*
@@ -188,10 +186,10 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
188 for_each_process_thread(g, t) { 186 for_each_process_thread(g, t) {
189 if (!max_count--) 187 if (!max_count--)
190 goto unlock; 188 goto unlock;
191 if (!--batch_count) { 189 if (time_after(jiffies, last_break + HUNG_TASK_LOCK_BREAK)) {
192 batch_count = HUNG_TASK_BATCHING;
193 if (!rcu_lock_break(g, t)) 190 if (!rcu_lock_break(g, t))
194 goto unlock; 191 goto unlock;
192 last_break = jiffies;
195 } 193 }
196 /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ 194 /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */
197 if (t->state == TASK_UNINTERRUPTIBLE) 195 if (t->state == TASK_UNINTERRUPTIBLE)