Blame view

kernel/softlockup.c 7.06 KB
8446f1d39   Ingo Molnar   [PATCH] detect so...
1
2
3
  /*
   * Detect Soft Lockups
   *
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
4
   * started by Ingo Molnar, Copyright (C) 2005, 2006 Red Hat, Inc.
8446f1d39   Ingo Molnar   [PATCH] detect so...
5
6
7
8
   *
   * this code detects soft lockups: incidents in where on a CPU
   * the kernel does not reschedule for 10 seconds or more.
   */
8446f1d39   Ingo Molnar   [PATCH] detect so...
9
10
  #include <linux/mm.h>
  #include <linux/cpu.h>
82a1fcb90   Ingo Molnar   softlockup: autom...
11
  #include <linux/nmi.h>
8446f1d39   Ingo Molnar   [PATCH] detect so...
12
13
  #include <linux/init.h>
  #include <linux/delay.h>
831441862   Rafael J. Wysocki   Freezer: make ker...
14
  #include <linux/freezer.h>
8446f1d39   Ingo Molnar   [PATCH] detect so...
15
  #include <linux/kthread.h>
8d5be7f4e   Vegard Nossum   softlockup: show ...
16
  #include <linux/lockdep.h>
8446f1d39   Ingo Molnar   [PATCH] detect so...
17
18
  #include <linux/notifier.h>
  #include <linux/module.h>
baf48f657   Mandeep Singh Baines   softlock: fix fal...
19
  #include <linux/sysctl.h>
8446f1d39   Ingo Molnar   [PATCH] detect so...
20

43581a100   Ingo Molnar   softlockup: impro...
21
  #include <asm/irq_regs.h>
8446f1d39   Ingo Molnar   [PATCH] detect so...
22
  static DEFINE_SPINLOCK(print_lock);
1871e52c7   Tejun Heo   percpu: make perc...
23
24
25
  static DEFINE_PER_CPU(unsigned long, softlockup_touch_ts); /* touch timestamp */
  static DEFINE_PER_CPU(unsigned long, softlockup_print_ts); /* print timestamp */
  static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog);
d6ad3e286   Jason Wessel   softlockup: Add s...
26
  static DEFINE_PER_CPU(bool, softlock_touch_sync);
8446f1d39   Ingo Molnar   [PATCH] detect so...
27

90739081e   Ingo Molnar   softlockup: fix s...
28
  static int __read_mostly did_panic;
9383d9679   Dimitri Sivanich   softlockup: fix s...
29
  int __read_mostly softlockup_thresh = 60;
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
30

9c44bc03f   Ingo Molnar   softlockup: allow...
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  /*
   * Should we panic (and reboot, if panic_timeout= is set) when a
   * soft-lockup occurs:
   */
  unsigned int __read_mostly softlockup_panic =
  				CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
  
  static int __init softlockup_panic_setup(char *str)
  {
  	softlockup_panic = simple_strtoul(str, NULL, 0);
  
  	return 1;
  }
  __setup("softlockup_panic=", softlockup_panic_setup);
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
45
46
  static int
  softlock_panic(struct notifier_block *this, unsigned long event, void *ptr)
8446f1d39   Ingo Molnar   [PATCH] detect so...
47
48
49
50
51
52
53
54
55
  {
  	did_panic = 1;
  
  	return NOTIFY_DONE;
  }
  
  static struct notifier_block panic_block = {
  	.notifier_call = softlock_panic,
  };
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
56
57
58
59
60
  /*
   * Returns seconds, approximately.  We don't need nanosecond
   * resolution, and we don't need to waste time with a big divide when
   * 2^30ns == 1.074s.
   */
a3b13c23f   Ingo Molnar   softlockup: use c...
61
  static unsigned long get_timestamp(int this_cpu)
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
62
  {
82a1fcb90   Ingo Molnar   softlockup: autom...
63
  	return cpu_clock(this_cpu) >> 30LL;  /* 2^30 ~= 10^9 */
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
64
  }
