Blame view

kernel/trace/trace_output.c 27.5 KB
f0868d1e2   Steven Rostedt   ftrace: set up tr...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  /*
   * trace_output.c
   *
   * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
   *
   */
  
  #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/ftrace.h>
  
  #include "trace_output.h"
  
  /* must be a power of 2 */
  #define EVENT_HASHSIZE	128
110bf2b76   Steven Rostedt   tracing: add prot...
16
  DECLARE_RWSEM(trace_event_mutex);
be74b73a5   Steven Rostedt   tracing: add __pr...
17

f0868d1e2   Steven Rostedt   ftrace: set up tr...
18
19
20
  static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
  
  static int next_event_type = __TRACE_LAST_TYPE + 1;
a63ce5b30   Steven Rostedt   tracing: Buffer t...
21
  int trace_print_seq(struct seq_file *m, struct trace_seq *s)
0706f1c48   Steven Rostedt   tracing: adding f...
22
23
  {
  	int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
a63ce5b30   Steven Rostedt   tracing: Buffer t...
24
25
26
  	int ret;
  
  	ret = seq_write(m, s->buffer, len);
0706f1c48   Steven Rostedt   tracing: adding f...
27

a63ce5b30   Steven Rostedt   tracing: Buffer t...
28
29
30
31
32
33
  	/*
  	 * Only reset this buffer if we successfully wrote to the
  	 * seq_file buffer.
  	 */
  	if (!ret)
  		trace_seq_init(s);
0706f1c48   Steven Rostedt   tracing: adding f...
34

a63ce5b30   Steven Rostedt   tracing: Buffer t...
35
  	return ret;
0706f1c48   Steven Rostedt   tracing: adding f...
36
  }
5ef841f6f   Steven Rostedt   tracing: make pri...
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
  {
  	struct trace_seq *s = &iter->seq;
  	struct trace_entry *entry = iter->ent;
  	struct bprint_entry *field;
  	int ret;
  
  	trace_assign_type(field, entry);
  
  	ret = trace_seq_bprintf(s, field->fmt, field->buf);
  	if (!ret)
  		return TRACE_TYPE_PARTIAL_LINE;
  
  	return TRACE_TYPE_HANDLED;
  }
  
  enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
  {
  	struct trace_seq *s = &iter->seq;
  	struct trace_entry *entry = iter->ent;
  	struct print_entry *field;
  	int ret;
  
  	trace_assign_type(field, entry);
  
  	ret = trace_seq_printf(s, "%s", field->buf);
  	if (!ret)
  		return TRACE_TYPE_PARTIAL_LINE;
  
  	return TRACE_TYPE_HANDLED;
  }
f0868d1e2   Steven Rostedt   ftrace: set up tr...
68
69
70
71
72
  /**
   * trace_seq_printf - sequence printing of trace information
   * @s: trace sequence descriptor
   * @fmt: printf format string
   *
3e69533b5   Jiri Olsa   tracing: Fix trac...
73
74
75
   * It returns 0 if the trace oversizes the buffer's free
   * space, 1 otherwise.
   *
f0868d1e2   Steven Rostedt   ftrace: set up tr...
76
77
78
79
80
81
82
83
84
85
86
87
   * The tracer may use either sequence operations or its own
   * copy to user routines. To simplify formating of a trace
   * trace_seq_printf is used to store strings into a special
   * buffer (@s). Then the output may be either used by
   * the sequencer or pulled into another buffer.
   */
  int
  trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
  {
  	int len = (PAGE_SIZE - 1) - s->len;
  	va_list ap;
  	int ret;
d184b31c0   Johannes Berg   tracing: Add full...
88
  	if (s->full || !len)
f0868d1e2   Steven Rostedt   ftrace: set up tr...
89
90
91
92
93
94
95
  		return 0;
  
  	va_start(ap, fmt);
  	ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
  	va_end(ap);
  
  	/* If we can't write it all, don't bother writing anything */
d184b31c0   Johannes Berg   tracing: Add full...
96
97
  	if (ret >= len) {
  		s->full = 1;
f0868d1e2   Steven Rostedt   ftrace: set up tr...
98
  		return 0;
d184b31c0   Johannes Berg   tracing: Add full...
99
  	}
f0868d1e2   Steven Rostedt   ftrace: set up tr...
100
101
  
  	s->len += ret;
3e69533b5   Jiri Olsa   tracing: Fix trac...
102
  	return 1;
f0868d1e2   Steven Rostedt   ftrace: set up tr...
103
  }
17c873ec2   Steven Rostedt   tracing/events: a...
104
  EXPORT_SYMBOL_GPL(trace_seq_printf);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
105

725c624a5   Steven Rostedt   tracing: add trac...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  /**
   * trace_seq_vprintf - sequence printing of trace information
   * @s: trace sequence descriptor
   * @fmt: printf format string
   *
   * The tracer may use either sequence operations or its own
   * copy to user routines. To simplify formating of a trace
   * trace_seq_printf is used to store strings into a special
   * buffer (@s). Then the output may be either used by
   * the sequencer or pulled into another buffer.
   */
  int
  trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
  {
  	int len = (PAGE_SIZE - 1) - s->len;
  	int ret;
d184b31c0   Johannes Berg   tracing: Add full...
122
  	if (s->full || !len)
725c624a5   Steven Rostedt   tracing: add trac...
123
124
125
126
127
  		return 0;
  
  	ret = vsnprintf(s->buffer + s->len, len, fmt, args);
  
  	/* If we can't write it all, don't bother writing anything */
d184b31c0   Johannes Berg   tracing: Add full...
128
129
  	if (ret >= len) {
  		s->full = 1;
725c624a5   Steven Rostedt   tracing: add trac...
130
  		return 0;
d184b31c0   Johannes Berg   tracing: Add full...
131
  	}
725c624a5   Steven Rostedt   tracing: add trac...
132
133
134
135
136
137
  
  	s->len += ret;
  
  	return len;
  }
  EXPORT_SYMBOL_GPL(trace_seq_vprintf);
769b0441f   Frederic Weisbecker   tracing/core: dro...
138
  int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
1427cdf05   Lai Jiangshan   tracing: infrastr...
139
140
141
  {
  	int len = (PAGE_SIZE - 1) - s->len;
  	int ret;
d184b31c0   Johannes Berg   tracing: Add full...
142
  	if (s->full || !len)
1427cdf05   Lai Jiangshan   tracing: infrastr...
143
144
145
146
147
  		return 0;
  
  	ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
  
  	/* If we can't write it all, don't bother writing anything */
d184b31c0   Johannes Berg   tracing: Add full...
148
149
  	if (ret >= len) {
  		s->full = 1;
1427cdf05   Lai Jiangshan   tracing: infrastr...
150
  		return 0;
d184b31c0   Johannes Berg   tracing: Add full...
151
  	}
1427cdf05   Lai Jiangshan   tracing: infrastr...
152
153
154
155
156
  
  	s->len += ret;
  
  	return len;
  }
