diff options
Diffstat (limited to 'kernel/trace/trace_events.c')
| -rw-r--r-- | kernel/trace/trace_events.c | 299 |
1 files changed, 161 insertions, 138 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 53cffc0b0801..09b4fa6e4d3b 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | DEFINE_MUTEX(event_mutex); | 28 | DEFINE_MUTEX(event_mutex); |
| 29 | 29 | ||
| 30 | LIST_HEAD(ftrace_events); | 30 | LIST_HEAD(ftrace_events); |
| 31 | LIST_HEAD(ftrace_common_fields); | ||
| 31 | 32 | ||
| 32 | struct list_head * | 33 | struct list_head * |
| 33 | trace_get_fields(struct ftrace_event_call *event_call) | 34 | trace_get_fields(struct ftrace_event_call *event_call) |
| @@ -37,15 +38,11 @@ trace_get_fields(struct ftrace_event_call *event_call) | |||
| 37 | return event_call->class->get_fields(event_call); | 38 | return event_call->class->get_fields(event_call); |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | int trace_define_field(struct ftrace_event_call *call, const char *type, | 41 | static int __trace_define_field(struct list_head *head, const char *type, |
| 41 | const char *name, int offset, int size, int is_signed, | 42 | const char *name, int offset, int size, |
| 42 | int filter_type) | 43 | int is_signed, int filter_type) |
| 43 | { | 44 | { |
| 44 | struct ftrace_event_field *field; | 45 | struct ftrace_event_field *field; |
| 45 | struct list_head *head; | ||
| 46 | |||
| 47 | if (WARN_ON(!call->class)) | ||
| 48 | return 0; | ||
| 49 | 46 | ||
| 50 | field = kzalloc(sizeof(*field), GFP_KERNEL); | 47 | field = kzalloc(sizeof(*field), GFP_KERNEL); |
| 51 | if (!field) | 48 | if (!field) |
| @@ -68,7 +65,6 @@ int trace_define_field(struct ftrace_event_call *call, const char *type, | |||
| 68 | field->size = size; | 65 | field->size = size; |
| 69 | field->is_signed = is_signed; | 66 | field->is_signed = is_signed; |
| 70 | 67 | ||
| 71 | head = trace_get_fields(call); | ||
| 72 | list_add(&field->link, head); | 68 | list_add(&field->link, head); |
| 73 | 69 | ||
| 74 | return 0; | 70 | return 0; |
| @@ -80,17 +76,32 @@ err: | |||
| 80 | 76 | ||
| 81 | return -ENOMEM; | 77 | return -ENOMEM; |
| 82 | } | 78 | } |
| 79 | |||
| 80 | int trace_define_field(struct ftrace_event_call *call, const char *type, | ||
| 81 | const char *name, int offset, int size, int is_signed, | ||
| 82 | int filter_type) | ||
| 83 | { | ||
| 84 | struct list_head *head; | ||
| 85 | |||
| 86 | if (WARN_ON(!call->class)) | ||
| 87 | return 0; | ||
| 88 | |||
| 89 | head = trace_get_fields(call); | ||
| 90 | return __trace_define_field(head, type, name, offset, size, | ||
| 91 | is_signed, filter_type); | ||
| 92 | } | ||
| 83 | EXPORT_SYMBOL_GPL(trace_define_field); | 93 | EXPORT_SYMBOL_GPL(trace_define_field); |
| 84 | 94 | ||
| 85 | #define __common_field(type, item) \ | 95 | #define __common_field(type, item) \ |
| 86 | ret = trace_define_field(call, #type, "common_" #item, \ | 96 | ret = __trace_define_field(&ftrace_common_fields, #type, \ |
| 87 | offsetof(typeof(ent), item), \ | 97 | "common_" #item, \ |
| 88 | sizeof(ent.item), \ | 98 | offsetof(typeof(ent), item), \ |
| 89 | is_signed_type(type), FILTER_OTHER); \ | 99 | sizeof(ent.item), \ |
| 100 | is_signed_type(type), FILTER_OTHER); \ | ||
| 90 | if (ret) \ | 101 | if (ret) \ |
| 91 | return ret; | 102 | return ret; |
| 92 | 103 | ||
| 93 | static int trace_define_common_fields(struct ftrace_event_call *call) | 104 | static int trace_define_common_fields(void) |
| 94 | { | 105 | { |
| 95 | int ret; | 106 | int ret; |
| 96 | struct trace_entry ent; | 107 | struct trace_entry ent; |
| @@ -130,6 +141,55 @@ int trace_event_raw_init(struct ftrace_event_call *call) | |||
| 130 | } | 141 | } |
| 131 | EXPORT_SYMBOL_GPL(trace_event_raw_init); | 142 | EXPORT_SYMBOL_GPL(trace_event_raw_init); |
| 132 | 143 | ||
| 144 | int ftrace_event_reg(struct ftrace_event_call *call, enum trace_reg type) | ||
| 145 | { | ||
| 146 | switch (type) { | ||
| 147 | case TRACE_REG_REGISTER: | ||
| 148 | return tracepoint_probe_register(call->name, | ||
| 149 | call->class->probe, | ||
| 150 | call); | ||
| 151 | case TRACE_REG_UNREGISTER: | ||
| 152 | tracepoint_probe_unregister(call->name, | ||
| 153 | call->class->probe, | ||
| 154 | call); | ||
| 155 | return 0; | ||
| 156 | |||
| 157 | #ifdef CONFIG_PERF_EVENTS | ||
| 158 | case TRACE_REG_PERF_REGISTER: | ||
| 159 | return tracepoint_probe_register(call->name, | ||
| 160 | call->class->perf_probe, | ||
| 161 | call); | ||
| 162 | case TRACE_REG_PERF_UNREGISTER: | ||
| 163 | tracepoint_probe_unregister(call->name, | ||
| 164 | call->class->perf_probe, | ||
| 165 | call); | ||
| 166 | return 0; | ||
| 167 | #endif | ||
| 168 | } | ||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | EXPORT_SYMBOL_GPL(ftrace_event_reg); | ||
| 172 | |||
| 173 | void trace_event_enable_cmd_record(bool enable) | ||
| 174 | { | ||
| 175 | struct ftrace_event_call *call; | ||
| 176 | |||
| 177 | mutex_lock(&event_mutex); | ||
| 178 | list_for_each_entry(call, &ftrace_events, list) { | ||
| 179 | if (!(call->flags & TRACE_EVENT_FL_ENABLED)) | ||
| 180 | continue; | ||
| 181 | |||
| 182 | if (enable) { | ||
| 183 | tracing_start_cmdline_record(); | ||
| 184 | call->flags |= TRACE_EVENT_FL_RECORDED_CMD; | ||
| 185 | } else { | ||
| 186 | tracing_stop_cmdline_record(); | ||
| 187 | call->flags &= ~TRACE_EVENT_FL_RECORDED_CMD; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | mutex_unlock(&event_mutex); | ||
| 191 | } | ||
| 192 | |||
| 133 | static int ftrace_event_enable_disable(struct ftrace_event_call *call, | 193 | static int ftrace_event_enable_disable(struct ftrace_event_call *call, |
| 134 | int enable) | 194 | int enable) |
| 135 | { | 195 | { |
| @@ -139,24 +199,20 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call, | |||
| 139 | case 0: | 199 | case 0: |
| 140 | if (call->flags & TRACE_EVENT_FL_ENABLED) { | 200 | if (call->flags & TRACE_EVENT_FL_ENABLED) { |
| 141 | call->flags &= ~TRACE_EVENT_FL_ENABLED; | 201 | call->flags &= ~TRACE_EVENT_FL_ENABLED; |
| 142 | tracing_stop_cmdline_record(); | 202 | if (call->flags & TRACE_EVENT_FL_RECORDED_CMD) { |
| 143 | if (call->class->reg) | 203 | tracing_stop_cmdline_record(); |
| 144 | call->class->reg(call, TRACE_REG_UNREGISTER); | 204 | call->flags &= ~TRACE_EVENT_FL_RECORDED_CMD; |
| 145 | else | 205 | } |
| 146 | tracepoint_probe_unregister(call->name, | 206 | call->class->reg(call, TRACE_REG_UNREGISTER); |
| 147 | call->class->probe, | ||
| 148 | call); | ||
| 149 | } | 207 | } |
| 150 | break; | 208 | break; |
| 151 | case 1: | 209 | case 1: |
| 152 | if (!(call->flags & TRACE_EVENT_FL_ENABLED)) { | 210 | if (!(call->flags & TRACE_EVENT_FL_ENABLED)) { |
| 153 | tracing_start_cmdline_record(); | 211 | if (trace_flags & TRACE_ITER_RECORD_CMD) { |
| 154 | if (call->class->reg) | 212 | tracing_start_cmdline_record(); |
| 155 | ret = call->class->reg(call, TRACE_REG_REGISTER); | 213 | call->flags |= TRACE_EVENT_FL_RECORDED_CMD; |
| 156 | else | 214 | } |
| 157 | ret = tracepoint_probe_register(call->name, | 215 | ret = call->class->reg(call, TRACE_REG_REGISTER); |
| 158 | call->class->probe, | ||
| 159 | call); | ||
| 160 | if (ret) { | 216 | if (ret) { |
| 161 | tracing_stop_cmdline_record(); | 217 | tracing_stop_cmdline_record(); |
| 162 | pr_info("event trace: Could not enable event " | 218 | pr_info("event trace: Could not enable event " |
| @@ -194,8 +250,7 @@ static int __ftrace_set_clr_event(const char *match, const char *sub, | |||
| 194 | mutex_lock(&event_mutex); | 250 | mutex_lock(&event_mutex); |
| 195 | list_for_each_entry(call, &ftrace_events, list) { | 251 | list_for_each_entry(call, &ftrace_events, list) { |
| 196 | 252 | ||
| 197 | if (!call->name || !call->class || | 253 | if (!call->name || !call->class || !call->class->reg) |
| 198 | (!call->class->probe && !call->class->reg)) | ||
| 199 | continue; | 254 | continue; |
| 200 | 255 | ||
| 201 | if (match && | 256 | if (match && |
| @@ -321,7 +376,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
| 321 | * The ftrace subsystem is for showing formats only. | 376 | * The ftrace subsystem is for showing formats only. |
| 322 | * They can not be enabled or disabled via the event files. | 377 | * They can not be enabled or disabled via the event files. |
| 323 | */ | 378 | */ |
| 324 | if (call->class && (call->class->probe || call->class->reg)) | 379 | if (call->class && call->class->reg) |
| 325 | return call; | 380 | return call; |
| 326 | } | 381 | } |
| 327 | 382 | ||
| @@ -474,8 +529,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 474 | 529 | ||
| 475 | mutex_lock(&event_mutex); | 530 | mutex_lock(&event_mutex); |
| 476 | list_for_each_entry(call, &ftrace_events, list) { | 531 | list_for_each_entry(call, &ftrace_events, list) { |
| 477 | if (!call->name || !call->class || | 532 | if (!call->name || !call->class || !call->class->reg) |
| 478 | (!call->class->probe && !call->class->reg)) | ||
| 479 | continue; | 533 | continue; |
| 480 | 534 | ||
| 481 | if (system && strcmp(call->class->system, system) != 0) | 535 | if (system && strcmp(call->class->system, system) != 0) |
| @@ -544,32 +598,10 @@ out: | |||
| 544 | return ret; | 598 | return ret; |
| 545 | } | 599 | } |
| 546 | 600 | ||
| 547 | static ssize_t | 601 | static void print_event_fields(struct trace_seq *s, struct list_head *head) |
| 548 | event_format_read(struct file *filp, char __user *ubuf, size_t cnt, | ||
| 549 | loff_t *ppos) | ||
| 550 | { | 602 | { |
| 551 | struct ftrace_event_call *call = filp->private_data; | ||
| 552 | struct ftrace_event_field *field; | 603 | struct ftrace_event_field *field; |
| 553 | struct list_head *head; | ||
| 554 | struct trace_seq *s; | ||
| 555 | int common_field_count = 5; | ||
| 556 | char *buf; | ||
| 557 | int r = 0; | ||
| 558 | |||
| 559 | if (*ppos) | ||
| 560 | return 0; | ||
| 561 | |||
| 562 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
| 563 | if (!s) | ||
| 564 | return -ENOMEM; | ||
| 565 | |||
| 566 | trace_seq_init(s); | ||
| 567 | |||
| 568 | trace_seq_printf(s, "name: %s\n", call->name); | ||
| 569 | trace_seq_printf(s, "ID: %d\n", call->event.type); | ||
| 570 | trace_seq_printf(s, "format:\n"); | ||
| 571 | 604 | ||
| 572 | head = trace_get_fields(call); | ||
| 573 | list_for_each_entry_reverse(field, head, link) { | 605 | list_for_each_entry_reverse(field, head, link) { |
| 574 | /* | 606 | /* |
| 575 | * Smartly shows the array type(except dynamic array). | 607 | * Smartly shows the array type(except dynamic array). |
| @@ -584,29 +616,54 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 584 | array_descriptor = NULL; | 616 | array_descriptor = NULL; |
| 585 | 617 | ||
| 586 | if (!array_descriptor) { | 618 | if (!array_descriptor) { |
| 587 | r = trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;" | 619 | trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;" |
| 588 | "\tsize:%u;\tsigned:%d;\n", | 620 | "\tsize:%u;\tsigned:%d;\n", |
| 589 | field->type, field->name, field->offset, | 621 | field->type, field->name, field->offset, |
| 590 | field->size, !!field->is_signed); | 622 | field->size, !!field->is_signed); |
| 591 | } else { | 623 | } else { |
| 592 | r = trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;" | 624 | trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;" |
| 593 | "\tsize:%u;\tsigned:%d;\n", | 625 | "\tsize:%u;\tsigned:%d;\n", |
| 594 | (int)(array_descriptor - field->type), | 626 | (int)(array_descriptor - field->type), |
| 595 | field->type, field->name, | 627 | field->type, field->name, |
| 596 | array_descriptor, field->offset, | 628 | array_descriptor, field->offset, |
| 597 | field->size, !!field->is_signed); | 629 | field->size, !!field->is_signed); |
| 598 | } | 630 | } |
| 631 | } | ||
| 632 | } | ||
| 599 | 633 | ||
| 600 | if (--common_field_count == 0) | 634 | static ssize_t |
| 601 | r = trace_seq_printf(s, "\n"); | 635 | event_format_read(struct file *filp, char __user *ubuf, size_t cnt, |
| 636 | loff_t *ppos) | ||
| 637 | { | ||
| 638 | struct ftrace_event_call *call = filp->private_data; | ||
| 639 | struct list_head *head; | ||
| 640 | struct trace_seq *s; | ||
| 641 | char *buf; | ||
| 642 | int r; | ||
| 602 | 643 | ||
| 603 | if (!r) | 644 | if (*ppos) |
| 604 | break; | 645 | return 0; |
| 605 | } | 646 | |
| 647 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
| 648 | if (!s) | ||
| 649 | return -ENOMEM; | ||
| 650 | |||
| 651 | trace_seq_init(s); | ||
| 652 | |||
| 653 | trace_seq_printf(s, "name: %s\n", call->name); | ||
| 654 | trace_seq_printf(s, "ID: %d\n", call->event.type); | ||
| 655 | trace_seq_printf(s, "format:\n"); | ||
| 656 | |||
| 657 | /* print common fields */ | ||
| 658 | print_event_fields(s, &ftrace_common_fields); | ||
| 606 | 659 | ||
| 607 | if (r) | 660 | trace_seq_putc(s, '\n'); |
| 608 | r = trace_seq_printf(s, "\nprint fmt: %s\n", | 661 | |
| 609 | call->print_fmt); | 662 | /* print event specific fields */ |
| 663 | head = trace_get_fields(call); | ||
| 664 | print_event_fields(s, head); | ||
| 665 | |||
| 666 | r = trace_seq_printf(s, "\nprint fmt: %s\n", call->print_fmt); | ||
| 610 | 667 | ||
| 611 | if (!r) { | 668 | if (!r) { |
| 612 | /* | 669 | /* |
| @@ -963,35 +1020,31 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | |||
| 963 | return -1; | 1020 | return -1; |
| 964 | } | 1021 | } |
| 965 | 1022 | ||
| 966 | if (call->class->probe || call->class->reg) | 1023 | if (call->class->reg) |
| 967 | trace_create_file("enable", 0644, call->dir, call, | 1024 | trace_create_file("enable", 0644, call->dir, call, |
| 968 | enable); | 1025 | enable); |
| 969 | 1026 | ||
| 970 | #ifdef CONFIG_PERF_EVENTS | 1027 | #ifdef CONFIG_PERF_EVENTS |
| 971 | if (call->event.type && (call->class->perf_probe || call->class->reg)) | 1028 | if (call->event.type && call->class->reg) |
| 972 | trace_create_file("id", 0444, call->dir, call, | 1029 | trace_create_file("id", 0444, call->dir, call, |
| 973 | id); | 1030 | id); |
| 974 | #endif | 1031 | #endif |
| 975 | 1032 | ||
| 976 | if (call->class->define_fields) { | 1033 | /* |
| 977 | /* | 1034 | * Other events may have the same class. Only update |
| 978 | * Other events may have the same class. Only update | 1035 | * the fields if they are not already defined. |
| 979 | * the fields if they are not already defined. | 1036 | */ |
| 980 | */ | 1037 | head = trace_get_fields(call); |
| 981 | head = trace_get_fields(call); | 1038 | if (list_empty(head)) { |
| 982 | if (list_empty(head)) { | 1039 | ret = call->class->define_fields(call); |
| 983 | ret = trace_define_common_fields(call); | 1040 | if (ret < 0) { |
| 984 | if (!ret) | 1041 | pr_warning("Could not initialize trace point" |
| 985 | ret = call->class->define_fields(call); | 1042 | " events/%s\n", call->name); |
| 986 | if (ret < 0) { | 1043 | return ret; |
| 987 | pr_warning("Could not initialize trace point" | ||
| 988 | " events/%s\n", call->name); | ||
| 989 | return ret; | ||
| 990 | } | ||
| 991 | } | 1044 | } |
| 992 | trace_create_file("filter", 0644, call->dir, call, | ||
| 993 | filter); | ||
| 994 | } | 1045 | } |
| 1046 | trace_create_file("filter", 0644, call->dir, call, | ||
| 1047 | filter); | ||
| 995 | 1048 | ||
| 996 | trace_create_file("format", 0444, call->dir, call, | 1049 | trace_create_file("format", 0444, call->dir, call, |
| 997 | format); | 1050 | format); |
| @@ -999,11 +1052,17 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | |||
| 999 | return 0; | 1052 | return 0; |
| 1000 | } | 1053 | } |
| 1001 | 1054 | ||
| 1002 | static int __trace_add_event_call(struct ftrace_event_call *call) | 1055 | static int |
| 1056 | __trace_add_event_call(struct ftrace_event_call *call, struct module *mod, | ||
| 1057 | const struct file_operations *id, | ||
| 1058 | const struct file_operations *enable, | ||
| 1059 | const struct file_operations *filter, | ||
| 1060 | const struct file_operations *format) | ||
| 1003 | { | 1061 | { |
| 1004 | struct dentry *d_events; | 1062 | struct dentry *d_events; |
| 1005 | int ret; | 1063 | int ret; |
| 1006 | 1064 | ||
| 1065 | /* The linker may leave blanks */ | ||
| 1007 | if (!call->name) | 1066 | if (!call->name) |
| 1008 | return -EINVAL; | 1067 | return -EINVAL; |
| 1009 | 1068 | ||
| @@ -1011,8 +1070,8 @@ static int __trace_add_event_call(struct ftrace_event_call *call) | |||
| 1011 | ret = call->class->raw_init(call); | 1070 | ret = call->class->raw_init(call); |
| 1012 | if (ret < 0) { | 1071 | if (ret < 0) { |
| 1013 | if (ret != -ENOSYS) | 1072 | if (ret != -ENOSYS) |
| 1014 | pr_warning("Could not initialize trace " | 1073 | pr_warning("Could not initialize trace events/%s\n", |
| 1015 | "events/%s\n", call->name); | 1074 | call->name); |
| 1016 | return ret; | 1075 | return ret; |
| 1017 | } | 1076 | } |
| 1018 | } | 1077 | } |
| @@ -1021,11 +1080,10 @@ static int __trace_add_event_call(struct ftrace_event_call *call) | |||
| 1021 | if (!d_events) | 1080 | if (!d_events) |
| 1022 | return -ENOENT; | 1081 | return -ENOENT; |
| 1023 | 1082 | ||
| 1024 | ret = event_create_dir(call, d_events, &ftrace_event_id_fops, | 1083 | ret = event_create_dir(call, d_events, id, enable, filter, format); |
| 1025 | &ftrace_enable_fops, &ftrace_event_filter_fops, | ||
| 1026 | &ftrace_event_format_fops); | ||
| 1027 | if (!ret) | 1084 | if (!ret) |
| 1028 | list_add(&call->list, &ftrace_events); | 1085 | list_add(&call->list, &ftrace_events); |
| 1086 | call->mod = mod; | ||
| 1029 | 1087 | ||
| 1030 | return ret; | 1088 | return ret; |
| 1031 | } | 1089 | } |
| @@ -1035,7 +1093,10 @@ int trace_add_event_call(struct ftrace_event_call *call) | |||
| 1035 | { | 1093 | { |
| 1036 | int ret; | 1094 | int ret; |
| 1037 | mutex_lock(&event_mutex); | 1095 | mutex_lock(&event_mutex); |
| 1038 | ret = __trace_add_event_call(call); | 1096 | ret = __trace_add_event_call(call, NULL, &ftrace_event_id_fops, |
| 1097 | &ftrace_enable_fops, | ||
| 1098 | &ftrace_event_filter_fops, | ||
| 1099 | &ftrace_event_format_fops); | ||
| 1039 | mutex_unlock(&event_mutex); | 1100 | mutex_unlock(&event_mutex); |
| 1040 | return ret; | 1101 | return ret; |
| 1041 | } | 1102 | } |
| @@ -1152,8 +1213,6 @@ static void trace_module_add_events(struct module *mod) | |||
| 1152 | { | 1213 | { |
| 1153 | struct ftrace_module_file_ops *file_ops = NULL; | 1214 | struct ftrace_module_file_ops *file_ops = NULL; |
| 1154 | struct ftrace_event_call *call, *start, *end; | 1215 | struct ftrace_event_call *call, *start, *end; |
| 1155 | struct dentry *d_events; | ||
| 1156 | int ret; | ||
| 1157 | 1216 | ||
| 1158 | start = mod->trace_events; | 1217 | start = mod->trace_events; |
| 1159 | end = mod->trace_events + mod->num_trace_events; | 1218 | end = mod->trace_events + mod->num_trace_events; |
| @@ -1161,38 +1220,14 @@ static void trace_module_add_events(struct module *mod) | |||
| 1161 | if (start == end) | 1220 | if (start == end) |
| 1162 | return; | 1221 | return; |
| 1163 | 1222 | ||
| 1164 | d_events = event_trace_events_dir(); | 1223 | file_ops = trace_create_file_ops(mod); |
| 1165 | if (!d_events) | 1224 | if (!file_ops) |
| 1166 | return; | 1225 | return; |
| 1167 | 1226 | ||
| 1168 | for_each_event(call, start, end) { | 1227 | for_each_event(call, start, end) { |
| 1169 | /* The linker may leave blanks */ | 1228 | __trace_add_event_call(call, mod, |
| 1170 | if (!call->name) | ||
| 1171 | continue; | ||
| 1172 | if (call->class->raw_init) { | ||
| 1173 | ret = call->class->raw_init(call); | ||
| 1174 | if (ret < 0) { | ||
| 1175 | if (ret != -ENOSYS) | ||
| 1176 | pr_warning("Could not initialize trace " | ||
| 1177 | "point events/%s\n", call->name); | ||
| 1178 | continue; | ||
| 1179 | } | ||
| 1180 | } | ||
| 1181 | /* | ||
| 1182 | * This module has events, create file ops for this module | ||
| 1183 | * if not already done. | ||
| 1184 | */ | ||
| 1185 | if (!file_ops) { | ||
| 1186 | file_ops = trace_create_file_ops(mod); | ||
| 1187 | if (!file_ops) | ||
| 1188 | return; | ||
| 1189 | } | ||
| 1190 | call->mod = mod; | ||
| 1191 | ret = event_create_dir(call, d_events, | ||
| 1192 | &file_ops->id, &file_ops->enable, | 1229 | &file_ops->id, &file_ops->enable, |
| 1193 | &file_ops->filter, &file_ops->format); | 1230 | &file_ops->filter, &file_ops->format); |
| 1194 | if (!ret) | ||
| 1195 | list_add(&call->list, &ftrace_events); | ||
| 1196 | } | 1231 | } |
| 1197 | } | 1232 | } |
| 1198 | 1233 | ||
| @@ -1319,25 +1354,14 @@ static __init int event_trace_init(void) | |||
| 1319 | trace_create_file("enable", 0644, d_events, | 1354 | trace_create_file("enable", 0644, d_events, |
| 1320 | NULL, &ftrace_system_enable_fops); | 1355 | NULL, &ftrace_system_enable_fops); |
| 1321 | 1356 | ||
| 1357 | if (trace_define_common_fields()) | ||
| 1358 | pr_warning("tracing: Failed to allocate common fields"); | ||
| 1359 | |||
| 1322 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { | 1360 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { |
| 1323 | /* The linker may leave blanks */ | 1361 | __trace_add_event_call(call, NULL, &ftrace_event_id_fops, |
| 1324 | if (!call->name) | ||
| 1325 | continue; | ||
| 1326 | if (call->class->raw_init) { | ||
| 1327 | ret = call->class->raw_init(call); | ||
| 1328 | if (ret < 0) { | ||
| 1329 | if (ret != -ENOSYS) | ||
| 1330 | pr_warning("Could not initialize trace " | ||
| 1331 | "point events/%s\n", call->name); | ||
| 1332 | continue; | ||
| 1333 | } | ||
| 1334 | } | ||
| 1335 | ret = event_create_dir(call, d_events, &ftrace_event_id_fops, | ||
| 1336 | &ftrace_enable_fops, | 1362 | &ftrace_enable_fops, |
| 1337 | &ftrace_event_filter_fops, | 1363 | &ftrace_event_filter_fops, |
| 1338 | &ftrace_event_format_fops); | 1364 | &ftrace_event_format_fops); |
| 1339 | if (!ret) | ||
| 1340 | list_add(&call->list, &ftrace_events); | ||
| 1341 | } | 1365 | } |
| 1342 | 1366 | ||
| 1343 | while (true) { | 1367 | while (true) { |
| @@ -1524,12 +1548,11 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip) | |||
| 1524 | struct ftrace_entry *entry; | 1548 | struct ftrace_entry *entry; |
| 1525 | unsigned long flags; | 1549 | unsigned long flags; |
| 1526 | long disabled; | 1550 | long disabled; |
| 1527 | int resched; | ||
| 1528 | int cpu; | 1551 | int cpu; |
| 1529 | int pc; | 1552 | int pc; |
| 1530 | 1553 | ||
| 1531 | pc = preempt_count(); | 1554 | pc = preempt_count(); |
| 1532 | resched = ftrace_preempt_disable(); | 1555 | preempt_disable_notrace(); |
| 1533 | cpu = raw_smp_processor_id(); | 1556 | cpu = raw_smp_processor_id(); |
| 1534 | disabled = atomic_inc_return(&per_cpu(ftrace_test_event_disable, cpu)); | 1557 | disabled = atomic_inc_return(&per_cpu(ftrace_test_event_disable, cpu)); |
| 1535 | 1558 | ||
| @@ -1551,7 +1574,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip) | |||
| 1551 | 1574 | ||
| 1552 | out: | 1575 | out: |
| 1553 | atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); | 1576 | atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); |
| 1554 | ftrace_preempt_enable(resched); | 1577 | preempt_enable_notrace(); |
| 1555 | } | 1578 | } |
| 1556 | 1579 | ||
| 1557 | static struct ftrace_ops trace_ops __initdata = | 1580 | static struct ftrace_ops trace_ops __initdata = |
