aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hung_task.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hung_task.c')
-rw-r--r--kernel/hung_task.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index ba8ccd432963..481ca8b5c2bc 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -17,9 +17,18 @@
17#include <linux/sysctl.h> 17#include <linux/sysctl.h>
18 18
19/* 19/*
20 * Have a reasonable limit on the number of tasks checked: 20 * The number of tasks checked:
21 */ 21 */
22unsigned long __read_mostly sysctl_hung_task_check_count = 1024; 22unsigned long __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT;
23
24/*
25 * Limit number of tasks checked in a batch.
26 *
27 * This value controls the preemptibility of khungtaskd since preemption
28 * is disabled during the critical section. It also controls the size of
29 * the RCU grace period. So it needs to be upper-bound.
30 */
31#define HUNG_TASK_BATCHING 1024
23 32
24/* 33/*
25 * Zero means infinite timeout - no checking done: 34 * Zero means infinite timeout - no checking done:
@@ -110,6 +119,24 @@ static void check_hung_task(struct task_struct *t, unsigned long now,
110} 119}
111 120
112/* 121/*
122 * To avoid extending the RCU grace period for an unbounded amount of time,
123 * periodically exit the critical section and enter a new one.
124 *
125 * For preemptible RCU it is sufficient to call rcu_read_unlock in order
126 * exit the grace period. For classic RCU, a reschedule is required.
127 */
128static void rcu_lock_break(struct task_struct *g, struct task_struct *t)
129{
130 get_task_struct(g);
131 get_task_struct(t);
132 rcu_read_unlock();
133 cond_resched();
134 rcu_read_lock();
135 put_task_struct(t);
136 put_task_struct(g);
137}
138
139/*
113 * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for 140 * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for
114 * a really long time (120 seconds). If that happens, print out 141 * a really long time (120 seconds). If that happens, print out
115 * a warning. 142 * a warning.
@@ -117,6 +144,7 @@ static void check_hung_task(struct task_struct *t, unsigned long now,
117static void check_hung_uninterruptible_tasks(unsigned long timeout) 144static void check_hung_uninterruptible_tasks(unsigned long timeout)
118{ 145{
119 int max_count = sysctl_hung_task_check_count; 146 int max_count = sysctl_hung_task_check_count;
147 int batch_count = HUNG_TASK_BATCHING;
120 unsigned long now = get_timestamp(); 148 unsigned long now = get_timestamp();
121 struct task_struct *g, *t; 149 struct task_struct *g, *t;
122 150
@@ -131,6 +159,13 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
131 do_each_thread(g, t) { 159 do_each_thread(g, t) {
132 if (!--max_count) 160 if (!--max_count)
133 goto unlock; 161 goto unlock;
162 if (!--batch_count) {
163 batch_count = HUNG_TASK_BATCHING;
164 rcu_lock_break(g, t);
165 /* Exit if t or g was unhashed during refresh. */
166 if (t->state == TASK_DEAD || g->state == TASK_DEAD)
167 goto unlock;
168 }
134 /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ 169 /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */
135 if (t->state == TASK_UNINTERRUPTIBLE) 170 if (t->state == TASK_UNINTERRUPTIBLE)
136 check_hung_task(t, now, timeout); 171 check_hung_task(t, now, timeout);