8c2238eaa   Jason Wessel   softlockup: fix N...
65
  static void __touch_softlockup_watchdog(void)
8446f1d39   Ingo Molnar   [PATCH] detect so...
66
  {
a3b13c23f   Ingo Molnar   softlockup: use c...
67
  	int this_cpu = raw_smp_processor_id();
1871e52c7   Tejun Heo   percpu: make perc...
68
  	__raw_get_cpu_var(softlockup_touch_ts) = get_timestamp(this_cpu);
8446f1d39   Ingo Molnar   [PATCH] detect so...
69
  }
8c2238eaa   Jason Wessel   softlockup: fix N...
70
71
72
  
  void touch_softlockup_watchdog(void)
  {
1871e52c7   Tejun Heo   percpu: make perc...
73
  	__raw_get_cpu_var(softlockup_touch_ts) = 0;
8c2238eaa   Jason Wessel   softlockup: fix N...
74
  }
8446f1d39   Ingo Molnar   [PATCH] detect so...
75
  EXPORT_SYMBOL(touch_softlockup_watchdog);
d6ad3e286   Jason Wessel   softlockup: Add s...
76
77
78
79
80
  void touch_softlockup_watchdog_sync(void)
  {
  	__raw_get_cpu_var(softlock_touch_sync) = true;
  	__raw_get_cpu_var(softlockup_touch_ts) = 0;
  }
04c9167f9   Jeremy Fitzhardinge   add touch_all_sof...
81
82
83
84
85
86
  void touch_all_softlockup_watchdogs(void)
  {
  	int cpu;
  
  	/* Cause each CPU to re-update its timestamp rather than complain */
  	for_each_online_cpu(cpu)
1871e52c7   Tejun Heo   percpu: make perc...
87
  		per_cpu(softlockup_touch_ts, cpu) = 0;
04c9167f9   Jeremy Fitzhardinge   add touch_all_sof...
88
89
  }
  EXPORT_SYMBOL(touch_all_softlockup_watchdogs);
baf48f657   Mandeep Singh Baines   softlock: fix fal...
90
  int proc_dosoftlockup_thresh(struct ctl_table *table, int write,
8d65af789   Alexey Dobriyan   sysctl: remove "s...
91
  			     void __user *buffer,
baf48f657   Mandeep Singh Baines   softlock: fix fal...
92
93
94
  			     size_t *lenp, loff_t *ppos)
  {
  	touch_all_softlockup_watchdogs();
8d65af789   Alexey Dobriyan   sysctl: remove "s...
95
  	return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
baf48f657   Mandeep Singh Baines   softlock: fix fal...
96
  }
8446f1d39   Ingo Molnar   [PATCH] detect so...
97
98
99
100
  /*
   * This callback runs from the timer interrupt, and checks
   * whether the watchdog thread has hung or not:
   */
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
101
  void softlockup_tick(void)