f0868d1e2   Steven Rostedt   ftrace: set up tr...
157
158
159
160
161
162
163
164
165
166
167
168
169
  /**
   * trace_seq_puts - trace sequence printing of simple string
   * @s: trace sequence descriptor
   * @str: simple string to record
   *
   * The tracer may use either the sequence operations or its own
   * copy to user routines. This function records a simple string
   * into a special buffer (@s) for later retrieval by a sequencer
   * or other mechanism.
   */
  int trace_seq_puts(struct trace_seq *s, const char *str)
  {
  	int len = strlen(str);
d184b31c0   Johannes Berg   tracing: Add full...
170
  	if (s->full)
f0868d1e2   Steven Rostedt   ftrace: set up tr...
171
  		return 0;
d184b31c0   Johannes Berg   tracing: Add full...
172
173
174
175
  	if (len > ((PAGE_SIZE - 1) - s->len)) {
  		s->full = 1;
  		return 0;
  	}
f0868d1e2   Steven Rostedt   ftrace: set up tr...
176
177
178
179
180
181
182
183
  	memcpy(s->buffer + s->len, str, len);
  	s->len += len;
  
  	return len;
  }
  
  int trace_seq_putc(struct trace_seq *s, unsigned char c)
  {
d184b31c0   Johannes Berg   tracing: Add full...
184
  	if (s->full)
f0868d1e2   Steven Rostedt   ftrace: set up tr...
185
  		return 0;
d184b31c0   Johannes Berg   tracing: Add full...
186
187
188
189
  	if (s->len >= (PAGE_SIZE - 1)) {
  		s->full = 1;
  		return 0;
  	}
f0868d1e2   Steven Rostedt   ftrace: set up tr...
190
191
192
193
  	s->buffer[s->len++] = c;
  
  	return 1;
  }
bf8162354   Kei Tokunaga   [SCSI] add scsi t...
194
  EXPORT_SYMBOL(trace_seq_putc);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
195

b14b70a6a   Li Zefan   trace: make argum...
196
  int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
f0868d1e2   Steven Rostedt   ftrace: set up tr...
197
  {
d184b31c0   Johannes Berg   tracing: Add full...
198
  	if (s->full)
f0868d1e2   Steven Rostedt   ftrace: set up tr...
199
  		return 0;
d184b31c0   Johannes Berg   tracing: Add full...
200
201
202
203
  	if (len > ((PAGE_SIZE - 1) - s->len)) {
  		s->full = 1;
  		return 0;
  	}
f0868d1e2   Steven Rostedt   ftrace: set up tr...
204
205
206
207
208
  	memcpy(s->buffer + s->len, mem, len);
  	s->len += len;
  
  	return len;
  }
b14b70a6a   Li Zefan   trace: make argum...
209
  int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
f0868d1e2   Steven Rostedt   ftrace: set up tr...
210
211
  {
  	unsigned char hex[HEX_CHARS];
b14b70a6a   Li Zefan   trace: make argum...
212
  	const unsigned char *data = mem;
f0868d1e2   Steven Rostedt   ftrace: set up tr...
213
  	int i, j;
d184b31c0   Johannes Berg   tracing: Add full...
214
215
  	if (s->full)
  		return 0;
f0868d1e2   Steven Rostedt   ftrace: set up tr...
216
217
218
219
220
221
222
223
224
225
226
227
  #ifdef __BIG_ENDIAN
  	for (i = 0, j = 0; i < len; i++) {
  #else
  	for (i = len-1, j = 0; i >= 0; i--) {
  #endif
  		hex[j++] = hex_asc_hi(data[i]);
  		hex[j++] = hex_asc_lo(data[i]);
  	}
  	hex[j++] = ' ';
  
  	return trace_seq_putmem(s, hex, j);
  }
bdd6df6af   Eduard - Gabriel Munteanu   tracing: provide ...
228
229
230
  void *trace_seq_reserve(struct trace_seq *s, size_t len)
  {
  	void *ret;
d184b31c0   Johannes Berg   tracing: Add full...
231
  	if (s->full)
668eb65f0   Thiago Farina   tracing: Fix "int...
232
  		return NULL;
d184b31c0   Johannes Berg   tracing: Add full...
233
234
235
  
  	if (len > ((PAGE_SIZE - 1) - s->len)) {
  		s->full = 1;
bdd6df6af   Eduard - Gabriel Munteanu   tracing: provide ...
236
  		return NULL;
d184b31c0   Johannes Berg   tracing: Add full...
237
  	}
bdd6df6af   Eduard - Gabriel Munteanu   tracing: provide ...
238
239
240
241
242
243
  
  	ret = s->buffer + s->len;
  	s->len += len;
  
  	return ret;
  }
f0868d1e2   Steven Rostedt   ftrace: set up tr...
244
245
246
  int trace_seq_path(struct trace_seq *s, struct path *path)
  {
  	unsigned char *p;
d184b31c0   Johannes Berg   tracing: Add full...
247
  	if (s->full)
f0868d1e2   Steven Rostedt   ftrace: set up tr...
248
  		return 0;
d184b31c0   Johannes Berg   tracing: Add full...
249
250
251
252
253
  
  	if (s->len >= (PAGE_SIZE - 1)) {
  		s->full = 1;
  		return 0;
  	}
f0868d1e2   Steven Rostedt   ftrace: set up tr...
254
255
256
257
258
259
260
261
262
263
264
265
  	p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
  	if (!IS_ERR(p)) {
  		p = mangle_path(s->buffer + s->len, p, "
  ");
  		if (p) {
  			s->len = p - s->buffer;
  			return 1;
  		}
  	} else {
  		s->buffer[s->len++] = '?';
  		return 1;
  	}
d184b31c0   Johannes Berg   tracing: Add full...
266
  	s->full = 1;
f0868d1e2   Steven Rostedt   ftrace: set up tr...
267
268
  	return 0;
  }
be74b73a5   Steven Rostedt   tracing: add __pr...
269
270
271
272
273
274
275
  const char *
  ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
  		       unsigned long flags,
  		       const struct trace_print_flags *flag_array)
  {
  	unsigned long mask;
  	const char *str;
56d8bd3f0   Steven Whitehouse   tracing: fix mult...
276
  	const char *ret = p->buffer + p->len;
be74b73a5   Steven Rostedt   tracing: add __pr...
277
  	int i;
be74b73a5   Steven Rostedt   tracing: add __pr...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  	for (i = 0;  flag_array[i].name && flags; i++) {
  
  		mask = flag_array[i].mask;
  		if ((flags & mask) != mask)
  			continue;
  
  		str = flag_array[i].name;
  		flags &= ~mask;
  		if (p->len && delim)
  			trace_seq_puts(p, delim);
  		trace_seq_puts(p, str);
  	}
  
  	/* check for left over flags */
  	if (flags) {
  		if (p->len && delim)
  			trace_seq_puts(p, delim);
  		trace_seq_printf(p, "0x%lx", flags);
  	}
  
  	trace_seq_putc(p, 0);
56d8bd3f0   Steven Whitehouse   tracing: fix mult...
299
  	return ret;
be74b73a5   Steven Rostedt   tracing: add __pr...
300
  }
ec081ddc3   Steven Whitehouse   tracing: add expo...
301
  EXPORT_SYMBOL(ftrace_print_flags_seq);
be74b73a5   Steven Rostedt   tracing: add __pr...
302

0f4fc29dd   Steven Rostedt   tracing: add __pr...
303
304
305
306
307
  const char *
  ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
  			 const struct trace_print_flags *symbol_array)
  {
  	int i;
56d8bd3f0   Steven Whitehouse   tracing: fix mult...
308
  	const char *ret = p->buffer + p->len;
0f4fc29dd   Steven Rostedt   tracing: add __pr...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
  
  	for (i = 0;  symbol_array[i].name; i++) {
  
  		if (val != symbol_array[i].mask)
  			continue;
  
  		trace_seq_puts(p, symbol_array[i].name);
  		break;
  	}
  
  	if (!p->len)
  		trace_seq_printf(p, "0x%lx", val);
  		
  	trace_seq_putc(p, 0);
56d8bd3f0   Steven Whitehouse   tracing: fix mult...
323
  	return ret;
0f4fc29dd   Steven Rostedt   tracing: add __pr...
324
  }
