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
Unified · Split
| @@ -7,7 +7,7 @@ user_events: User-based Event Tracing · 6 unmodified lines | ||
| 7 | 7 | Overview |
| 8 | 8 | -------- |
| 9 | 9 | User based trace events allow user processes to create events and trace data |
| 10 | −that can be viewed via existing tools, such as ftrace, perf and eBPF. | |
| 10 | +that can be viewed via existing tools, such as ftrace and perf. | |
| 11 | 11 | To enable this feature, build your kernel with CONFIG_USER_EVENTS=y. |
| 12 | 12 | |
| 13 | 13 | Programs can view status of the events via |
| @@ -67,8 +67,7 @@ The command string format is as follows:: · 53 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | Supported Flags |
| 69 | 69 | ^^^^^^^^^^^^^^^ |
| 70 | −**BPF_ITER** - EBPF programs attached to this event will get the raw iovec | |
| 71 | −struct instead of any data copies for max performance. | |
| 70 | +None yet | |
| 72 | 71 | |
| 73 | 72 | Field Format |
| 74 | 73 | ^^^^^^^^^^^^ |
| @@ -160,7 +159,7 @@ The following values are defined to aid in checking what has been attached: · 85 unmodified lines | ||
| 160 | 159 | |
| 161 | 160 | **EVENT_STATUS_FTRACE** - Bit set if ftrace has been attached (Bit 0). |
| 162 | 161 | |
| 163 | −**EVENT_STATUS_PERF** - Bit set if perf/eBPF has been attached (Bit 1). | |
| 162 | +**EVENT_STATUS_PERF** - Bit set if perf has been attached (Bit 1). | |
| 164 | 163 | |
| 165 | 164 | Writing Data |
| 166 | 165 | ------------ |
| @@ -204,13 +203,6 @@ It's advised for user programs to do the following:: · 37 unmodified lines | ||
| 204 | 203 | |
| 205 | 204 | **NOTE:** *The write_index is not emitted out into the trace being recorded.* |
| 206 | 205 | |
| 207 | −EBPF | |
| 208 | −---- | |
| 209 | −EBPF programs that attach to a user-based event tracepoint are given a pointer | |
| 210 | −to a struct user_bpf_context. The bpf context contains the data type (which can | |
| 211 | −be a user or kernel buffer, or can be a pointer to the iovec) and the data | |
| 212 | −length that was emitted (minus the write_index). | |
| 213 | − | |
| 214 | 206 | Example Code |
| 215 | 207 | ------------ |
| 216 | 208 | See sample code in samples/user_events. |
| @@ -32,6 +32,8 @@ static int __init copy_xbc_key_value_list(char *dst, size_t size) · 31 unmodified lines | ||
| 32 | 32 | int ret = 0; |
| 33 | 33 | |
| 34 | 34 | key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL); |
| 35 | + if (!key) | |
| 36 | + return -ENOMEM; | |
| 35 | 37 | |
| 36 | 38 | xbc_for_each_key_value(leaf, val) { |
| 37 | 39 | ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <linux/trace_recursion.h> |
| 11 | 11 | #include <linux/trace_clock.h> |
| 12 | +#include <linux/jump_label.h> | |
| 12 | 13 | #include <linux/kallsyms.h> |
| 13 | 14 | #include <linux/linkage.h> |
| 14 | 15 | #include <linux/bitops.h> |
| @@ -1018,7 +1019,20 @@ unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx, · 1003 unmodified lines | ||
| 1018 | 1019 | extern int register_ftrace_graph(struct fgraph_ops *ops); |
| 1019 | 1020 | extern void unregister_ftrace_graph(struct fgraph_ops *ops); |
| 1020 | 1021 | |
| 1021 | −extern bool ftrace_graph_is_dead(void); | |
| 1022 | +/** | |
| 1023 | + * ftrace_graph_is_dead - returns true if ftrace_graph_stop() was called | |
| 1024 | + * | |
| 1025 | + * ftrace_graph_stop() is called when a severe error is detected in | |
| 1026 | + * the function graph tracing. This function is called by the critical | |
| 1027 | + * paths of function graph to keep those paths from doing any more harm. | |
| 1028 | + */ | |
| 1029 | +DECLARE_STATIC_KEY_FALSE(kill_ftrace_graph); | |
| 1030 | + | |
| 1031 | +static inline bool ftrace_graph_is_dead(void) | |
| 1032 | +{ | |
| 1033 | + return static_branch_unlikely(&kill_ftrace_graph); | |
| 1034 | +} | |
| 1035 | + | |
| 1022 | 1036 | extern void ftrace_graph_stop(void); |
| 1023 | 1037 | |
| 1024 | 1038 | /* The current handlers in use */ |
| @@ -32,9 +32,6 @@ · 31 unmodified lines | ||
| 32 | 32 | /* Create dynamic location entry within a 32-bit value */ |
| 33 | 33 | #define DYN_LOC(offset, size) ((size) << 16 | (offset)) |
| 34 | 34 | |
| 35 | −/* Use raw iterator for attached BPF program(s), no affect on ftrace/perf */ | |
| 36 | −#define FLAG_BPF_ITER (1 << 0) | |
| 37 | − | |
| 38 | 35 | /* |
| 39 | 36 | * Describes an event registration and stores the results of the registration. |
| 40 | 37 | * This structure is passed to the DIAG_IOCSREG ioctl, callers at a minimum |
| @@ -63,54 +60,4 @@ struct user_reg { · 22 unmodified lines | ||
| 63 | 60 | /* Requests to delete a user_event */ |
| 64 | 61 | #define DIAG_IOCSDEL _IOW(DIAG_IOC_MAGIC, 1, char*) |
| 65 | 62 | |
| 66 | −/* Data type that was passed to the BPF program */ | |
| 67 | −enum { | |
| 68 | − /* Data resides in kernel space */ | |
| 69 | − USER_BPF_DATA_KERNEL, | |
| 70 | − | |
| 71 | − /* Data resides in user space */ | |
| 72 | − USER_BPF_DATA_USER, | |
| 73 | − | |
| 74 | − /* Data is a pointer to a user_bpf_iter structure */ | |
| 75 | − USER_BPF_DATA_ITER, | |
| 76 | −}; | |
| 77 | − | |
| 78 | −/* | |
| 79 | − * Describes an iovec iterator that BPF programs can use to access data for | |
| 80 | − * a given user_event write() / writev() call. | |
| 81 | − */ | |
| 82 | −struct user_bpf_iter { | |
| 83 | − | |
| 84 | − /* Offset of the data within the first iovec */ | |
| 85 | − __u32 iov_offset; | |
| 86 | − | |
| 87 | − /* Number of iovec structures */ | |
| 88 | − __u32 nr_segs; | |
| 89 | − | |
| 90 | − /* Pointer to iovec structures */ | |
| 91 | − const struct iovec *iov; | |
| 92 | −}; | |
| 93 | − | |
| 94 | −/* Context that BPF programs receive when attached to a user_event */ | |
| 95 | −struct user_bpf_context { | |
| 96 | − | |
| 97 | − /* Data type being passed (see union below) */ | |
| 98 | − __u32 data_type; | |
| 99 | − | |
| 100 | − /* Length of the data */ | |
| 101 | − __u32 data_len; | |
| 102 | − | |
| 103 | − /* Pointer to data, varies by data type */ | |
| 104 | − union { | |
| 105 | − /* Kernel data (data_type == USER_BPF_DATA_KERNEL) */ | |
| 106 | − void *kdata; | |
| 107 | − | |
| 108 | − /* User data (data_type == USER_BPF_DATA_USER) */ | |
| 109 | − void *udata; | |
| 110 | − | |
| 111 | − /* Direct iovec (data_type == USER_BPF_DATA_ITER) */ | |
| 112 | − struct user_bpf_iter *iter; | |
| 113 | − }; | |
| 114 | −}; | |
| 115 | − | |
| 116 | 63 | #endif /* _UAPI_LINUX_USER_EVENTS_H */ |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | /* Stage 1 creates the structure of the recorded event layout */ |
| 37 | 37 | |
| 38 | −#include "stages/stage1_defines.h" | |
| 38 | +#include "stages/stage1_struct_define.h" | |
| 39 | 39 | |
| 40 | 40 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 41 | 41 | #define DECLARE_CUSTOM_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ |
| @@ -56,7 +56,7 @@ · 14 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | /* Stage 2 creates the custom class */ |
| 58 | 58 | |
| 59 | −#include "stages/stage2_defines.h" | |
| 59 | +#include "stages/stage2_data_offsets.h" | |
| 60 | 60 | |
| 61 | 61 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 62 | 62 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -71,7 +71,7 @@ · 8 unmodified lines | ||
| 71 | 71 | |
| 72 | 72 | /* Stage 3 create the way to print the custom event */ |
| 73 | 73 | |
| 74 | −#include "stages/stage3_defines.h" | |
| 74 | +#include "stages/stage3_trace_output.h" | |
| 75 | 75 | |
| 76 | 76 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 77 | 77 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -102,7 +102,7 @@ static struct trace_event_functions trace_custom_event_type_funcs_##call = { \ · 24 unmodified lines | ||
| 102 | 102 | |
| 103 | 103 | /* Stage 4 creates the offset layout for the fields */ |
| 104 | 104 | |
| 105 | −#include "stages/stage4_defines.h" | |
| 105 | +#include "stages/stage4_event_fields.h" | |
| 106 | 106 | |
| 107 | 107 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 108 | 108 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, func, print) \ |
| @@ -114,7 +114,7 @@ static struct trace_event_fields trace_custom_event_fields_##call[] = { \ · 5 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | /* Stage 5 creates the helper function for dynamic fields */ |
| 116 | 116 | |
| 117 | −#include "stages/stage5_defines.h" | |
| 117 | +#include "stages/stage5_get_offsets.h" | |
| 118 | 118 | |
| 119 | 119 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 120 | 120 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -134,7 +134,7 @@ static inline notrace int trace_custom_event_get_offsets_##call( \ · 13 unmodified lines | ||
| 134 | 134 | |
| 135 | 135 | /* Stage 6 creates the probe function that records the event */ |
| 136 | 136 | |
| 137 | −#include "stages/stage6_defines.h" | |
| 137 | +#include "stages/stage6_event_callback.h" | |
| 138 | 138 | |
| 139 | 139 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 140 | 140 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -182,7 +182,7 @@ static inline void ftrace_test_custom_probe_##call(void) \ · 41 unmodified lines | ||
| 182 | 182 | |
| 183 | 183 | /* Stage 7 creates the actual class and event structure for the custom event */ |
| 184 | 184 | |
| 185 | −#include "stages/stage7_defines.h" | |
| 185 | +#include "stages/stage7_class_define.h" | |
| 186 | 186 | |
| 187 | 187 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 188 | 188 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | PARAMS(print)); \ |
| 46 | 46 | DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); |
| 47 | 47 | |
| 48 | −#include "stages/stage1_defines.h" | |
| 48 | +#include "stages/stage1_struct_define.h" | |
| 49 | 49 | |
| 50 | 50 | #undef DECLARE_EVENT_CLASS |
| 51 | 51 | #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ |
| @@ -109,7 +109,7 @@ · 57 unmodified lines | ||
| 109 | 109 | * The size of an array is also encoded, in the higher 16 bits of <item>. |
| 110 | 110 | */ |
| 111 | 111 | |
| 112 | −#include "stages/stage2_defines.h" | |
| 112 | +#include "stages/stage2_data_offsets.h" | |
| 113 | 113 | |
| 114 | 114 | #undef DECLARE_EVENT_CLASS |
| 115 | 115 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -181,7 +181,7 @@ · 65 unmodified lines | ||
| 181 | 181 | * in binary. |
| 182 | 182 | */ |
| 183 | 183 | |
| 184 | −#include "stages/stage3_defines.h" | |
| 184 | +#include "stages/stage3_trace_output.h" | |
| 185 | 185 | |
| 186 | 186 | #undef DECLARE_EVENT_CLASS |
| 187 | 187 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -236,7 +236,7 @@ static struct trace_event_functions trace_event_type_funcs_##call = { \ · 48 unmodified lines | ||
| 236 | 236 | |
| 237 | 237 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 238 | 238 | |
| 239 | −#include "stages/stage4_defines.h" | |
| 239 | +#include "stages/stage4_event_fields.h" | |
| 240 | 240 | |
| 241 | 241 | #undef DECLARE_EVENT_CLASS |
| 242 | 242 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \ |
| @@ -249,7 +249,7 @@ static struct trace_event_fields trace_event_fields_##call[] = { \ · 6 unmodified lines | ||
| 249 | 249 | |
| 250 | 250 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 251 | 251 | |
| 252 | −#include "stages/stage5_defines.h" | |
| 252 | +#include "stages/stage5_get_offsets.h" | |
| 253 | 253 | |
| 254 | 254 | #undef DECLARE_EVENT_CLASS |
| 255 | 255 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -372,7 +372,7 @@ static inline notrace int trace_event_get_offsets_##call( \ · 116 unmodified lines | ||
| 372 | 372 | #define _TRACE_PERF_INIT(call) |
| 373 | 373 | #endif /* CONFIG_PERF_EVENTS */ |
| 374 | 374 | |
| 375 | −#include "stages/stage6_defines.h" | |
| 375 | +#include "stages/stage6_event_callback.h" | |
| 376 | 376 | |
| 377 | 377 | #undef DECLARE_EVENT_CLASS |
| 378 | 378 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -418,7 +418,7 @@ static inline void ftrace_test_probe_##call(void) \ · 39 unmodified lines | ||
| 418 | 418 | |
| 419 | 419 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 420 | 420 | |
| 421 | −#include "stages/stage7_defines.h" | |
| 421 | +#include "stages/stage7_class_define.h" | |
| 422 | 422 | |
| 423 | 423 | #undef DECLARE_EVENT_CLASS |
| 424 | 424 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -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 | } |