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 | Overview | 7 | Overview |
| 8 | -------- | 8 | -------- |
| 9 | User based trace events allow user processes to create events and trace data | 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 | To enable this feature, build your kernel with CONFIG_USER_EVENTS=y. | 11 | To enable this feature, build your kernel with CONFIG_USER_EVENTS=y. |
| 12 | 12 | ||
| 13 | Programs can view status of the events via | 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 | Supported Flags | 68 | Supported Flags |
| 69 | ^^^^^^^^^^^^^^^ | 69 | ^^^^^^^^^^^^^^^ |
| 70 | **BPF_ITER** - EBPF programs attached to this event will get the raw iovec | 70 | None yet |
| 71 | struct instead of any data copies for max performance. | ||
| 72 | 71 | ||
| 73 | Field Format | 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 | **EVENT_STATUS_FTRACE** - Bit set if ftrace has been attached (Bit 0). | 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 | Writing Data | 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 | **NOTE:** *The write_index is not emitted out into the trace being recorded.* | 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 | Example Code | 206 | Example Code |
| 215 | ------------ | 207 | ------------ |
| 216 | See sample code in samples/user_events. | 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 | int ret = 0; | 32 | int ret = 0; |
| 33 | 33 | ||
| 34 | key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL); | 34 | key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL); |
| 35 | if (!key) | ||
| 36 | return -ENOMEM; | ||
| 35 | 37 | ||
| 36 | xbc_for_each_key_value(leaf, val) { | 38 | xbc_for_each_key_value(leaf, val) { |
| 37 | ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX); | 39 | ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <linux/trace_recursion.h> | 10 | #include <linux/trace_recursion.h> |
| 11 | #include <linux/trace_clock.h> | 11 | #include <linux/trace_clock.h> |
| 12 | #include <linux/jump_label.h> | ||
| 12 | #include <linux/kallsyms.h> | 13 | #include <linux/kallsyms.h> |
| 13 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
| 14 | #include <linux/bitops.h> | 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 | extern int register_ftrace_graph(struct fgraph_ops *ops); | 1019 | extern int register_ftrace_graph(struct fgraph_ops *ops); |
| 1019 | extern void unregister_ftrace_graph(struct fgraph_ops *ops); | 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 | extern void ftrace_graph_stop(void); | 1036 | extern void ftrace_graph_stop(void); |
| 1023 | 1037 | ||
| 1024 | /* The current handlers in use */ | 1038 | /* The current handlers in use */ |
| @@ -32,9 +32,6 @@ · 31 unmodified lines | |||
| 32 | /* Create dynamic location entry within a 32-bit value */ | 32 | /* Create dynamic location entry within a 32-bit value */ |
| 33 | #define DYN_LOC(offset, size) ((size) << 16 | (offset)) | 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 | * Describes an event registration and stores the results of the registration. | 36 | * Describes an event registration and stores the results of the registration. |
| 40 | * This structure is passed to the DIAG_IOCSREG ioctl, callers at a minimum | 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 | /* Requests to delete a user_event */ | 60 | /* Requests to delete a user_event */ |
| 64 | #define DIAG_IOCSDEL _IOW(DIAG_IOC_MAGIC, 1, char*) | 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 | #endif /* _UAPI_LINUX_USER_EVENTS_H */ | 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 | /* Stage 1 creates the structure of the recorded event layout */ | 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 | #undef DECLARE_CUSTOM_EVENT_CLASS | 40 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 41 | #define DECLARE_CUSTOM_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ | 41 | #define DECLARE_CUSTOM_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ |
| @@ -56,7 +56,7 @@ · 14 unmodified lines | |||
| 56 | 56 | ||
| 57 | /* Stage 2 creates the custom class */ | 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 | #undef DECLARE_CUSTOM_EVENT_CLASS | 61 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 62 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 62 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -71,7 +71,7 @@ · 8 unmodified lines | |||
| 71 | 71 | ||
| 72 | /* Stage 3 create the way to print the custom event */ | 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 | #undef DECLARE_CUSTOM_EVENT_CLASS | 76 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 77 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 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 | /* Stage 4 creates the offset layout for the fields */ | 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 | #undef DECLARE_CUSTOM_EVENT_CLASS | 107 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 108 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, func, print) \ | 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 | /* Stage 5 creates the helper function for dynamic fields */ | 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 | #undef DECLARE_CUSTOM_EVENT_CLASS | 119 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 120 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 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 | /* Stage 6 creates the probe function that records the event */ | 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 | #undef DECLARE_CUSTOM_EVENT_CLASS | 139 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 140 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 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 | /* Stage 7 creates the actual class and event structure for the custom event */ | 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 | #undef DECLARE_CUSTOM_EVENT_CLASS | 187 | #undef DECLARE_CUSTOM_EVENT_CLASS |
| 188 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 188 | #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | |||
| 45 | PARAMS(print)); \ | 45 | PARAMS(print)); \ |
| 46 | DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); | 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 | #undef DECLARE_EVENT_CLASS | 50 | #undef DECLARE_EVENT_CLASS |
| 51 | #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ | 51 | #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ |
| @@ -109,7 +109,7 @@ · 57 unmodified lines | |||
| 109 | * The size of an array is also encoded, in the higher 16 bits of <item>. | 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 | #undef DECLARE_EVENT_CLASS | 114 | #undef DECLARE_EVENT_CLASS |
| 115 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 115 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -181,7 +181,7 @@ · 65 unmodified lines | |||
| 181 | * in binary. | 181 | * in binary. |
| 182 | */ | 182 | */ |
| 183 | 183 | ||
| 184 | #include "stages/stage3_defines.h" | 184 | #include "stages/stage3_trace_output.h" |
| 185 | 185 | ||
| 186 | #undef DECLARE_EVENT_CLASS | 186 | #undef DECLARE_EVENT_CLASS |
| 187 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 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 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 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 | #undef DECLARE_EVENT_CLASS | 241 | #undef DECLARE_EVENT_CLASS |
| 242 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \ | 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 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 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 | #undef DECLARE_EVENT_CLASS | 254 | #undef DECLARE_EVENT_CLASS |
| 255 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 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 | #define _TRACE_PERF_INIT(call) | 372 | #define _TRACE_PERF_INIT(call) |
| 373 | #endif /* CONFIG_PERF_EVENTS */ | 373 | #endif /* CONFIG_PERF_EVENTS */ |
| 374 | 374 | ||
| 375 | #include "stages/stage6_defines.h" | 375 | #include "stages/stage6_event_callback.h" |
| 376 | 376 | ||
| 377 | #undef DECLARE_EVENT_CLASS | 377 | #undef DECLARE_EVENT_CLASS |
| 378 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 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 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 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 | #undef DECLARE_EVENT_CLASS | 423 | #undef DECLARE_EVENT_CLASS |
| 424 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 424 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| @@ -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 | } |