ec081ddc3   Steven Whitehouse   tracing: add expo...
325
  EXPORT_SYMBOL(ftrace_print_symbols_seq);
0f4fc29dd   Steven Rostedt   tracing: add __pr...
326

2fc1b6f0d   liubo   tracing: Add __pr...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  #if BITS_PER_LONG == 32
  const char *
  ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
  			 const struct trace_print_flags_u64 *symbol_array)
  {
  	int i;
  	const char *ret = p->buffer + p->len;
  
  	for (i = 0;  symbol_array[i].name; i++) {
  
  		if (val != symbol_array[i].mask)
  			continue;
  
  		trace_seq_puts(p, symbol_array[i].name);
  		break;
  	}
  
  	if (!p->len)
  		trace_seq_printf(p, "0x%llx", val);
  
  	trace_seq_putc(p, 0);
  
  	return ret;
  }
  EXPORT_SYMBOL(ftrace_print_symbols_seq_u64);
  #endif
5a2e39959   Kei Tokunaga   [SCSI] ftrace: ad...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  const char *
  ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len)
  {
  	int i;
  	const char *ret = p->buffer + p->len;
  
  	for (i = 0; i < buf_len; i++)
  		trace_seq_printf(p, "%s%2.2x", i == 0 ? "" : " ", buf[i]);
  
  	trace_seq_putc(p, 0);
  
  	return ret;
  }
  EXPORT_SYMBOL(ftrace_print_hex_seq);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
  #ifdef CONFIG_KRETPROBES
  static inline const char *kretprobed(const char *name)
  {
  	static const char tramp_name[] = "kretprobe_trampoline";
  	int size = sizeof(tramp_name);
  
  	if (strncmp(tramp_name, name, size) == 0)
  		return "[unknown/kretprobe'd]";
  	return name;
  }
  #else
  static inline const char *kretprobed(const char *name)
  {
  	return name;
  }
  #endif /* CONFIG_KRETPROBES */
  
  static int
  seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
  {
  #ifdef CONFIG_KALLSYMS
  	char str[KSYM_SYMBOL_LEN];
  	const char *name;
  
  	kallsyms_lookup(address, NULL, NULL, NULL, str);
  
  	name = kretprobed(str);
  
  	return trace_seq_printf(s, fmt, name);
  #endif
  	return 1;
  }
  
  static int
  seq_print_sym_offset(struct trace_seq *s, const char *fmt,
  		     unsigned long address)
  {
  #ifdef CONFIG_KALLSYMS
  	char str[KSYM_SYMBOL_LEN];
  	const char *name;
  
  	sprint_symbol(str, address);
  	name = kretprobed(str);
  
  	return trace_seq_printf(s, fmt, name);
  #endif
  	return 1;
  }
  
  #ifndef CONFIG_64BIT
  # define IP_FMT "%08lx"
  #else
  # define IP_FMT "%016lx"
  #endif
  
  int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
  		      unsigned long ip, unsigned long sym_flags)
  {
  	struct file *file = NULL;
  	unsigned long vmstart = 0;
  	int ret = 1;
d184b31c0   Johannes Berg   tracing: Add full...
428
429
  	if (s->full)
  		return 0;
f0868d1e2   Steven Rostedt   ftrace: set up tr...
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  	if (mm) {
  		const struct vm_area_struct *vma;
  
  		down_read(&mm->mmap_sem);
  		vma = find_vma(mm, ip);
  		if (vma) {
  			file = vma->vm_file;
  			vmstart = vma->vm_start;
  		}
  		if (file) {
  			ret = trace_seq_path(s, &file->f_path);
  			if (ret)
  				ret = trace_seq_printf(s, "[+0x%lx]",
  						       ip - vmstart);
  		}
  		up_read(&mm->mmap_sem);
  	}
  	if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
  		ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
  	return ret;
  }
  
  int
  seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
  		      unsigned long sym_flags)
  {
  	struct mm_struct *mm = NULL;
  	int ret = 1;
  	unsigned int i;
  
  	if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
  		struct task_struct *task;
  		/*
  		 * we do the lookup on the thread group leader,
  		 * since individual threads might have already quit!
  		 */
  		rcu_read_lock();
48659d311   Steven Rostedt   tracing: move tgi...
467
  		task = find_task_by_vpid(entry->tgid);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
468
469
470
471
472
473
474
475
476
477
  		if (task)
  			mm = get_task_mm(task);
  		rcu_read_unlock();
  	}
  
  	for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
  		unsigned long ip = entry->caller[i];
  
  		if (ip == ULONG_MAX || !ret)
  			break;
048dc50c5   walimis   tracing/events: f...
478
479
  		if (ret)
  			ret = trace_seq_puts(s, " => ");
f0868d1e2   Steven Rostedt   ftrace: set up tr...
480
481
482
  		if (!ip) {
  			if (ret)
  				ret = trace_seq_puts(s, "??");
048dc50c5   walimis   tracing/events: f...
483
484
485
  			if (ret)
  				ret = trace_seq_puts(s, "
  ");
f0868d1e2   Steven Rostedt   ftrace: set up tr...
486
487
488
489
490
491
  			continue;
  		}
  		if (!ret)
  			break;
  		if (ret)
  			ret = seq_print_user_ip(s, mm, ip, sym_flags);
048dc50c5   walimis   tracing/events: f...
492
493
  		ret = trace_seq_puts(s, "
  ");
f0868d1e2   Steven Rostedt   ftrace: set up tr...
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  	}
  
  	if (mm)
  		mmput(mm);
  	return ret;
  }
  
  int
  seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
  {
  	int ret;
  
  	if (!ip)
  		return trace_seq_printf(s, "0");
  
  	if (sym_flags & TRACE_ITER_SYM_OFFSET)
  		ret = seq_print_sym_offset(s, "%s", ip);
  	else
  		ret = seq_print_sym_short(s, "%s", ip);
  
  	if (!ret)
  		return 0;
  
  	if (sym_flags & TRACE_ITER_SYM_ADDR)
  		ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
  	return ret;
  }