8446f1d39   Ingo Molnar   [PATCH] detect so...
102
103
  {
  	int this_cpu = smp_processor_id();
1871e52c7   Tejun Heo   percpu: make perc...
104
105
  	unsigned long touch_ts = per_cpu(softlockup_touch_ts, this_cpu);
  	unsigned long print_ts;
43581a100   Ingo Molnar   softlockup: impro...
106
  	struct pt_regs *regs = get_irq_regs();
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
107
  	unsigned long now;
8446f1d39   Ingo Molnar   [PATCH] detect so...
108

9383d9679   Dimitri Sivanich   softlockup: fix s...
109
  	/* Is detection switched off? */
1871e52c7   Tejun Heo   percpu: make perc...
110
  	if (!per_cpu(softlockup_watchdog, this_cpu) || softlockup_thresh <= 0) {
9383d9679   Dimitri Sivanich   softlockup: fix s...
111
  		/* Be sure we don't false trigger if switched back on */
1871e52c7   Tejun Heo   percpu: make perc...
112
113
  		if (touch_ts)
  			per_cpu(softlockup_touch_ts, this_cpu) = 0;
9383d9679   Dimitri Sivanich   softlockup: fix s...
114
115
  		return;
  	}
1871e52c7   Tejun Heo   percpu: make perc...
116
  	if (touch_ts == 0) {
d6ad3e286   Jason Wessel   softlockup: Add s...
117
118
119
120
121
122
123
124
  		if (unlikely(per_cpu(softlock_touch_sync, this_cpu))) {
  			/*
  			 * If the time stamp was touched atomically
  			 * make sure the scheduler tick is up to date.
  			 */
  			per_cpu(softlock_touch_sync, this_cpu) = false;
  			sched_clock_tick();
  		}
8c2238eaa   Jason Wessel   softlockup: fix N...
125
  		__touch_softlockup_watchdog();
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
126
  		return;
04c9167f9   Jeremy Fitzhardinge   add touch_all_sof...
127
  	}
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
128

1871e52c7   Tejun Heo   percpu: make perc...
129
  	print_ts = per_cpu(softlockup_print_ts, this_cpu);
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
130
131
  
  	/* report at most once a second */
1871e52c7   Tejun Heo   percpu: make perc...
132
  	if (print_ts == touch_ts || did_panic)
8446f1d39   Ingo Molnar   [PATCH] detect so...
133
  		return;
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
134
135
  	/* do not print during early bootup: */
  	if (unlikely(system_state != SYSTEM_RUNNING)) {
8c2238eaa   Jason Wessel   softlockup: fix N...
136
  		__touch_softlockup_watchdog();
8446f1d39   Ingo Molnar   [PATCH] detect so...
137
  		return;
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
138
  	}
8446f1d39   Ingo Molnar   [PATCH] detect so...
139

a3b13c23f   Ingo Molnar   softlockup: use c...
140
  	now = get_timestamp(this_cpu);
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
141

dd7a1e561   Johannes Weiner   softlockup: fix w...
142
143
144
145
  	/*
  	 * Wake up the high-prio watchdog task twice per
  	 * threshold timespan.
  	 */
8c2eb4805   Colin Ian King   softlockup: Stop ...
146
  	if (time_after(now - softlockup_thresh/2, touch_ts))
1871e52c7   Tejun Heo   percpu: make perc...
147
  		wake_up_process(per_cpu(softlockup_watchdog, this_cpu));
ed50d6cbc   Peter Zijlstra   debug: softlockup...
148

82a1fcb90   Ingo Molnar   softlockup: autom...
149
  	/* Warn about unreasonable delays: */
8c2eb4805   Colin Ian King   softlockup: Stop ...
150
  	if (time_before_eq(now - softlockup_thresh, touch_ts))
43581a100   Ingo Molnar   softlockup: impro...
151
  		return;
8446f1d39   Ingo Molnar   [PATCH] detect so...
152

1871e52c7   Tejun Heo   percpu: make perc...
153
  	per_cpu(softlockup_print_ts, this_cpu) = touch_ts;
43581a100   Ingo Molnar   softlockup: impro...
154
155
  
  	spin_lock(&print_lock);
c4f3b63fe   Ravikiran G Thirumalai   softlockup: add a...
156
157
  	printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]
  ",
1871e52c7   Tejun Heo   percpu: make perc...
158
  			this_cpu, now - touch_ts,
ba25f9dcc   Pavel Emelyanov   Use helpers to ob...
159
  			current->comm, task_pid_nr(current));
688c91755   Arjan van de Ven   softlockup: print...
160
  	print_modules();
8d5be7f4e   Vegard Nossum   softlockup: show ...
161
  	print_irqtrace_events(current);
43581a100   Ingo Molnar   softlockup: impro...
162
163
164
  	if (regs)
  		show_regs(regs);
  	else
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
165
  		dump_stack();
43581a100   Ingo Molnar   softlockup: impro...
166
  	spin_unlock(&print_lock);
9c44bc03f   Ingo Molnar   softlockup: allow...
167
168
169
  
  	if (softlockup_panic)
  		panic("softlockup: hung tasks");
