135728b82SThomas Gleixner // SPDX-License-Identifier: GPL-2.0
2289f480aSIngo Molnar /*
3289f480aSIngo Molnar * List pending timers
4289f480aSIngo Molnar *
5289f480aSIngo Molnar * Copyright(C) 2006, Red Hat, Inc., Ingo Molnar
6289f480aSIngo Molnar */
7289f480aSIngo Molnar
8289f480aSIngo Molnar #include <linux/proc_fs.h>
9289f480aSIngo Molnar #include <linux/module.h>
10289f480aSIngo Molnar #include <linux/spinlock.h>
11289f480aSIngo Molnar #include <linux/sched.h>
12289f480aSIngo Molnar #include <linux/seq_file.h>
13289f480aSIngo Molnar #include <linux/kallsyms.h>
1401070427STom Hromatka #include <linux/nmi.h>
15289f480aSIngo Molnar
167c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
17289f480aSIngo Molnar
18c1797bafSThomas Gleixner #include "tick-internal.h"
19b3956a89SNathan Zimmer
20b3956a89SNathan Zimmer struct timer_list_iter {
21b3956a89SNathan Zimmer int cpu;
22b3956a89SNathan Zimmer bool second_pass;
23b3956a89SNathan Zimmer u64 now;
24b3956a89SNathan Zimmer };
25b3956a89SNathan Zimmer
26289f480aSIngo Molnar /*
27289f480aSIngo Molnar * This allows printing both to /proc/timer_list and
28289f480aSIngo Molnar * to the console (on SysRq-Q):
29289f480aSIngo Molnar */
307de4e744SJoe Perches __printf(2, 3)
SEQ_printf(struct seq_file * m,const char * fmt,...)317de4e744SJoe Perches static void SEQ_printf(struct seq_file *m, const char *fmt, ...)
327de4e744SJoe Perches {
337de4e744SJoe Perches va_list args;
347de4e744SJoe Perches
357de4e744SJoe Perches va_start(args, fmt);
367de4e744SJoe Perches
377de4e744SJoe Perches if (m)
387de4e744SJoe Perches seq_vprintf(m, fmt, args);
397de4e744SJoe Perches else
407de4e744SJoe Perches vprintk(fmt, args);
417de4e744SJoe Perches
427de4e744SJoe Perches va_end(args);
437de4e744SJoe Perches }
44289f480aSIngo Molnar
45289f480aSIngo Molnar static void
print_timer(struct seq_file * m,struct hrtimer * taddr,struct hrtimer * timer,int idx,u64 now)46e67ef25aSThomas Gleixner print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
47e67ef25aSThomas Gleixner int idx, u64 now)
48289f480aSIngo Molnar {
49*04257da0SNam Cao SEQ_printf(m, " #%d: <%p>, %ps", idx, taddr, ACCESS_PRIVATE(timer, function));
50203cbf77SThomas Gleixner SEQ_printf(m, ", S:%02x", timer->state);
51289f480aSIngo Molnar SEQ_printf(m, "\n");
52704af52bSArjan van de Ven SEQ_printf(m, " # expires at %Lu-%Lu nsecs [in %Ld to %Ld nsecs]\n",
53704af52bSArjan van de Ven (unsigned long long)ktime_to_ns(hrtimer_get_softexpires(timer)),
54cc584b21SArjan van de Ven (unsigned long long)ktime_to_ns(hrtimer_get_expires(timer)),
55704af52bSArjan van de Ven (long long)(ktime_to_ns(hrtimer_get_softexpires(timer)) - now),
56cc584b21SArjan van de Ven (long long)(ktime_to_ns(hrtimer_get_expires(timer)) - now));
57289f480aSIngo Molnar }
58289f480aSIngo Molnar
59289f480aSIngo Molnar static void
print_active_timers(struct seq_file * m,struct hrtimer_clock_base * base,u64 now)60289f480aSIngo Molnar print_active_timers(struct seq_file *m, struct hrtimer_clock_base *base,
61289f480aSIngo Molnar u64 now)
62289f480aSIngo Molnar {
63289f480aSIngo Molnar struct hrtimer *timer, tmp;
64289f480aSIngo Molnar unsigned long next = 0, i;
65998adc3dSJohn Stultz struct timerqueue_node *curr;
66289f480aSIngo Molnar unsigned long flags;
67289f480aSIngo Molnar
68289f480aSIngo Molnar next_one:
69289f480aSIngo Molnar i = 0;
7001070427STom Hromatka
7101070427STom Hromatka touch_nmi_watchdog();
7201070427STom Hromatka
73ecb49d1aSThomas Gleixner raw_spin_lock_irqsave(&base->cpu_base->lock, flags);
74289f480aSIngo Molnar
75998adc3dSJohn Stultz curr = timerqueue_getnext(&base->active);
76289f480aSIngo Molnar /*
77289f480aSIngo Molnar * Crude but we have to do this O(N*N) thing, because
78289f480aSIngo Molnar * we have to unlock the base when printing:
79289f480aSIngo Molnar */
80289f480aSIngo Molnar while (curr && i < next) {
81998adc3dSJohn Stultz curr = timerqueue_iterate_next(curr);
82289f480aSIngo Molnar i++;
83289f480aSIngo Molnar }
84289f480aSIngo Molnar
85289f480aSIngo Molnar if (curr) {
86289f480aSIngo Molnar
87998adc3dSJohn Stultz timer = container_of(curr, struct hrtimer, node);
88289f480aSIngo Molnar tmp = *timer;
89ecb49d1aSThomas Gleixner raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags);
90289f480aSIngo Molnar
91e67ef25aSThomas Gleixner print_timer(m, timer, &tmp, i, now);
92289f480aSIngo Molnar next++;
93289f480aSIngo Molnar goto next_one;
94289f480aSIngo Molnar }
95ecb49d1aSThomas Gleixner raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags);
96289f480aSIngo Molnar }
97289f480aSIngo Molnar
98289f480aSIngo Molnar static void
print_base(struct seq_file * m,struct hrtimer_clock_base * base,u64 now)99289f480aSIngo Molnar print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
100289f480aSIngo Molnar {
101a52067c2SThomas Weißschuh SEQ_printf(m, " .base: %p\n", base);
102398ca17fSThomas Gleixner SEQ_printf(m, " .index: %d\n", base->index);
103398ca17fSThomas Gleixner
1047551b02bSMars Cheng SEQ_printf(m, " .resolution: %u nsecs\n", hrtimer_resolution);
105398ca17fSThomas Gleixner
106da88f9b3SHelge Deller SEQ_printf(m, " .get_time: %ps\n", base->get_time);
107289f480aSIngo Molnar #ifdef CONFIG_HIGH_RES_TIMERS
1089b04bd27SDavid Miller SEQ_printf(m, " .offset: %Lu nsecs\n",
1099b04bd27SDavid Miller (unsigned long long) ktime_to_ns(base->offset));
110289f480aSIngo Molnar #endif
111289f480aSIngo Molnar SEQ_printf(m, "active timers:\n");
11238bf985bSJohn Stultz print_active_timers(m, base, now + ktime_to_ns(base->offset));
113289f480aSIngo Molnar }
114289f480aSIngo Molnar
print_cpu(struct seq_file * m,int cpu,u64 now)115289f480aSIngo Molnar static void print_cpu(struct seq_file *m, int cpu, u64 now)
116289f480aSIngo Molnar {
117289f480aSIngo Molnar struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
118289f480aSIngo Molnar int i;
119289f480aSIngo Molnar
120129f1d2cSVegard Nossum SEQ_printf(m, "cpu: %d\n", cpu);
121289f480aSIngo Molnar for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
122289f480aSIngo Molnar SEQ_printf(m, " clock %d:\n", i);
123289f480aSIngo Molnar print_base(m, cpu_base->clock_base + i, now);
124289f480aSIngo Molnar }
125289f480aSIngo Molnar #define P(x) \
1269b04bd27SDavid Miller SEQ_printf(m, " .%-15s: %Lu\n", #x, \
1279b04bd27SDavid Miller (unsigned long long)(cpu_base->x))
128289f480aSIngo Molnar #define P_ns(x) \
1299b04bd27SDavid Miller SEQ_printf(m, " .%-15s: %Lu nsecs\n", #x, \
1309b04bd27SDavid Miller (unsigned long long)(ktime_to_ns(cpu_base->x)))
131289f480aSIngo Molnar
132289f480aSIngo Molnar #ifdef CONFIG_HIGH_RES_TIMERS
133289f480aSIngo Molnar P_ns(expires_next);
134289f480aSIngo Molnar P(hres_active);
135289f480aSIngo Molnar P(nr_events);
13641d2e494SThomas Gleixner P(nr_retries);
13741d2e494SThomas Gleixner P(nr_hangs);
138a6ffebceSThomas Gleixner P(max_hang_time);
139289f480aSIngo Molnar #endif
140289f480aSIngo Molnar #undef P
141289f480aSIngo Molnar #undef P_ns
142289f480aSIngo Molnar
143289f480aSIngo Molnar #ifdef CONFIG_TICK_ONESHOT
144289f480aSIngo Molnar # define P(x) \
1459b04bd27SDavid Miller SEQ_printf(m, " .%-15s: %Lu\n", #x, \
1469b04bd27SDavid Miller (unsigned long long)(ts->x))
147289f480aSIngo Molnar # define P_ns(x) \
1489b04bd27SDavid Miller SEQ_printf(m, " .%-15s: %Lu nsecs\n", #x, \
1499b04bd27SDavid Miller (unsigned long long)(ktime_to_ns(ts->x)))
150a478ffb2SFrederic Weisbecker # define P_flag(x, f) \
151a478ffb2SFrederic Weisbecker SEQ_printf(m, " .%-15s: %d\n", #x, !!(ts->flags & (f)))
152a478ffb2SFrederic Weisbecker
153289f480aSIngo Molnar {
154289f480aSIngo Molnar struct tick_sched *ts = tick_get_tick_sched(cpu);
1557988e5aeSFrederic Weisbecker P_flag(nohz, TS_FLAG_NOHZ);
1567988e5aeSFrederic Weisbecker P_flag(highres, TS_FLAG_HIGHRES);
157f5d411c9SFrederic Weisbecker P_ns(last_tick);
158a478ffb2SFrederic Weisbecker P_flag(tick_stopped, TS_FLAG_STOPPED);
159289f480aSIngo Molnar P(idle_jiffies);
160289f480aSIngo Molnar P(idle_calls);
161289f480aSIngo Molnar P(idle_sleeps);
162289f480aSIngo Molnar P_ns(idle_entrytime);
1635df7fa1cSThomas Gleixner P_ns(idle_waketime);
1645df7fa1cSThomas Gleixner P_ns(idle_exittime);
165289f480aSIngo Molnar P_ns(idle_sleeptime);
1660224cf4cSArjan van de Ven P_ns(iowait_sleeptime);
167289f480aSIngo Molnar P(last_jiffies);
168c1ad348bSThomas Gleixner P(next_timer);
169289f480aSIngo Molnar P_ns(idle_expires);
1709b04bd27SDavid Miller SEQ_printf(m, "jiffies: %Lu\n",
1719b04bd27SDavid Miller (unsigned long long)jiffies);
172289f480aSIngo Molnar }
173289f480aSIngo Molnar #endif
174289f480aSIngo Molnar
175289f480aSIngo Molnar #undef P
176289f480aSIngo Molnar #undef P_ns
17760cf7ea8SNathan Zimmer SEQ_printf(m, "\n");
178289f480aSIngo Molnar }
179289f480aSIngo Molnar
180289f480aSIngo Molnar #ifdef CONFIG_GENERIC_CLOCKEVENTS
181289f480aSIngo Molnar static void
print_tickdevice(struct seq_file * m,struct tick_device * td,int cpu)182c5b77a3dSThomas Gleixner print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
183289f480aSIngo Molnar {
184289f480aSIngo Molnar struct clock_event_device *dev = td->evtdev;
185289f480aSIngo Molnar
18601070427STom Hromatka touch_nmi_watchdog();
18701070427STom Hromatka
188129f1d2cSVegard Nossum SEQ_printf(m, "Tick Device: mode: %d\n", td->mode);
189c5b77a3dSThomas Gleixner if (cpu < 0)
190c5b77a3dSThomas Gleixner SEQ_printf(m, "Broadcast device\n");
191c5b77a3dSThomas Gleixner else
192c5b77a3dSThomas Gleixner SEQ_printf(m, "Per CPU device: %d\n", cpu);
193289f480aSIngo Molnar
194289f480aSIngo Molnar SEQ_printf(m, "Clock Event Device: ");
195289f480aSIngo Molnar if (!dev) {
196289f480aSIngo Molnar SEQ_printf(m, "<NULL>\n");
197289f480aSIngo Molnar return;
198289f480aSIngo Molnar }
199289f480aSIngo Molnar SEQ_printf(m, "%s\n", dev->name);
20097813f2fSJon Hunter SEQ_printf(m, " max_delta_ns: %llu\n",
20197813f2fSJon Hunter (unsigned long long) dev->max_delta_ns);
20297813f2fSJon Hunter SEQ_printf(m, " min_delta_ns: %llu\n",
20397813f2fSJon Hunter (unsigned long long) dev->min_delta_ns);
20423af368eSThomas Gleixner SEQ_printf(m, " mult: %u\n", dev->mult);
20523af368eSThomas Gleixner SEQ_printf(m, " shift: %u\n", dev->shift);
206eef7635aSViresh Kumar SEQ_printf(m, " mode: %d\n", clockevent_get_state(dev));
207289f480aSIngo Molnar SEQ_printf(m, " next_event: %Ld nsecs\n",
208289f480aSIngo Molnar (unsigned long long) ktime_to_ns(dev->next_event));
209289f480aSIngo Molnar
210da88f9b3SHelge Deller SEQ_printf(m, " set_next_event: %ps\n", dev->set_next_event);
211289f480aSIngo Molnar
212da88f9b3SHelge Deller if (dev->set_state_shutdown)
213da88f9b3SHelge Deller SEQ_printf(m, " shutdown: %ps\n",
214da88f9b3SHelge Deller dev->set_state_shutdown);
215bd624d75SViresh Kumar
216da88f9b3SHelge Deller if (dev->set_state_periodic)
217da88f9b3SHelge Deller SEQ_printf(m, " periodic: %ps\n",
218da88f9b3SHelge Deller dev->set_state_periodic);
219bd624d75SViresh Kumar
220da88f9b3SHelge Deller if (dev->set_state_oneshot)
221da88f9b3SHelge Deller SEQ_printf(m, " oneshot: %ps\n",
222da88f9b3SHelge Deller dev->set_state_oneshot);
223bd624d75SViresh Kumar
224da88f9b3SHelge Deller if (dev->set_state_oneshot_stopped)
225da88f9b3SHelge Deller SEQ_printf(m, " oneshot stopped: %ps\n",
226da88f9b3SHelge Deller dev->set_state_oneshot_stopped);
2278fff52fdSViresh Kumar
228da88f9b3SHelge Deller if (dev->tick_resume)
229da88f9b3SHelge Deller SEQ_printf(m, " resume: %ps\n",
230da88f9b3SHelge Deller dev->tick_resume);
231289f480aSIngo Molnar
232da88f9b3SHelge Deller SEQ_printf(m, " event_handler: %ps\n", dev->event_handler);
233289f480aSIngo Molnar SEQ_printf(m, "\n");
23480a05b9fSThomas Gleixner SEQ_printf(m, " retries: %lu\n", dev->retries);
235245a057fSWill Deacon
236245a057fSWill Deacon #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
237245a057fSWill Deacon if (cpu >= 0) {
238245a057fSWill Deacon const struct clock_event_device *wd = tick_get_wakeup_device(cpu);
239245a057fSWill Deacon
240245a057fSWill Deacon SEQ_printf(m, "Wakeup Device: %s\n", wd ? wd->name : "<NULL>");
241245a057fSWill Deacon }
242245a057fSWill Deacon #endif
24360cf7ea8SNathan Zimmer SEQ_printf(m, "\n");
244289f480aSIngo Molnar }
245289f480aSIngo Molnar
timer_list_show_tickdevices_header(struct seq_file * m)24660cf7ea8SNathan Zimmer static void timer_list_show_tickdevices_header(struct seq_file *m)
247289f480aSIngo Molnar {
248289f480aSIngo Molnar #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
249c5b77a3dSThomas Gleixner print_tickdevice(m, tick_get_broadcast_device(), -1);
2501ef09cd7SPreeti U Murthy SEQ_printf(m, "tick_broadcast_mask: %*pb\n",
2511ef09cd7SPreeti U Murthy cpumask_pr_args(tick_get_broadcast_mask()));
252289f480aSIngo Molnar #ifdef CONFIG_TICK_ONESHOT
2531ef09cd7SPreeti U Murthy SEQ_printf(m, "tick_broadcast_oneshot_mask: %*pb\n",
2541ef09cd7SPreeti U Murthy cpumask_pr_args(tick_get_broadcast_oneshot_mask()));
255289f480aSIngo Molnar #endif
256289f480aSIngo Molnar SEQ_printf(m, "\n");
257289f480aSIngo Molnar #endif
258289f480aSIngo Molnar }
259289f480aSIngo Molnar #endif
260289f480aSIngo Molnar
timer_list_header(struct seq_file * m,u64 now)261b3956a89SNathan Zimmer static inline void timer_list_header(struct seq_file *m, u64 now)
262289f480aSIngo Molnar {
2637988e5aeSFrederic Weisbecker SEQ_printf(m, "Timer List Version: v0.10\n");
264289f480aSIngo Molnar SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES);
265289f480aSIngo Molnar SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now);
26660cf7ea8SNathan Zimmer SEQ_printf(m, "\n");
267b3956a89SNathan Zimmer }
268289f480aSIngo Molnar
sysrq_timer_list_show(void)269289f480aSIngo Molnar void sysrq_timer_list_show(void)
270289f480aSIngo Molnar {
271b3956a89SNathan Zimmer u64 now = ktime_to_ns(ktime_get());
272b3956a89SNathan Zimmer int cpu;
273b3956a89SNathan Zimmer
274b3956a89SNathan Zimmer timer_list_header(NULL, now);
275b3956a89SNathan Zimmer
276b3956a89SNathan Zimmer for_each_online_cpu(cpu)
277b3956a89SNathan Zimmer print_cpu(NULL, cpu, now);
278b3956a89SNathan Zimmer
279b3956a89SNathan Zimmer #ifdef CONFIG_GENERIC_CLOCKEVENTS
280b3956a89SNathan Zimmer timer_list_show_tickdevices_header(NULL);
281b3956a89SNathan Zimmer for_each_online_cpu(cpu)
282b3956a89SNathan Zimmer print_tickdevice(NULL, tick_get_device(cpu), cpu);
283b3956a89SNathan Zimmer #endif
284b3956a89SNathan Zimmer return;
285289f480aSIngo Molnar }
286289f480aSIngo Molnar
287a9314773SNathan Huckleberry #ifdef CONFIG_PROC_FS
timer_list_show(struct seq_file * m,void * v)288a9314773SNathan Huckleberry static int timer_list_show(struct seq_file *m, void *v)
289a9314773SNathan Huckleberry {
290a9314773SNathan Huckleberry struct timer_list_iter *iter = v;
291a9314773SNathan Huckleberry
292a9314773SNathan Huckleberry if (iter->cpu == -1 && !iter->second_pass)
293a9314773SNathan Huckleberry timer_list_header(m, iter->now);
294a9314773SNathan Huckleberry else if (!iter->second_pass)
295a9314773SNathan Huckleberry print_cpu(m, iter->cpu, iter->now);
296a9314773SNathan Huckleberry #ifdef CONFIG_GENERIC_CLOCKEVENTS
297a9314773SNathan Huckleberry else if (iter->cpu == -1 && iter->second_pass)
298a9314773SNathan Huckleberry timer_list_show_tickdevices_header(m);
299a9314773SNathan Huckleberry else
300a9314773SNathan Huckleberry print_tickdevice(m, tick_get_device(iter->cpu), iter->cpu);
301a9314773SNathan Huckleberry #endif
302a9314773SNathan Huckleberry return 0;
303a9314773SNathan Huckleberry }
304a9314773SNathan Huckleberry
move_iter(struct timer_list_iter * iter,loff_t offset)30584a78a65SNathan Zimmer static void *move_iter(struct timer_list_iter *iter, loff_t offset)
306b3956a89SNathan Zimmer {
30784a78a65SNathan Zimmer for (; offset; offset--) {
30884a78a65SNathan Zimmer iter->cpu = cpumask_next(iter->cpu, cpu_online_mask);
30984a78a65SNathan Zimmer if (iter->cpu >= nr_cpu_ids) {
310b3956a89SNathan Zimmer #ifdef CONFIG_GENERIC_CLOCKEVENTS
311b3956a89SNathan Zimmer if (!iter->second_pass) {
312b3956a89SNathan Zimmer iter->cpu = -1;
313b3956a89SNathan Zimmer iter->second_pass = true;
314b3956a89SNathan Zimmer } else
315b3956a89SNathan Zimmer return NULL;
316b3956a89SNathan Zimmer #else
317b3956a89SNathan Zimmer return NULL;
318b3956a89SNathan Zimmer #endif
319b3956a89SNathan Zimmer }
32084a78a65SNathan Zimmer }
321b3956a89SNathan Zimmer return iter;
322b3956a89SNathan Zimmer }
323b3956a89SNathan Zimmer
timer_list_start(struct seq_file * file,loff_t * offset)32484a78a65SNathan Zimmer static void *timer_list_start(struct seq_file *file, loff_t *offset)
32584a78a65SNathan Zimmer {
32684a78a65SNathan Zimmer struct timer_list_iter *iter = file->private;
32784a78a65SNathan Zimmer
32884a78a65SNathan Zimmer if (!*offset)
32984a78a65SNathan Zimmer iter->now = ktime_to_ns(ktime_get());
33084a78a65SNathan Zimmer iter->cpu = -1;
33184a78a65SNathan Zimmer iter->second_pass = false;
33284a78a65SNathan Zimmer return move_iter(iter, *offset);
33384a78a65SNathan Zimmer }
33484a78a65SNathan Zimmer
timer_list_next(struct seq_file * file,void * v,loff_t * offset)335b3956a89SNathan Zimmer static void *timer_list_next(struct seq_file *file, void *v, loff_t *offset)
336b3956a89SNathan Zimmer {
337b3956a89SNathan Zimmer struct timer_list_iter *iter = file->private;
338b3956a89SNathan Zimmer ++*offset;
33984a78a65SNathan Zimmer return move_iter(iter, 1);
340b3956a89SNathan Zimmer }
341b3956a89SNathan Zimmer
timer_list_stop(struct seq_file * seq,void * v)342b3956a89SNathan Zimmer static void timer_list_stop(struct seq_file *seq, void *v)
343b3956a89SNathan Zimmer {
344b3956a89SNathan Zimmer }
345b3956a89SNathan Zimmer
346b3956a89SNathan Zimmer static const struct seq_operations timer_list_sops = {
347b3956a89SNathan Zimmer .start = timer_list_start,
348b3956a89SNathan Zimmer .next = timer_list_next,
349b3956a89SNathan Zimmer .stop = timer_list_stop,
350b3956a89SNathan Zimmer .show = timer_list_show,
351b3956a89SNathan Zimmer };
352b3956a89SNathan Zimmer
init_timer_list_procfs(void)353289f480aSIngo Molnar static int __init init_timer_list_procfs(void)
354289f480aSIngo Molnar {
355289f480aSIngo Molnar struct proc_dir_entry *pe;
356289f480aSIngo Molnar
35744414d82SChristoph Hellwig pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops,
35844414d82SChristoph Hellwig sizeof(struct timer_list_iter), NULL);
359289f480aSIngo Molnar if (!pe)
360289f480aSIngo Molnar return -ENOMEM;
361289f480aSIngo Molnar return 0;
362289f480aSIngo Molnar }
363289f480aSIngo Molnar __initcall(init_timer_list_procfs);
364a9314773SNathan Huckleberry #endif
365