f81c972d2   Steven Rostedt   tracing: consolid...
521
522
523
524
525
526
  /**
   * trace_print_lat_fmt - print the irq, preempt and lockdep fields
   * @s: trace seq struct to write to
   * @entry: The trace entry field from the ring buffer
   *
   * Prints the generic fields of irqs off, in hard or softirq, preempt
e6e1e2593   Steven Rostedt   tracing: Remove l...
527
   * count.
f81c972d2   Steven Rostedt   tracing: consolid...
528
529
   */
  int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
c4a8e8be2   Frederic Weisbecker   trace: better man...
530
  {
10da37a64   David Sharp   tracing: Adjust c...
531
532
533
534
535
  	char hardsoft_irq;
  	char need_resched;
  	char irqs_off;
  	int hardirq;
  	int softirq;
637e7e864   Steven Rostedt   tracing: add lock...
536
  	int ret;
c4a8e8be2   Frederic Weisbecker   trace: better man...
537

c4a8e8be2   Frederic Weisbecker   trace: better man...
538
539
  	hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
  	softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
540

10da37a64   David Sharp   tracing: Adjust c...
541
542
543
544
545
546
547
548
549
550
551
  	irqs_off =
  		(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
  		(entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' :
  		'.';
  	need_resched =
  		(entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.';
  	hardsoft_irq =
  		(hardirq && softirq) ? 'H' :
  		hardirq ? 'h' :
  		softirq ? 's' :
  		'.';
f81c972d2   Steven Rostedt   tracing: consolid...
552
  	if (!trace_seq_printf(s, "%c%c%c",
10da37a64   David Sharp   tracing: Adjust c...
553
  			      irqs_off, need_resched, hardsoft_irq))
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
554
  		return 0;
c4a8e8be2   Frederic Weisbecker   trace: better man...
555

829b876df   Steven Rostedt   tracing: fix tran...
556
557
  	if (entry->preempt_count)
  		ret = trace_seq_printf(s, "%x", entry->preempt_count);
637e7e864   Steven Rostedt   tracing: add lock...
558
  	else
829b876df   Steven Rostedt   tracing: fix tran...
559
  		ret = trace_seq_putc(s, '.');
e6e1e2593   Steven Rostedt   tracing: Remove l...
560
  	return ret;
c4a8e8be2   Frederic Weisbecker   trace: better man...
561
  }
f81c972d2   Steven Rostedt   tracing: consolid...
562
563
564
565
566
567
568
569
570
571
572
573
574
  static int
  lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
  {
  	char comm[TASK_COMM_LEN];
  
  	trace_find_cmdline(entry->pid, comm);
  
  	if (!trace_seq_printf(s, "%8.8s-%-5d %3d",
  			      comm, entry->pid, cpu))
  		return 0;
  
  	return trace_print_lat_fmt(s, entry);
  }
c4a8e8be2   Frederic Weisbecker   trace: better man...
575
  static unsigned long preempt_mark_thresh = 100;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
576
  static int
c4a8e8be2   Frederic Weisbecker   trace: better man...
577
578
579
  lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
  		    unsigned long rel_usecs)
  {
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
580
581
582
  	return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
  				rel_usecs > preempt_mark_thresh ? '!' :
  				  rel_usecs > 1 ? '+' : ' ');
c4a8e8be2   Frederic Weisbecker   trace: better man...
583
584
585
586
587
588
  }
  
  int trace_print_context(struct trace_iterator *iter)
  {
  	struct trace_seq *s = &iter->seq;
  	struct trace_entry *entry = iter->ent;
c4a8e8be2   Frederic Weisbecker   trace: better man...
589
590
591
  	unsigned long long t = ns2usecs(iter->ts);
  	unsigned long usec_rem = do_div(t, USEC_PER_SEC);
  	unsigned long secs = (unsigned long)t;
4ca530852   Steven Rostedt   tracing: protect ...
592
  	char comm[TASK_COMM_LEN];
77271ce4b   Steven Rostedt   tracing: Add irq,...
593
  	int ret;
4ca530852   Steven Rostedt   tracing: protect ...
594
595
  
  	trace_find_cmdline(entry->pid, comm);
c4a8e8be2   Frederic Weisbecker   trace: better man...
596

77271ce4b   Steven Rostedt   tracing: Add irq,...
597
598
599
600
601
602
603
604
605
606
607
608
609
  	ret = trace_seq_printf(s, "%16s-%-5d [%03d] ",
  			       comm, entry->pid, iter->cpu);
  	if (!ret)
  		return 0;
  
  	if (trace_flags & TRACE_ITER_IRQ_INFO) {
  		ret = trace_print_lat_fmt(s, entry);
  		if (!ret)
  			return 0;
  	}
  
  	return trace_seq_printf(s, " %5lu.%06lu: ",
  				secs, usec_rem);
c4a8e8be2   Frederic Weisbecker   trace: better man...
610
611
612
613
614
  }
  
  int trace_print_lat_context(struct trace_iterator *iter)
  {
  	u64 next_ts;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
615
  	int ret;
c4a8e8be2   Frederic Weisbecker   trace: better man...
616
617
618
619
620
621
622
623
624
625
626
627
628
  	struct trace_seq *s = &iter->seq;
  	struct trace_entry *entry = iter->ent,
  			   *next_entry = trace_find_next_entry(iter, NULL,
  							       &next_ts);
  	unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
  	unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
  	unsigned long rel_usecs;
  
  	if (!next_entry)
  		next_ts = iter->ts;
  	rel_usecs = ns2usecs(next_ts - iter->ts);
  
  	if (verbose) {
4ca530852   Steven Rostedt   tracing: protect ...
629
630
631
  		char comm[TASK_COMM_LEN];
  
  		trace_find_cmdline(entry->pid, comm);
cf8e34746   Lai Jiangshan   tracing: fix inco...
632
  		ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]"
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
633
  				       " %ld.%03ldms (+%ld.%03ldms): ", comm,
1830b52d0   Steven Rostedt   trace: remove dep...
634
  				       entry->pid, iter->cpu, entry->flags,
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
635
636
637
638
639
640
  				       entry->preempt_count, iter->idx,
  				       ns2usecs(iter->ts),
  				       abs_usecs / USEC_PER_MSEC,
  				       abs_usecs % USEC_PER_MSEC,
  				       rel_usecs / USEC_PER_MSEC,
  				       rel_usecs % USEC_PER_MSEC);
c4a8e8be2   Frederic Weisbecker   trace: better man...
641
  	} else {
1830b52d0   Steven Rostedt   trace: remove dep...
642
  		ret = lat_print_generic(s, entry, iter->cpu);
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
643
644
  		if (ret)
  			ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
c4a8e8be2   Frederic Weisbecker   trace: better man...
645
  	}
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
646
  	return ret;
