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 | 8 | * Highly modified by Steven Rostedt (VMware). |
| 9 | 9 | */ |
| 10 | +#include <linux/jump_label.h> | |
| 10 | 11 | #include <linux/suspend.h> |
| 11 | 12 | #include <linux/ftrace.h> |
| 12 | 13 | #include <linux/slab.h> |
| @@ -23,24 +24,12 @@ · 10 unmodified lines | ||
| 23 | 24 | #define ASSIGN_OPS_HASH(opsname, val) |
| 24 | 25 | #endif |
| 25 | 26 | |
| 26 | −static bool kill_ftrace_graph; | |
| 27 | +DEFINE_STATIC_KEY_FALSE(kill_ftrace_graph); | |
| 27 | 28 | int ftrace_graph_active; |
| 28 | 29 | |
| 29 | 30 | /* Both enabled by default (can be cleared by function_graph tracer flags */ |
| 30 | 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 | 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 | 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 | 46 | /* Add a function return address to the trace stack on thread info.*/ |
| @@ -47,9 +47,6 @@ · 46 unmodified lines | ||
| 47 | 47 | #define MAX_FIELD_ARRAY_SIZE 1024 |
| 48 | 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 | 50 | static char *register_page_data; |
| 54 | 51 | |
| 55 | 52 | static DEFINE_MUTEX(reg_mutex); |
| @@ -410,19 +407,6 @@ parse: · 354 unmodified lines | ||
| 410 | 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 | 410 | static int user_event_parse_fields(struct user_event *user, char *args) |
| 427 | 411 | { |
| 428 | 412 | char *field; |
| @@ -718,64 +702,14 @@ discard: · 289 unmodified lines | ||
| 718 | 702 | } |
| 719 | 703 | |
| 720 | 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 | 708 | static void user_event_perf(struct user_event *user, struct iov_iter *i, |
| 772 | 709 | void *tpdata, bool *faulted) |
| 773 | 710 | { |
| 774 | 711 | struct hlist_head *perf_head; |
| 775 | 712 | |
| 776 | − if (bpf_prog_array_valid(&user->call)) | |
| 777 | − user_event_bpf(user, i); | |
| 778 | − | |
| 779 | 713 | perf_head = this_cpu_ptr(user->call.perf_events); |
| 780 | 714 | |
| 781 | 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 | 1076 | user->tracepoint.name = name; |
| 1143 | 1077 | |
| 1144 | − user_event_parse_flags(user, flags); | |
| 1145 | − | |
| 1146 | 1078 | ret = user_event_parse_fields(user, args); |
| 1147 | 1079 | |
| 1148 | 1080 | if (ret) |
| @@ -1170,11 +1102,11 @@ static int user_event_parse(char *name, char *args, char *flags, · 21 unmodified lines | ||
| 1170 | 1102 | #endif |
| 1171 | 1103 | |
| 1172 | 1104 | mutex_lock(&event_mutex); |
| 1105 | + | |
| 1173 | 1106 | ret = user_event_trace_register(user); |
| 1174 | − mutex_unlock(&event_mutex); | |
| 1175 | 1107 | |
| 1176 | 1108 | if (ret) |
| 1177 | − goto put_user; | |
| 1109 | + goto put_user_lock; | |
| 1178 | 1110 | |
| 1179 | 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 | 1118 | set_bit(user->index, page_bitmap); |
| 1187 | 1119 | hash_add(register_table, &user->node, key); |
| 1188 | 1120 | |
| 1121 | + mutex_unlock(&event_mutex); | |
| 1122 | + | |
| 1189 | 1123 | *newuser = user; |
| 1190 | 1124 | return 0; |
| 1125 | +put_user_lock: | |
| 1126 | + mutex_unlock(&event_mutex); | |
| 1191 | 1127 | put_user: |
| 1192 | 1128 | user_event_destroy_fields(user); |
| 1193 | 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 | 1516 | busy++; |
| 1581 | 1517 | } |
| 1582 | 1518 | |
| 1583 | − if (flags & FLAG_BPF_ITER) | |
| 1584 | − seq_puts(m, " FLAG:BPF_ITER"); | |
| 1585 | − | |
| 1586 | 1519 | seq_puts(m, "\n"); |
| 1587 | 1520 | active++; |
| 1588 | 1521 | } |