Blame view

kernel/time/timer_list.c 8.94 KB
35728b820   Thomas Gleixner   time: Add SPDX li...
1
  // SPDX-License-Identifier: GPL-2.0
289f480af   Ingo Molnar   [PATCH] Add debug...
2
  /*
289f480af   Ingo Molnar   [PATCH] Add debug...
3
4
5
   * List pending timers
   *
   * Copyright(C) 2006, Red Hat, Inc., Ingo Molnar
289f480af   Ingo Molnar   [PATCH] Add debug...
6
7
8
9
10
11
12
13
   */
  
  #include <linux/proc_fs.h>
  #include <linux/module.h>
  #include <linux/spinlock.h>
  #include <linux/sched.h>
  #include <linux/seq_file.h>
  #include <linux/kallsyms.h>
010704276   Tom Hromatka   sysrq: Reset the ...
14
  #include <linux/nmi.h>
289f480af   Ingo Molnar   [PATCH] Add debug...
15

7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
16
  #include <linux/uaccess.h>
289f480af   Ingo Molnar   [PATCH] Add debug...
17

c1797baf6   Thomas Gleixner   tick: Move core o...
18
  #include "tick-internal.h"
b3956a896   Nathan Zimmer   timer_list: Conve...
19
20
21
22
23
24
  
  struct timer_list_iter {
  	int cpu;
  	bool second_pass;
  	u64 now;
  };
289f480af   Ingo Molnar   [PATCH] Add debug...
25
26
27
28
  /*
   * This allows printing both to /proc/timer_list and
   * to the console (on SysRq-Q):
   */
7de4e7443   Joe Perches   timer_list: Reduc...
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  __printf(2, 3)
  static void SEQ_printf(struct seq_file *m, const char *fmt, ...)
  {
  	va_list args;
  
  	va_start(args, fmt);
  
  	if (m)
  		seq_vprintf(m, fmt, args);
  	else
  		vprintk(fmt, args);
  
  	va_end(args);
  }
289f480af   Ingo Molnar   [PATCH] Add debug...
43
44
45
  
  static void print_name_offset(struct seq_file *m, void *sym)
  {
9281acea6   Tejun Heo   kallsyms: make KS...
46
  	char symname[KSYM_NAME_LEN];
289f480af   Ingo Molnar   [PATCH] Add debug...
47

9d65cb4a1   Alexey Dobriyan   Fix race between ...
48
  	if (lookup_symbol_name((unsigned long)sym, symname) < 0)
f59030853   Kees Cook   timer debug: Hide...
49
  		SEQ_printf(m, "<%pK>", sym);
9d65cb4a1   Alexey Dobriyan   Fix race between ...
50
51
  	else
  		SEQ_printf(m, "%s", symname);
289f480af   Ingo Molnar   [PATCH] Add debug...
52
53
54
  }
  
  static void
e67ef25a3   Thomas Gleixner   timer_list: print...
55
56
  print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
  	    int idx, u64 now)
