Pull more tracing updates from Steven Rostedt: - Rename the staging files to give them some meaning. Just stage1,stag2,etc, does not show what they are for - Check for NULL from allocation in bootconfig - Hold event mutex for dyn_event call in user events - Mark user events to broken (to work on the API) - Remove eBPF updates from user events - Remove user events from uapi header to keep it from being installed. - Move ftrace_graph_is_dead() into inline as it is called from hot paths and also convert it into a static branch. * tag 'trace-v5.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Move user_events.h temporarily out of include/uapi ftrace: Make ftrace_graph_is_dead() a static branch tracing: Set user_events to BROKEN tracing/user_events: Remove eBPF interfaces tracing/user_events: Hold event_mutex during dyn_event_add proc: bootconfig: Add null pointer check tracing: Rename the staging files for trace_events
Showing the changes to kernel (2 of 15 files). Show all
Unified · Split
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | * | 7 | * |
| 8 | * Highly modified by Steven Rostedt (VMware). | 8 | * Highly modified by Steven Rostedt (VMware). |
| 9 | */ | 9 | */ |
| 10 | #include <linux/jump_label.h> | ||
| 10 | #include <linux/suspend.h> | 11 | #include <linux/suspend.h> |
| 11 | #include <linux/ftrace.h> | 12 | #include <linux/ftrace.h> |
| 12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| @@ -23,24 +24,12 @@ · 10 unmodified lines | |||
| 23 | #define ASSIGN_OPS_HASH(opsname, val) | 24 | #define ASSIGN_OPS_HASH(opsname, val) |
| 24 | #endif | 25 | #endif |
| 25 | 26 | ||
| 26 | static bool kill_ftrace_graph; | 27 | DEFINE_STATIC_KEY_FALSE(kill_ftrace_graph); |
| 27 | int ftrace_graph_active; | 28 | int ftrace_graph_active; |
| 28 | 29 | ||
| 29 | /* Both enabled by default (can be cleared by function_graph tracer flags */ | 30 | /* Both enabled by default (can be cleared by function_graph tracer flags */ |
| 30 | static bool fgraph_sleep_time = true; | 31 | static bool fgraph_sleep_time = true; |
| 31 | 32 | ||
| 32 | /** | ||
| 33 | * ftrace_graph_is_dead - returns true if ftrace_graph_stop() was called | ||
| 34 | * | ||
| 35 | * ftrace_graph_stop() is called when a severe error is detected in | ||
| 36 | * the function graph tracing. This function is called by the critical | ||
| 37 | * paths of function graph to keep those paths from doing any more harm. | ||
| 38 | */ | ||
| 39 | bool ftrace_graph_is_dead(void) | ||
| 40 | { | ||
| 41 | return kill_ftrace_graph; | ||
| 42 | } | ||
| 43 | |||
| 44 | /** | 33 | /** |
| 45 | * ftrace_graph_stop - set to permanently disable function graph tracing | 34 | * ftrace_graph_stop - set to permanently disable function graph tracing |
| 46 | * | 35 | * |
| @@ -51,7 +40,7 @@ bool ftrace_graph_is_dead(void) · 4 unmodified lines | |||
| 51 | */ | 40 | */ |
| 52 | void ftrace_graph_stop(void) | 41 | void ftrace_graph_stop(void) |
| 53 | { | 42 | { |
| 54 | kill_ftrace_graph = true; | 43 | static_branch_enable(&kill_ftrace_graph); |
| 55 | } | 44 | } |
| 56 | 45 | ||
| 57 | /* Add a function return address to the trace stack on thread info.*/ | 46 | /* Add a function return address to the trace stack on thread info.*/ |
| @@ -47,9 +47,6 @@ · 46 unmodified lines | |||
| 47 | #define MAX_FIELD_ARRAY_SIZE 1024 | 47 | #define MAX_FIELD_ARRAY_SIZE 1024 |
| 48 | #define MAX_FIELD_ARG_NAME 256 | 48 | #define MAX_FIELD_ARG_NAME 256 |
| 49 | 49 | ||
| 50 | #define MAX_BPF_COPY_SIZE PAGE_SIZE | ||
| 51 | #define MAX_STACK_BPF_DATA 512 | ||
| 52 | |||
| 53 | static char *register_page_data; | 50 | static char *register_page_data; |
| 54 | 51 | ||
| 55 | static DEFINE_MUTEX(reg_mutex); | 52 | static DEFINE_MUTEX(reg_mutex); |
| @@ -410,19 +407,6 @@ parse: · 354 unmodified lines | |||
| 410 | type[0] != 'u', FILTER_OTHER); | 407 | type[0] != 'u', FILTER_OTHER); |
| 411 | } | 408 | } |
| 412 | 409 | ||
| 413 | static void user_event_parse_flags(struct user_event *user, char *flags) | ||
| 414 | { | ||
| 415 | char *flag; | ||
| 416 | |||
| 417 | if (flags == NULL) | ||
| 418 | return; | ||
| 419 | |||
| 420 | while ((flag = strsep(&flags, ",")) != NULL) { | ||
| 421 | if (strcmp(flag, "BPF_ITER") == 0) | ||
| 422 | user->flags |= FLAG_BPF_ITER; | ||
| 423 | } | ||
| 424 | } | ||
| 425 | |||
| 426 | static int user_event_parse_fields(struct user_event *user, char *args) | 410 | static int user_event_parse_fields(struct user_event *user, char *args) |
| 427 | { | 411 | { |
| 428 | char *field; | 412 | char *field; |
| @@ -718,64 +702,14 @@ discard: · 289 unmodified lines | |||
| 718 | } | 702 | } |
| 719 | 703 | ||
| 720 | #ifdef CONFIG_PERF_EVENTS | 704 | #ifdef CONFIG_PERF_EVENTS |
| 721 | static void user_event_bpf(struct user_event *user, struct iov_iter *i) | ||
| 722 | { | ||
| 723 | struct user_bpf_context context; | ||
| 724 | struct user_bpf_iter bpf_i; | ||
| 725 | char fast_data[MAX_STACK_BPF_DATA]; | ||
| 726 | void *temp = NULL; | ||
| 727 | |||
| 728 | if ((user->flags & FLAG_BPF_ITER) && iter_is_iovec(i)) { | ||
| 729 | /* Raw iterator */ | ||
| 730 | context.data_type = USER_BPF_DATA_ITER; | ||
| 731 | context.data_len = i->count; | ||
| 732 | context.iter = &bpf_i; | ||
| 733 | |||
| 734 | bpf_i.iov_offset = i->iov_offset; | ||
| 735 | bpf_i.iov = i->iov; | ||
| 736 | bpf_i.nr_segs = i->nr_segs; | ||
| 737 | } else if (i->nr_segs == 1 && iter_is_iovec(i)) { | ||
| 738 | /* Single buffer from user */ | ||
| 739 | context.data_type = USER_BPF_DATA_USER; | ||
| 740 | context.data_len = i->count; | ||
| 741 | context.udata = i->iov->iov_base + i->iov_offset; | ||
| 742 | } else { | ||
| 743 | /* Multi buffer from user */ | ||
| 744 | struct iov_iter copy = *i; | ||
| 745 | size_t copy_size = min_t(size_t, i->count, MAX_BPF_COPY_SIZE); | ||
| 746 | |||
| 747 | context.data_type = USER_BPF_DATA_KERNEL; | ||
| 748 | context.kdata = fast_data; | ||
| 749 | |||
| 750 | if (unlikely(copy_size > sizeof(fast_data))) { | ||
| 751 | temp = kmalloc(copy_size, GFP_NOWAIT); | ||
| 752 | |||
| 753 | if (temp) | ||
| 754 | context.kdata = temp; | ||
| 755 | else | ||
| 756 | copy_size = sizeof(fast_data); | ||
| 757 | } | ||
| 758 | |||
| 759 | context.data_len = copy_nofault(context.kdata, | ||
| 760 | copy_size, ©); | ||
| 761 | } | ||
| 762 | |||
| 763 | trace_call_bpf(&user->call, &context); | ||
| 764 | |||
| 765 | kfree(temp); | ||
| 766 | } | ||
| 767 | |||
| 768 | /* | 705 | /* |
| 769 | * Writes the user supplied payload out to perf ring buffer or eBPF program. | 706 | * Writes the user supplied payload out to perf ring buffer. |
| 770 | */ | 707 | */ |
| 771 | static void user_event_perf(struct user_event *user, struct iov_iter *i, | 708 | static void user_event_perf(struct user_event *user, struct iov_iter *i, |
| 772 | void *tpdata, bool *faulted) | 709 | void *tpdata, bool *faulted) |
| 773 | { | 710 | { |
| 774 | struct hlist_head *perf_head; | 711 | struct hlist_head *perf_head; |
| 775 | 712 | ||
| 776 | if (bpf_prog_array_valid(&user->call)) | ||
| 777 | user_event_bpf(user, i); | ||
| 778 | |||
| 779 | perf_head = this_cpu_ptr(user->call.perf_events); | 713 | perf_head = this_cpu_ptr(user->call.perf_events); |
| 780 | 714 | ||
| 781 | if (perf_head && !hlist_empty(perf_head)) { | 715 | if (perf_head && !hlist_empty(perf_head)) { |
| @@ -1141,8 +1075,6 @@ static int user_event_parse(char *name, char *args, char *flags, · 359 unmodified lines | |||
| 1141 | 1075 | ||
| 1142 | user->tracepoint.name = name; | 1076 | user->tracepoint.name = name; |
| 1143 | 1077 | ||
| 1144 | user_event_parse_flags(user, flags); | ||
| 1145 | |||
| 1146 | ret = user_event_parse_fields(user, args); | 1078 | ret = user_event_parse_fields(user, args); |
| 1147 | 1079 | ||
| 1148 | if (ret) | 1080 | if (ret) |
| @@ -1170,11 +1102,11 @@ static int user_event_parse(char *name, char *args, char *flags, · 21 unmodified lines | |||
| 1170 | #endif | 1102 | #endif |
| 1171 | 1103 | ||
| 1172 | mutex_lock(&event_mutex); | 1104 | mutex_lock(&event_mutex); |
| 1105 | |||
| 1173 | ret = user_event_trace_register(user); | 1106 | ret = user_event_trace_register(user); |
| 1174 | mutex_unlock(&event_mutex); | ||
| 1175 | 1107 | ||
| 1176 | if (ret) | 1108 | if (ret) |
| 1177 | goto put_user; | 1109 | goto put_user_lock; |
| 1178 | 1110 | ||
| 1179 | user->index = index; | 1111 | user->index = index; |
| 1180 | 1112 | ||
| @@ -1186,8 +1118,12 @@ static int user_event_parse(char *name, char *args, char *flags, · 5 unmodified lines | |||
| 1186 | set_bit(user->index, page_bitmap); | 1118 | set_bit(user->index, page_bitmap); |
| 1187 | hash_add(register_table, &user->node, key); | 1119 | hash_add(register_table, &user->node, key); |
| 1188 | 1120 | ||
| 1121 | mutex_unlock(&event_mutex); | ||
| 1122 | |||
| 1189 | *newuser = user; | 1123 | *newuser = user; |
| 1190 | return 0; | 1124 | return 0; |
| 1125 | put_user_lock: | ||
| 1126 | mutex_unlock(&event_mutex); | ||
| 1191 | put_user: | 1127 | put_user: |
| 1192 | user_event_destroy_fields(user); | 1128 | user_event_destroy_fields(user); |
| 1193 | user_event_destroy_validators(user); | 1129 | user_event_destroy_validators(user); |
| @@ -1580,9 +1516,6 @@ static int user_seq_show(struct seq_file *m, void *p) · 386 unmodified lines | |||
| 1580 | busy++; | 1516 | busy++; |
| 1581 | } | 1517 | } |
| 1582 | 1518 | ||
| 1583 | if (flags & FLAG_BPF_ITER) | ||
| 1584 | seq_puts(m, " FLAG:BPF_ITER"); | ||
| 1585 | |||
| 1586 | seq_puts(m, "\n"); | 1519 | seq_puts(m, "\n"); |
| 1587 | active++; | 1520 | active++; |
| 1588 | } | 1521 | } |