Implement state dump
[lttng-modules.git] / lttng-statedump-impl.c
1 /*
2 * Linux Trace Toolkit Next Generation Kernel State Dump
3 *
4 * Copyright 2005 Jean-Hugues Deschenes <jean-hugues.deschenes@polymtl.ca>
5 * Copyright 2006-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 *
7 * Changes:
8 * Eric Clement: Add listing of network IP interface
9 * 2006, 2007 Mathieu Desnoyers Fix kernel threads
10 * Various updates
11 *
12 * Dual LGPL v2.1/GPL v2 license.
13 */
14
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/netlink.h>
18 #include <linux/inet.h>
19 #include <linux/ip.h>
20 #include <linux/kthread.h>
21 #include <linux/proc_fs.h>
22 #include <linux/file.h>
23 #include <linux/interrupt.h>
24 #include <linux/irqnr.h>
25 #include <linux/cpu.h>
26 #include <linux/netdevice.h>
27 #include <linux/inetdevice.h>
28 #include <linux/sched.h>
29 #include <linux/mm.h>
30 #include <linux/fdtable.h>
31 #include <linux/swap.h>
32 #include <linux/wait.h>
33 #include <linux/mutex.h>
34
35 #include "lttng-events.h"
36 #include "wrapper/irqdesc.h"
37
38 #ifdef CONFIG_GENERIC_HARDIRQS
39 #include <linux/irq.h>
40 #endif
41
42 /* Define the tracepoints, but do not build the probes */
43 #define CREATE_TRACE_POINTS
44 #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
45 #define TRACE_INCLUDE_FILE lttng-statedump
46 #include "instrumentation/events/lttng-module/lttng-statedump.h"
47
48 /*
49 * Protected by the trace lock.
50 */
51 static struct delayed_work cpu_work[NR_CPUS];
52 static DECLARE_WAIT_QUEUE_HEAD(statedump_wq);
53 static atomic_t kernel_threads_to_run;
54
55 enum lttng_thread_type {
56 LTTNG_USER_THREAD = 0,
57 LTTNG_KERNEL_THREAD = 1,
58 };
59
60 enum lttng_execution_mode {
61 LTTNG_USER_MODE = 0,
62 LTTNG_SYSCALL = 1,
63 LTTNG_TRAP = 2,
64 LTTNG_IRQ = 3,
65 LTTNG_SOFTIRQ = 4,
66 LTTNG_MODE_UNKNOWN = 5,
67 };
68
69 enum lttng_execution_submode {
70 LTTNG_NONE = 0,
71 LTTNG_UNKNOWN = 1,
72 };
73
74 enum lttng_process_status {
75 LTTNG_UNNAMED = 0,
76 LTTNG_WAIT_FORK = 1,
77 LTTNG_WAIT_CPU = 2,
78 LTTNG_EXIT = 3,
79 LTTNG_ZOMBIE = 4,
80 LTTNG_WAIT = 5,
81 LTTNG_RUN = 6,
82 LTTNG_DEAD = 7,
83 };
84
85 #ifdef CONFIG_INET
86 static
87 void lttng_enumerate_device(struct lttng_session *session,
88 struct net_device *dev)
89 {
90 struct in_device *in_dev;
91 struct in_ifaddr *ifa;
92
93 if (dev->flags & IFF_UP) {
94 in_dev = in_dev_get(dev);
95 if (in_dev) {
96 for (ifa = in_dev->ifa_list; ifa != NULL;
97 ifa = ifa->ifa_next) {
98 trace_lttng_statedump_network_interface(
99 session, dev, ifa);
100 }
101 in_dev_put(in_dev);
102 }
103 } else {
104 trace_lttng_statedump_network_interface(
105 session, dev, NULL);
106 }
107 }
108
109 static
110 int lttng_enumerate_network_ip_interface(struct lttng_session *session)
111 {
112 struct net_device *dev;
113
114 read_lock(&dev_base_lock);
115 for_each_netdev(&init_net, dev)
116 lttng_enumerate_device(session, dev);
117 read_unlock(&dev_base_lock);
118
119 return 0;
120 }
121 #else /* CONFIG_INET */
122 static inline
123 int lttng_enumerate_network_ip_interface(struct lttng_session *session)
124 {
125 return 0;
126 }
127 #endif /* CONFIG_INET */
128
129
130 static
131 void lttng_enumerate_task_fd(struct lttng_session *session,
132 struct task_struct *p, char *tmp)
133 {
134 struct fdtable *fdt;
135 struct file *filp;
136 unsigned int i;
137 const unsigned char *path;
138
139 task_lock(p);
140 if (!p->files)
141 goto unlock_task;
142 spin_lock(&p->files->file_lock);
143 fdt = files_fdtable(p->files);
144 for (i = 0; i < fdt->max_fds; i++) {
145 filp = fcheck_files(p->files, i);
146 if (!filp)
147 continue;
148 path = d_path(&filp->f_path, tmp, PAGE_SIZE);
149 /* Make sure we give at least some info */
150 trace_lttng_statedump_file_descriptor(session, p, i,
151 IS_ERR(path) ?
152 filp->f_dentry->d_name.name :
153 path);
154 }
155 spin_unlock(&p->files->file_lock);
156 unlock_task:
157 task_unlock(p);
158 }
159
160 static
161 int lttng_enumerate_file_descriptors(struct lttng_session *session)
162 {
163 struct task_struct *p;
164 char *tmp = (char *) __get_free_page(GFP_KERNEL);
165
166 /* Enumerate active file descriptors */
167 rcu_read_lock();
168 for_each_process(p)
169 lttng_enumerate_task_fd(session, p, tmp);
170 rcu_read_unlock();
171 free_page((unsigned long) tmp);
172 return 0;
173 }
174
175 static
176 void lttng_enumerate_task_vm_maps(struct lttng_session *session,
177 struct task_struct *p)
178 {
179 struct mm_struct *mm;
180 struct vm_area_struct *map;
181 unsigned long ino;
182
183 /* get_task_mm does a task_lock... */
184 mm = get_task_mm(p);
185 if (!mm)
186 return;
187
188 map = mm->mmap;
189 if (map) {
190 down_read(&mm->mmap_sem);
191 while (map) {
192 if (map->vm_file)
193 ino = map->vm_file->f_dentry->d_inode->i_ino;
194 else
195 ino = 0;
196 trace_lttng_statedump_vm_map(session, p, map, ino);
197 map = map->vm_next;
198 }
199 up_read(&mm->mmap_sem);
200 }
201 mmput(mm);
202 }
203
204 static
205 int lttng_enumerate_vm_maps(struct lttng_session *session)
206 {
207 struct task_struct *p;
208
209 rcu_read_lock();
210 for_each_process(p)
211 lttng_enumerate_task_vm_maps(session, p);
212 rcu_read_unlock();
213 return 0;
214 }
215
216 #ifdef CONFIG_GENERIC_HARDIRQS
217 static
218 void lttng_list_interrupts(struct lttng_session *session)
219 {
220 unsigned int irq;
221 unsigned long flags = 0;
222 struct irq_desc *desc;
223
224 #define irq_to_desc wrapper_irq_to_desc
225 /* needs irq_desc */
226 for_each_irq_desc(irq, desc) {
227 struct irqaction *action;
228 const char *irq_chip_name =
229 irq_desc_get_chip(desc)->name ? : "unnamed_irq_chip";
230
231 local_irq_save(flags);
232 raw_spin_lock(&desc->lock);
233 for (action = desc->action; action; action = action->next) {
234 trace_lttng_statedump_interrupt(session,
235 irq, irq_chip_name, action);
236 }
237 raw_spin_unlock(&desc->lock);
238 local_irq_restore(flags);
239 }
240 #undef irq_to_desc
241 }
242 #else
243 static inline
244 void list_interrupts(struct lttng_session *session)
245 {
246 }
247 #endif
248
249 static
250 int lttng_enumerate_process_states(struct lttng_session *session)
251 {
252 struct task_struct *g, *p;
253
254 rcu_read_lock();
255 for_each_process(g) {
256 p = g;
257 do {
258 enum lttng_execution_mode mode =
259 LTTNG_MODE_UNKNOWN;
260 enum lttng_execution_submode submode =
261 LTTNG_UNKNOWN;
262 enum lttng_process_status status;
263 enum lttng_thread_type type;
264
265 task_lock(p);
266 if (p->exit_state == EXIT_ZOMBIE)
267 status = LTTNG_ZOMBIE;
268 else if (p->exit_state == EXIT_DEAD)
269 status = LTTNG_DEAD;
270 else if (p->state == TASK_RUNNING) {
271 /* Is this a forked child that has not run yet? */
272 if (list_empty(&p->rt.run_list))
273 status = LTTNG_WAIT_FORK;
274 else
275 /*
276 * All tasks are considered as wait_cpu;
277 * the viewer will sort out if the task
278 * was really running at this time.
279 */
280 status = LTTNG_WAIT_CPU;
281 } else if (p->state &
282 (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)) {
283 /* Task is waiting for something to complete */
284 status = LTTNG_WAIT;
285 } else
286 status = LTTNG_UNNAMED;
287 submode = LTTNG_NONE;
288
289 /*
290 * Verification of t->mm is to filter out kernel
291 * threads; Viewer will further filter out if a
292 * user-space thread was in syscall mode or not.
293 */
294 if (p->mm)
295 type = LTTNG_USER_THREAD;
296 else
297 type = LTTNG_KERNEL_THREAD;
298 trace_lttng_statedump_process_state(session,
299 p, type, mode, submode, status);
300 task_unlock(p);
301 } while_each_thread(g, p);
302 }
303 rcu_read_unlock();
304
305 return 0;
306 }
307
308 static
309 void lttng_statedump_work_func(struct work_struct *work)
310 {
311 if (atomic_dec_and_test(&kernel_threads_to_run))
312 /* If we are the last thread, wake up do_lttng_statedump */
313 wake_up(&statedump_wq);
314 }
315
316 static
317 int do_lttng_statedump(struct lttng_session *session)
318 {
319 int cpu;
320
321 printk(KERN_DEBUG "LTT state dump thread start\n");
322 trace_lttng_statedump_start(session);
323 lttng_enumerate_process_states(session);
324 lttng_enumerate_file_descriptors(session);
325 lttng_enumerate_vm_maps(session);
326 lttng_list_interrupts(session);
327 lttng_enumerate_network_ip_interface(session);
328
329 /* TODO lttng_dump_idt_table(session); */
330 /* TODO lttng_dump_softirq_vec(session); */
331 /* TODO lttng_list_modules(session); */
332 /* TODO lttng_dump_swap_files(session); */
333
334 /*
335 * Fire off a work queue on each CPU. Their sole purpose in life
336 * is to guarantee that each CPU has been in a state where is was in
337 * syscall mode (i.e. not in a trap, an IRQ or a soft IRQ).
338 */
339 get_online_cpus();
340 atomic_set(&kernel_threads_to_run, num_online_cpus());
341 for_each_online_cpu(cpu) {
342 INIT_DELAYED_WORK(&cpu_work[cpu], lttng_statedump_work_func);
343 schedule_delayed_work_on(cpu, &cpu_work[cpu], 0);
344 }
345 /* Wait for all threads to run */
346 __wait_event(statedump_wq, (atomic_read(&kernel_threads_to_run) != 0));
347 put_online_cpus();
348 /* Our work is done */
349 printk(KERN_DEBUG "LTT state dump end\n");
350 trace_lttng_statedump_end(session);
351 return 0;
352 }
353
354 /*
355 * Called with session mutex held.
356 */
357 int lttng_statedump_start(struct lttng_session *session)
358 {
359 printk(KERN_DEBUG "LTTng: state dump begin\n");
360 return do_lttng_statedump(session);
361 }
362 EXPORT_SYMBOL_GPL(lttng_statedump_start);
363
364 MODULE_LICENSE("GPL and additional rights");
365 MODULE_AUTHOR("Jean-Hugues Deschenes");
366 MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Statedump");
This page took 0.037018 seconds and 5 git commands to generate.