diff options
| -rw-r--r-- | include/linux/tracepoint.h | 3 | ||||
| -rw-r--r-- | include/trace/sched_event_types.h | 48 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 5 | ||||
| -rw-r--r-- | kernel/trace/trace_event_types.h | 3 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 159 | ||||
| -rw-r--r-- | kernel/trace/trace_events_stage_1.h | 28 | ||||
| -rw-r--r-- | kernel/trace/trace_events_stage_2.h | 89 | ||||
| -rw-r--r-- | kernel/trace/trace_events_stage_3.h | 34 | ||||
| -rw-r--r-- | kernel/trace/trace_export.c | 23 |
9 files changed, 159 insertions, 233 deletions
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 3bcc3e171443..6b4f1bb3701e 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
| @@ -160,4 +160,7 @@ static inline void tracepoint_synchronize_unregister(void) | |||
| 160 | #define TRACE_EVENT_FORMAT(name, proto, args, fmt, struct, tpfmt) \ | 160 | #define TRACE_EVENT_FORMAT(name, proto, args, fmt, struct, tpfmt) \ |
| 161 | TRACE_FORMAT(name, PARAMS(proto), PARAMS(args), PARAMS(fmt)) | 161 | TRACE_FORMAT(name, PARAMS(proto), PARAMS(args), PARAMS(fmt)) |
| 162 | 162 | ||
| 163 | #define TRACE_EVENT(name, proto, args, struct, print, assign) \ | ||
| 164 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | ||
| 165 | |||
| 163 | #endif | 166 | #endif |
diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h index 71b14828a957..aa77fb754038 100644 --- a/include/trace/sched_event_types.h +++ b/include/trace/sched_event_types.h | |||
| @@ -62,25 +62,41 @@ TRACE_EVENT_FORMAT(sched_wakeup_new, | |||
| 62 | TP_RAW_FMT("task %d success=%d") | 62 | TP_RAW_FMT("task %d success=%d") |
| 63 | ); | 63 | ); |
| 64 | 64 | ||
| 65 | TRACE_EVENT_FORMAT(sched_switch, | 65 | /* |
| 66 | * Tracepoint for task switches, performed by the scheduler: | ||
| 67 | * | ||
| 68 | * (NOTE: the 'rq' argument is not used by generic trace events, | ||
| 69 | * but used by the latency tracer plugin. ) | ||
| 70 | */ | ||
| 71 | TRACE_EVENT(sched_switch, | ||
| 72 | |||
| 66 | TP_PROTO(struct rq *rq, struct task_struct *prev, | 73 | TP_PROTO(struct rq *rq, struct task_struct *prev, |
| 67 | struct task_struct *next), | 74 | struct task_struct *next), |
| 75 | |||
| 68 | TP_ARGS(rq, prev, next), | 76 | TP_ARGS(rq, prev, next), |
| 69 | TP_FMT("task %s:%d ==> %s:%d", | 77 | |
| 70 | prev->comm, prev->pid, next->comm, next->pid), | 78 | TP_STRUCT__entry( |
| 71 | TRACE_STRUCT( | 79 | __array( char, prev_comm, TASK_COMM_LEN ) |
| 72 | TRACE_FIELD(pid_t, prev_pid, prev->pid) | 80 | __field( pid_t, prev_pid ) |
| 73 | TRACE_FIELD(int, prev_prio, prev->prio) | 81 | __field( int, prev_prio ) |
| 74 | TRACE_FIELD_SPECIAL(char next_comm[TASK_COMM_LEN], | 82 | __array( char, next_comm, TASK_COMM_LEN ) |
| 75 | next_comm, | 83 | __field( pid_t, next_pid ) |
| 76 | TP_CMD(memcpy(TRACE_ENTRY->next_comm, | 84 | __field( int, next_prio ) |
| 77 | next->comm, | ||
| 78 | TASK_COMM_LEN))) | ||
| 79 | TRACE_FIELD(pid_t, next_pid, next->pid) | ||
| 80 | TRACE_FIELD(int, next_prio, next->prio) | ||
| 81 | ), | 85 | ), |
| 82 | TP_RAW_FMT("prev %d:%d ==> next %s:%d:%d") | 86 | |
| 83 | ); | 87 | TP_printk("task %s:%d [%d] ==> %s:%d [%d]", |
| 88 | __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, | ||
| 89 | __entry->next_comm, __entry->next_pid, __entry->next_prio), | ||
| 90 | |||
| 91 | TP_fast_assign( | ||
| 92 | memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); | ||
| 93 | __entry->prev_pid = prev->pid; | ||
| 94 | __entry->prev_prio = prev->prio; | ||
| 95 | memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); | ||
| 96 | __entry->next_pid = next->pid; | ||
| 97 | __entry->next_prio = next->prio; | ||
| 98 | ) | ||
| 99 | ); | ||
| 84 | 100 | ||
| 85 | TRACE_EVENT_FORMAT(sched_migrate_task, | 101 | TRACE_EVENT_FORMAT(sched_migrate_task, |
| 86 | TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu), | 102 | TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu), |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 2bfb7d11fc17..c5e1d8865fe4 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -751,12 +751,7 @@ struct ftrace_event_call { | |||
| 751 | int (*regfunc)(void); | 751 | int (*regfunc)(void); |
| 752 | void (*unregfunc)(void); | 752 | void (*unregfunc)(void); |
| 753 | int id; | 753 | int id; |
| 754 | struct dentry *raw_dir; | ||
| 755 | int raw_enabled; | ||
| 756 | int type; | ||
| 757 | int (*raw_init)(void); | 754 | int (*raw_init)(void); |
| 758 | int (*raw_reg)(void); | ||
| 759 | void (*raw_unreg)(void); | ||
| 760 | int (*show_format)(struct trace_seq *s); | 755 | int (*show_format)(struct trace_seq *s); |
| 761 | }; | 756 | }; |
| 762 | 757 | ||
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h index d94179aa1fc2..5cca4c978bde 100644 --- a/kernel/trace/trace_event_types.h +++ b/kernel/trace/trace_event_types.h | |||
| @@ -106,9 +106,10 @@ TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore, | |||
| 106 | TRACE_STRUCT( | 106 | TRACE_STRUCT( |
| 107 | TRACE_FIELD(unsigned long, ip, ip) | 107 | TRACE_FIELD(unsigned long, ip, ip) |
| 108 | TRACE_FIELD(unsigned int, depth, depth) | 108 | TRACE_FIELD(unsigned int, depth, depth) |
| 109 | TRACE_FIELD(char *, fmt, fmt) | ||
| 109 | TRACE_FIELD_ZERO_CHAR(buf) | 110 | TRACE_FIELD_ZERO_CHAR(buf) |
| 110 | ), | 111 | ), |
| 111 | TP_RAW_FMT("%08lx (%d) %s") | 112 | TP_RAW_FMT("%08lx (%d) fmt:%p %s") |
| 112 | ); | 113 | ); |
| 113 | 114 | ||
| 114 | TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore, | 115 | TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore, |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index fa32ca320767..1880a6438097 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -59,22 +59,12 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call, | |||
| 59 | call->enabled = 0; | 59 | call->enabled = 0; |
| 60 | call->unregfunc(); | 60 | call->unregfunc(); |
| 61 | } | 61 | } |
| 62 | if (call->raw_enabled) { | ||
| 63 | call->raw_enabled = 0; | ||
| 64 | call->raw_unreg(); | ||
| 65 | } | ||
| 66 | break; | 62 | break; |
| 67 | case 1: | 63 | case 1: |
| 68 | if (!call->enabled && | 64 | if (!call->enabled) { |
| 69 | (call->type & TRACE_EVENT_TYPE_PRINTF)) { | ||
| 70 | call->enabled = 1; | 65 | call->enabled = 1; |
| 71 | call->regfunc(); | 66 | call->regfunc(); |
| 72 | } | 67 | } |
| 73 | if (!call->raw_enabled && | ||
| 74 | (call->type & TRACE_EVENT_TYPE_RAW)) { | ||
| 75 | call->raw_enabled = 1; | ||
| 76 | call->raw_reg(); | ||
| 77 | } | ||
| 78 | break; | 68 | break; |
| 79 | } | 69 | } |
| 80 | } | 70 | } |
| @@ -300,7 +290,7 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 300 | struct ftrace_event_call *call = filp->private_data; | 290 | struct ftrace_event_call *call = filp->private_data; |
| 301 | char *buf; | 291 | char *buf; |
| 302 | 292 | ||
| 303 | if (call->enabled || call->raw_enabled) | 293 | if (call->enabled) |
| 304 | buf = "1\n"; | 294 | buf = "1\n"; |
| 305 | else | 295 | else |
| 306 | buf = "0\n"; | 296 | buf = "0\n"; |
| @@ -346,107 +336,6 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
| 346 | return cnt; | 336 | return cnt; |
| 347 | } | 337 | } |
| 348 | 338 | ||
| 349 | static ssize_t | ||
| 350 | event_type_read(struct file *filp, char __user *ubuf, size_t cnt, | ||
| 351 | loff_t *ppos) | ||
| 352 | { | ||
| 353 | struct ftrace_event_call *call = filp->private_data; | ||
| 354 | char buf[16]; | ||
| 355 | int r = 0; | ||
| 356 | |||
| 357 | if (call->type & TRACE_EVENT_TYPE_PRINTF) | ||
| 358 | r += sprintf(buf, "printf\n"); | ||
| 359 | |||
| 360 | if (call->type & TRACE_EVENT_TYPE_RAW) | ||
| 361 | r += sprintf(buf+r, "raw\n"); | ||
| 362 | |||
| 363 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | ||
| 364 | } | ||
| 365 | |||
| 366 | static ssize_t | ||
| 367 | event_type_write(struct file *filp, const char __user *ubuf, size_t cnt, | ||
| 368 | loff_t *ppos) | ||
| 369 | { | ||
| 370 | struct ftrace_event_call *call = filp->private_data; | ||
| 371 | char buf[64]; | ||
| 372 | |||
| 373 | /* | ||
| 374 | * If there's only one type, we can't change it. | ||
| 375 | * And currently we always have printf type, and we | ||
| 376 | * may or may not have raw type. | ||
| 377 | * | ||
| 378 | * This is a redundant check, the file should be read | ||
| 379 | * only if this is the case anyway. | ||
| 380 | */ | ||
| 381 | |||
| 382 | if (!call->raw_init) | ||
| 383 | return -EPERM; | ||
| 384 | |||
| 385 | if (cnt >= sizeof(buf)) | ||
| 386 | return -EINVAL; | ||
| 387 | |||
| 388 | if (copy_from_user(&buf, ubuf, cnt)) | ||
| 389 | return -EFAULT; | ||
| 390 | |||
| 391 | buf[cnt] = 0; | ||
| 392 | |||
| 393 | if (!strncmp(buf, "printf", 6) && | ||
| 394 | (!buf[6] || isspace(buf[6]))) { | ||
| 395 | |||
| 396 | call->type = TRACE_EVENT_TYPE_PRINTF; | ||
| 397 | |||
| 398 | /* | ||
| 399 | * If raw enabled, the disable it and enable | ||
| 400 | * printf type. | ||
| 401 | */ | ||
| 402 | if (call->raw_enabled) { | ||
| 403 | call->raw_enabled = 0; | ||
| 404 | call->raw_unreg(); | ||
| 405 | |||
| 406 | call->enabled = 1; | ||
| 407 | call->regfunc(); | ||
| 408 | } | ||
| 409 | |||
| 410 | } else if (!strncmp(buf, "raw", 3) && | ||
| 411 | (!buf[3] || isspace(buf[3]))) { | ||
| 412 | |||
| 413 | call->type = TRACE_EVENT_TYPE_RAW; | ||
| 414 | |||
| 415 | /* | ||
| 416 | * If printf enabled, the disable it and enable | ||
| 417 | * raw type. | ||
| 418 | */ | ||
| 419 | if (call->enabled) { | ||
| 420 | call->enabled = 0; | ||
| 421 | call->unregfunc(); | ||
| 422 | |||
| 423 | call->raw_enabled = 1; | ||
| 424 | call->raw_reg(); | ||
| 425 | } | ||
| 426 | } else | ||
| 427 | return -EINVAL; | ||
| 428 | |||
| 429 | *ppos += cnt; | ||
| 430 | |||
| 431 | return cnt; | ||
| 432 | } | ||
| 433 | |||
| 434 | static ssize_t | ||
| 435 | event_available_types_read(struct file *filp, char __user *ubuf, size_t cnt, | ||
| 436 | loff_t *ppos) | ||
| 437 | { | ||
| 438 | struct ftrace_event_call *call = filp->private_data; | ||
| 439 | char buf[16]; | ||
| 440 | int r = 0; | ||
| 441 | |||
| 442 | r += sprintf(buf, "printf\n"); | ||
| 443 | |||
| 444 | if (call->raw_init) | ||
| 445 | r += sprintf(buf+r, "raw\n"); | ||
| 446 | |||
| 447 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | ||
| 448 | } | ||
| 449 | |||
| 450 | #undef FIELD | 339 | #undef FIELD |
| 451 | #define FIELD(type, name) \ | 340 | #define FIELD(type, name) \ |
| 452 | #type, #name, (unsigned int)offsetof(typeof(field), name), \ | 341 | #type, #name, (unsigned int)offsetof(typeof(field), name), \ |
| @@ -470,6 +359,7 @@ static int trace_write_header(struct trace_seq *s) | |||
| 470 | FIELD(int, pid), | 359 | FIELD(int, pid), |
| 471 | FIELD(int, tgid)); | 360 | FIELD(int, tgid)); |
| 472 | } | 361 | } |
| 362 | |||
| 473 | static ssize_t | 363 | static ssize_t |
| 474 | event_format_read(struct file *filp, char __user *ubuf, size_t cnt, | 364 | event_format_read(struct file *filp, char __user *ubuf, size_t cnt, |
| 475 | loff_t *ppos) | 365 | loff_t *ppos) |
| @@ -527,13 +417,6 @@ static const struct seq_operations show_set_event_seq_ops = { | |||
| 527 | .stop = t_stop, | 417 | .stop = t_stop, |
| 528 | }; | 418 | }; |
| 529 | 419 | ||
| 530 | static const struct file_operations ftrace_avail_fops = { | ||
| 531 | .open = ftrace_event_seq_open, | ||
| 532 | .read = seq_read, | ||
| 533 | .llseek = seq_lseek, | ||
| 534 | .release = seq_release, | ||
| 535 | }; | ||
| 536 | |||
| 537 | static const struct file_operations ftrace_set_event_fops = { | 420 | static const struct file_operations ftrace_set_event_fops = { |
| 538 | .open = ftrace_event_seq_open, | 421 | .open = ftrace_event_seq_open, |
| 539 | .read = seq_read, | 422 | .read = seq_read, |
| @@ -548,17 +431,6 @@ static const struct file_operations ftrace_enable_fops = { | |||
| 548 | .write = event_enable_write, | 431 | .write = event_enable_write, |
| 549 | }; | 432 | }; |
| 550 | 433 | ||
| 551 | static const struct file_operations ftrace_type_fops = { | ||
| 552 | .open = tracing_open_generic, | ||
| 553 | .read = event_type_read, | ||
| 554 | .write = event_type_write, | ||
| 555 | }; | ||
| 556 | |||
| 557 | static const struct file_operations ftrace_available_types_fops = { | ||
| 558 | .open = tracing_open_generic, | ||
| 559 | .read = event_available_types_read, | ||
| 560 | }; | ||
| 561 | |||
| 562 | static const struct file_operations ftrace_event_format_fops = { | 434 | static const struct file_operations ftrace_event_format_fops = { |
| 563 | .open = tracing_open_generic, | 435 | .open = tracing_open_generic, |
| 564 | .read = event_format_read, | 436 | .read = event_format_read, |
| @@ -647,9 +519,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events) | |||
| 647 | } | 519 | } |
| 648 | } | 520 | } |
| 649 | 521 | ||
| 650 | /* default the output to printf */ | ||
| 651 | call->type = TRACE_EVENT_TYPE_PRINTF; | ||
| 652 | |||
| 653 | call->dir = debugfs_create_dir(call->name, d_events); | 522 | call->dir = debugfs_create_dir(call->name, d_events); |
| 654 | if (!call->dir) { | 523 | if (!call->dir) { |
| 655 | pr_warning("Could not create debugfs " | 524 | pr_warning("Could not create debugfs " |
| @@ -665,21 +534,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events) | |||
| 665 | "'%s/enable' entry\n", call->name); | 534 | "'%s/enable' entry\n", call->name); |
| 666 | } | 535 | } |
| 667 | 536 | ||
| 668 | /* Only let type be writable, if we can change it */ | ||
| 669 | entry = debugfs_create_file("type", | ||
| 670 | call->raw_init ? 0644 : 0444, | ||
| 671 | call->dir, call, | ||
| 672 | &ftrace_type_fops); | ||
| 673 | if (!entry) | ||
| 674 | pr_warning("Could not create debugfs " | ||
| 675 | "'%s/type' entry\n", call->name); | ||
| 676 | |||
| 677 | entry = debugfs_create_file("available_types", 0444, call->dir, call, | ||
| 678 | &ftrace_available_types_fops); | ||
| 679 | if (!entry) | ||
| 680 | pr_warning("Could not create debugfs " | ||
| 681 | "'%s/available_types' entry\n", call->name); | ||
| 682 | |||
| 683 | /* A trace may not want to export its format */ | 537 | /* A trace may not want to export its format */ |
| 684 | if (!call->show_format) | 538 | if (!call->show_format) |
| 685 | return 0; | 539 | return 0; |
| @@ -704,13 +558,6 @@ static __init int event_trace_init(void) | |||
| 704 | if (!d_tracer) | 558 | if (!d_tracer) |
| 705 | return 0; | 559 | return 0; |
| 706 | 560 | ||
| 707 | entry = debugfs_create_file("available_events", 0444, d_tracer, | ||
| 708 | (void *)&show_event_seq_ops, | ||
| 709 | &ftrace_avail_fops); | ||
| 710 | if (!entry) | ||
| 711 | pr_warning("Could not create debugfs " | ||
| 712 | "'available_events' entry\n"); | ||
| 713 | |||
| 714 | entry = debugfs_create_file("set_event", 0644, d_tracer, | 561 | entry = debugfs_create_file("set_event", 0644, d_tracer, |
| 715 | (void *)&show_set_event_seq_ops, | 562 | (void *)&show_set_event_seq_ops, |
| 716 | &ftrace_set_event_fops); | 563 | &ftrace_set_event_fops); |
diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h index 3830a731424c..edfcbd3a0d1b 100644 --- a/kernel/trace/trace_events_stage_1.h +++ b/kernel/trace/trace_events_stage_1.h | |||
| @@ -18,19 +18,23 @@ | |||
| 18 | #define TRACE_FORMAT(call, proto, args, fmt) | 18 | #define TRACE_FORMAT(call, proto, args, fmt) |
| 19 | 19 | ||
| 20 | #undef TRACE_EVENT_FORMAT | 20 | #undef TRACE_EVENT_FORMAT |
| 21 | #define TRACE_EVENT_FORMAT(name, proto, args, fmt, tstruct, tpfmt) \ | 21 | #define TRACE_EVENT_FORMAT(name, proto, args, fmt, tstruct, tpfmt) |
| 22 | struct ftrace_raw_##name { \ | 22 | |
| 23 | struct trace_entry ent; \ | 23 | #undef __array |
| 24 | tstruct \ | 24 | #define __array(type, item, len) type item[len]; |
| 25 | }; \ | ||
| 26 | static struct ftrace_event_call event_##name | ||
| 27 | 25 | ||
| 28 | #undef TRACE_STRUCT | 26 | #undef __field |
| 29 | #define TRACE_STRUCT(args...) args | 27 | #define __field(type, item) type item; |
| 30 | 28 | ||
| 31 | #define TRACE_FIELD(type, item, assign) \ | 29 | #undef TP_STRUCT__entry |
| 32 | type item; | 30 | #define TP_STRUCT__entry(args...) args |
| 33 | #define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ | 31 | |
| 34 | type_item; | 32 | #undef TRACE_EVENT |
| 33 | #define TRACE_EVENT(name, proto, args, tstruct, print, assign) \ | ||
| 34 | struct ftrace_raw_##name { \ | ||
| 35 | struct trace_entry ent; \ | ||
| 36 | tstruct \ | ||
| 37 | }; \ | ||
| 38 | static struct ftrace_event_call event_##name | ||
| 35 | 39 | ||
| 36 | #include <trace/trace_event_types.h> | 40 | #include <trace/trace_event_types.h> |
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h index 8e2e0f56c2a8..d91bf4c56661 100644 --- a/kernel/trace/trace_events_stage_2.h +++ b/kernel/trace/trace_events_stage_2.h | |||
| @@ -32,23 +32,14 @@ | |||
| 32 | * in binary. | 32 | * in binary. |
| 33 | */ | 33 | */ |
| 34 | 34 | ||
| 35 | #undef TRACE_STRUCT | 35 | #undef __entry |
| 36 | #define TRACE_STRUCT(args...) args | 36 | #define __entry field |
| 37 | 37 | ||
| 38 | #undef TRACE_FIELD | 38 | #undef TP_printk |
| 39 | #define TRACE_FIELD(type, item, assign) \ | 39 | #define TP_printk(fmt, args...) fmt "\n", args |
| 40 | field->item, | ||
| 41 | 40 | ||
| 42 | #undef TRACE_FIELD_SPECIAL | 41 | #undef TRACE_EVENT |
| 43 | #define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ | 42 | #define TRACE_EVENT(call, proto, args, tstruct, print, assign) \ |
| 44 | field->item, | ||
| 45 | |||
| 46 | |||
| 47 | #undef TP_RAW_FMT | ||
| 48 | #define TP_RAW_FMT(args...) args | ||
| 49 | |||
| 50 | #undef TRACE_EVENT_FORMAT | ||
| 51 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ | ||
| 52 | enum print_line_t \ | 43 | enum print_line_t \ |
| 53 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | 44 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ |
| 54 | { \ | 45 | { \ |
| @@ -66,14 +57,76 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
| 66 | \ | 57 | \ |
| 67 | field = (typeof(field))entry; \ | 58 | field = (typeof(field))entry; \ |
| 68 | \ | 59 | \ |
| 69 | ret = trace_seq_printf(s, tpfmt "%s", tstruct "\n"); \ | 60 | ret = trace_seq_printf(s, print); \ |
| 70 | if (!ret) \ | 61 | if (!ret) \ |
| 71 | return TRACE_TYPE_PARTIAL_LINE; \ | 62 | return TRACE_TYPE_PARTIAL_LINE; \ |
| 72 | \ | 63 | \ |
| 73 | return TRACE_TYPE_HANDLED; \ | 64 | return TRACE_TYPE_HANDLED; \ |
| 74 | } | 65 | } |
| 75 | 66 | ||
| 76 | #include <trace/trace_event_types.h> | 67 | #include <trace/trace_event_types.h> |
| 77 | 68 | ||
| 78 | #include "trace_format.h" | 69 | /* |
| 70 | * Setup the showing format of trace point. | ||
| 71 | * | ||
| 72 | * int | ||
| 73 | * ftrace_format_##call(struct trace_seq *s) | ||
| 74 | * { | ||
| 75 | * struct ftrace_raw_##call field; | ||
| 76 | * int ret; | ||
| 77 | * | ||
| 78 | * ret = trace_seq_printf(s, #type " " #item ";" | ||
| 79 | * " size:%d; offset:%d;\n", | ||
| 80 | * sizeof(field.type), | ||
| 81 | * offsetof(struct ftrace_raw_##call, | ||
| 82 | * item)); | ||
| 83 | * | ||
| 84 | * } | ||
| 85 | */ | ||
| 86 | |||
| 87 | #undef TP_STRUCT__entry | ||
| 88 | #define TP_STRUCT__entry(args...) args | ||
| 89 | |||
| 90 | #undef __field | ||
| 91 | #define __field(type, item) \ | ||
| 92 | ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ | ||
| 93 | "offset:%u;\tsize:%u;\n", \ | ||
| 94 | (unsigned int)offsetof(typeof(field), item), \ | ||
| 95 | (unsigned int)sizeof(field.item)); \ | ||
| 96 | if (!ret) \ | ||
| 97 | return 0; | ||
| 98 | |||
| 99 | #undef __array | ||
| 100 | #define __array(type, item, len) \ | ||
| 101 | ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ | ||
| 102 | "offset:%u;\tsize:%u;\n", \ | ||
| 103 | (unsigned int)offsetof(typeof(field), item), \ | ||
| 104 | (unsigned int)sizeof(field.item)); \ | ||
| 105 | if (!ret) \ | ||
| 106 | return 0; | ||
| 107 | |||
| 108 | #undef __entry | ||
| 109 | #define __entry "REC" | ||
| 110 | |||
| 111 | #undef TP_printk | ||
| 112 | #define TP_printk(fmt, args...) "%s, %s\n", #fmt, #args | ||
| 113 | |||
| 114 | #undef TP_fast_assign | ||
| 115 | #define TP_fast_assign(args...) args | ||
| 116 | |||
| 117 | #undef TRACE_EVENT | ||
| 118 | #define TRACE_EVENT(call, proto, args, tstruct, print, func) \ | ||
| 119 | static int \ | ||
| 120 | ftrace_format_##call(struct trace_seq *s) \ | ||
| 121 | { \ | ||
| 122 | struct ftrace_raw_##call field; \ | ||
| 123 | int ret; \ | ||
| 124 | \ | ||
| 125 | tstruct; \ | ||
| 126 | \ | ||
| 127 | trace_seq_printf(s, "\nprint fmt: " print); \ | ||
| 128 | \ | ||
| 129 | return ret; \ | ||
| 130 | } | ||
| 131 | |||
| 79 | #include <trace/trace_event_types.h> | 132 | #include <trace/trace_event_types.h> |
diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h index 41b82b93c9c7..8e398d864096 100644 --- a/kernel/trace/trace_events_stage_3.h +++ b/kernel/trace/trace_events_stage_3.h | |||
| @@ -144,27 +144,15 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
| 144 | .unregfunc = ftrace_unreg_event_##call, \ | 144 | .unregfunc = ftrace_unreg_event_##call, \ |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | #undef TRACE_FIELD | 147 | #undef TRACE_EVENT_FORMAT |
| 148 | #define TRACE_FIELD(type, item, assign)\ | 148 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, raw) \ |
| 149 | entry->item = assign; | 149 | TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) |
| 150 | |||
| 151 | #undef TRACE_FIELD | ||
| 152 | #define TRACE_FIELD(type, item, assign)\ | ||
| 153 | entry->item = assign; | ||
| 154 | |||
| 155 | #undef TP_CMD | ||
| 156 | #define TP_CMD(cmd...) cmd | ||
| 157 | |||
| 158 | #undef TRACE_ENTRY | ||
| 159 | #define TRACE_ENTRY entry | ||
| 160 | 150 | ||
| 161 | #undef TRACE_FIELD_SPECIAL | 151 | #undef __entry |
| 162 | #define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ | 152 | #define __entry entry |
| 163 | cmd; | ||
| 164 | 153 | ||
| 165 | #undef TRACE_EVENT_FORMAT | 154 | #undef TRACE_EVENT |
| 166 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ | 155 | #define TRACE_EVENT(call, proto, args, tstruct, print, assign) \ |
| 167 | _TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \ | ||
| 168 | \ | 156 | \ |
| 169 | static struct ftrace_event_call event_##call; \ | 157 | static struct ftrace_event_call event_##call; \ |
| 170 | \ | 158 | \ |
| @@ -185,7 +173,7 @@ static void ftrace_raw_event_##call(proto) \ | |||
| 185 | return; \ | 173 | return; \ |
| 186 | entry = ring_buffer_event_data(event); \ | 174 | entry = ring_buffer_event_data(event); \ |
| 187 | \ | 175 | \ |
| 188 | tstruct; \ | 176 | assign; \ |
| 189 | \ | 177 | \ |
| 190 | trace_current_buffer_unlock_commit(event, irq_flags, pc); \ | 178 | trace_current_buffer_unlock_commit(event, irq_flags, pc); \ |
| 191 | } \ | 179 | } \ |
| @@ -226,10 +214,8 @@ __attribute__((__aligned__(4))) \ | |||
| 226 | __attribute__((section("_ftrace_events"))) event_##call = { \ | 214 | __attribute__((section("_ftrace_events"))) event_##call = { \ |
| 227 | .name = #call, \ | 215 | .name = #call, \ |
| 228 | .system = __stringify(TRACE_SYSTEM), \ | 216 | .system = __stringify(TRACE_SYSTEM), \ |
| 229 | .regfunc = ftrace_reg_event_##call, \ | ||
| 230 | .unregfunc = ftrace_unreg_event_##call, \ | ||
| 231 | .raw_init = ftrace_raw_init_event_##call, \ | 217 | .raw_init = ftrace_raw_init_event_##call, \ |
| 232 | .raw_reg = ftrace_raw_reg_event_##call, \ | 218 | .regfunc = ftrace_raw_reg_event_##call, \ |
| 233 | .raw_unreg = ftrace_raw_unreg_event_##call, \ | 219 | .unregfunc = ftrace_raw_unreg_event_##call, \ |
| 234 | .show_format = ftrace_format_##call, \ | 220 | .show_format = ftrace_format_##call, \ |
| 235 | } | 221 | } |
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index e62bc10f8103..23ae78430d58 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c | |||
| @@ -15,7 +15,28 @@ | |||
| 15 | 15 | ||
| 16 | #include "trace_output.h" | 16 | #include "trace_output.h" |
| 17 | 17 | ||
| 18 | #include "trace_format.h" | 18 | |
| 19 | #undef TRACE_STRUCT | ||
| 20 | #define TRACE_STRUCT(args...) args | ||
| 21 | |||
| 22 | #undef TRACE_FIELD | ||
| 23 | #define TRACE_FIELD(type, item, assign) \ | ||
| 24 | ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ | ||
| 25 | "offset:%u;\tsize:%u;\n", \ | ||
| 26 | (unsigned int)offsetof(typeof(field), item), \ | ||
| 27 | (unsigned int)sizeof(field.item)); \ | ||
| 28 | if (!ret) \ | ||
| 29 | return 0; | ||
| 30 | |||
| 31 | |||
| 32 | #undef TRACE_FIELD_SPECIAL | ||
| 33 | #define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ | ||
| 34 | ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \ | ||
| 35 | "offset:%u;\tsize:%u;\n", \ | ||
| 36 | (unsigned int)offsetof(typeof(field), item), \ | ||
| 37 | (unsigned int)sizeof(field.item)); \ | ||
| 38 | if (!ret) \ | ||
| 39 | return 0; | ||
| 19 | 40 | ||
| 20 | #undef TRACE_FIELD_ZERO_CHAR | 41 | #undef TRACE_FIELD_ZERO_CHAR |
| 21 | #define TRACE_FIELD_ZERO_CHAR(item) \ | 42 | #define TRACE_FIELD_ZERO_CHAR(item) \ |