289f480af   Ingo Molnar   [PATCH] Add debug...
57
  {
289f480af   Ingo Molnar   [PATCH] Add debug...
58
  	SEQ_printf(m, " #%d: ", idx);
e67ef25a3   Thomas Gleixner   timer_list: print...
59
  	print_name_offset(m, taddr);
289f480af   Ingo Molnar   [PATCH] Add debug...
60
61
  	SEQ_printf(m, ", ");
  	print_name_offset(m, timer->function);
203cbf77d   Thomas Gleixner   hrtimer: Handle r...
62
  	SEQ_printf(m, ", S:%02x", timer->state);
289f480af   Ingo Molnar   [PATCH] Add debug...
63
64
  	SEQ_printf(m, "
  ");
704af52bd   Arjan van de Ven   hrtimer: show the...
65
66
67
  	SEQ_printf(m, " # expires at %Lu-%Lu nsecs [in %Ld to %Ld nsecs]
  ",
  		(unsigned long long)ktime_to_ns(hrtimer_get_softexpires(timer)),
cc584b213   Arjan van de Ven   hrtimer: convert ...
68
  		(unsigned long long)ktime_to_ns(hrtimer_get_expires(timer)),
704af52bd   Arjan van de Ven   hrtimer: show the...
69
  		(long long)(ktime_to_ns(hrtimer_get_softexpires(timer)) - now),
cc584b213   Arjan van de Ven   hrtimer: convert ...
70
  		(long long)(ktime_to_ns(hrtimer_get_expires(timer)) - now));
289f480af   Ingo Molnar   [PATCH] Add debug...
71
72
73
74
75
76
77
78
  }
  
  static void
  print_active_timers(struct seq_file *m, struct hrtimer_clock_base *base,
  		    u64 now)
  {
  	struct hrtimer *timer, tmp;
  	unsigned long next = 0, i;
998adc3dd   John Stultz   hrtimers: Convert...
79
  	struct timerqueue_node *curr;
289f480af   Ingo Molnar   [PATCH] Add debug...
80
81
82
83
  	unsigned long flags;
  
  next_one:
  	i = 0;
010704276   Tom Hromatka   sysrq: Reset the ...
84
85
  
  	touch_nmi_watchdog();
ecb49d1a6   Thomas Gleixner   hrtimers: Convert...
86
  	raw_spin_lock_irqsave(&base->cpu_base->lock, flags);
289f480af   Ingo Molnar   [PATCH] Add debug...
87

998adc3dd   John Stultz   hrtimers: Convert...
88
  	curr = timerqueue_getnext(&base->active);
289f480af   Ingo Molnar   [PATCH] Add debug...
89
90
91
92
93
  	/*
  	 * Crude but we have to do this O(N*N) thing, because
  	 * we have to unlock the base when printing:
  	 */
  	while (curr && i < next) {
998adc3dd   John Stultz   hrtimers: Convert...
94
  		curr = timerqueue_iterate_next(curr);
289f480af   Ingo Molnar   [PATCH] Add debug...
95
96
97
98
  		i++;
  	}
  
  	if (curr) {
998adc3dd   John Stultz   hrtimers: Convert...
99
  		timer = container_of(curr, struct hrtimer, node);
289f480af   Ingo Molnar   [PATCH] Add debug...
100
  		tmp = *timer;
ecb49d1a6   Thomas Gleixner   hrtimers: Convert...
101
  		raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags);
289f480af   Ingo Molnar   [PATCH] Add debug...
102

e67ef25a3   Thomas Gleixner   timer_list: print...
103
  		print_timer(m, timer, &tmp, i, now);
289f480af   Ingo Molnar   [PATCH] Add debug...
104
105
106
  		next++;
  		goto next_one;
  	}
ecb49d1a6   Thomas Gleixner   hrtimers: Convert...
107
  	raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags);