c4a8e8be2   Frederic Weisbecker   trace: better man...
647
  }
f633cef02   Steven Rostedt   ftrace: change tr...
648
649
650
651
652
653
654
655
  static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
  
  static int task_state_char(unsigned long state)
  {
  	int bit = state ? __ffs(state) + 1 : 0;
  
  	return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
  }
f0868d1e2   Steven Rostedt   ftrace: set up tr...
656
657
658
659
660
  /**
   * ftrace_find_event - find a registered event
   * @type: the type of event to look for
   *
   * Returns an event of type @type otherwise NULL
4f5359685   Lai Jiangshan   tracing: add trac...
661
   * Called with trace_event_read_lock() held.
f0868d1e2   Steven Rostedt   ftrace: set up tr...
662
663
664
665
666
667
668
669
   */
  struct trace_event *ftrace_find_event(int type)
  {
  	struct trace_event *event;
  	struct hlist_node *n;
  	unsigned key;
  
  	key = type & (EVENT_HASHSIZE - 1);
4f5359685   Lai Jiangshan   tracing: add trac...
670
  	hlist_for_each_entry(event, n, &event_hash[key], node) {
f0868d1e2   Steven Rostedt   ftrace: set up tr...
671
672
673
674
675
676
  		if (event->type == type)
  			return event;
  	}
  
  	return NULL;
  }
060fa5c83   Steven Rostedt   tracing/events: r...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
  static LIST_HEAD(ftrace_event_list);
  
  static int trace_search_list(struct list_head **list)
  {
  	struct trace_event *e;
  	int last = __TRACE_LAST_TYPE;
  
  	if (list_empty(&ftrace_event_list)) {
  		*list = &ftrace_event_list;
  		return last + 1;
  	}
  
  	/*
  	 * We used up all possible max events,
  	 * lets see if somebody freed one.
  	 */
  	list_for_each_entry(e, &ftrace_event_list, list) {
  		if (e->type != last + 1)
  			break;
  		last++;
  	}
  
  	/* Did we used up all 65 thousand events??? */
  	if ((last + 1) > FTRACE_MAX_EVENT)
  		return 0;
  
  	*list = &e->list;
  	return last + 1;
  }
4f5359685   Lai Jiangshan   tracing: add trac...
706
707
708
709
710
711
712
713
714
  void trace_event_read_lock(void)
  {
  	down_read(&trace_event_mutex);
  }
  
  void trace_event_read_unlock(void)
  {
  	up_read(&trace_event_mutex);
  }