8446f1d39   Ingo Molnar   [PATCH] detect so...
170
171
172
173
174
  }
  
  /*
   * The watchdog thread - runs every second and touches the timestamp.
   */
a5f2ce3c6   Ingo Molnar   softlockup watchd...
175
  static int watchdog(void *__bind_cpu)
8446f1d39   Ingo Molnar   [PATCH] detect so...
176
  {
02fb6149f   Oleg Nesterov   softlockup: s/99/...
177
  	struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
8446f1d39   Ingo Molnar   [PATCH] detect so...
178
179
  
  	sched_setscheduler(current, SCHED_FIFO, &param);
8446f1d39   Ingo Molnar   [PATCH] detect so...
180

966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
181
  	/* initialize timestamp */
8c2238eaa   Jason Wessel   softlockup: fix N...
182
  	__touch_softlockup_watchdog();
966812dc9   Jeremy Fitzhardinge   Ignore stolen tim...
183

7be2a03e3   Dmitry Adamushko   softlockup: fix t...
184
  	set_current_state(TASK_INTERRUPTIBLE);
8446f1d39   Ingo Molnar   [PATCH] detect so...
185
  	/*
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
186
  	 * Run briefly once per second to reset the softlockup timestamp.
82a1fcb90   Ingo Molnar   softlockup: autom...
187
  	 * If this gets delayed for more than 60 seconds then the
6687a97d4   Ingo Molnar   [PATCH] timer-irq...
188
  	 * debug-printout triggers in softlockup_tick().
8446f1d39   Ingo Molnar   [PATCH] detect so...
189
190
  	 */
  	while (!kthread_should_stop()) {
8c2238eaa   Jason Wessel   softlockup: fix N...
191
  		__touch_softlockup_watchdog();
ed50d6cbc   Peter Zijlstra   debug: softlockup...
192
193
194
195
  		schedule();
  
  		if (kthread_should_stop())
  			break;
82a1fcb90   Ingo Molnar   softlockup: autom...
196

7be2a03e3   Dmitry Adamushko   softlockup: fix t...
197
  		set_current_state(TASK_INTERRUPTIBLE);
8446f1d39   Ingo Molnar   [PATCH] detect so...
198
  	}
7be2a03e3   Dmitry Adamushko   softlockup: fix t...
199
  	__set_current_state(TASK_RUNNING);
8446f1d39   Ingo Molnar   [PATCH] detect so...
200
201
202
203
204
205
206
  
  	return 0;
  }
  
  /*
   * Create/destroy watchdog threads as CPUs come and go:
   */
8c78f3075   Chandra Seetharaman   [PATCH] cpu hotpl...
207
  static int __cpuinit