289f480af   Ingo Molnar   [PATCH] Add debug...
108
109
110
111
112
  }
  
  static void
  print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
  {
f59030853   Kees Cook   timer debug: Hide...
113
114
  	SEQ_printf(m, "  .base:       %pK
  ", base);
398ca17fb   Thomas Gleixner   hrtimer: Get rid ...
115
116
  	SEQ_printf(m, "  .index:      %d
  ", base->index);
7551b02b9   Mars Cheng   timer_list: Remov...
117
118
  	SEQ_printf(m, "  .resolution: %u nsecs
  ", hrtimer_resolution);
398ca17fb   Thomas Gleixner   hrtimer: Get rid ...
119

289f480af   Ingo Molnar   [PATCH] Add debug...
120
121
122
123
124
  	SEQ_printf(m,   "  .get_time:   ");
  	print_name_offset(m, base->get_time);
  	SEQ_printf(m,   "
  ");
  #ifdef CONFIG_HIGH_RES_TIMERS
9b04bd275   David Miller   Fix printk format...
125
126
127
  	SEQ_printf(m, "  .offset:     %Lu nsecs
  ",
  		   (unsigned long long) ktime_to_ns(base->offset));
289f480af   Ingo Molnar   [PATCH] Add debug...
128
129
130
  #endif
  	SEQ_printf(m,   "active timers:
  ");
38bf985b0   John Stultz   timer_list: Add t...
131
  	print_active_timers(m, base, now + ktime_to_ns(base->offset));
289f480af   Ingo Molnar   [PATCH] Add debug...
132
133
134
135
136
137
  }
  
  static void print_cpu(struct seq_file *m, int cpu, u64 now)
  {
  	struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
  	int i;
129f1d2c5   Vegard Nossum   timer_list: Fix p...
138
139
  	SEQ_printf(m, "cpu: %d
  ", cpu);
289f480af   Ingo Molnar   [PATCH] Add debug...
140
141
142
143
144
145
  	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
  		SEQ_printf(m, " clock %d:
  ", i);
  		print_base(m, cpu_base->clock_base + i, now);
  	}
  #define P(x) \
9b04bd275   David Miller   Fix printk format...
146
147
148
  	SEQ_printf(m, "  .%-15s: %Lu
  ", #x, \
  		   (unsigned long long)(cpu_base->x))
289f480af   Ingo Molnar   [PATCH] Add debug...
149
  #define P_ns(x) \
9b04bd275   David Miller   Fix printk format...
150
151
152
  	SEQ_printf(m, "  .%-15s: %Lu nsecs
  ", #x, \
  		   (unsigned long long)(ktime_to_ns(cpu_base->x)))
289f480af   Ingo Molnar   [PATCH] Add debug...
153
154
155
156
157
  
  #ifdef CONFIG_HIGH_RES_TIMERS
  	P_ns(expires_next);
  	P(hres_active);
  	P(nr_events);
41d2e4949   Thomas Gleixner   hrtimer: Tune hrt...
158
159
  	P(nr_retries);
  	P(nr_hangs);
a6ffebce7   Thomas Gleixner   hrtimer: Make the...
160
  	P(max_hang_time);
289f480af   Ingo Molnar   [PATCH] Add debug...
161
162
163
164
165
166
  #endif
  #undef P
  #undef P_ns
  
  #ifdef CONFIG_TICK_ONESHOT
  # define P(x) \
9b04bd275   David Miller   Fix printk format...
167
168
169
  	SEQ_printf(m, "  .%-15s: %Lu
  ", #x, \
  		   (unsigned long long)(ts->x))
289f480af   Ingo Molnar   [PATCH] Add debug...
170
  # define P_ns(x) \
9b04bd275   David Miller   Fix printk format...
171
172
173
  	SEQ_printf(m, "  .%-15s: %Lu nsecs
  ", #x, \
  		   (unsigned long long)(ktime_to_ns(ts->x)))
289f480af   Ingo Molnar   [PATCH] Add debug...
174
175
176
  	{
  		struct tick_sched *ts = tick_get_tick_sched(cpu);
  		P(nohz_mode);
f5d411c91   Frederic Weisbecker   nohz: Rename ts->...
177
  		P_ns(last_tick);
289f480af   Ingo Molnar   [PATCH] Add debug...
178
179
180
181
182
  		P(tick_stopped);
  		P(idle_jiffies);
  		P(idle_calls);
  		P(idle_sleeps);
  		P_ns(idle_entrytime);
5df7fa1c6   Thomas Gleixner   tick-sched: add m...
183
184
  		P_ns(idle_waketime);
  		P_ns(idle_exittime);
289f480af   Ingo Molnar   [PATCH] Add debug...
185
  		P_ns(idle_sleeptime);
0224cf4c5   Arjan van de Ven   sched: Intoduce g...
186
  		P_ns(iowait_sleeptime);
289f480af   Ingo Molnar   [PATCH] Add debug...
187
  		P(last_jiffies);
c1ad348b4   Thomas Gleixner   tick: Nohz: Rewor...
188
  		P(next_timer);
289f480af   Ingo Molnar   [PATCH] Add debug...
189
  		P_ns(idle_expires);
9b04bd275   David Miller   Fix printk format...
190
191
192
  		SEQ_printf(m, "jiffies: %Lu
  ",
  			   (unsigned long long)jiffies);
289f480af   Ingo Molnar   [PATCH] Add debug...
193
194
195
196
197
  	}
  #endif
  
  #undef P
  #undef P_ns
60cf7ea84   Nathan Zimmer   timer_list: Split...
198
199
  	SEQ_printf(m, "
  ");
289f480af   Ingo Molnar   [PATCH] Add debug...
200
201
202
203
  }
  
  #ifdef CONFIG_GENERIC_CLOCKEVENTS
  static void
c5b77a3d3   Thomas Gleixner   timer_list: print...
204
  print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
289f480af   Ingo Molnar   [PATCH] Add debug...
205
206
  {
  	struct clock_event_device *dev = td->evtdev;
010704276   Tom Hromatka   sysrq: Reset the ...
207
  	touch_nmi_watchdog();
129f1d2c5   Vegard Nossum   timer_list: Fix p...
208
209
  	SEQ_printf(m, "Tick Device: mode:     %d
  ", td->mode);
c5b77a3d3   Thomas Gleixner   timer_list: print...
210
211
212
213
214
215
  	if (cpu < 0)
  		SEQ_printf(m, "Broadcast device
  ");
  	else
  		SEQ_printf(m, "Per CPU device: %d
  ", cpu);
289f480af   Ingo Molnar   [PATCH] Add debug...
216
217
218
219
220
221
222
223
224
  
  	SEQ_printf(m, "Clock Event Device: ");
  	if (!dev) {
  		SEQ_printf(m, "<NULL>
  ");
  		return;
  	}
  	SEQ_printf(m, "%s
  ", dev->name);
97813f2fe   Jon Hunter   nohz: Allow 32-bi...
225
226
227
228
229
230
  	SEQ_printf(m, " max_delta_ns:   %llu
  ",
  		   (unsigned long long) dev->max_delta_ns);
  	SEQ_printf(m, " min_delta_ns:   %llu
  ",
  		   (unsigned long long) dev->min_delta_ns);
23af368e9   Thomas Gleixner   clockevents: Use ...
231
232
233
234
  	SEQ_printf(m, " mult:           %u
  ", dev->mult);
  	SEQ_printf(m, " shift:          %u
  ", dev->shift);
eef7635a2   Viresh Kumar   clockevents: Remo...
235
236
  	SEQ_printf(m, " mode:           %d
  ", clockevent_get_state(dev));
289f480af   Ingo Molnar   [PATCH] Add debug...
237
238
239
240
241
242
243
244
  	SEQ_printf(m, " next_event:     %Ld nsecs
  ",
  		   (unsigned long long) ktime_to_ns(dev->next_event));
  
  	SEQ_printf(m, " set_next_event: ");
  	print_name_offset(m, dev->set_next_event);
  	SEQ_printf(m, "
  ");
eef7635a2   Viresh Kumar   clockevents: Remo...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  	if (dev->set_state_shutdown) {
  		SEQ_printf(m, " shutdown: ");
  		print_name_offset(m, dev->set_state_shutdown);
  		SEQ_printf(m, "
  ");
  	}
  
  	if (dev->set_state_periodic) {
  		SEQ_printf(m, " periodic: ");
  		print_name_offset(m, dev->set_state_periodic);
  		SEQ_printf(m, "
  ");
  	}
  
  	if (dev->set_state_oneshot) {
  		SEQ_printf(m, " oneshot:  ");
  		print_name_offset(m, dev->set_state_oneshot);
  		SEQ_printf(m, "
  ");
  	}
  
  	if (dev->set_state_oneshot_stopped) {
  		SEQ_printf(m, " oneshot stopped: ");
  		print_name_offset(m, dev->set_state_oneshot_stopped);
  		SEQ_printf(m, "
  ");
  	}
  
  	if (dev->tick_resume) {
  		SEQ_printf(m, " resume:   ");
  		print_name_offset(m, dev->tick_resume);
bd624d75d   Viresh Kumar   clockevents: Intr...
276
277
  		SEQ_printf(m, "
  ");
bd624d75d   Viresh Kumar   clockevents: Intr...
278
  	}
289f480af   Ingo Molnar   [PATCH] Add debug...
279
280
281
282
283
  
  	SEQ_printf(m, " event_handler:  ");
  	print_name_offset(m, dev->event_handler);
  	SEQ_printf(m, "
  ");
80a05b9ff   Thomas Gleixner   clockevents: Sani...
284
285
  	SEQ_printf(m, " retries:        %lu
  ", dev->retries);
60cf7ea84   Nathan Zimmer   timer_list: Split...
286
287
  	SEQ_printf(m, "
  ");
289f480af   Ingo Molnar   [PATCH] Add debug...
288
  }
60cf7ea84   Nathan Zimmer   timer_list: Split...
289
  static void timer_list_show_tickdevices_header(struct seq_file *m)
289f480af   Ingo Molnar   [PATCH] Add debug...
290
  {
289f480af   Ingo Molnar   [PATCH] Add debug...
291
  #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
c5b77a3d3   Thomas Gleixner   timer_list: print...
292
  	print_tickdevice(m, tick_get_broadcast_device(), -1);
1ef09cd71   Preeti U Murthy   tick-broadcast: F...
293
294
295
  	SEQ_printf(m, "tick_broadcast_mask: %*pb
  ",
  		   cpumask_pr_args(tick_get_broadcast_mask()));
289f480af   Ingo Molnar   [PATCH] Add debug...
296
  #ifdef CONFIG_TICK_ONESHOT
1ef09cd71   Preeti U Murthy   tick-broadcast: F...
297
298
299
  	SEQ_printf(m, "tick_broadcast_oneshot_mask: %*pb
  ",
  		   cpumask_pr_args(tick_get_broadcast_oneshot_mask()));
289f480af   Ingo Molnar   [PATCH] Add debug...
300
301
302
303
  #endif
  	SEQ_printf(m, "
  ");
  #endif
289f480af   Ingo Molnar   [PATCH] Add debug...
304
  }
289f480af   Ingo Molnar   [PATCH] Add debug...
305
  #endif
b3956a896   Nathan Zimmer   timer_list: Conve...
306
  static inline void timer_list_header(struct seq_file *m, u64 now)
289f480af   Ingo Molnar   [PATCH] Add debug...
307
  {
c1ad348b4   Thomas Gleixner   tick: Nohz: Rewor...
308
309
  	SEQ_printf(m, "Timer List Version: v0.8
  ");
289f480af   Ingo Molnar   [PATCH] Add debug...
310
311
312
313
  	SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d
  ", HRTIMER_MAX_CLOCK_BASES);
  	SEQ_printf(m, "now at %Ld nsecs
  ", (unsigned long long)now);
60cf7ea84   Nathan Zimmer   timer_list: Split...
314
315
  	SEQ_printf(m, "
  ");
b3956a896   Nathan Zimmer   timer_list: Conve...
316
  }
b3956a896   Nathan Zimmer   timer_list: Conve...
317
318
319
320
321
322
  void sysrq_timer_list_show(void)
  {
  	u64 now = ktime_to_ns(ktime_get());
  	int cpu;
  
  	timer_list_header(NULL, now);
289f480af   Ingo Molnar   [PATCH] Add debug...
323
324
  
  	for_each_online_cpu(cpu)
b3956a896   Nathan Zimmer   timer_list: Conve...
325
  		print_cpu(NULL, cpu, now);
289f480af   Ingo Molnar   [PATCH] Add debug...
326

60cf7ea84   Nathan Zimmer   timer_list: Split...
327
  #ifdef CONFIG_GENERIC_CLOCKEVENTS
b3956a896   Nathan Zimmer   timer_list: Conve...
328
  	timer_list_show_tickdevices_header(NULL);
60cf7ea84   Nathan Zimmer   timer_list: Split...
329
  	for_each_online_cpu(cpu)
b3956a896   Nathan Zimmer   timer_list: Conve...
330
  		print_tickdevice(NULL, tick_get_device(cpu), cpu);
60cf7ea84   Nathan Zimmer   timer_list: Split...
331
  #endif
b3956a896   Nathan Zimmer   timer_list: Conve...
332
333
  	return;
  }
289f480af   Ingo Molnar   [PATCH] Add debug...
334

a9314773a   Nathan Huckleberry   timer_list: Guard...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  #ifdef CONFIG_PROC_FS
  static int timer_list_show(struct seq_file *m, void *v)
  {
  	struct timer_list_iter *iter = v;
  
  	if (iter->cpu == -1 && !iter->second_pass)
  		timer_list_header(m, iter->now);
  	else if (!iter->second_pass)
  		print_cpu(m, iter->cpu, iter->now);
  #ifdef CONFIG_GENERIC_CLOCKEVENTS
  	else if (iter->cpu == -1 && iter->second_pass)
  		timer_list_show_tickdevices_header(m);
  	else
  		print_tickdevice(m, tick_get_device(iter->cpu), iter->cpu);
  #endif
  	return 0;
  }
84a78a650   Nathan Zimmer   timer_list: corre...
352
  static void *move_iter(struct timer_list_iter *iter, loff_t offset)
b3956a896   Nathan Zimmer   timer_list: Conve...
353
  {
84a78a650   Nathan Zimmer   timer_list: corre...
354
355
356
  	for (; offset; offset--) {
  		iter->cpu = cpumask_next(iter->cpu, cpu_online_mask);
  		if (iter->cpu >= nr_cpu_ids) {
b3956a896   Nathan Zimmer   timer_list: Conve...
357
  #ifdef CONFIG_GENERIC_CLOCKEVENTS
84a78a650   Nathan Zimmer   timer_list: corre...
358
359
360
361
362
  			if (!iter->second_pass) {
  				iter->cpu = -1;
  				iter->second_pass = true;
  			} else
  				return NULL;
b3956a896   Nathan Zimmer   timer_list: Conve...
363
  #else
84a78a650   Nathan Zimmer   timer_list: corre...
364
  			return NULL;
b3956a896   Nathan Zimmer   timer_list: Conve...
365
  #endif
84a78a650   Nathan Zimmer   timer_list: corre...
366
  		}
b3956a896   Nathan Zimmer   timer_list: Conve...
367
368
  	}
  	return iter;
289f480af   Ingo Molnar   [PATCH] Add debug...
369
  }
84a78a650   Nathan Zimmer   timer_list: corre...
370
371
372
373
374
375
376
377
378
379
  static void *timer_list_start(struct seq_file *file, loff_t *offset)
  {
  	struct timer_list_iter *iter = file->private;
  
  	if (!*offset)
  		iter->now = ktime_to_ns(ktime_get());
  	iter->cpu = -1;
  	iter->second_pass = false;
  	return move_iter(iter, *offset);
  }
b3956a896   Nathan Zimmer   timer_list: Conve...
380
  static void *timer_list_next(struct seq_file *file, void *v, loff_t *offset)
289f480af   Ingo Molnar   [PATCH] Add debug...
381
  {
b3956a896   Nathan Zimmer   timer_list: Conve...
382
  	struct timer_list_iter *iter = file->private;
b3956a896   Nathan Zimmer   timer_list: Conve...
383
  	++*offset;
84a78a650   Nathan Zimmer   timer_list: corre...
384
  	return move_iter(iter, 1);
289f480af   Ingo Molnar   [PATCH] Add debug...
385
  }
b3956a896   Nathan Zimmer   timer_list: Conve...
386
387
388
389
390
391
392
393
394
395
  static void timer_list_stop(struct seq_file *seq, void *v)
  {
  }
  
  static const struct seq_operations timer_list_sops = {
  	.start = timer_list_start,
  	.next = timer_list_next,
  	.stop = timer_list_stop,
  	.show = timer_list_show,
  };
289f480af   Ingo Molnar   [PATCH] Add debug...
396
397
398
  static int __init init_timer_list_procfs(void)
  {
  	struct proc_dir_entry *pe;
44414d82c   Christoph Hellwig   proc: introduce p...
399
400
  	pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops,
  			sizeof(struct timer_list_iter), NULL);
289f480af   Ingo Molnar   [PATCH] Add debug...
401
402
  	if (!pe)
  		return -ENOMEM;
289f480af   Ingo Molnar   [PATCH] Add debug...
403
404
405
  	return 0;
  }
  __initcall(init_timer_list_procfs);
a9314773a   Nathan Huckleberry   timer_list: Guard...
406
  #endif