f0868d1e2   Steven Rostedt   ftrace: set up tr...
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
  /**
   * register_ftrace_event - register output for an event type
   * @event: the event type to register
   *
   * Event types are stored in a hash and this hash is used to
   * find a way to print an event. If the @event->type is set
   * then it will use that type, otherwise it will assign a
   * type to use.
   *
   * If you assign your own type, please make sure it is added
   * to the trace_type enum in trace.h, to avoid collisions
   * with the dynamic types.
   *
   * Returns the event type number or zero on error.
   */
  int register_ftrace_event(struct trace_event *event)
  {
  	unsigned key;
  	int ret = 0;
4f5359685   Lai Jiangshan   tracing: add trac...
734
  	down_write(&trace_event_mutex);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
735

060fa5c83   Steven Rostedt   tracing/events: r...
736
  	if (WARN_ON(!event))
28bea271e   Peter Zijlstra   ftrace: ensure ev...
737
  		goto out;
28bea271e   Peter Zijlstra   ftrace: ensure ev...
738

a9a577638   Steven Rostedt   tracing: Allow ev...
739
740
  	if (WARN_ON(!event->funcs))
  		goto out;
060fa5c83   Steven Rostedt   tracing/events: r...
741
742
743
  	INIT_LIST_HEAD(&event->list);
  
  	if (!event->type) {
48dd0fed9   Jaswinder Singh Rajput   tracing: trace_ou...
744
  		struct list_head *list = NULL;
060fa5c83   Steven Rostedt   tracing/events: r...
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
  
  		if (next_event_type > FTRACE_MAX_EVENT) {
  
  			event->type = trace_search_list(&list);
  			if (!event->type)
  				goto out;
  
  		} else {
  			
  			event->type = next_event_type++;
  			list = &ftrace_event_list;
  		}
  
  		if (WARN_ON(ftrace_find_event(event->type)))
  			goto out;
  
  		list_add_tail(&event->list, list);
  
  	} else if (event->type > __TRACE_LAST_TYPE) {
f0868d1e2   Steven Rostedt   ftrace: set up tr...
764
765
766
  		printk(KERN_WARNING "Need to add type to trace.h
  ");
  		WARN_ON(1);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
767
  		goto out;
060fa5c83   Steven Rostedt   tracing/events: r...
768
769
770
771
772
  	} else {
  		/* Is this event already used */
  		if (ftrace_find_event(event->type))
  			goto out;
  	}
f0868d1e2   Steven Rostedt   ftrace: set up tr...
773

a9a577638   Steven Rostedt   tracing: Allow ev...
774
775
776
777
778
779
780
781
  	if (event->funcs->trace == NULL)
  		event->funcs->trace = trace_nop_print;
  	if (event->funcs->raw == NULL)
  		event->funcs->raw = trace_nop_print;
  	if (event->funcs->hex == NULL)
  		event->funcs->hex = trace_nop_print;
  	if (event->funcs->binary == NULL)
  		event->funcs->binary = trace_nop_print;
268ccda0c   Arnaldo Carvalho de Melo   trace: assign def...
782

f0868d1e2   Steven Rostedt   ftrace: set up tr...
783
  	key = event->type & (EVENT_HASHSIZE - 1);
4f5359685   Lai Jiangshan   tracing: add trac...
784
  	hlist_add_head(&event->node, &event_hash[key]);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
785
786
787
  
  	ret = event->type;
   out:
4f5359685   Lai Jiangshan   tracing: add trac...
788
  	up_write(&trace_event_mutex);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
789
790
791
  
  	return ret;
  }
17c873ec2   Steven Rostedt   tracing/events: a...
792
  EXPORT_SYMBOL_GPL(register_ftrace_event);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
793

110bf2b76   Steven Rostedt   tracing: add prot...
794
795
796
797
798
799
800
801
802
  /*
   * Used by module code with the trace_event_mutex held for write.
   */
  int __unregister_ftrace_event(struct trace_event *event)
  {
  	hlist_del(&event->node);
  	list_del(&event->list);
  	return 0;
  }
f0868d1e2   Steven Rostedt   ftrace: set up tr...
803
804
805
806
807
808
  /**
   * unregister_ftrace_event - remove a no longer used event
   * @event: the event to remove
   */
  int unregister_ftrace_event(struct trace_event *event)
  {
4f5359685   Lai Jiangshan   tracing: add trac...
809
  	down_write(&trace_event_mutex);
110bf2b76   Steven Rostedt   tracing: add prot...
810
  	__unregister_ftrace_event(event);
4f5359685   Lai Jiangshan   tracing: add trac...
811
  	up_write(&trace_event_mutex);
f0868d1e2   Steven Rostedt   ftrace: set up tr...
812
813
814
  
  	return 0;
  }
17c873ec2   Steven Rostedt   tracing/events: a...
815
  EXPORT_SYMBOL_GPL(unregister_ftrace_event);
f633cef02   Steven Rostedt   ftrace: change tr...
816
817
818
819
  
  /*
   * Standard events
   */
a9a577638   Steven Rostedt   tracing: Allow ev...
820
821
  enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags,
  				  struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
822
  {
ee5e51f51   Jiri Olsa   tracing: Avoid so...
823
824
825
  	if (!trace_seq_printf(&iter->seq, "type: %d
  ", iter->ent->type))
  		return TRACE_TYPE_PARTIAL_LINE;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
826
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
827
828
829
  }
  
  /* TRACE_FN */
a9a577638   Steven Rostedt   tracing: Allow ev...
830
831
  static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags,
  					struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
832
833
  {
  	struct ftrace_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
834
  	struct trace_seq *s = &iter->seq;
f633cef02   Steven Rostedt   ftrace: change tr...
835

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
836
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
  
  	if (!seq_print_ip_sym(s, field->ip, flags))
  		goto partial;
  
  	if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
  		if (!trace_seq_printf(s, " <-"))
  			goto partial;
  		if (!seq_print_ip_sym(s,
  				      field->parent_ip,
  				      flags))
  			goto partial;
  	}
  	if (!trace_seq_printf(s, "
  "))
  		goto partial;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
852
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
853
854
855
856
  
   partial:
  	return TRACE_TYPE_PARTIAL_LINE;
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
857
858
  static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags,
  				      struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
859
860
  {
  	struct ftrace_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
861
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
862

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
863
864
  	if (!trace_seq_printf(&iter->seq, "%lx %lx
  ",
6c1a99afb   Lai Jiangshan   ftrace: fix trace...
865
866
  			      field->ip,
  			      field->parent_ip))
f633cef02   Steven Rostedt   ftrace: change tr...
867
  		return TRACE_TYPE_PARTIAL_LINE;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
868
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
869
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
870
871
  static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags,
  				      struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
872
873
  {
  	struct ftrace_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
874
  	struct trace_seq *s = &iter->seq;
f633cef02   Steven Rostedt   ftrace: change tr...
875

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
876
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
877
878
879
  
  	SEQ_PUT_HEX_FIELD_RET(s, field->ip);
  	SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
880
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
881
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
882
883
  static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags,
  				      struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
884
885
  {
  	struct ftrace_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
886
  	struct trace_seq *s = &iter->seq;
f633cef02   Steven Rostedt   ftrace: change tr...
887

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
888
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
889
890
891
  
  	SEQ_PUT_FIELD_RET(s, field->ip);
  	SEQ_PUT_FIELD_RET(s, field->parent_ip);
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
892
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
893
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
894
  static struct trace_event_functions trace_fn_funcs = {
f633cef02   Steven Rostedt   ftrace: change tr...
895
  	.trace		= trace_fn_trace,
f633cef02   Steven Rostedt   ftrace: change tr...
896
897
898
899
  	.raw		= trace_fn_raw,
  	.hex		= trace_fn_hex,
  	.binary		= trace_fn_bin,
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
900
901
902
903
  static struct trace_event trace_fn_event = {
  	.type		= TRACE_FN,
  	.funcs		= &trace_fn_funcs,
  };
f633cef02   Steven Rostedt   ftrace: change tr...
904
  /* TRACE_CTX an TRACE_WAKE */
ae7462b4f   Arnaldo Carvalho de Melo   trace: make the t...
905
906
  static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
  					     char *delim)
f633cef02   Steven Rostedt   ftrace: change tr...
907
908
  {
  	struct ctx_switch_entry *field;
4ca530852   Steven Rostedt   tracing: protect ...
909
  	char comm[TASK_COMM_LEN];
f633cef02   Steven Rostedt   ftrace: change tr...
910
  	int S, T;
4ca530852   Steven Rostedt   tracing: protect ...
911

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
912
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
913
914
915
  
  	T = task_state_char(field->next_state);
  	S = task_state_char(field->prev_state);
4ca530852   Steven Rostedt   tracing: protect ...
916
  	trace_find_cmdline(field->next_pid, comm);
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
917
918
919
  	if (!trace_seq_printf(&iter->seq,
  			      " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s
  ",
6c1a99afb   Lai Jiangshan   ftrace: fix trace...
920
921
922
923
924
925
926
  			      field->prev_pid,
  			      field->prev_prio,
  			      S, delim,
  			      field->next_cpu,
  			      field->next_pid,
  			      field->next_prio,
  			      T, comm))
f633cef02   Steven Rostedt   ftrace: change tr...
927
  		return TRACE_TYPE_PARTIAL_LINE;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
928
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
929
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
930
931
  static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags,
  					 struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
932
  {
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
933
  	return trace_ctxwake_print(iter, "==>");
f633cef02   Steven Rostedt   ftrace: change tr...
934
  }
ae7462b4f   Arnaldo Carvalho de Melo   trace: make the t...
935
  static enum print_line_t trace_wake_print(struct trace_iterator *iter,
a9a577638   Steven Rostedt   tracing: Allow ev...
936
  					  int flags, struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
937
  {
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
938
  	return trace_ctxwake_print(iter, "  +");
f633cef02   Steven Rostedt   ftrace: change tr...
939
  }
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
940
  static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
f633cef02   Steven Rostedt   ftrace: change tr...
941
942
943
  {
  	struct ctx_switch_entry *field;
  	int T;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
944
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
945
946
  
  	if (!S)
b0f56f1a6   Hiroshi Shimamoto   trace: Fix missin...
947
  		S = task_state_char(field->prev_state);
f633cef02   Steven Rostedt   ftrace: change tr...
948
  	T = task_state_char(field->next_state);
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
949
950
  	if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c
  ",
6c1a99afb   Lai Jiangshan   ftrace: fix trace...
951
952
953
954
955
956
957
  			      field->prev_pid,
  			      field->prev_prio,
  			      S,
  			      field->next_cpu,
  			      field->next_pid,
  			      field->next_prio,
  			      T))
f633cef02   Steven Rostedt   ftrace: change tr...
958
  		return TRACE_TYPE_PARTIAL_LINE;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
959
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
960
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
961
962
  static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags,
  				       struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
963
  {
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
964
  	return trace_ctxwake_raw(iter, 0);
f633cef02   Steven Rostedt   ftrace: change tr...
965
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
966
967
  static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags,
  					struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
968
  {
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
969
  	return trace_ctxwake_raw(iter, '+');
f633cef02   Steven Rostedt   ftrace: change tr...
970
  }
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
971
  static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
f633cef02   Steven Rostedt   ftrace: change tr...
972
973
  {
  	struct ctx_switch_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
974
  	struct trace_seq *s = &iter->seq;
f633cef02   Steven Rostedt   ftrace: change tr...
975
  	int T;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
976
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
977
978
  
  	if (!S)
b0f56f1a6   Hiroshi Shimamoto   trace: Fix missin...
979
  		S = task_state_char(field->prev_state);
f633cef02   Steven Rostedt   ftrace: change tr...
980
981
982
983
984
985
986
987
988
  	T = task_state_char(field->next_state);
  
  	SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
  	SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
  	SEQ_PUT_HEX_FIELD_RET(s, S);
  	SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
  	SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
  	SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
  	SEQ_PUT_HEX_FIELD_RET(s, T);
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
989
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
990
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
991
992
  static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags,
  				       struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
993
  {
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
994
  	return trace_ctxwake_hex(iter, 0);
f633cef02   Steven Rostedt   ftrace: change tr...
995
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
996
997
  static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags,
  					struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
998
  {
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
999
  	return trace_ctxwake_hex(iter, '+');
f633cef02   Steven Rostedt   ftrace: change tr...
1000
  }
ae7462b4f   Arnaldo Carvalho de Melo   trace: make the t...
1001
  static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
a9a577638   Steven Rostedt   tracing: Allow ev...
1002
  					   int flags, struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
1003
1004
  {
  	struct ctx_switch_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
1005
  	struct trace_seq *s = &iter->seq;
f633cef02   Steven Rostedt   ftrace: change tr...
1006

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
1007
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
1008
1009
1010
1011
1012
1013
1014
  
  	SEQ_PUT_FIELD_RET(s, field->prev_pid);
  	SEQ_PUT_FIELD_RET(s, field->prev_prio);
  	SEQ_PUT_FIELD_RET(s, field->prev_state);
  	SEQ_PUT_FIELD_RET(s, field->next_pid);
  	SEQ_PUT_FIELD_RET(s, field->next_prio);
  	SEQ_PUT_FIELD_RET(s, field->next_state);
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
1015
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
1016
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
1017
  static struct trace_event_functions trace_ctx_funcs = {
f633cef02   Steven Rostedt   ftrace: change tr...
1018
  	.trace		= trace_ctx_print,
f633cef02   Steven Rostedt   ftrace: change tr...
1019
1020
1021
1022
  	.raw		= trace_ctx_raw,
  	.hex		= trace_ctx_hex,
  	.binary		= trace_ctxwake_bin,
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
1023
1024
1025
1026
1027
1028
  static struct trace_event trace_ctx_event = {
  	.type		= TRACE_CTX,
  	.funcs		= &trace_ctx_funcs,
  };
  
  static struct trace_event_functions trace_wake_funcs = {
f633cef02   Steven Rostedt   ftrace: change tr...
1029
  	.trace		= trace_wake_print,
f633cef02   Steven Rostedt   ftrace: change tr...
1030
1031
1032
1033
  	.raw		= trace_wake_raw,
  	.hex		= trace_wake_hex,
  	.binary		= trace_ctxwake_bin,
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
1034
1035
1036
1037
  static struct trace_event trace_wake_event = {
  	.type		= TRACE_WAKE,
  	.funcs		= &trace_wake_funcs,
  };
f633cef02   Steven Rostedt   ftrace: change tr...
1038
  /* TRACE_STACK */
ae7462b4f   Arnaldo Carvalho de Melo   trace: make the t...
1039
  static enum print_line_t trace_stack_print(struct trace_iterator *iter,
a9a577638   Steven Rostedt   tracing: Allow ev...
1040
  					   int flags, struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
1041
1042
  {
  	struct stack_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
1043
  	struct trace_seq *s = &iter->seq;
4a9bd3f13   Steven Rostedt   tracing: Have dyn...
1044
1045
  	unsigned long *p;
  	unsigned long *end;
f633cef02   Steven Rostedt   ftrace: change tr...
1046

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
1047
  	trace_assign_type(field, iter->ent);
4a9bd3f13   Steven Rostedt   tracing: Have dyn...
1048
  	end = (unsigned long *)((long)iter->ent + iter->ent_size);
f633cef02   Steven Rostedt   ftrace: change tr...
1049

563af16c3   Steven Rostedt   tracing: add anno...
1050
1051
  	if (!trace_seq_puts(s, "<stack trace>
  "))
f11b3f4e2   walimis   tracing/events: f...
1052
  		goto partial;
4a9bd3f13   Steven Rostedt   tracing: Have dyn...
1053
1054
  
  	for (p = field->caller; p && *p != ULONG_MAX && p < end; p++) {
f11b3f4e2   walimis   tracing/events: f...
1055
1056
  		if (!trace_seq_puts(s, " => "))
  			goto partial;
f633cef02   Steven Rostedt   ftrace: change tr...
1057

4a9bd3f13   Steven Rostedt   tracing: Have dyn...
1058
  		if (!seq_print_ip_sym(s, *p, flags))
f11b3f4e2   walimis   tracing/events: f...
1059
  			goto partial;
6c1a99afb   Lai Jiangshan   ftrace: fix trace...
1060
1061
  		if (!trace_seq_puts(s, "
  "))
f633cef02   Steven Rostedt   ftrace: change tr...
1062
1063
  			goto partial;
  	}
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
1064
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
1065
1066
1067
1068
  
   partial:
  	return TRACE_TYPE_PARTIAL_LINE;
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
1069
  static struct trace_event_functions trace_stack_funcs = {
f633cef02   Steven Rostedt   ftrace: change tr...
1070
  	.trace		= trace_stack_print,
f633cef02   Steven Rostedt   ftrace: change tr...
1071
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
1072
1073
1074
1075
  static struct trace_event trace_stack_event = {
  	.type		= TRACE_STACK,
  	.funcs		= &trace_stack_funcs,
  };
f633cef02   Steven Rostedt   ftrace: change tr...
1076
  /* TRACE_USER_STACK */
ae7462b4f   Arnaldo Carvalho de Melo   trace: make the t...
1077
  static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
a9a577638   Steven Rostedt   tracing: Allow ev...
1078
  						int flags, struct trace_event *event)
f633cef02   Steven Rostedt   ftrace: change tr...
1079
1080
  {
  	struct userstack_entry *field;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
1081
  	struct trace_seq *s = &iter->seq;
f633cef02   Steven Rostedt   ftrace: change tr...
1082

2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
1083
  	trace_assign_type(field, iter->ent);
f633cef02   Steven Rostedt   ftrace: change tr...
1084

563af16c3   Steven Rostedt   tracing: add anno...
1085
1086
  	if (!trace_seq_puts(s, "<user stack trace>
  "))
f633cef02   Steven Rostedt   ftrace: change tr...
1087
  		goto partial;
048dc50c5   walimis   tracing/events: f...
1088
  	if (!seq_print_userip_objs(field, s, flags))
f633cef02   Steven Rostedt   ftrace: change tr...
1089
  		goto partial;
d9793bd80   Arnaldo Carvalho de Melo   trace: judicious ...
1090
  	return TRACE_TYPE_HANDLED;
f633cef02   Steven Rostedt   ftrace: change tr...
1091
1092
1093
1094
  
   partial:
  	return TRACE_TYPE_PARTIAL_LINE;
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
1095
  static struct trace_event_functions trace_user_stack_funcs = {
f633cef02   Steven Rostedt   ftrace: change tr...
1096
  	.trace		= trace_user_stack_print,
f633cef02   Steven Rostedt   ftrace: change tr...
1097
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
1098
1099
1100
1101
  static struct trace_event trace_user_stack_event = {
  	.type		= TRACE_USER_STACK,
  	.funcs		= &trace_user_stack_funcs,
  };
48ead0203   Frederic Weisbecker   tracing/core: bri...
1102
  /* TRACE_BPRINT */
1427cdf05   Lai Jiangshan   tracing: infrastr...
1103
  static enum print_line_t
a9a577638   Steven Rostedt   tracing: Allow ev...
1104
1105
  trace_bprint_print(struct trace_iterator *iter, int flags,
  		   struct trace_event *event)
1427cdf05   Lai Jiangshan   tracing: infrastr...
1106
1107
1108
  {
  	struct trace_entry *entry = iter->ent;
  	struct trace_seq *s = &iter->seq;
48ead0203   Frederic Weisbecker   tracing/core: bri...
1109
  	struct bprint_entry *field;
1427cdf05   Lai Jiangshan   tracing: infrastr...
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
  
  	trace_assign_type(field, entry);
  
  	if (!seq_print_ip_sym(s, field->ip, flags))
  		goto partial;
  
  	if (!trace_seq_puts(s, ": "))
  		goto partial;
  
  	if (!trace_seq_bprintf(s, field->fmt, field->buf))
  		goto partial;
  
  	return TRACE_TYPE_HANDLED;
  
   partial:
  	return TRACE_TYPE_PARTIAL_LINE;
  }
769b0441f   Frederic Weisbecker   tracing/core: dro...
1127

48ead0203   Frederic Weisbecker   tracing/core: bri...
1128
  static enum print_line_t
a9a577638   Steven Rostedt   tracing: Allow ev...
1129
1130
  trace_bprint_raw(struct trace_iterator *iter, int flags,
  		 struct trace_event *event)
1427cdf05   Lai Jiangshan   tracing: infrastr...
1131
  {
48ead0203   Frederic Weisbecker   tracing/core: bri...
1132
  	struct bprint_entry *field;
1427cdf05   Lai Jiangshan   tracing: infrastr...
1133
  	struct trace_seq *s = &iter->seq;
1427cdf05   Lai Jiangshan   tracing: infrastr...
1134

769b0441f   Frederic Weisbecker   tracing/core: dro...
1135
  	trace_assign_type(field, iter->ent);
1427cdf05   Lai Jiangshan   tracing: infrastr...
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
  
  	if (!trace_seq_printf(s, ": %lx : ", field->ip))
  		goto partial;
  
  	if (!trace_seq_bprintf(s, field->fmt, field->buf))
  		goto partial;
  
  	return TRACE_TYPE_HANDLED;
  
   partial:
  	return TRACE_TYPE_PARTIAL_LINE;
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
1148
1149
1150
1151
  static struct trace_event_functions trace_bprint_funcs = {
  	.trace		= trace_bprint_print,
  	.raw		= trace_bprint_raw,
  };
769b0441f   Frederic Weisbecker   tracing/core: dro...
1152

48ead0203   Frederic Weisbecker   tracing/core: bri...
1153
1154
  static struct trace_event trace_bprint_event = {
  	.type		= TRACE_BPRINT,
a9a577638   Steven Rostedt   tracing: Allow ev...
1155
  	.funcs		= &trace_bprint_funcs,
48ead0203   Frederic Weisbecker   tracing/core: bri...
1156
1157
1158
1159
  };
  
  /* TRACE_PRINT */
  static enum print_line_t trace_print_print(struct trace_iterator *iter,
a9a577638   Steven Rostedt   tracing: Allow ev...
1160
  					   int flags, struct trace_event *event)
48ead0203   Frederic Weisbecker   tracing/core: bri...
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
  {
  	struct print_entry *field;
  	struct trace_seq *s = &iter->seq;
  
  	trace_assign_type(field, iter->ent);
  
  	if (!seq_print_ip_sym(s, field->ip, flags))
  		goto partial;
  
  	if (!trace_seq_printf(s, ": %s", field->buf))
  		goto partial;
  
  	return TRACE_TYPE_HANDLED;
  
   partial:
  	return TRACE_TYPE_PARTIAL_LINE;
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
1178
1179
  static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags,
  					 struct trace_event *event)
48ead0203   Frederic Weisbecker   tracing/core: bri...
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
  {
  	struct print_entry *field;
  
  	trace_assign_type(field, iter->ent);
  
  	if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
  		goto partial;
  
  	return TRACE_TYPE_HANDLED;
  
   partial:
  	return TRACE_TYPE_PARTIAL_LINE;
  }
a9a577638   Steven Rostedt   tracing: Allow ev...
1193
  static struct trace_event_functions trace_print_funcs = {
769b0441f   Frederic Weisbecker   tracing/core: dro...
1194
1195
  	.trace		= trace_print_print,
  	.raw		= trace_print_raw,
1427cdf05   Lai Jiangshan   tracing: infrastr...
1196
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
1197
1198
1199
1200
  static struct trace_event trace_print_event = {
  	.type	 	= TRACE_PRINT,
  	.funcs		= &trace_print_funcs,
  };
48ead0203   Frederic Weisbecker   tracing/core: bri...
1201

f633cef02   Steven Rostedt   ftrace: change tr...
1202
1203
1204
1205
  static struct trace_event *events[] __initdata = {
  	&trace_fn_event,
  	&trace_ctx_event,
  	&trace_wake_event,
f633cef02   Steven Rostedt   ftrace: change tr...
1206
1207
  	&trace_stack_event,
  	&trace_user_stack_event,
48ead0203   Frederic Weisbecker   tracing/core: bri...
1208
  	&trace_bprint_event,
f633cef02   Steven Rostedt   ftrace: change tr...
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
  	&trace_print_event,
  	NULL
  };
  
  __init static int init_events(void)
  {
  	struct trace_event *event;
  	int i, ret;
  
  	for (i = 0; events[i]; i++) {
  		event = events[i];
  
  		ret = register_ftrace_event(event);
  		if (!ret) {
  			printk(KERN_WARNING "event %d failed to register
  ",
  			       event->type);
  			WARN_ON_ONCE(1);
  		}
  	}
  
  	return 0;
  }
  device_initcall(init_events);