8446f1d39   Ingo Molnar   [PATCH] detect so...
208
209
210
211
212
213
214
  cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
  {
  	int hotcpu = (unsigned long)hcpu;
  	struct task_struct *p;
  
  	switch (action) {
  	case CPU_UP_PREPARE:
8bb784428   Rafael J. Wysocki   Add suspend-relat...
215
  	case CPU_UP_PREPARE_FROZEN:
1871e52c7   Tejun Heo   percpu: make perc...
216
  		BUG_ON(per_cpu(softlockup_watchdog, hotcpu));
8446f1d39   Ingo Molnar   [PATCH] detect so...
217
218
  		p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu);
  		if (IS_ERR(p)) {
a5f2ce3c6   Ingo Molnar   softlockup watchd...
219
220
  			printk(KERN_ERR "watchdog for %i failed
  ", hotcpu);
8446f1d39   Ingo Molnar   [PATCH] detect so...
221
222
  			return NOTIFY_BAD;
  		}
1871e52c7   Tejun Heo   percpu: make perc...
223
224
  		per_cpu(softlockup_touch_ts, hotcpu) = 0;
  		per_cpu(softlockup_watchdog, hotcpu) = p;
8446f1d39   Ingo Molnar   [PATCH] detect so...
225
  		kthread_bind(p, hotcpu);
a5f2ce3c6   Ingo Molnar   softlockup watchd...
226
  		break;
8446f1d39   Ingo Molnar   [PATCH] detect so...
227
  	case CPU_ONLINE:
8bb784428   Rafael J. Wysocki   Add suspend-relat...
228
  	case CPU_ONLINE_FROZEN:
1871e52c7   Tejun Heo   percpu: make perc...
229
  		wake_up_process(per_cpu(softlockup_watchdog, hotcpu));
8446f1d39   Ingo Molnar   [PATCH] detect so...
230
231
  		break;
  #ifdef CONFIG_HOTPLUG_CPU
ed50d6cbc   Peter Zijlstra   debug: softlockup...
232
233
  	case CPU_UP_CANCELED:
  	case CPU_UP_CANCELED_FROZEN:
1871e52c7   Tejun Heo   percpu: make perc...
234
  		if (!per_cpu(softlockup_watchdog, hotcpu))
ed50d6cbc   Peter Zijlstra   debug: softlockup...
235
236
  			break;
  		/* Unbind so it can run.  Fall thru. */
1871e52c7   Tejun Heo   percpu: make perc...
237
  		kthread_bind(per_cpu(softlockup_watchdog, hotcpu),
f1fc057c7   Rusty Russell   cpumask: remove a...
238
  			     cpumask_any(cpu_online_mask));
8446f1d39   Ingo Molnar   [PATCH] detect so...
239
  	case CPU_DEAD:
8bb784428   Rafael J. Wysocki   Add suspend-relat...
240
  	case CPU_DEAD_FROZEN:
1871e52c7   Tejun Heo   percpu: make perc...
241
242
  		p = per_cpu(softlockup_watchdog, hotcpu);
  		per_cpu(softlockup_watchdog, hotcpu) = NULL;
8446f1d39   Ingo Molnar   [PATCH] detect so...
243
244
245
  		kthread_stop(p);
  		break;
  #endif /* CONFIG_HOTPLUG_CPU */
a5f2ce3c6   Ingo Molnar   softlockup watchd...
246
  	}
8446f1d39   Ingo Molnar   [PATCH] detect so...
247
248
  	return NOTIFY_OK;
  }
8c78f3075   Chandra Seetharaman   [PATCH] cpu hotpl...
249
  static struct notifier_block __cpuinitdata cpu_nfb = {
8446f1d39   Ingo Molnar   [PATCH] detect so...
250
251
  	.notifier_call = cpu_callback
  };
7babe8db9   Eduard - Gabriel Munteanu   Full conversion t...
252
253
254
255
256
257
258
259
260
261
  static int __initdata nosoftlockup;
  
  static int __init nosoftlockup_setup(char *str)
  {
  	nosoftlockup = 1;
  	return 1;
  }
  __setup("nosoftlockup", nosoftlockup_setup);
  
  static int __init spawn_softlockup_task(void)
8446f1d39   Ingo Molnar   [PATCH] detect so...
262
263
  {
  	void *cpu = (void *)(long)smp_processor_id();
7babe8db9   Eduard - Gabriel Munteanu   Full conversion t...
264
  	int err;
8446f1d39   Ingo Molnar   [PATCH] detect so...
265

7babe8db9   Eduard - Gabriel Munteanu   Full conversion t...
266
267
268
269
270
271
272
273
  	if (nosoftlockup)
  		return 0;
  
  	err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
  	if (err == NOTIFY_BAD) {
  		BUG();
  		return 1;
  	}
8446f1d39   Ingo Molnar   [PATCH] detect so...
274
275
  	cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
  	register_cpu_notifier(&cpu_nfb);
e041c6834   Alan Stern   [PATCH] Notifier ...
276
  	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
7babe8db9   Eduard - Gabriel Munteanu   Full conversion t...
277
278
  
  	return 0;
8446f1d39   Ingo Molnar   [PATCH] detect so...
279
  }
7babe8db9   Eduard - Gabriel Munteanu   Full conversion t...
280
  early_initcall(spawn_softlockup_task);