Blame view
kernel/hung_task.c
7.48 KB
457c89965 treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
e162b39a3 softlockup: decou... |
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * Detect Hung Task * * kernel/hung_task.c - kernel thread for detecting tasks stuck in D state * */ #include <linux/mm.h> #include <linux/cpu.h> #include <linux/nmi.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/freezer.h> #include <linux/kthread.h> #include <linux/lockdep.h> |
9984de1a5 kernel: Map most ... |
17 |
#include <linux/export.h> |
e162b39a3 softlockup: decou... |
18 |
#include <linux/sysctl.h> |
a1c6ca3c6 kernel: hung_task... |
19 |
#include <linux/suspend.h> |
41e85ce82 hung_task debuggi... |
20 |
#include <linux/utsname.h> |
3f07c0144 sched/headers: Pr... |
21 |
#include <linux/sched/signal.h> |
b17b01533 sched/headers: Pr... |
22 |
#include <linux/sched/debug.h> |
a98eb6f19 kernel/hung_task.... |
23 |
#include <linux/sched/sysctl.h> |
3f07c0144 sched/headers: Pr... |
24 |
|
6a716c90a hung_task debuggi... |
25 |
#include <trace/events/sched.h> |
e162b39a3 softlockup: decou... |
26 27 |
/* |
ce9dbe244 softlockup: check... |
28 |
* The number of tasks checked: |
e162b39a3 softlockup: decou... |
29 |
*/ |
cd64647f0 hung_task: Change... |
30 |
int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; |
ce9dbe244 softlockup: check... |
31 32 33 34 35 36 37 38 |
/* * Limit number of tasks checked in a batch. * * This value controls the preemptibility of khungtaskd since preemption * is disabled during the critical section. It also controls the size of * the RCU grace period. So it needs to be upper-bound. */ |
304ae4273 kernel/hung_task.... |
39 |
#define HUNG_TASK_LOCK_BREAK (HZ / 10) |
e162b39a3 softlockup: decou... |
40 41 42 43 |
/* * Zero means infinite timeout - no checking done: */ |
e11feaa11 watchdog, hung_ta... |
44 |
unsigned long __read_mostly sysctl_hung_task_timeout_secs = CONFIG_DEFAULT_HUNG_TASK_TIMEOUT; |
e162b39a3 softlockup: decou... |
45 |
|
a2e514453 kernel/hung_task.... |
46 47 48 49 |
/* * Zero (default value) means use sysctl_hung_task_timeout_secs: */ unsigned long __read_mostly sysctl_hung_task_check_interval_secs; |
270750dbc hung_task: Displa... |
50 |
int __read_mostly sysctl_hung_task_warnings = 10; |
e162b39a3 softlockup: decou... |
51 52 |
static int __read_mostly did_panic; |
780cbcf28 kernel/hung_task.... |
53 |
static bool hung_task_show_lock; |
401c636a0 kernel/hung_task.... |
54 |
static bool hung_task_call_panic; |
0ec9dc9bc kernel/hung_task.... |
55 |
static bool hung_task_show_all_bt; |
e162b39a3 softlockup: decou... |
56 57 |
static struct task_struct *watchdog_task; |
0ec9dc9bc kernel/hung_task.... |
58 59 60 61 62 63 64 |
#ifdef CONFIG_SMP /* * Should we dump all CPUs backtraces in a hung task event? * Defaults to 0, can be changed via sysctl. */ unsigned int __read_mostly sysctl_hung_task_all_cpu_backtrace; #endif /* CONFIG_SMP */ |
e162b39a3 softlockup: decou... |
65 66 67 68 69 70 |
/* * Should we panic (and reboot, if panic_timeout= is set) when a * hung task is detected: */ unsigned int __read_mostly sysctl_hung_task_panic = CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE; |
e162b39a3 softlockup: decou... |
71 72 73 74 75 76 77 78 79 80 81 |
static int hung_task_panic(struct notifier_block *this, unsigned long event, void *ptr) { did_panic = 1; return NOTIFY_DONE; } static struct notifier_block panic_block = { .notifier_call = hung_task_panic, }; |
17406b82d softlockup: remov... |
82 |
static void check_hung_task(struct task_struct *t, unsigned long timeout) |
e162b39a3 softlockup: decou... |
83 84 |
{ unsigned long switch_count = t->nvcsw + t->nivcsw; |
cf2592f59 softlockup: ensur... |
85 86 |
/* * Ensure the task is not frozen. |
f9fab10bb hung_task: fix fa... |
87 |
* Also, skip vfork and any other user process that freezer should skip. |
cf2592f59 softlockup: ensur... |
88 |
*/ |
f9fab10bb hung_task: fix fa... |
89 90 91 92 93 94 95 96 97 |
if (unlikely(t->flags & (PF_FROZEN | PF_FREEZER_SKIP))) return; /* * When a freshly created task is scheduled once, changes its state to * TASK_UNINTERRUPTIBLE without having ever been switched out once, it * musn't be checked. */ if (unlikely(!switch_count)) |
e162b39a3 softlockup: decou... |
98 |
return; |
17406b82d softlockup: remov... |
99 |
if (switch_count != t->last_switch_count) { |
e162b39a3 softlockup: decou... |
100 |
t->last_switch_count = switch_count; |
a2e514453 kernel/hung_task.... |
101 |
t->last_switch_time = jiffies; |
e162b39a3 softlockup: decou... |
102 103 |
return; } |
a2e514453 kernel/hung_task.... |
104 105 |
if (time_is_after_jiffies(t->last_switch_time + timeout * HZ)) return; |
6a716c90a hung_task debuggi... |
106 107 |
trace_sched_process_hang(t); |
168e06f79 kernel/hung_task.... |
108 109 110 111 112 |
if (sysctl_hung_task_panic) { console_verbose(); hung_task_show_lock = true; hung_task_call_panic = true; } |
270750dbc hung_task: Displa... |
113 |
|
e162b39a3 softlockup: decou... |
114 115 116 117 |
/* * Ok, the task did not get scheduled for more than 2 minutes, * complain: */ |
48a6d64ed hung_task: allow ... |
118 |
if (sysctl_hung_task_warnings) { |
4ca5ede07 hung_task: decrem... |
119 120 |
if (sysctl_hung_task_warnings > 0) sysctl_hung_task_warnings--; |
48a6d64ed hung_task: allow ... |
121 122 |
pr_err("INFO: task %s:%d blocked for more than %ld seconds. ", |
b014bebab kernel/hung_task.... |
123 |
t->comm, t->pid, (jiffies - t->last_switch_time) / HZ); |
48a6d64ed hung_task: allow ... |
124 125 126 127 128 129 130 131 132 |
pr_err(" %s %s %.*s ", print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); pr_err("\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" " disables this message. "); sched_show_task(t); |
780cbcf28 kernel/hung_task.... |
133 |
hung_task_show_lock = true; |
0ec9dc9bc kernel/hung_task.... |
134 135 136 |
if (sysctl_hung_task_all_cpu_backtrace) hung_task_show_all_bt = true; |
48a6d64ed hung_task: allow ... |
137 |
} |
e162b39a3 softlockup: decou... |
138 |
|
e162b39a3 softlockup: decou... |
139 |
touch_nmi_watchdog(); |
e162b39a3 softlockup: decou... |
140 141 142 |
} /* |
ce9dbe244 softlockup: check... |
143 144 145 146 |
* To avoid extending the RCU grace period for an unbounded amount of time, * periodically exit the critical section and enter a new one. * * For preemptible RCU it is sufficient to call rcu_read_unlock in order |
6a103b0d4 lockup detector: ... |
147 |
* to exit the grace period. For classic RCU, a reschedule is required. |
ce9dbe244 softlockup: check... |
148 |
*/ |
6027ce497 hung_task: fix th... |
149 |
static bool rcu_lock_break(struct task_struct *g, struct task_struct *t) |
ce9dbe244 softlockup: check... |
150 |
{ |
6027ce497 hung_task: fix th... |
151 |
bool can_cont; |
ce9dbe244 softlockup: check... |
152 153 154 155 156 |
get_task_struct(g); get_task_struct(t); rcu_read_unlock(); cond_resched(); rcu_read_lock(); |
6027ce497 hung_task: fix th... |
157 |
can_cont = pid_alive(g) && pid_alive(t); |
ce9dbe244 softlockup: check... |
158 159 |
put_task_struct(t); put_task_struct(g); |
6027ce497 hung_task: fix th... |
160 161 |
return can_cont; |
ce9dbe244 softlockup: check... |
162 163 164 |
} /* |
e162b39a3 softlockup: decou... |
165 166 167 168 |
* Check whether a TASK_UNINTERRUPTIBLE does not get woken up for * a really long time (120 seconds). If that happens, print out * a warning. */ |
603a148f4 softlockup: fix p... |
169 |
static void check_hung_uninterruptible_tasks(unsigned long timeout) |
e162b39a3 softlockup: decou... |
170 171 |
{ int max_count = sysctl_hung_task_check_count; |
304ae4273 kernel/hung_task.... |
172 |
unsigned long last_break = jiffies; |
e162b39a3 softlockup: decou... |
173 174 175 176 177 178 179 180 |
struct task_struct *g, *t; /* * If the system crashed already then all bets are off, * do not report extra hung tasks: */ if (test_taint(TAINT_DIE) || did_panic) return; |
780cbcf28 kernel/hung_task.... |
181 |
hung_task_show_lock = false; |
94be52dc0 softlockup: conve... |
182 |
rcu_read_lock(); |
972fae699 kernel/hung_task.... |
183 |
for_each_process_thread(g, t) { |
e5af02261 softlockup: Fix h... |
184 |
if (!max_count--) |
e162b39a3 softlockup: decou... |
185 |
goto unlock; |
304ae4273 kernel/hung_task.... |
186 |
if (time_after(jiffies, last_break + HUNG_TASK_LOCK_BREAK)) { |
6027ce497 hung_task: fix th... |
187 |
if (!rcu_lock_break(g, t)) |
ce9dbe244 softlockup: check... |
188 |
goto unlock; |
304ae4273 kernel/hung_task.... |
189 |
last_break = jiffies; |
ce9dbe244 softlockup: check... |
190 |
} |
e162b39a3 softlockup: decou... |
191 192 |
/* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) |
17406b82d softlockup: remov... |
193 |
check_hung_task(t, timeout); |
972fae699 kernel/hung_task.... |
194 |
} |
e162b39a3 softlockup: decou... |
195 |
unlock: |
94be52dc0 softlockup: conve... |
196 |
rcu_read_unlock(); |
780cbcf28 kernel/hung_task.... |
197 198 |
if (hung_task_show_lock) debug_show_all_locks(); |
0ec9dc9bc kernel/hung_task.... |
199 200 201 |
if (hung_task_show_all_bt) { hung_task_show_all_bt = false; |
401c636a0 kernel/hung_task.... |
202 |
trigger_all_cpu_backtrace(); |
401c636a0 kernel/hung_task.... |
203 |
} |
0ec9dc9bc kernel/hung_task.... |
204 205 206 |
if (hung_task_call_panic) panic("hung_task: blocked tasks"); |
e162b39a3 softlockup: decou... |
207 |
} |
b4aa14a63 kernel/hung_task.... |
208 209 |
static long hung_timeout_jiffies(unsigned long last_checked, unsigned long timeout) |
e162b39a3 softlockup: decou... |
210 211 |
{ /* timeout of 0 will disable the watchdog */ |
b4aa14a63 kernel/hung_task.... |
212 213 |
return timeout ? last_checked - jiffies + timeout * HZ : MAX_SCHEDULE_TIMEOUT; |
e162b39a3 softlockup: decou... |
214 215 216 217 218 219 |
} /* * Process updating of timeout sysctl */ int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, |
3b70ae4f5 kernel/hung_task.... |
220 |
void *buffer, size_t *lenp, loff_t *ppos) |
e162b39a3 softlockup: decou... |
221 222 |
{ int ret; |
8d65af789 sysctl: remove "s... |
223 |
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); |
e162b39a3 softlockup: decou... |
224 225 226 |
if (ret || !write) goto out; |
e162b39a3 softlockup: decou... |
227 228 229 230 231 |
wake_up_process(watchdog_task); out: return ret; } |
8b414521b hung_task: add me... |
232 233 234 235 236 237 238 |
static atomic_t reset_hung_task = ATOMIC_INIT(0); void reset_hung_task_detector(void) { atomic_set(&reset_hung_task, 1); } EXPORT_SYMBOL_GPL(reset_hung_task_detector); |
a1c6ca3c6 kernel: hung_task... |
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
static bool hung_detector_suspended; static int hungtask_pm_notify(struct notifier_block *self, unsigned long action, void *hcpu) { switch (action) { case PM_SUSPEND_PREPARE: case PM_HIBERNATION_PREPARE: case PM_RESTORE_PREPARE: hung_detector_suspended = true; break; case PM_POST_SUSPEND: case PM_POST_HIBERNATION: case PM_POST_RESTORE: hung_detector_suspended = false; break; default: break; } return NOTIFY_OK; } |
e162b39a3 softlockup: decou... |
260 261 262 263 264 |
/* * kthread which checks for tasks stuck in D state */ static int watchdog(void *dummy) { |
b4aa14a63 kernel/hung_task.... |
265 |
unsigned long hung_last_checked = jiffies; |
e162b39a3 softlockup: decou... |
266 |
set_user_nice(current, 0); |
e162b39a3 softlockup: decou... |
267 268 |
for ( ; ; ) { |
17406b82d softlockup: remov... |
269 |
unsigned long timeout = sysctl_hung_task_timeout_secs; |
a2e514453 kernel/hung_task.... |
270 271 |
unsigned long interval = sysctl_hung_task_check_interval_secs; long t; |
603a148f4 softlockup: fix p... |
272 |
|
a2e514453 kernel/hung_task.... |
273 274 275 276 |
if (interval == 0) interval = timeout; interval = min_t(unsigned long, interval, timeout); t = hung_timeout_jiffies(hung_last_checked, interval); |
b4aa14a63 kernel/hung_task.... |
277 |
if (t <= 0) { |
a1c6ca3c6 kernel: hung_task... |
278 279 |
if (!atomic_xchg(&reset_hung_task, 0) && !hung_detector_suspended) |
b4aa14a63 kernel/hung_task.... |
280 281 |
check_hung_uninterruptible_tasks(timeout); hung_last_checked = jiffies; |
8b414521b hung_task: add me... |
282 |
continue; |
b4aa14a63 kernel/hung_task.... |
283 284 |
} schedule_timeout_interruptible(t); |
e162b39a3 softlockup: decou... |
285 286 287 288 289 290 291 292 |
} return 0; } static int __init hung_task_init(void) { atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
a1c6ca3c6 kernel: hung_task... |
293 294 295 |
/* Disable hung task detector on suspend */ pm_notifier(hungtask_pm_notify, 0); |
e162b39a3 softlockup: decou... |
296 297 298 299 |
watchdog_task = kthread_run(watchdog, NULL, "khungtaskd"); return 0; } |
c96d6660d kernel: audit/fix... |
300 |
subsys_initcall(hung_task_init); |