History

Merge tag 'trace-v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing updates from Steven Rostedt: "Major changes: - Changed location of tracing repo from personal git repo to: git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git - Added Masami Hiramatsu as co-maintainer - Updated MAINTAINERS file to separate out FTRACE as it is more than just TRACING. Minor changes: - Added Mark Rutland as FTRACE reviewer - Updated user_events to make it on its way to remove the BROKEN tag. The changes should now be acceptable but will run it through a cycle and hopefully we can remove the BROKEN tag next release. - Added filtering to eprobes - Added a delta time to the benchmark trace event - Have the histogram and filter callbacks called via a switch statement instead of indirect functions. This speeds it up to avoid retpolines. - Add a way to wake up ring buffer waiters waiting for the ring buffer to fill up to its watermark. - New ioctl() on the trace_pipe_raw file to wake up ring buffer waiters. - Wake up waiters when the ring buffer is disabled. A reader may block when the ring buffer is disabled, but if it was blocked when the ring buffer is disabled it should then wake up. Fixes: - Allow splice to read partially read ring buffer pages. This fixes splice never moving forward. - Fix inverted compare that made the "shortest" ring buffer wait queue actually the longest. - Fix a race in the ring buffer between resetting a page when a writer goes to another page, and the reader. - Fix ftrace accounting bug when function hooks are added at boot up before the weak functions are set to "disabled". - Fix bug that freed a user allocated snapshot buffer when enabling a tracer. - Fix possible recursive locks in osnoise tracer - Fix recursive locking direct functions - Other minor clean ups and fixes" * tag 'trace-v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: (44 commits) ftrace: Create separate entry in MAINTAINERS for function hooks tracing: Update MAINTAINERS to reflect new tracing git repo tracing: Do not free snapshot if tracer is on cmdline ftrace: Still disable enabled records marked as disabled tracing/user_events: Move pages/locks into groups to prepare for namespaces tracing: Add Masami Hiramatsu as co-maintainer tracing: Remove unused variable 'dups' MAINTAINERS: add myself as a tracing reviewer ring-buffer: Fix race between reset page and reading page tracing/user_events: Update ABI documentation to align to bits vs bytes tracing/user_events: Use bits vs bytes for enabled status page data tracing/user_events: Use refcount instead of atomic for ref tracking tracing/user_events: Ensure user provided strings are safely formatted tracing/user_events: Use WRITE instead of READ for io vector import tracing/user_events: Use NULL for strstr checks tracing: Fix spelling mistake "preapre" -> "prepare" tracing: Wake up waiters when tracing is disabled tracing: Add ioctl() to force ring buffer waiters to wake up tracing: Wake up ring buffer waiters on closing of the file ring-buffer: Add ring_buffer_wake_waiters() ...

Linus Torvalds committed 4 years ago

Commit cdf072a2 parents dc55342 4f881a634 files · +1299 −486Browse files

Unified · Split

34 files
  1. Documentation/trace/user_events.rst +58 −28
  2. MAINTAINERS +18 −8
  3. arch/x86/include/asm/ftrace.h +0 −1
  4. arch/x86/include/asm/kprobes.h +0 −2
  5. arch/x86/kernel/kprobes/core.c +0 −2
  6. include/linux/ftrace.h +0 −41
  7. include/linux/ring_buffer.h +1 −1
  8. include/linux/sched.h +0 −3
  9. include/linux/trace_events.h +1 −0
  10. include/linux/user_events.h +3 −12
  11. kernel/trace/ftrace.c +27 −7
  12. kernel/trace/kprobe_event_gen_test.c +44 −5
  13. kernel/trace/ring_buffer.c +84 −3
  14. kernel/trace/rv/monitors/wip/wip.c +4 −4
  15. kernel/trace/rv/monitors/wwnr/wwnr.c +4 −4
  16. kernel/trace/trace.c +73 −5
  17. kernel/trace/trace.h +0 −13
  18. kernel/trace/trace_benchmark.c +1 −1
  19. kernel/trace/trace_benchmark.h +5 −3
  20. kernel/trace/trace_eprobe.c +97 −10
  21. kernel/trace/trace_events_filter.c +168 −71
  22. kernel/trace/trace_events_hist.c +169 −77
  23. kernel/trace/trace_events_user.c +426 −142
  24. kernel/trace/trace_osnoise.c +2 −1
  25. kernel/trace/trace_probe.h +2 −1
  26. kernel/trace/tracing_map.c +2 −3
  27. kernel/tracepoint.c +6 −8
  28. samples/user_events/example.c +18 −7
  29. tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc +27 −0
  30. tools/testing/selftests/user_events/ftrace_test.c +39 −8
  31. tools/testing/selftests/user_events/perf_test.c +8 −3
  32. tools/verification/dot2/dot2k_templates/main_global.c +4 −4
  33. tools/verification/dot2/dot2k_templates/main_per_cpu.c +4 −4
  34. tools/verification/dot2/dot2k_templates/main_per_task.c +4 −4
Documentation/trace/user_events.rst+58−28
@@ -20,14 +20,14 @@ dynamic_events is the same as the ioctl with the u: prefix applied. · 19 unmodified lines
20 20
21Typically programs will register a set of events that they wish to expose to21Typically programs will register a set of events that they wish to expose to
22tools that can read trace_events (such as ftrace and perf). The registration22tools that can read trace_events (such as ftrace and perf). The registration
23process gives back two ints to the program for each event. The first int is the23process gives back two ints to the program for each event. The first int is
24status index. This index describes which byte in the24the status bit. This describes which bit in little-endian format in the
25/sys/kernel/debug/tracing/user_events_status file represents this event. The25/sys/kernel/debug/tracing/user_events_status file represents this event. The
26second int is the write index. This index describes the data when a write() or26second int is the write index which describes the data when a write() or
27writev() is called on the /sys/kernel/debug/tracing/user_events_data file.27writev() is called on the /sys/kernel/debug/tracing/user_events_data file.
28 28
29The structures referenced in this document are contained with the29The structures referenced in this document are contained within the
30/include/uap/linux/user_events.h file in the source tree.30/include/uapi/linux/user_events.h file in the source tree.
31 31
32**NOTE:** *Both user_events_status and user_events_data are under the tracefs32**NOTE:** *Both user_events_status and user_events_data are under the tracefs
33filesystem and may be mounted at different paths than above.*33filesystem and may be mounted at different paths than above.*
@@ -38,18 +38,18 @@ Registering within a user process is done via ioctl() out to the · 4 unmodified lines
38/sys/kernel/debug/tracing/user_events_data file. The command to issue is38/sys/kernel/debug/tracing/user_events_data file. The command to issue is
39DIAG_IOCSREG.39DIAG_IOCSREG.
40 40
41This command takes a struct user_reg as an argument::41This command takes a packed struct user_reg as an argument::
42 42
43 struct user_reg {43 struct user_reg {
44 u32 size;44 u32 size;
45 u64 name_args;45 u64 name_args;
46 u32 status_index;46 u32 status_bit;
47 u32 write_index;47 u32 write_index;
48 };48 };
49 49
50The struct user_reg requires two inputs, the first is the size of the structure50The struct user_reg requires two inputs, the first is the size of the structure
51to ensure forward and backward compatibility. The second is the command string51to ensure forward and backward compatibility. The second is the command string
52to issue for registering. Upon success two outputs are set, the status index52to issue for registering. Upon success two outputs are set, the status bit
53and the write index.53and the write index.
54 54
55User based events show up under tracefs like any other event under the55User based events show up under tracefs like any other event under the
@@ -111,15 +111,56 @@ in realtime. This allows user programs to only incur the cost of the write() or · 55 unmodified lines
111writev() calls when something is actively attached to the event.111writev() calls when something is actively attached to the event.
112 112
113User programs call mmap() on /sys/kernel/debug/tracing/user_events_status to113User programs call mmap() on /sys/kernel/debug/tracing/user_events_status to
114check the status for each event that is registered. The byte to check in the114check the status for each event that is registered. The bit to check in the
115file is given back after the register ioctl() via user_reg.status_index.115file is given back after the register ioctl() via user_reg.status_bit. The bit
116is always in little-endian format. Programs can check if the bit is set either
117using a byte-wise index with a mask or a long-wise index with a little-endian
118mask.
119
116Currently the size of user_events_status is a single page, however, custom120Currently the size of user_events_status is a single page, however, custom
117kernel configurations can change this size to allow more user based events. In121kernel configurations can change this size to allow more user based events. In
118all cases the size of the file is a multiple of a page size.122all cases the size of the file is a multiple of a page size.
119 123
120For example, if the register ioctl() gives back a status_index of 3 you would124For example, if the register ioctl() gives back a status_bit of 3 you would
121check byte 3 of the returned mmap data to see if anything is attached to that125check byte 0 (3 / 8) of the returned mmap data and then AND the result with 8
122event.126(1 << (3 % 8)) to see if anything is attached to that event.
127
128A byte-wise index check is performed as follows::
129
130 int index, mask;
131 char *status_page;
132
133 index = status_bit / 8;
134 mask = 1 << (status_bit % 8);
135
136 ...
137
138 if (status_page[index] & mask) {
139 /* Enabled */
140 }
141
142A long-wise index check is performed as follows::
143
144 #include <asm/bitsperlong.h>
145 #include <endian.h>
146
147 #if __BITS_PER_LONG == 64
148 #define endian_swap(x) htole64(x)
149 #else
150 #define endian_swap(x) htole32(x)
151 #endif
152
153 long index, mask, *status_page;
154
155 index = status_bit / __BITS_PER_LONG;
156 mask = 1L << (status_bit % __BITS_PER_LONG);
157 mask = endian_swap(mask);
158
159 ...
160
161 if (status_page[index] & mask) {
162 /* Enabled */
163 }
123 164
124Administrators can easily check the status of all registered events by reading165Administrators can easily check the status of all registered events by reading
125the user_events_status file directly via a terminal. The output is as follows::166the user_events_status file directly via a terminal. The output is as follows::
@@ -137,7 +178,7 @@ For example, on a system that has a single event the output looks like this:: · 11 unmodified lines
137 178
138 Active: 1179 Active: 1
139 Busy: 0180 Busy: 0
140 Max: 4096181 Max: 32768
141 182
142If a user enables the user event via ftrace, the output would change to this::183If a user enables the user event via ftrace, the output would change to this::
143 184
@@ -145,21 +186,10 @@ If a user enables the user event via ftrace, the output would change to this:: · 1 unmodified line
145 186
146 Active: 1187 Active: 1
147 Busy: 1188 Busy: 1
148 Max: 4096189 Max: 32768
149
150**NOTE:** *A status index of 0 will never be returned. This allows user
151programs to have an index that can be used on error cases.*
152
153Status Bits
154^^^^^^^^^^^
155The byte being checked will be non-zero if anything is attached. Programs can
156check specific bits in the byte to see what mechanism has been attached.
157
158The following values are defined to aid in checking what has been attached:
159
160**EVENT_STATUS_FTRACE** - Bit set if ftrace has been attached (Bit 0).
161 190
162**EVENT_STATUS_PERF** - Bit set if perf has been attached (Bit 1).191**NOTE:** *A status bit of 0 will never be returned. This allows user programs
192to have a bit that can be used on error cases.*
163 193
164Writing Data194Writing Data
165------------195------------
MAINTAINERS+18−8
@@ -8433,6 +8433,19 @@ L: platform-driver-x86@vger.kernel.org · 8432 unmodified lines
8433S: Maintained8433S: Maintained
8434F: drivers/platform/x86/fujitsu-tablet.c8434F: drivers/platform/x86/fujitsu-tablet.c
8435 8435
8436FUNCTION HOOKS (FTRACE)
8437M: Steven Rostedt <rostedt@goodmis.org>
8438M: Masami Hiramatsu <mhiramat@kernel.org>
8439R: Mark Rutland <mark.rutland@arm.com>
8440S: Maintained
8441T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
8442F: Documentation/trace/ftrace*
8443F: kernel/trace/ftrace*
8444F: kernel/trace/fgraph.c
8445F: arch/*/*/*/*ftrace*
8446F: arch/*/*/*ftrace*
8447F: include/*/ftrace.h
8448
8436FUNGIBLE ETHERNET DRIVERS8449FUNGIBLE ETHERNET DRIVERS
8437M: Dimitris Michailidis <dmichail@fungible.com>8450M: Dimitris Michailidis <dmichail@fungible.com>
8438L: netdev@vger.kernel.org8451L: netdev@vger.kernel.org
@@ -11422,7 +11435,7 @@ M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> · 2983 unmodified lines
11422M: "David S. Miller" <davem@davemloft.net>11435M: "David S. Miller" <davem@davemloft.net>
11423M: Masami Hiramatsu <mhiramat@kernel.org>11436M: Masami Hiramatsu <mhiramat@kernel.org>
11424S: Maintained11437S: Maintained
11425T: git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git11438T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
11426F: Documentation/trace/kprobes.rst11439F: Documentation/trace/kprobes.rst
11427F: include/asm-generic/kprobes.h11440F: include/asm-generic/kprobes.h
11428F: include/linux/kprobes.h11441F: include/linux/kprobes.h
@@ -20771,14 +20784,11 @@ F: drivers/hwmon/pmbus/tps546d24.c · 9342 unmodified lines
20771 20784
20772TRACING20785TRACING
20773M: Steven Rostedt <rostedt@goodmis.org>20786M: Steven Rostedt <rostedt@goodmis.org>
20774M: Ingo Molnar <mingo@redhat.com>20787M: Masami Hiramatsu <mhiramat@kernel.org>
20775S: Maintained20788S: Maintained
20776T: git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git20789T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
20777F: Documentation/trace/ftrace.rst20790F: Documentation/trace/*
20778F: arch/*/*/*/*ftrace*
20779F: arch/*/*/*ftrace*
20780F: fs/tracefs/20791F: fs/tracefs/
20781F: include/*/ftrace.h
20782F: include/linux/trace*.h20792F: include/linux/trace*.h
20783F: include/trace/20793F: include/trace/
20784F: kernel/trace/20794F: kernel/trace/
@@ -20787,7 +20797,7 @@ F: tools/testing/selftests/ftrace/ · 2 unmodified lines
20787 20797
20788TRACING MMIO ACCESSES (MMIOTRACE)20798TRACING MMIO ACCESSES (MMIOTRACE)
20789M: Steven Rostedt <rostedt@goodmis.org>20799M: Steven Rostedt <rostedt@goodmis.org>
20790M: Ingo Molnar <mingo@kernel.org>20800M: Masami Hiramatsu <mhiramat@kernel.org>
20791R: Karol Herbst <karolherbst@gmail.com>20801R: Karol Herbst <karolherbst@gmail.com>
20792R: Pekka Paalanen <ppaalanen@gmail.com>20802R: Pekka Paalanen <ppaalanen@gmail.com>
20793L: linux-kernel@vger.kernel.org20803L: linux-kernel@vger.kernel.org
arch/x86/include/asm/ftrace.h+0−1
@@ -23,7 +23,6 @@ · 22 unmodified lines
23#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR23#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
24 24
25#ifndef __ASSEMBLY__25#ifndef __ASSEMBLY__
26extern atomic_t modifying_ftrace_code;
27extern void __fentry__(void);26extern void __fentry__(void);
28 27
29static inline unsigned long ftrace_call_adjust(unsigned long addr)28static inline unsigned long ftrace_call_adjust(unsigned long addr)
arch/x86/include/asm/kprobes.h+0−2
@@ -50,8 +50,6 @@ extern const int kretprobe_blacklist_size; · 49 unmodified lines
50 50
51void arch_remove_kprobe(struct kprobe *p);51void arch_remove_kprobe(struct kprobe *p);
52 52
53extern void arch_kprobe_override_function(struct pt_regs *regs);
54
55/* Architecture specific copy of original instruction*/53/* Architecture specific copy of original instruction*/
56struct arch_specific_insn {54struct arch_specific_insn {
57 /* copy of the original instruction */55 /* copy of the original instruction */
arch/x86/kernel/kprobes/core.c+0−2
@@ -59,8 +59,6 @@ · 58 unmodified lines
59DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;59DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
60DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);60DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
61 61
62#define stack_addr(regs) ((unsigned long *)regs->sp)
63
64#define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\62#define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
65 (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \63 (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
66 (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \64 (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \
include/linux/ftrace.h+0−41
@@ -1122,47 +1122,6 @@ static inline void unpause_graph_tracing(void) { } · 1121 unmodified lines
1122#endif /* CONFIG_FUNCTION_GRAPH_TRACER */1122#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
1123 1123
1124#ifdef CONFIG_TRACING1124#ifdef CONFIG_TRACING
1125
1126/* flags for current->trace */
1127enum {
1128 TSK_TRACE_FL_TRACE_BIT = 0,
1129 TSK_TRACE_FL_GRAPH_BIT = 1,
1130};
1131enum {
1132 TSK_TRACE_FL_TRACE = 1 << TSK_TRACE_FL_TRACE_BIT,
1133 TSK_TRACE_FL_GRAPH = 1 << TSK_TRACE_FL_GRAPH_BIT,
1134};
1135
1136static inline void set_tsk_trace_trace(struct task_struct *tsk)
1137{
1138 set_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace);
1139}
1140
1141static inline void clear_tsk_trace_trace(struct task_struct *tsk)
1142{
1143 clear_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace);
1144}
1145
1146static inline int test_tsk_trace_trace(struct task_struct *tsk)
1147{
1148 return tsk->trace & TSK_TRACE_FL_TRACE;
1149}
1150
1151static inline void set_tsk_trace_graph(struct task_struct *tsk)
1152{
1153 set_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace);
1154}
1155
1156static inline void clear_tsk_trace_graph(struct task_struct *tsk)
1157{
1158 clear_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace);
1159}
1160
1161static inline int test_tsk_trace_graph(struct task_struct *tsk)
1162{
1163 return tsk->trace & TSK_TRACE_FL_GRAPH;
1164}
1165
1166enum ftrace_dump_mode;1125enum ftrace_dump_mode;
1167 1126
1168extern enum ftrace_dump_mode ftrace_dump_on_oops;1127extern enum ftrace_dump_mode ftrace_dump_on_oops;
include/linux/ring_buffer.h+1−1
@@ -101,7 +101,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k · 100 unmodified lines
101int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);101int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);
102__poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,102__poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
103 struct file *filp, poll_table *poll_table);103 struct file *filp, poll_table *poll_table);
104 104void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu);
105 105
106#define RING_BUFFER_ALL_CPUS -1106#define RING_BUFFER_ALL_CPUS -1
107 107
include/linux/sched.h+0−3
@@ -1390,9 +1390,6 @@ struct task_struct { · 1389 unmodified lines
1390#endif1390#endif
1391 1391
1392#ifdef CONFIG_TRACING1392#ifdef CONFIG_TRACING
1393 /* State flags for use by tracers: */
1394 unsigned long trace;
1395
1396 /* Bitmask and counter of trace recursion: */1393 /* Bitmask and counter of trace recursion: */
1397 unsigned long trace_recursion;1394 unsigned long trace_recursion;
1398#endif /* CONFIG_TRACING */1395#endif /* CONFIG_TRACING */
include/linux/trace_events.h+1−0
@@ -92,6 +92,7 @@ struct trace_iterator { · 91 unmodified lines
92 unsigned int temp_size;92 unsigned int temp_size;
93 char *fmt; /* modified format holder */93 char *fmt; /* modified format holder */
94 unsigned int fmt_size;94 unsigned int fmt_size;
95 long wait_index;
95 96
96 /* trace_seq for __print_flags() and __print_symbolic() etc. */97 /* trace_seq for __print_flags() and __print_symbolic() etc. */
97 struct trace_seq tmp_seq;98 struct trace_seq tmp_seq;
include/linux/user_events.h+3−12
@@ -20,15 +20,6 @@ · 19 unmodified lines
20#define USER_EVENTS_SYSTEM "user_events"20#define USER_EVENTS_SYSTEM "user_events"
21#define USER_EVENTS_PREFIX "u:"21#define USER_EVENTS_PREFIX "u:"
22 22
23/* Bits 0-6 are for known probe types, Bit 7 is for unknown probes */
24#define EVENT_BIT_FTRACE 0
25#define EVENT_BIT_PERF 1
26#define EVENT_BIT_OTHER 7
27
28#define EVENT_STATUS_FTRACE (1 << EVENT_BIT_FTRACE)
29#define EVENT_STATUS_PERF (1 << EVENT_BIT_PERF)
30#define EVENT_STATUS_OTHER (1 << EVENT_BIT_OTHER)
31
32/* Create dynamic location entry within a 32-bit value */23/* Create dynamic location entry within a 32-bit value */
33#define DYN_LOC(offset, size) ((size) << 16 | (offset))24#define DYN_LOC(offset, size) ((size) << 16 | (offset))
34 25
@@ -45,12 +36,12 @@ struct user_reg { · 10 unmodified lines
45 /* Input: Pointer to string with event name, description and flags */36 /* Input: Pointer to string with event name, description and flags */
46 __u64 name_args;37 __u64 name_args;
47 38
48 /* Output: Byte index of the event within the status page */39 /* Output: Bitwise index of the event within the status page */
49 __u32 status_index;40 __u32 status_bit;
50 41
51 /* Output: Index of the event to use when writing data */42 /* Output: Index of the event to use when writing data */
52 __u32 write_index;43 __u32 write_index;
53};44} __attribute__((__packed__));
54 45
55#define DIAG_IOC_MAGIC '*'46#define DIAG_IOC_MAGIC '*'
56 47
kernel/trace/ftrace.c+27−7
@@ -1644,6 +1644,18 @@ ftrace_find_tramp_ops_any_other(struct dyn_ftrace *rec, struct ftrace_ops *op_ex · 1643 unmodified lines
1644static struct ftrace_ops *1644static struct ftrace_ops *
1645ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);1645ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
1646 1646
1647static bool skip_record(struct dyn_ftrace *rec)
1648{
1649 /*
1650 * At boot up, weak functions are set to disable. Function tracing
1651 * can be enabled before they are, and they still need to be disabled now.
1652 * If the record is disabled, still continue if it is marked as already
1653 * enabled (this is needed to keep the accounting working).
1654 */
1655 return rec->flags & FTRACE_FL_DISABLED &&
1656 !(rec->flags & FTRACE_FL_ENABLED);
1657}
1658
1647static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,1659static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
1648 int filter_hash,1660 int filter_hash,
1649 bool inc)1661 bool inc)
@@ -1693,7 +1705,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops, · 43 unmodified lines
1693 int in_hash = 0;1705 int in_hash = 0;
1694 int match = 0;1706 int match = 0;
1695 1707
1696 if (rec->flags & FTRACE_FL_DISABLED)1708 if (skip_record(rec))
1697 continue;1709 continue;
1698 1710
1699 if (all) {1711 if (all) {
@@ -2126,7 +2138,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update) · 426 unmodified lines
2126 2138
2127 ftrace_bug_type = FTRACE_BUG_UNKNOWN;2139 ftrace_bug_type = FTRACE_BUG_UNKNOWN;
2128 2140
2129 if (rec->flags & FTRACE_FL_DISABLED)2141 if (skip_record(rec))
2130 return FTRACE_UPDATE_IGNORE;2142 return FTRACE_UPDATE_IGNORE;
2131 2143
2132 /*2144 /*
@@ -2241,7 +2253,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update) · 108 unmodified lines
2241 if (update) {2253 if (update) {
2242 /* If there's no more users, clear all flags */2254 /* If there's no more users, clear all flags */
2243 if (!ftrace_rec_count(rec))2255 if (!ftrace_rec_count(rec))
2244 rec->flags = 0;2256 rec->flags &= FTRACE_FL_DISABLED;
2245 else2257 else
2246 /*2258 /*
2247 * Just disable the record, but keep the ops TRAMP2259 * Just disable the record, but keep the ops TRAMP
@@ -2634,7 +2646,7 @@ void __weak ftrace_replace_code(int mod_flags) · 386 unmodified lines
2634 2646
2635 do_for_each_ftrace_rec(pg, rec) {2647 do_for_each_ftrace_rec(pg, rec) {
2636 2648
2637 if (rec->flags & FTRACE_FL_DISABLED)2649 if (skip_record(rec))
2638 continue;2650 continue;
2639 2651
2640 failed = __ftrace_replace_code(rec, enable);2652 failed = __ftrace_replace_code(rec, enable);
@@ -5427,6 +5439,8 @@ static struct ftrace_ops stub_ops = { · 2786 unmodified lines
5427 * it is safe to modify the ftrace record, where it should be5439 * it is safe to modify the ftrace record, where it should be
5428 * currently calling @old_addr directly, to call @new_addr.5440 * currently calling @old_addr directly, to call @new_addr.
5429 *5441 *
5442 * This is called with direct_mutex locked.
5443 *
5430 * Safety checks should be made to make sure that the code at5444 * Safety checks should be made to make sure that the code at
5431 * @rec->ip is currently calling @old_addr. And this must5445 * @rec->ip is currently calling @old_addr. And this must
5432 * also update entry->direct to @new_addr.5446 * also update entry->direct to @new_addr.
@@ -5439,6 +5453,8 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry, · 6 unmodified lines
5439 unsigned long ip = rec->ip;5453 unsigned long ip = rec->ip;
5440 int ret;5454 int ret;
5441 5455
5456 lockdep_assert_held(&direct_mutex);
5457
5442 /*5458 /*
5443 * The ftrace_lock was used to determine if the record5459 * The ftrace_lock was used to determine if the record
5444 * had more than one registered user to it. If it did,5460 * had more than one registered user to it. If it did,
@@ -5461,7 +5477,7 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry, · 16 unmodified lines
5461 if (ret)5477 if (ret)
5462 goto out_lock;5478 goto out_lock;
5463 5479
5464 ret = register_ftrace_function(&stub_ops);5480 ret = register_ftrace_function_nolock(&stub_ops);
5465 if (ret) {5481 if (ret) {
5466 ftrace_set_filter_ip(&stub_ops, ip, 1, 0);5482 ftrace_set_filter_ip(&stub_ops, ip, 1, 0);
5467 goto out_lock;5483 goto out_lock;
@@ -6081,8 +6097,12 @@ int ftrace_regex_release(struct inode *inode, struct file *file) · 613 unmodified lines
6081 6097
6082 if (filter_hash) {6098 if (filter_hash) {
6083 orig_hash = &iter->ops->func_hash->filter_hash;6099 orig_hash = &iter->ops->func_hash->filter_hash;
6084 if (iter->tr && !list_empty(&iter->tr->mod_trace))6100 if (iter->tr) {
6085 iter->hash->flags |= FTRACE_HASH_FL_MOD;6101 if (list_empty(&iter->tr->mod_trace))
6102 iter->hash->flags &= ~FTRACE_HASH_FL_MOD;
6103 else
6104 iter->hash->flags |= FTRACE_HASH_FL_MOD;
6105 }
6086 } else6106 } else
6087 orig_hash = &iter->ops->func_hash->notrace_hash;6107 orig_hash = &iter->ops->func_hash->notrace_hash;
6088 6108
kernel/trace/kprobe_event_gen_test.c+44−5
@@ -35,6 +35,45 @@ · 34 unmodified lines
35static struct trace_event_file *gen_kprobe_test;35static struct trace_event_file *gen_kprobe_test;
36static struct trace_event_file *gen_kretprobe_test;36static struct trace_event_file *gen_kretprobe_test;
37 37
38#define KPROBE_GEN_TEST_FUNC "do_sys_open"
39
40/* X86 */
41#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
42#define KPROBE_GEN_TEST_ARG0 "dfd=%ax"
43#define KPROBE_GEN_TEST_ARG1 "filename=%dx"
44#define KPROBE_GEN_TEST_ARG2 "flags=%cx"
45#define KPROBE_GEN_TEST_ARG3 "mode=+4($stack)"
46
47/* ARM64 */
48#elif defined(CONFIG_ARM64)
49#define KPROBE_GEN_TEST_ARG0 "dfd=%x0"
50#define KPROBE_GEN_TEST_ARG1 "filename=%x1"
51#define KPROBE_GEN_TEST_ARG2 "flags=%x2"
52#define KPROBE_GEN_TEST_ARG3 "mode=%x3"
53
54/* ARM */
55#elif defined(CONFIG_ARM)
56#define KPROBE_GEN_TEST_ARG0 "dfd=%r0"
57#define KPROBE_GEN_TEST_ARG1 "filename=%r1"
58#define KPROBE_GEN_TEST_ARG2 "flags=%r2"
59#define KPROBE_GEN_TEST_ARG3 "mode=%r3"
60
61/* RISCV */
62#elif defined(CONFIG_RISCV)
63#define KPROBE_GEN_TEST_ARG0 "dfd=%a0"
64#define KPROBE_GEN_TEST_ARG1 "filename=%a1"
65#define KPROBE_GEN_TEST_ARG2 "flags=%a2"
66#define KPROBE_GEN_TEST_ARG3 "mode=%a3"
67
68/* others */
69#else
70#define KPROBE_GEN_TEST_ARG0 NULL
71#define KPROBE_GEN_TEST_ARG1 NULL
72#define KPROBE_GEN_TEST_ARG2 NULL
73#define KPROBE_GEN_TEST_ARG3 NULL
74#endif
75
76
38/*77/*
39 * Test to make sure we can create a kprobe event, then add more78 * Test to make sure we can create a kprobe event, then add more
40 * fields.79 * fields.
@@ -58,14 +97,14 @@ static int __init test_gen_kprobe_cmd(void) · 17 unmodified lines
58 * fields.97 * fields.
59 */98 */
60 ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test",99 ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test",
61 "do_sys_open",100 KPROBE_GEN_TEST_FUNC,
62 "dfd=%ax", "filename=%dx");101 KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1);
63 if (ret)102 if (ret)
64 goto free;103 goto free;
65 104
66 /* Use kprobe_event_add_fields to add the rest of the fields */105 /* Use kprobe_event_add_fields to add the rest of the fields */
67 106
68 ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)");107 ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3);
69 if (ret)108 if (ret)
70 goto free;109 goto free;
71 110
@@ -128,7 +167,7 @@ static int __init test_gen_kretprobe_cmd(void) · 56 unmodified lines
128 * Define the kretprobe event.167 * Define the kretprobe event.
129 */168 */
130 ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",169 ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
131 "do_sys_open",170 KPROBE_GEN_TEST_FUNC,
132 "$retval");171 "$retval");
133 if (ret)172 if (ret)
134 goto free;173 goto free;
@@ -206,7 +245,7 @@ static void __exit kprobe_event_gen_test_exit(void) · 71 unmodified lines
206 WARN_ON(kprobe_event_delete("gen_kprobe_test"));245 WARN_ON(kprobe_event_delete("gen_kprobe_test"));
207 246
208 /* Disable the event or you can't remove it */247 /* Disable the event or you can't remove it */
209 WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,248 WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
210 "kprobes",249 "kprobes",
211 "gen_kretprobe_test", false));250 "gen_kretprobe_test", false));
212 251
kernel/trace/ring_buffer.c+84−3
@@ -413,6 +413,7 @@ struct rb_irq_work { · 412 unmodified lines
413 struct irq_work work;413 struct irq_work work;
414 wait_queue_head_t waiters;414 wait_queue_head_t waiters;
415 wait_queue_head_t full_waiters;415 wait_queue_head_t full_waiters;
416 long wait_index;
416 bool waiters_pending;417 bool waiters_pending;
417 bool full_waiters_pending;418 bool full_waiters_pending;
418 bool wakeup_full;419 bool wakeup_full;
@@ -917,12 +918,44 @@ static void rb_wake_up_waiters(struct irq_work *work) · 498 unmodified lines
917 struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work);918 struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work);
918 919
919 wake_up_all(&rbwork->waiters);920 wake_up_all(&rbwork->waiters);
920 if (rbwork->wakeup_full) {921 if (rbwork->full_waiters_pending || rbwork->wakeup_full) {
921 rbwork->wakeup_full = false;922 rbwork->wakeup_full = false;
923 rbwork->full_waiters_pending = false;
922 wake_up_all(&rbwork->full_waiters);924 wake_up_all(&rbwork->full_waiters);
923 }925 }
924}926}
925 927
928/**
929 * ring_buffer_wake_waiters - wake up any waiters on this ring buffer
930 * @buffer: The ring buffer to wake waiters on
931 *
932 * In the case of a file that represents a ring buffer is closing,
933 * it is prudent to wake up any waiters that are on this.
934 */
935void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
936{
937 struct ring_buffer_per_cpu *cpu_buffer;
938 struct rb_irq_work *rbwork;
939
940 if (cpu == RING_BUFFER_ALL_CPUS) {
941
942 /* Wake up individual ones too. One level recursion */
943 for_each_buffer_cpu(buffer, cpu)
944 ring_buffer_wake_waiters(buffer, cpu);
945
946 rbwork = &buffer->irq_work;
947 } else {
948 cpu_buffer = buffer->buffers[cpu];
949 rbwork = &cpu_buffer->irq_work;
950 }
951
952 rbwork->wait_index++;
953 /* make sure the waiters see the new index */
954 smp_wmb();
955
956 rb_wake_up_waiters(&rbwork->work);
957}
958
926/**959/**
927 * ring_buffer_wait - wait for input to the ring buffer960 * ring_buffer_wait - wait for input to the ring buffer
928 * @buffer: buffer to wait on961 * @buffer: buffer to wait on
@@ -938,6 +971,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) · 9 unmodified lines
938 struct ring_buffer_per_cpu *cpu_buffer;971 struct ring_buffer_per_cpu *cpu_buffer;
939 DEFINE_WAIT(wait);972 DEFINE_WAIT(wait);
940 struct rb_irq_work *work;973 struct rb_irq_work *work;
974 long wait_index;
941 int ret = 0;975 int ret = 0;
942 976
943 /*977 /*
@@ -956,6 +990,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) · 12 unmodified lines
956 work = &cpu_buffer->irq_work;990 work = &cpu_buffer->irq_work;
957 }991 }
958 992
993 wait_index = READ_ONCE(work->wait_index);
959 994
960 while (true) {995 while (true) {
961 if (full)996 if (full)
@@ -1011,7 +1046,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) · 49 unmodified lines
1011 nr_pages = cpu_buffer->nr_pages;1046 nr_pages = cpu_buffer->nr_pages;
1012 dirty = ring_buffer_nr_dirty_pages(buffer, cpu);1047 dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
1013 if (!cpu_buffer->shortest_full ||1048 if (!cpu_buffer->shortest_full ||
1014 cpu_buffer->shortest_full < full)1049 cpu_buffer->shortest_full > full)
1015 cpu_buffer->shortest_full = full;1050 cpu_buffer->shortest_full = full;
1016 raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);1051 raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
1017 if (!pagebusy &&1052 if (!pagebusy &&
@@ -1020,6 +1055,11 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) · 2 unmodified lines
1020 }1055 }
1021 1056
1022 schedule();1057 schedule();
1058
1059 /* Make sure to see the new wait index */
1060 smp_rmb();
1061 if (wait_index != work->wait_index)
1062 break;
1023 }1063 }
1024 1064
1025 if (full)1065 if (full)
@@ -2608,6 +2648,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, · 1582 unmodified lines
2608 /* Mark the rest of the page with padding */2648 /* Mark the rest of the page with padding */
2609 rb_event_set_padding(event);2649 rb_event_set_padding(event);
2610 2650
2651 /* Make sure the padding is visible before the write update */
2652 smp_wmb();
2653
2611 /* Set the write back to the previous setting */2654 /* Set the write back to the previous setting */
2612 local_sub(length, &tail_page->write);2655 local_sub(length, &tail_page->write);
2613 return;2656 return;
@@ -2619,6 +2662,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, · 5 unmodified lines
2619 /* time delta must be non zero */2662 /* time delta must be non zero */
2620 event->time_delta = 1;2663 event->time_delta = 1;
2621 2664
2665 /* Make sure the padding is visible before the tail_page->write update */
2666 smp_wmb();
2667
2622 /* Set write to end of buffer */2668 /* Set write to end of buffer */
2623 length = (tail + length) - BUF_PAGE_SIZE;2669 length = (tail + length) - BUF_PAGE_SIZE;
2624 local_sub(length, &tail_page->write);2670 local_sub(length, &tail_page->write);
@@ -4587,6 +4633,33 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) · 1962 unmodified lines
4587 arch_spin_unlock(&cpu_buffer->lock);4633 arch_spin_unlock(&cpu_buffer->lock);
4588 local_irq_restore(flags);4634 local_irq_restore(flags);
4589 4635
4636 /*
4637 * The writer has preempt disable, wait for it. But not forever
4638 * Although, 1 second is pretty much "forever"
4639 */
4640#define USECS_WAIT 1000000
4641 for (nr_loops = 0; nr_loops < USECS_WAIT; nr_loops++) {
4642 /* If the write is past the end of page, a writer is still updating it */
4643 if (likely(!reader || rb_page_write(reader) <= BUF_PAGE_SIZE))
4644 break;
4645
4646 udelay(1);
4647
4648 /* Get the latest version of the reader write value */
4649 smp_rmb();
4650 }
4651
4652 /* The writer is not moving forward? Something is wrong */
4653 if (RB_WARN_ON(cpu_buffer, nr_loops == USECS_WAIT))
4654 reader = NULL;
4655
4656 /*
4657 * Make sure we see any padding after the write update
4658 * (see rb_reset_tail())
4659 */
4660 smp_rmb();
4661
4662
4590 return reader;4663 return reader;
4591}4664}
4592 4665
@@ -5616,7 +5689,15 @@ int ring_buffer_read_page(struct trace_buffer *buffer, · 1023 unmodified lines
5616 unsigned int pos = 0;5689 unsigned int pos = 0;
5617 unsigned int size;5690 unsigned int size;
5618 5691
5619 if (full)5692 /*
5693 * If a full page is expected, this can still be returned
5694 * if there's been a previous partial read and the
5695 * rest of the page can be read and the commit page is off
5696 * the reader page.
5697 */
5698 if (full &&
5699 (!read || (len < (commit - read)) ||
5700 cpu_buffer->reader_page == cpu_buffer->commit_page))
5620 goto out_unlock;5701 goto out_unlock;
5621 5702
5622 if (len > (commit - read))5703 if (len > (commit - read))
kernel/trace/rv/monitors/wip/wip.c+4−4
@@ -16,7 +16,7 @@ · 15 unmodified lines
16 16
17#include "wip.h"17#include "wip.h"
18 18
19struct rv_monitor rv_wip;19static struct rv_monitor rv_wip;
20DECLARE_DA_MON_PER_CPU(wip, unsigned char);20DECLARE_DA_MON_PER_CPU(wip, unsigned char);
21 21
22static void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip)22static void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip)
@@ -60,7 +60,7 @@ static void disable_wip(void) · 37 unmodified lines
60 da_monitor_destroy_wip();60 da_monitor_destroy_wip();
61}61}
62 62
63struct rv_monitor rv_wip = {63static struct rv_monitor rv_wip = {
64 .name = "wip",64 .name = "wip",
65 .description = "wakeup in preemptive per-cpu testing monitor.",65 .description = "wakeup in preemptive per-cpu testing monitor.",
66 .enable = enable_wip,66 .enable = enable_wip,
@@ -69,13 +69,13 @@ struct rv_monitor rv_wip = { · 2 unmodified lines
69 .enabled = 0,69 .enabled = 0,
70};70};
71 71
72static int register_wip(void)72static int __init register_wip(void)
73{73{
74 rv_register_monitor(&rv_wip);74 rv_register_monitor(&rv_wip);
75 return 0;75 return 0;
76}76}
77 77
78static void unregister_wip(void)78static void __exit unregister_wip(void)
79{79{
80 rv_unregister_monitor(&rv_wip);80 rv_unregister_monitor(&rv_wip);
81}81}
kernel/trace/rv/monitors/wwnr/wwnr.c+4−4
@@ -15,7 +15,7 @@ · 14 unmodified lines
15 15
16#include "wwnr.h"16#include "wwnr.h"
17 17
18struct rv_monitor rv_wwnr;18static struct rv_monitor rv_wwnr;
19DECLARE_DA_MON_PER_TASK(wwnr, unsigned char);19DECLARE_DA_MON_PER_TASK(wwnr, unsigned char);
20 20
21static void handle_switch(void *data, bool preempt, struct task_struct *p,21static void handle_switch(void *data, bool preempt, struct task_struct *p,
@@ -59,7 +59,7 @@ static void disable_wwnr(void) · 37 unmodified lines
59 da_monitor_destroy_wwnr();59 da_monitor_destroy_wwnr();
60}60}
61 61
62struct rv_monitor rv_wwnr = {62static struct rv_monitor rv_wwnr = {
63 .name = "wwnr",63 .name = "wwnr",
64 .description = "wakeup while not running per-task testing model.",64 .description = "wakeup while not running per-task testing model.",
65 .enable = enable_wwnr,65 .enable = enable_wwnr,
@@ -68,13 +68,13 @@ struct rv_monitor rv_wwnr = { · 2 unmodified lines
68 .enabled = 0,68 .enabled = 0,
69};69};
70 70
71static int register_wwnr(void)71static int __init register_wwnr(void)
72{72{
73 rv_register_monitor(&rv_wwnr);73 rv_register_monitor(&rv_wwnr);
74 return 0;74 return 0;
75}75}
76 76
77static void unregister_wwnr(void)77static void __exit unregister_wwnr(void)
78{78{
79 rv_unregister_monitor(&rv_wwnr);79 rv_unregister_monitor(&rv_wwnr);
80}80}
kernel/trace/trace.c+73−5
@@ -1193,12 +1193,14 @@ void *tracing_cond_snapshot_data(struct trace_array *tr) · 1192 unmodified lines
1193{1193{
1194 void *cond_data = NULL;1194 void *cond_data = NULL;
1195 1195
1196 local_irq_disable();
1196 arch_spin_lock(&tr->max_lock);1197 arch_spin_lock(&tr->max_lock);
1197 1198
1198 if (tr->cond_snapshot)1199 if (tr->cond_snapshot)
1199 cond_data = tr->cond_snapshot->cond_data;1200 cond_data = tr->cond_snapshot->cond_data;
1200 1201
1201 arch_spin_unlock(&tr->max_lock);1202 arch_spin_unlock(&tr->max_lock);
1203 local_irq_enable();
1202 1204
1203 return cond_data;1205 return cond_data;
1204}1206}
@@ -1334,9 +1336,11 @@ int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data, · 129 unmodified lines
1334 goto fail_unlock;1336 goto fail_unlock;
1335 }1337 }
1336 1338
1339 local_irq_disable();
1337 arch_spin_lock(&tr->max_lock);1340 arch_spin_lock(&tr->max_lock);
1338 tr->cond_snapshot = cond_snapshot;1341 tr->cond_snapshot = cond_snapshot;
1339 arch_spin_unlock(&tr->max_lock);1342 arch_spin_unlock(&tr->max_lock);
1343 local_irq_enable();
1340 1344
1341 mutex_unlock(&trace_types_lock);1345 mutex_unlock(&trace_types_lock);
1342 1346
@@ -1363,6 +1367,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr) · 20 unmodified lines
1363{1367{
1364 int ret = 0;1368 int ret = 0;
1365 1369
1370 local_irq_disable();
1366 arch_spin_lock(&tr->max_lock);1371 arch_spin_lock(&tr->max_lock);
1367 1372
1368 if (!tr->cond_snapshot)1373 if (!tr->cond_snapshot)
@@ -1373,6 +1378,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr) · 4 unmodified lines
1373 }1378 }
1374 1379
1375 arch_spin_unlock(&tr->max_lock);1380 arch_spin_unlock(&tr->max_lock);
1381 local_irq_enable();
1376 1382
1377 return ret;1383 return ret;
1378}1384}
@@ -2200,6 +2206,11 @@ static size_t tgid_map_max; · 821 unmodified lines
2200 2206
2201#define SAVED_CMDLINES_DEFAULT 1282207#define SAVED_CMDLINES_DEFAULT 128
2202#define NO_CMDLINE_MAP UINT_MAX2208#define NO_CMDLINE_MAP UINT_MAX
2209/*
2210 * Preemption must be disabled before acquiring trace_cmdline_lock.
2211 * The various trace_arrays' max_lock must be acquired in a context
2212 * where interrupt is disabled.
2213 */
2203static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;2214static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
2204struct saved_cmdlines_buffer {2215struct saved_cmdlines_buffer {
2205 unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];2216 unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
@@ -2412,7 +2423,11 @@ static int trace_save_cmdline(struct task_struct *tsk) · 206 unmodified lines
2412 * the lock, but we also don't want to spin2423 * the lock, but we also don't want to spin
2413 * nor do we want to disable interrupts,2424 * nor do we want to disable interrupts,
2414 * so if we miss here, then better luck next time.2425 * so if we miss here, then better luck next time.
2426 *
2427 * This is called within the scheduler and wake up, so interrupts
2428 * had better been disabled and run queue lock been held.
2415 */2429 */
2430 lockdep_assert_preemption_disabled();
2416 if (!arch_spin_trylock(&trace_cmdline_lock))2431 if (!arch_spin_trylock(&trace_cmdline_lock))
2417 return 0;2432 return 0;
2418 2433
@@ -5890,9 +5905,11 @@ tracing_saved_cmdlines_size_read(struct file *filp, char __user *ubuf, · 3471 unmodified lines
5890 char buf[64];5905 char buf[64];
5891 int r;5906 int r;
5892 5907
5908 preempt_disable();
5893 arch_spin_lock(&trace_cmdline_lock);5909 arch_spin_lock(&trace_cmdline_lock);
5894 r = scnprintf(buf, sizeof(buf), "%u\n", savedcmd->cmdline_num);5910 r = scnprintf(buf, sizeof(buf), "%u\n", savedcmd->cmdline_num);
5895 arch_spin_unlock(&trace_cmdline_lock);5911 arch_spin_unlock(&trace_cmdline_lock);
5912 preempt_enable();
5896 5913
5897 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);5914 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
5898}5915}
@@ -5917,10 +5934,12 @@ static int tracing_resize_saved_cmdlines(unsigned int val) · 18 unmodified lines
5917 return -ENOMEM;5934 return -ENOMEM;
5918 }5935 }
5919 5936
5937 preempt_disable();
5920 arch_spin_lock(&trace_cmdline_lock);5938 arch_spin_lock(&trace_cmdline_lock);
5921 savedcmd_temp = savedcmd;5939 savedcmd_temp = savedcmd;
5922 savedcmd = s;5940 savedcmd = s;
5923 arch_spin_unlock(&trace_cmdline_lock);5941 arch_spin_unlock(&trace_cmdline_lock);
5942 preempt_enable();
5924 free_saved_cmdlines_buffer(savedcmd_temp);5943 free_saved_cmdlines_buffer(savedcmd_temp);
5925 5944
5926 return 0;5945 return 0;
@@ -6373,10 +6392,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) · 446 unmodified lines
6373 6392
6374#ifdef CONFIG_TRACER_SNAPSHOT6393#ifdef CONFIG_TRACER_SNAPSHOT
6375 if (t->use_max_tr) {6394 if (t->use_max_tr) {
6395 local_irq_disable();
6376 arch_spin_lock(&tr->max_lock);6396 arch_spin_lock(&tr->max_lock);
6377 if (tr->cond_snapshot)6397 if (tr->cond_snapshot)
6378 ret = -EBUSY;6398 ret = -EBUSY;
6379 arch_spin_unlock(&tr->max_lock);6399 arch_spin_unlock(&tr->max_lock);
6400 local_irq_enable();
6380 if (ret)6401 if (ret)
6381 goto out;6402 goto out;
6382 }6403 }
@@ -6407,12 +6428,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) · 24 unmodified lines
6407 if (tr->current_trace->reset)6428 if (tr->current_trace->reset)
6408 tr->current_trace->reset(tr);6429 tr->current_trace->reset(tr);
6409 6430
6431#ifdef CONFIG_TRACER_MAX_TRACE
6432 had_max_tr = tr->current_trace->use_max_tr;
6433
6410 /* Current trace needs to be nop_trace before synchronize_rcu */6434 /* Current trace needs to be nop_trace before synchronize_rcu */
6411 tr->current_trace = &nop_trace;6435 tr->current_trace = &nop_trace;
6412 6436
6413#ifdef CONFIG_TRACER_MAX_TRACE
6414 had_max_tr = tr->allocated_snapshot;
6415
6416 if (had_max_tr && !t->use_max_tr) {6437 if (had_max_tr && !t->use_max_tr) {
6417 /*6438 /*
6418 * We need to make sure that the update_max_tr sees that6439 * We need to make sure that the update_max_tr sees that
@@ -6425,11 +6446,13 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) · 6 unmodified lines
6425 free_snapshot(tr);6446 free_snapshot(tr);
6426 }6447 }
6427 6448
6428 if (t->use_max_tr && !had_max_tr) {6449 if (t->use_max_tr && !tr->allocated_snapshot) {
6429 ret = tracing_alloc_snapshot_instance(tr);6450 ret = tracing_alloc_snapshot_instance(tr);
6430 if (ret < 0)6451 if (ret < 0)
6431 goto out;6452 goto out;
6432 }6453 }
6454#else
6455 tr->current_trace = &nop_trace;
6433#endif6456#endif
6434 6457
6435 if (t->init) {6458 if (t->init) {
@@ -7436,10 +7459,12 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, · 1000 unmodified lines
7436 goto out;7459 goto out;
7437 }7460 }
7438 7461
7462 local_irq_disable();
7439 arch_spin_lock(&tr->max_lock);7463 arch_spin_lock(&tr->max_lock);
7440 if (tr->cond_snapshot)7464 if (tr->cond_snapshot)
7441 ret = -EBUSY;7465 ret = -EBUSY;
7442 arch_spin_unlock(&tr->max_lock);7466 arch_spin_unlock(&tr->max_lock);
7467 local_irq_enable();
7443 if (ret)7468 if (ret)
7444 goto out;7469 goto out;
7445 7470
@@ -8137,6 +8162,12 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) · 691 unmodified lines
8137 8162
8138 __trace_array_put(iter->tr);8163 __trace_array_put(iter->tr);
8139 8164
8165 iter->wait_index++;
8166 /* Make sure the waiters see the new wait_index */
8167 smp_wmb();
8168
8169 ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
8170
8140 if (info->spare)8171 if (info->spare)
8141 ring_buffer_free_read_page(iter->array_buffer->buffer,8172 ring_buffer_free_read_page(iter->array_buffer->buffer,
8142 info->spare_cpu, info->spare);8173 info->spare_cpu, info->spare);
@@ -8290,6 +8321,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, · 147 unmodified lines
8290 8321
8291 /* did we read anything? */8322 /* did we read anything? */
8292 if (!spd.nr_pages) {8323 if (!spd.nr_pages) {
8324 long wait_index;
8325
8293 if (ret)8326 if (ret)
8294 goto out;8327 goto out;
8295 8328
@@ -8297,10 +8330,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, · 1 unmodified line
8297 if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))8330 if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))
8298 goto out;8331 goto out;
8299 8332
8333 wait_index = READ_ONCE(iter->wait_index);
8334
8300 ret = wait_on_pipe(iter, iter->tr->buffer_percent);8335 ret = wait_on_pipe(iter, iter->tr->buffer_percent);
8301 if (ret)8336 if (ret)
8302 goto out;8337 goto out;
8303 8338
8339 /* No need to wait after waking up when tracing is off */
8340 if (!tracer_tracing_is_on(iter->tr))
8341 goto out;
8342
8343 /* Make sure we see the new wait_index */
8344 smp_rmb();
8345 if (wait_index != iter->wait_index)
8346 goto out;
8347
8304 goto again;8348 goto again;
8305 }8349 }
8306 8350
@@ -8311,12 +8355,34 @@ out: · 4 unmodified lines
8311 return ret;8355 return ret;
8312}8356}
8313 8357
8358/* An ioctl call with cmd 0 to the ring buffer file will wake up all waiters */
8359static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
8360{
8361 struct ftrace_buffer_info *info = file->private_data;
8362 struct trace_iterator *iter = &info->iter;
8363
8364 if (cmd)
8365 return -ENOIOCTLCMD;
8366
8367 mutex_lock(&trace_types_lock);
8368
8369 iter->wait_index++;
8370 /* Make sure the waiters see the new wait_index */
8371 smp_wmb();
8372
8373 ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
8374
8375 mutex_unlock(&trace_types_lock);
8376 return 0;
8377}
8378
8314static const struct file_operations tracing_buffers_fops = {8379static const struct file_operations tracing_buffers_fops = {
8315 .open = tracing_buffers_open,8380 .open = tracing_buffers_open,
8316 .read = tracing_buffers_read,8381 .read = tracing_buffers_read,
8317 .poll = tracing_buffers_poll,8382 .poll = tracing_buffers_poll,
8318 .release = tracing_buffers_release,8383 .release = tracing_buffers_release,
8319 .splice_read = tracing_buffers_splice_read,8384 .splice_read = tracing_buffers_splice_read,
8385 .unlocked_ioctl = tracing_buffers_ioctl,
8320 .llseek = no_llseek,8386 .llseek = no_llseek,
8321};8387};
8322 8388
@@ -9005,6 +9071,8 @@ rb_simple_write(struct file *filp, const char __user *ubuf, · 682 unmodified lines
9005 tracer_tracing_off(tr);9071 tracer_tracing_off(tr);
9006 if (tr->current_trace->stop)9072 if (tr->current_trace->stop)
9007 tr->current_trace->stop(tr);9073 tr->current_trace->stop(tr);
9074 /* Wake up any waiters */
9075 ring_buffer_wake_waiters(buffer, RING_BUFFER_ALL_CPUS);
9008 }9076 }
9009 mutex_unlock(&trace_types_lock);9077 mutex_unlock(&trace_types_lock);
9010 }9078 }
@@ -10091,7 +10159,7 @@ __init static int tracer_alloc_buffers(void) · 1080 unmodified lines
10091 * buffer. The memory will be removed once the "instance" is removed.10159 * buffer. The memory will be removed once the "instance" is removed.
10092 */10160 */
10093 ret = cpuhp_setup_state_multi(CPUHP_TRACE_RB_PREPARE,10161 ret = cpuhp_setup_state_multi(CPUHP_TRACE_RB_PREPARE,
10094 "trace/RB:preapre", trace_rb_cpu_prepare,10162 "trace/RB:prepare", trace_rb_cpu_prepare,
10095 NULL);10163 NULL);
10096 if (ret < 0)10164 if (ret < 0)
10097 goto out_free_cpumask;10165 goto out_free_cpumask;
kernel/trace/trace.h+0−13
@@ -1435,8 +1435,6 @@ event_trigger_unlock_commit(struct trace_event_file *file, · 1434 unmodified lines
1435struct filter_pred;1435struct filter_pred;
1436struct regex;1436struct regex;
1437 1437
1438typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event);
1439
1440typedef int (*regex_match_func)(char *str, struct regex *r, int len);1438typedef int (*regex_match_func)(char *str, struct regex *r, int len);
1441 1439
1442enum regex_type {1440enum regex_type {
@@ -1455,17 +1453,6 @@ struct regex { · 12 unmodified lines
1455 regex_match_func match;1453 regex_match_func match;
1456};1454};
1457 1455
1458struct filter_pred {
1459 filter_pred_fn_t fn;
1460 u64 val;
1461 struct regex regex;
1462 unsigned short *ops;
1463 struct ftrace_event_field *field;
1464 int offset;
1465 int not;
1466 int op;
1467};
1468
1469static inline bool is_string_field(struct ftrace_event_field *field)1456static inline bool is_string_field(struct ftrace_event_field *field)
1470{1457{
1471 return field->filter_type == FILTER_DYN_STRING ||1458 return field->filter_type == FILTER_DYN_STRING ||
kernel/trace/trace_benchmark.c+1−1
@@ -51,7 +51,7 @@ static void trace_do_benchmark(void) · 50 unmodified lines
51 51
52 local_irq_disable();52 local_irq_disable();
53 start = trace_clock_local();53 start = trace_clock_local();
54 trace_benchmark_event(bm_str);54 trace_benchmark_event(bm_str, bm_last);
55 stop = trace_clock_local();55 stop = trace_clock_local();
56 local_irq_enable();56 local_irq_enable();
57 57
kernel/trace/trace_benchmark.h+5−3
@@ -14,19 +14,21 @@ extern void trace_benchmark_unreg(void); · 13 unmodified lines
14 14
15TRACE_EVENT_FN(benchmark_event,15TRACE_EVENT_FN(benchmark_event,
16 16
17 TP_PROTO(const char *str),17 TP_PROTO(const char *str, u64 delta),
18 18
19 TP_ARGS(str),19 TP_ARGS(str, delta),
20 20
21 TP_STRUCT__entry(21 TP_STRUCT__entry(
22 __array( char, str, BENCHMARK_EVENT_STRLEN )22 __array( char, str, BENCHMARK_EVENT_STRLEN )
23 __field( u64, delta)
23 ),24 ),
24 25
25 TP_fast_assign(26 TP_fast_assign(
26 memcpy(__entry->str, str, BENCHMARK_EVENT_STRLEN);27 memcpy(__entry->str, str, BENCHMARK_EVENT_STRLEN);
28 __entry->delta = delta;
27 ),29 ),
28 30
29 TP_printk("%s", __entry->str),31 TP_printk("%s delta=%llu", __entry->str, __entry->delta),
30 32
31 trace_benchmark_reg, trace_benchmark_unreg33 trace_benchmark_reg, trace_benchmark_unreg
32);34);
kernel/trace/trace_eprobe.c+97−10
@@ -26,6 +26,9 @@ struct trace_eprobe { · 25 unmodified lines
26 /* tracepoint event */26 /* tracepoint event */
27 const char *event_name;27 const char *event_name;
28 28
29 /* filter string for the tracepoint */
30 char *filter_str;
31
29 struct trace_event_call *event;32 struct trace_event_call *event;
30 33
31 struct dyn_event devent;34 struct dyn_event devent;
@@ -664,14 +667,15 @@ static struct event_trigger_data * · 632 unmodified lines
664new_eprobe_trigger(struct trace_eprobe *ep, struct trace_event_file *file)667new_eprobe_trigger(struct trace_eprobe *ep, struct trace_event_file *file)
665{668{
666 struct event_trigger_data *trigger;669 struct event_trigger_data *trigger;
670 struct event_filter *filter = NULL;
667 struct eprobe_data *edata;671 struct eprobe_data *edata;
672 int ret;
668 673
669 edata = kzalloc(sizeof(*edata), GFP_KERNEL);674 edata = kzalloc(sizeof(*edata), GFP_KERNEL);
670 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);675 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
671 if (!trigger || !edata) {676 if (!trigger || !edata) {
672 kfree(edata);677 ret = -ENOMEM;
673 kfree(trigger);678 goto error;
674 return ERR_PTR(-ENOMEM);
675 }679 }
676 680
677 trigger->flags = EVENT_TRIGGER_FL_PROBE;681 trigger->flags = EVENT_TRIGGER_FL_PROBE;
@@ -686,13 +690,25 @@ new_eprobe_trigger(struct trace_eprobe *ep, struct trace_event_file *file) · 8 unmodified lines
686 trigger->cmd_ops = &event_trigger_cmd;690 trigger->cmd_ops = &event_trigger_cmd;
687 691
688 INIT_LIST_HEAD(&trigger->list);692 INIT_LIST_HEAD(&trigger->list);
689 RCU_INIT_POINTER(trigger->filter, NULL);693
694 if (ep->filter_str) {
695 ret = create_event_filter(file->tr, file->event_call,
696 ep->filter_str, false, &filter);
697 if (ret)
698 goto error;
699 }
700 RCU_INIT_POINTER(trigger->filter, filter);
690 701
691 edata->file = file;702 edata->file = file;
692 edata->ep = ep;703 edata->ep = ep;
693 trigger->private_data = edata;704 trigger->private_data = edata;
694 705
695 return trigger;706 return trigger;
707error:
708 free_event_filter(filter);
709 kfree(edata);
710 kfree(trigger);
711 return ERR_PTR(ret);
696}712}
697 713
698static int enable_eprobe(struct trace_eprobe *ep,714static int enable_eprobe(struct trace_eprobe *ep,
@@ -726,6 +742,7 @@ static int disable_eprobe(struct trace_eprobe *ep, · 27 unmodified lines
726{742{
727 struct event_trigger_data *trigger = NULL, *iter;743 struct event_trigger_data *trigger = NULL, *iter;
728 struct trace_event_file *file;744 struct trace_event_file *file;
745 struct event_filter *filter;
729 struct eprobe_data *edata;746 struct eprobe_data *edata;
730 747
731 file = find_event_file(tr, ep->event_system, ep->event_name);748 file = find_event_file(tr, ep->event_system, ep->event_name);
@@ -752,6 +769,10 @@ static int disable_eprobe(struct trace_eprobe *ep, · 20 unmodified lines
752 /* Make sure nothing is using the edata or trigger */769 /* Make sure nothing is using the edata or trigger */
753 tracepoint_synchronize_unregister();770 tracepoint_synchronize_unregister();
754 771
772 filter = rcu_access_pointer(trigger->filter);
773
774 if (filter)
775 free_event_filter(filter);
755 kfree(edata);776 kfree(edata);
756 kfree(trigger);777 kfree(trigger);
757 778
@@ -927,12 +948,62 @@ static int trace_eprobe_tp_update_arg(struct trace_eprobe *ep, const char *argv[ · 169 unmodified lines
927 return ret;948 return ret;
928}949}
929 950
951static int trace_eprobe_parse_filter(struct trace_eprobe *ep, int argc, const char *argv[])
952{
953 struct event_filter *dummy;
954 int i, ret, len = 0;
955 char *p;
956
957 if (argc == 0) {
958 trace_probe_log_err(0, NO_EP_FILTER);
959 return -EINVAL;
960 }
961
962 /* Recover the filter string */
963 for (i = 0; i < argc; i++)
964 len += strlen(argv[i]) + 1;
965
966 ep->filter_str = kzalloc(len, GFP_KERNEL);
967 if (!ep->filter_str)
968 return -ENOMEM;
969
970 p = ep->filter_str;
971 for (i = 0; i < argc; i++) {
972 ret = snprintf(p, len, "%s ", argv[i]);
973 if (ret < 0)
974 goto error;
975 if (ret > len) {
976 ret = -E2BIG;
977 goto error;
978 }
979 p += ret;
980 len -= ret;
981 }
982 p[-1] = '\0';
983
984 /*
985 * Ensure the filter string can be parsed correctly. Note, this
986 * filter string is for the original event, not for the eprobe.
987 */
988 ret = create_event_filter(top_trace_array(), ep->event, ep->filter_str,
989 true, &dummy);
990 free_event_filter(dummy);
991 if (ret)
992 goto error;
993
994 return 0;
995error:
996 kfree(ep->filter_str);
997 ep->filter_str = NULL;
998 return ret;
999}
1000
930static int __trace_eprobe_create(int argc, const char *argv[])1001static int __trace_eprobe_create(int argc, const char *argv[])
931{1002{
932 /*1003 /*
933 * Argument syntax:1004 * Argument syntax:
934 * e[:[GRP/][ENAME]] SYSTEM.EVENT [FETCHARGS]1005 * e[:[GRP/][ENAME]] SYSTEM.EVENT [FETCHARGS] [if FILTER]
935 * Fetch args:1006 * Fetch args (no space):
936 * <name>=$<field>[:TYPE]1007 * <name>=$<field>[:TYPE]
937 */1008 */
938 const char *event = NULL, *group = EPROBE_EVENT_SYSTEM;1009 const char *event = NULL, *group = EPROBE_EVENT_SYSTEM;
@@ -942,8 +1013,8 @@ static int __trace_eprobe_create(int argc, const char *argv[]) · 3 unmodified lines
942 char buf1[MAX_EVENT_NAME_LEN];1013 char buf1[MAX_EVENT_NAME_LEN];
943 char buf2[MAX_EVENT_NAME_LEN];1014 char buf2[MAX_EVENT_NAME_LEN];
944 char gbuf[MAX_EVENT_NAME_LEN];1015 char gbuf[MAX_EVENT_NAME_LEN];
945 int ret = 0;1016 int ret = 0, filter_idx = 0;
946 int i;1017 int i, filter_cnt;
947 1018
948 if (argc < 2 || argv[0][0] != 'e')1019 if (argc < 2 || argv[0][0] != 'e')
949 return -ECANCELED;1020 return -ECANCELED;
@@ -968,11 +1039,19 @@ static int __trace_eprobe_create(int argc, const char *argv[]) · 18 unmodified lines
968 }1039 }
969 1040
970 if (!event) {1041 if (!event) {
971 strscpy(buf1, argv[1], MAX_EVENT_NAME_LEN);1042 strscpy(buf1, sys_event, MAX_EVENT_NAME_LEN);
972 sanitize_event_name(buf1);
973 event = buf1;1043 event = buf1;
974 }1044 }
975 1045
1046 for (i = 2; i < argc; i++) {
1047 if (!strcmp(argv[i], "if")) {
1048 filter_idx = i + 1;
1049 filter_cnt = argc - filter_idx;
1050 argc = i;
1051 break;
1052 }
1053 }
1054
976 mutex_lock(&event_mutex);1055 mutex_lock(&event_mutex);
977 event_call = find_and_get_event(sys_name, sys_event);1056 event_call = find_and_get_event(sys_name, sys_event);
978 ep = alloc_event_probe(group, event, event_call, argc - 2);1057 ep = alloc_event_probe(group, event, event_call, argc - 2);
@@ -988,6 +1067,14 @@ static int __trace_eprobe_create(int argc, const char *argv[]) · 9 unmodified lines
988 goto error;1067 goto error;
989 }1068 }
990 1069
1070 if (filter_idx) {
1071 trace_probe_log_set_index(filter_idx);
1072 ret = trace_eprobe_parse_filter(ep, filter_cnt, argv + filter_idx);
1073 if (ret)
1074 goto parse_error;
1075 } else
1076 ep->filter_str = NULL;
1077
991 argc -= 2; argv += 2;1078 argc -= 2; argv += 2;
992 /* parse arguments */1079 /* parse arguments */
993 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {1080 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
kernel/trace/trace_events_filter.c+168−71
@@ -43,6 +43,42 @@ enum filter_op_ids { OPS }; · 42 unmodified lines
43 43
44static const char * ops[] = { OPS };44static const char * ops[] = { OPS };
45 45
46enum filter_pred_fn {
47 FILTER_PRED_FN_NOP,
48 FILTER_PRED_FN_64,
49 FILTER_PRED_FN_S64,
50 FILTER_PRED_FN_U64,
51 FILTER_PRED_FN_32,
52 FILTER_PRED_FN_S32,
53 FILTER_PRED_FN_U32,
54 FILTER_PRED_FN_16,
55 FILTER_PRED_FN_S16,
56 FILTER_PRED_FN_U16,
57 FILTER_PRED_FN_8,
58 FILTER_PRED_FN_S8,
59 FILTER_PRED_FN_U8,
60 FILTER_PRED_FN_COMM,
61 FILTER_PRED_FN_STRING,
62 FILTER_PRED_FN_STRLOC,
63 FILTER_PRED_FN_STRRELLOC,
64 FILTER_PRED_FN_PCHAR_USER,
65 FILTER_PRED_FN_PCHAR,
66 FILTER_PRED_FN_CPU,
67 FILTER_PRED_FN_,
68 FILTER_PRED_TEST_VISITED,
69};
70
71struct filter_pred {
72 enum filter_pred_fn fn_num;
73 u64 val;
74 struct regex regex;
75 unsigned short *ops;
76 struct ftrace_event_field *field;
77 int offset;
78 int not;
79 int op;
80};
81
46/*82/*
47 * pred functions are OP_LE, OP_LT, OP_GE, OP_GT, and OP_BAND83 * pred functions are OP_LE, OP_LT, OP_GE, OP_GT, and OP_BAND
48 * pred_funcs_##type below must match the order of them above.84 * pred_funcs_##type below must match the order of them above.
@@ -590,44 +626,48 @@ out_free: · 541 unmodified lines
590 return ERR_PTR(ret);626 return ERR_PTR(ret);
591}627}
592 628
629enum pred_cmp_types {
630 PRED_CMP_TYPE_NOP,
631 PRED_CMP_TYPE_LT,
632 PRED_CMP_TYPE_LE,
633 PRED_CMP_TYPE_GT,
634 PRED_CMP_TYPE_GE,
635 PRED_CMP_TYPE_BAND,
636};
637
593#define DEFINE_COMPARISON_PRED(type) \638#define DEFINE_COMPARISON_PRED(type) \
594static int filter_pred_LT_##type(struct filter_pred *pred, void *event) \639static int filter_pred_##type(struct filter_pred *pred, void *event) \
595{ \
596 type *addr = (type *)(event + pred->offset); \
597 type val = (type)pred->val; \
598 return *addr < val; \
599} \
600static int filter_pred_LE_##type(struct filter_pred *pred, void *event) \
601{ \
602 type *addr = (type *)(event + pred->offset); \
603 type val = (type)pred->val; \
604 return *addr <= val; \
605} \
606static int filter_pred_GT_##type(struct filter_pred *pred, void *event) \
607{ \640{ \
608 type *addr = (type *)(event + pred->offset); \641 switch (pred->op) { \
609 type val = (type)pred->val; \642 case OP_LT: { \
610 return *addr > val; \643 type *addr = (type *)(event + pred->offset); \
611} \644 type val = (type)pred->val; \
612static int filter_pred_GE_##type(struct filter_pred *pred, void *event) \645 return *addr < val; \
613{ \646 } \
614 type *addr = (type *)(event + pred->offset); \647 case OP_LE: { \
615 type val = (type)pred->val; \648 type *addr = (type *)(event + pred->offset); \
616 return *addr >= val; \649 type val = (type)pred->val; \
617} \650 return *addr <= val; \
618static int filter_pred_BAND_##type(struct filter_pred *pred, void *event) \651 } \
619{ \652 case OP_GT: { \
620 type *addr = (type *)(event + pred->offset); \653 type *addr = (type *)(event + pred->offset); \
621 type val = (type)pred->val; \654 type val = (type)pred->val; \
622 return !!(*addr & val); \655 return *addr > val; \
623} \656 } \
624static const filter_pred_fn_t pred_funcs_##type[] = { \657 case OP_GE: { \
625 filter_pred_LE_##type, \658 type *addr = (type *)(event + pred->offset); \
626 filter_pred_LT_##type, \659 type val = (type)pred->val; \
627 filter_pred_GE_##type, \660 return *addr >= val; \
628 filter_pred_GT_##type, \661 } \
629 filter_pred_BAND_##type, \662 case OP_BAND: { \
630};663 type *addr = (type *)(event + pred->offset); \
664 type val = (type)pred->val; \
665 return !!(*addr & val); \
666 } \
667 default: \
668 return 0; \
669 } \
670}
631 671
632#define DEFINE_EQUALITY_PRED(size) \672#define DEFINE_EQUALITY_PRED(size) \
633static int filter_pred_##size(struct filter_pred *pred, void *event) \673static int filter_pred_##size(struct filter_pred *pred, void *event) \
@@ -836,11 +876,6 @@ static int filter_pred_comm(struct filter_pred *pred, void *event) · 202 unmodified lines
836 return cmp ^ pred->not;876 return cmp ^ pred->not;
837}877}
838 878
839static int filter_pred_none(struct filter_pred *pred, void *event)
840{
841 return 0;
842}
843
844/*879/*
845 * regex_match_foo - Basic regex callbacks880 * regex_match_foo - Basic regex callbacks
846 *881 *
@@ -986,6 +1021,19 @@ static void filter_build_regex(struct filter_pred *pred) · 139 unmodified lines
986 }1021 }
987}1022}
988 1023
1024
1025#ifdef CONFIG_FTRACE_STARTUP_TEST
1026static int test_pred_visited_fn(struct filter_pred *pred, void *event);
1027#else
1028static int test_pred_visited_fn(struct filter_pred *pred, void *event)
1029{
1030 return 0;
1031}
1032#endif
1033
1034
1035static int filter_pred_fn_call(struct filter_pred *pred, void *event);
1036
989/* return 1 if event matches, 0 otherwise (discard) */1037/* return 1 if event matches, 0 otherwise (discard) */
990int filter_match_preds(struct event_filter *filter, void *rec)1038int filter_match_preds(struct event_filter *filter, void *rec)
991{1039{
@@ -1003,7 +1051,7 @@ int filter_match_preds(struct event_filter *filter, void *rec) · 11 unmodified lines
1003 1051
1004 for (i = 0; prog[i].pred; i++) {1052 for (i = 0; prog[i].pred; i++) {
1005 struct filter_pred *pred = prog[i].pred;1053 struct filter_pred *pred = prog[i].pred;
1006 int match = pred->fn(pred, rec);1054 int match = filter_pred_fn_call(pred, rec);
1007 if (match == prog[i].when_to_branch)1055 if (match == prog[i].when_to_branch)
1008 i = prog[i].target;1056 i = prog[i].target;
1009 }1057 }
@@ -1189,10 +1237,10 @@ int filter_assign_type(const char *type) · 179 unmodified lines
1189 return FILTER_OTHER;1237 return FILTER_OTHER;
1190}1238}
1191 1239
1192static filter_pred_fn_t select_comparison_fn(enum filter_op_ids op,1240static enum filter_pred_fn select_comparison_fn(enum filter_op_ids op,
1193 int field_size, int field_is_signed)1241 int field_size, int field_is_signed)
1194{1242{
1195 filter_pred_fn_t fn = NULL;1243 enum filter_pred_fn fn = FILTER_PRED_FN_NOP;
1196 int pred_func_index = -1;1244 int pred_func_index = -1;
1197 1245
1198 switch (op) {1246 switch (op) {
@@ -1201,50 +1249,99 @@ static filter_pred_fn_t select_comparison_fn(enum filter_op_ids op, · 2 unmodified lines
1201 break;1249 break;
1202 default:1250 default:
1203 if (WARN_ON_ONCE(op < PRED_FUNC_START))1251 if (WARN_ON_ONCE(op < PRED_FUNC_START))
1204 return NULL;1252 return fn;
1205 pred_func_index = op - PRED_FUNC_START;1253 pred_func_index = op - PRED_FUNC_START;
1206 if (WARN_ON_ONCE(pred_func_index > PRED_FUNC_MAX))1254 if (WARN_ON_ONCE(pred_func_index > PRED_FUNC_MAX))
1207 return NULL;1255 return fn;
1208 }1256 }
1209 1257
1210 switch (field_size) {1258 switch (field_size) {
1211 case 8:1259 case 8:
1212 if (pred_func_index < 0)1260 if (pred_func_index < 0)
1213 fn = filter_pred_64;1261 fn = FILTER_PRED_FN_64;
1214 else if (field_is_signed)1262 else if (field_is_signed)
1215 fn = pred_funcs_s64[pred_func_index];1263 fn = FILTER_PRED_FN_S64;
1216 else1264 else
1217 fn = pred_funcs_u64[pred_func_index];1265 fn = FILTER_PRED_FN_U64;
1218 break;1266 break;
1219 case 4:1267 case 4:
1220 if (pred_func_index < 0)1268 if (pred_func_index < 0)
1221 fn = filter_pred_32;1269 fn = FILTER_PRED_FN_32;
1222 else if (field_is_signed)1270 else if (field_is_signed)
1223 fn = pred_funcs_s32[pred_func_index];1271 fn = FILTER_PRED_FN_S32;
1224 else1272 else
1225 fn = pred_funcs_u32[pred_func_index];1273 fn = FILTER_PRED_FN_U32;
1226 break;1274 break;
1227 case 2:1275 case 2:
1228 if (pred_func_index < 0)1276 if (pred_func_index < 0)
1229 fn = filter_pred_16;1277 fn = FILTER_PRED_FN_16;
1230 else if (field_is_signed)1278 else if (field_is_signed)
1231 fn = pred_funcs_s16[pred_func_index];1279 fn = FILTER_PRED_FN_S16;
1232 else1280 else
1233 fn = pred_funcs_u16[pred_func_index];1281 fn = FILTER_PRED_FN_U16;
1234 break;1282 break;
1235 case 1:1283 case 1:
1236 if (pred_func_index < 0)1284 if (pred_func_index < 0)
1237 fn = filter_pred_8;1285 fn = FILTER_PRED_FN_8;
1238 else if (field_is_signed)1286 else if (field_is_signed)
1239 fn = pred_funcs_s8[pred_func_index];1287 fn = FILTER_PRED_FN_S8;
1240 else1288 else
1241 fn = pred_funcs_u8[pred_func_index];1289 fn = FILTER_PRED_FN_U8;
1242 break;1290 break;
1243 }1291 }
1244 1292
1245 return fn;1293 return fn;
1246}1294}
1247 1295
1296
1297static int filter_pred_fn_call(struct filter_pred *pred, void *event)
1298{
1299 switch (pred->fn_num) {
1300 case FILTER_PRED_FN_64:
1301 return filter_pred_64(pred, event);
1302 case FILTER_PRED_FN_S64:
1303 return filter_pred_s64(pred, event);
1304 case FILTER_PRED_FN_U64:
1305 return filter_pred_u64(pred, event);
1306 case FILTER_PRED_FN_32:
1307 return filter_pred_32(pred, event);
1308 case FILTER_PRED_FN_S32:
1309 return filter_pred_s32(pred, event);
1310 case FILTER_PRED_FN_U32:
1311 return filter_pred_u32(pred, event);
1312 case FILTER_PRED_FN_16:
1313 return filter_pred_16(pred, event);
1314 case FILTER_PRED_FN_S16:
1315 return filter_pred_s16(pred, event);
1316 case FILTER_PRED_FN_U16:
1317 return filter_pred_u16(pred, event);
1318 case FILTER_PRED_FN_8:
1319 return filter_pred_8(pred, event);
1320 case FILTER_PRED_FN_S8:
1321 return filter_pred_s8(pred, event);
1322 case FILTER_PRED_FN_U8:
1323 return filter_pred_u8(pred, event);
1324 case FILTER_PRED_FN_COMM:
1325 return filter_pred_comm(pred, event);
1326 case FILTER_PRED_FN_STRING:
1327 return filter_pred_string(pred, event);
1328 case FILTER_PRED_FN_STRLOC:
1329 return filter_pred_strloc(pred, event);
1330 case FILTER_PRED_FN_STRRELLOC:
1331 return filter_pred_strrelloc(pred, event);
1332 case FILTER_PRED_FN_PCHAR_USER:
1333 return filter_pred_pchar_user(pred, event);
1334 case FILTER_PRED_FN_PCHAR:
1335 return filter_pred_pchar(pred, event);
1336 case FILTER_PRED_FN_CPU:
1337 return filter_pred_cpu(pred, event);
1338 case FILTER_PRED_TEST_VISITED:
1339 return test_pred_visited_fn(pred, event);
1340 default:
1341 return 0;
1342 }
1343}
1344
1248/* Called when a predicate is encountered by predicate_parse() */1345/* Called when a predicate is encountered by predicate_parse() */
1249static int parse_pred(const char *str, void *data,1346static int parse_pred(const char *str, void *data,
1250 int pos, struct filter_parse_error *pe,1347 int pos, struct filter_parse_error *pe,
@@ -1338,7 +1435,7 @@ static int parse_pred(const char *str, void *data, · 87 unmodified lines
1338 parse_error(pe, FILT_ERR_IP_FIELD_ONLY, pos + i);1435 parse_error(pe, FILT_ERR_IP_FIELD_ONLY, pos + i);
1339 goto err_free;1436 goto err_free;
1340 }1437 }
1341 pred->fn = filter_pred_none;1438 pred->fn_num = FILTER_PRED_FN_NOP;
1342 1439
1343 /*1440 /*
1344 * Quotes are not required, but if they exist then we need1441 * Quotes are not required, but if they exist then we need
@@ -1416,16 +1513,16 @@ static int parse_pred(const char *str, void *data, · 71 unmodified lines
1416 filter_build_regex(pred);1513 filter_build_regex(pred);
1417 1514
1418 if (field->filter_type == FILTER_COMM) {1515 if (field->filter_type == FILTER_COMM) {
1419 pred->fn = filter_pred_comm;1516 pred->fn_num = FILTER_PRED_FN_COMM;
1420 1517
1421 } else if (field->filter_type == FILTER_STATIC_STRING) {1518 } else if (field->filter_type == FILTER_STATIC_STRING) {
1422 pred->fn = filter_pred_string;1519 pred->fn_num = FILTER_PRED_FN_STRING;
1423 pred->regex.field_len = field->size;1520 pred->regex.field_len = field->size;
1424 1521
1425 } else if (field->filter_type == FILTER_DYN_STRING) {1522 } else if (field->filter_type == FILTER_DYN_STRING) {
1426 pred->fn = filter_pred_strloc;1523 pred->fn_num = FILTER_PRED_FN_STRLOC;
1427 } else if (field->filter_type == FILTER_RDYN_STRING)1524 } else if (field->filter_type == FILTER_RDYN_STRING)
1428 pred->fn = filter_pred_strrelloc;1525 pred->fn_num = FILTER_PRED_FN_STRRELLOC;
1429 else {1526 else {
1430 1527
1431 if (!ustring_per_cpu) {1528 if (!ustring_per_cpu) {
@@ -1436,9 +1533,9 @@ static int parse_pred(const char *str, void *data, · 4 unmodified lines
1436 }1533 }
1437 1534
1438 if (ustring)1535 if (ustring)
1439 pred->fn = filter_pred_pchar_user;1536 pred->fn_num = FILTER_PRED_FN_PCHAR_USER;
1440 else1537 else
1441 pred->fn = filter_pred_pchar;1538 pred->fn_num = FILTER_PRED_FN_PCHAR;
1442 }1539 }
1443 /* go past the last quote */1540 /* go past the last quote */
1444 i++;1541 i++;
@@ -1486,10 +1583,10 @@ static int parse_pred(const char *str, void *data, · 41 unmodified lines
1486 pred->val = val;1583 pred->val = val;
1487 1584
1488 if (field->filter_type == FILTER_CPU)1585 if (field->filter_type == FILTER_CPU)
1489 pred->fn = filter_pred_cpu;1586 pred->fn_num = FILTER_PRED_FN_CPU;
1490 else {1587 else {
1491 pred->fn = select_comparison_fn(pred->op, field->size,1588 pred->fn_num = select_comparison_fn(pred->op, field->size,
1492 field->is_signed);1589 field->is_signed);
1493 if (pred->op == OP_NE)1590 if (pred->op == OP_NE)
1494 pred->not = 1;1591 pred->not = 1;
1495 }1592 }
@@ -2296,7 +2393,7 @@ static void update_pred_fn(struct event_filter *filter, char *fields) · 800 unmodified lines
2296 struct filter_pred *pred = prog[i].pred;2393 struct filter_pred *pred = prog[i].pred;
2297 struct ftrace_event_field *field = pred->field;2394 struct ftrace_event_field *field = pred->field;
2298 2395
2299 WARN_ON_ONCE(!pred->fn);2396 WARN_ON_ONCE(pred->fn_num == FILTER_PRED_FN_NOP);
2300 2397
2301 if (!field) {2398 if (!field) {
2302 WARN_ONCE(1, "all leafs should have field defined %d", i);2399 WARN_ONCE(1, "all leafs should have field defined %d", i);
@@ -2306,7 +2403,7 @@ static void update_pred_fn(struct event_filter *filter, char *fields) · 3 unmodified lines
2306 if (!strchr(fields, *field->name))2403 if (!strchr(fields, *field->name))
2307 continue;2404 continue;
2308 2405
2309 pred->fn = test_pred_visited_fn;2406 pred->fn_num = FILTER_PRED_TEST_VISITED;
2310 }2407 }
2311}2408}
2312 2409
kernel/trace/trace_events_hist.c+169−77
@@ -104,6 +104,38 @@ enum field_op_id { · 103 unmodified lines
104 FIELD_OP_MULT,104 FIELD_OP_MULT,
105};105};
106 106
107enum hist_field_fn {
108 HIST_FIELD_FN_NOP,
109 HIST_FIELD_FN_VAR_REF,
110 HIST_FIELD_FN_COUNTER,
111 HIST_FIELD_FN_CONST,
112 HIST_FIELD_FN_LOG2,
113 HIST_FIELD_FN_BUCKET,
114 HIST_FIELD_FN_TIMESTAMP,
115 HIST_FIELD_FN_CPU,
116 HIST_FIELD_FN_STRING,
117 HIST_FIELD_FN_DYNSTRING,
118 HIST_FIELD_FN_RELDYNSTRING,
119 HIST_FIELD_FN_PSTRING,
120 HIST_FIELD_FN_S64,
121 HIST_FIELD_FN_U64,
122 HIST_FIELD_FN_S32,
123 HIST_FIELD_FN_U32,
124 HIST_FIELD_FN_S16,
125 HIST_FIELD_FN_U16,
126 HIST_FIELD_FN_S8,
127 HIST_FIELD_FN_U8,
128 HIST_FIELD_FN_UMINUS,
129 HIST_FIELD_FN_MINUS,
130 HIST_FIELD_FN_PLUS,
131 HIST_FIELD_FN_DIV,
132 HIST_FIELD_FN_MULT,
133 HIST_FIELD_FN_DIV_POWER2,
134 HIST_FIELD_FN_DIV_NOT_POWER2,
135 HIST_FIELD_FN_DIV_MULT_SHIFT,
136 HIST_FIELD_FN_EXECNAME,
137};
138
107/*139/*
108 * A hist_var (histogram variable) contains variable information for140 * A hist_var (histogram variable) contains variable information for
109 * hist_fields having the HIST_FIELD_FL_VAR or HIST_FIELD_FL_VAR_REF141 * hist_fields having the HIST_FIELD_FL_VAR or HIST_FIELD_FL_VAR_REF
@@ -123,15 +155,15 @@ struct hist_var { · 13 unmodified lines
123struct hist_field {155struct hist_field {
124 struct ftrace_event_field *field;156 struct ftrace_event_field *field;
125 unsigned long flags;157 unsigned long flags;
126 hist_field_fn_t fn;
127 unsigned int ref;
128 unsigned int size;
129 unsigned int offset;
130 unsigned int is_signed;
131 unsigned long buckets;158 unsigned long buckets;
132 const char *type;159 const char *type;
133 struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];160 struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];
134 struct hist_trigger_data *hist_data;161 struct hist_trigger_data *hist_data;
162 enum hist_field_fn fn_num;
163 unsigned int ref;
164 unsigned int size;
165 unsigned int offset;
166 unsigned int is_signed;
135 167
136 /*168 /*
137 * Variable fields contain variable-specific info in var.169 * Variable fields contain variable-specific info in var.
@@ -166,14 +198,11 @@ struct hist_field { · 28 unmodified lines
166 u64 div_multiplier;198 u64 div_multiplier;
167};199};
168 200
169static u64 hist_field_none(struct hist_field *field,201static u64 hist_fn_call(struct hist_field *hist_field,
170 struct tracing_map_elt *elt,202 struct tracing_map_elt *elt,
171 struct trace_buffer *buffer,203 struct trace_buffer *buffer,
172 struct ring_buffer_event *rbe,204 struct ring_buffer_event *rbe,
173 void *event)205 void *event);
174{
175 return 0;
176}
177 206
178static u64 hist_field_const(struct hist_field *field,207static u64 hist_field_const(struct hist_field *field,
179 struct tracing_map_elt *elt,208 struct tracing_map_elt *elt,
@@ -250,7 +279,7 @@ static u64 hist_field_log2(struct hist_field *hist_field, · 70 unmodified lines
250{279{
251 struct hist_field *operand = hist_field->operands[0];280 struct hist_field *operand = hist_field->operands[0];
252 281
253 u64 val = operand->fn(operand, elt, buffer, rbe, event);282 u64 val = hist_fn_call(operand, elt, buffer, rbe, event);
254 283
255 return (u64) ilog2(roundup_pow_of_two(val));284 return (u64) ilog2(roundup_pow_of_two(val));
256}285}
@@ -264,7 +293,7 @@ static u64 hist_field_bucket(struct hist_field *hist_field, · 7 unmodified lines
264 struct hist_field *operand = hist_field->operands[0];293 struct hist_field *operand = hist_field->operands[0];
265 unsigned long buckets = hist_field->buckets;294 unsigned long buckets = hist_field->buckets;
266 295
267 u64 val = operand->fn(operand, elt, buffer, rbe, event);296 u64 val = hist_fn_call(operand, elt, buffer, rbe, event);
268 297
269 if (WARN_ON_ONCE(!buckets))298 if (WARN_ON_ONCE(!buckets))
270 return val;299 return val;
@@ -285,8 +314,8 @@ static u64 hist_field_plus(struct hist_field *hist_field, · 14 unmodified lines
285 struct hist_field *operand1 = hist_field->operands[0];314 struct hist_field *operand1 = hist_field->operands[0];
286 struct hist_field *operand2 = hist_field->operands[1];315 struct hist_field *operand2 = hist_field->operands[1];
287 316
288 u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event);317 u64 val1 = hist_fn_call(operand1, elt, buffer, rbe, event);
289 u64 val2 = operand2->fn(operand2, elt, buffer, rbe, event);318 u64 val2 = hist_fn_call(operand2, elt, buffer, rbe, event);
290 319
291 return val1 + val2;320 return val1 + val2;
292}321}
@@ -300,8 +329,8 @@ static u64 hist_field_minus(struct hist_field *hist_field, · 7 unmodified lines
300 struct hist_field *operand1 = hist_field->operands[0];329 struct hist_field *operand1 = hist_field->operands[0];
301 struct hist_field *operand2 = hist_field->operands[1];330 struct hist_field *operand2 = hist_field->operands[1];
302 331
303 u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event);332 u64 val1 = hist_fn_call(operand1, elt, buffer, rbe, event);
304 u64 val2 = operand2->fn(operand2, elt, buffer, rbe, event);333 u64 val2 = hist_fn_call(operand2, elt, buffer, rbe, event);
305 334
306 return val1 - val2;335 return val1 - val2;
307}336}
@@ -315,8 +344,8 @@ static u64 hist_field_div(struct hist_field *hist_field, · 7 unmodified lines
315 struct hist_field *operand1 = hist_field->operands[0];344 struct hist_field *operand1 = hist_field->operands[0];
316 struct hist_field *operand2 = hist_field->operands[1];345 struct hist_field *operand2 = hist_field->operands[1];
317 346
318 u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event);347 u64 val1 = hist_fn_call(operand1, elt, buffer, rbe, event);
319 u64 val2 = operand2->fn(operand2, elt, buffer, rbe, event);348 u64 val2 = hist_fn_call(operand2, elt, buffer, rbe, event);
320 349
321 /* Return -1 for the undefined case */350 /* Return -1 for the undefined case */
322 if (!val2)351 if (!val2)
@@ -338,7 +367,7 @@ static u64 div_by_power_of_two(struct hist_field *hist_field, · 15 unmodified lines
338 struct hist_field *operand1 = hist_field->operands[0];367 struct hist_field *operand1 = hist_field->operands[0];
339 struct hist_field *operand2 = hist_field->operands[1];368 struct hist_field *operand2 = hist_field->operands[1];
340 369
341 u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event);370 u64 val1 = hist_fn_call(operand1, elt, buffer, rbe, event);
342 371
343 return val1 >> __ffs64(operand2->constant);372 return val1 >> __ffs64(operand2->constant);
344}373}
@@ -352,7 +381,7 @@ static u64 div_by_not_power_of_two(struct hist_field *hist_field, · 7 unmodified lines
352 struct hist_field *operand1 = hist_field->operands[0];381 struct hist_field *operand1 = hist_field->operands[0];
353 struct hist_field *operand2 = hist_field->operands[1];382 struct hist_field *operand2 = hist_field->operands[1];
354 383
355 u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event);384 u64 val1 = hist_fn_call(operand1, elt, buffer, rbe, event);
356 385
357 return div64_u64(val1, operand2->constant);386 return div64_u64(val1, operand2->constant);
358}387}
@@ -366,7 +395,7 @@ static u64 div_by_mult_and_shift(struct hist_field *hist_field, · 7 unmodified lines
366 struct hist_field *operand1 = hist_field->operands[0];395 struct hist_field *operand1 = hist_field->operands[0];
367 struct hist_field *operand2 = hist_field->operands[1];396 struct hist_field *operand2 = hist_field->operands[1];
368 397
369 u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event);398 u64 val1 = hist_fn_call(operand1, elt, buffer, rbe, event);
370 399
371 /*400 /*
372 * If the divisor is a constant, do a multiplication and shift instead.401 * If the divisor is a constant, do a multiplication and shift instead.
@@ -400,8 +429,8 @@ static u64 hist_field_mult(struct hist_field *hist_field, · 27 unmodified lines
400 struct hist_field *operand1 = hist_field->operands[0];429 struct hist_field *operand1 = hist_field->operands[0];
401 struct hist_field *operand2 = hist_field->operands[1];430 struct hist_field *operand2 = hist_field->operands[1];
402 431
403 u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event);432 u64 val1 = hist_fn_call(operand1, elt, buffer, rbe, event);
404 u64 val2 = operand2->fn(operand2, elt, buffer, rbe, event);433 u64 val2 = hist_fn_call(operand2, elt, buffer, rbe, event);
405 434
406 return val1 * val2;435 return val1 * val2;
407}436}
@@ -414,7 +443,7 @@ static u64 hist_field_unary_minus(struct hist_field *hist_field, · 6 unmodified lines
414{443{
415 struct hist_field *operand = hist_field->operands[0];444 struct hist_field *operand = hist_field->operands[0];
416 445
417 s64 sval = (s64)operand->fn(operand, elt, buffer, rbe, event);446 s64 sval = (s64)hist_fn_call(operand, elt, buffer, rbe, event);
418 u64 val = (u64)-sval;447 u64 val = (u64)-sval;
419 448
420 return val;449 return val;
@@ -657,19 +686,19 @@ struct snapshot_context { · 236 unmodified lines
657 * Returns the specific division function to use if the divisor686 * Returns the specific division function to use if the divisor
658 * is constant. This avoids extra branches when the trigger is hit.687 * is constant. This avoids extra branches when the trigger is hit.
659 */688 */
660static hist_field_fn_t hist_field_get_div_fn(struct hist_field *divisor)689static enum hist_field_fn hist_field_get_div_fn(struct hist_field *divisor)
661{690{
662 u64 div = divisor->constant;691 u64 div = divisor->constant;
663 692
664 if (!(div & (div - 1)))693 if (!(div & (div - 1)))
665 return div_by_power_of_two;694 return HIST_FIELD_FN_DIV_POWER2;
666 695
667 /* If the divisor is too large, do a regular division */696 /* If the divisor is too large, do a regular division */
668 if (div > (1 << HIST_DIV_SHIFT))697 if (div > (1 << HIST_DIV_SHIFT))
669 return div_by_not_power_of_two;698 return HIST_FIELD_FN_DIV_NOT_POWER2;
670 699
671 divisor->div_multiplier = div64_u64((u64)(1 << HIST_DIV_SHIFT), div);700 divisor->div_multiplier = div64_u64((u64)(1 << HIST_DIV_SHIFT), div);
672 return div_by_mult_and_shift;701 return HIST_FIELD_FN_DIV_MULT_SHIFT;
673}702}
674 703
675static void track_data_free(struct track_data *track_data)704static void track_data_free(struct track_data *track_data)
@@ -1334,38 +1363,32 @@ static const char *hist_field_name(struct hist_field *field, · 658 unmodified lines
1334 return field_name;1363 return field_name;
1335}1364}
1336 1365
1337static hist_field_fn_t select_value_fn(int field_size, int field_is_signed)1366static enum hist_field_fn select_value_fn(int field_size, int field_is_signed)
1338{1367{
1339 hist_field_fn_t fn = NULL;
1340
1341 switch (field_size) {1368 switch (field_size) {
1342 case 8:1369 case 8:
1343 if (field_is_signed)1370 if (field_is_signed)
1344 fn = hist_field_s64;1371 return HIST_FIELD_FN_S64;
1345 else1372 else
1346 fn = hist_field_u64;1373 return HIST_FIELD_FN_U64;
1347 break;
1348 case 4:1374 case 4:
1349 if (field_is_signed)1375 if (field_is_signed)
1350 fn = hist_field_s32;1376 return HIST_FIELD_FN_S32;
1351 else1377 else
1352 fn = hist_field_u32;1378 return HIST_FIELD_FN_U32;
1353 break;
1354 case 2:1379 case 2:
1355 if (field_is_signed)1380 if (field_is_signed)
1356 fn = hist_field_s16;1381 return HIST_FIELD_FN_S16;
1357 else1382 else
1358 fn = hist_field_u16;1383 return HIST_FIELD_FN_U16;
1359 break;
1360 case 1:1384 case 1:
1361 if (field_is_signed)1385 if (field_is_signed)
1362 fn = hist_field_s8;1386 return HIST_FIELD_FN_S8;
1363 else1387 else
1364 fn = hist_field_u8;1388 return HIST_FIELD_FN_U8;
1365 break;
1366 }1389 }
1367 1390
1368 return fn;1391 return HIST_FIELD_FN_NOP;
1369}1392}
1370 1393
1371static int parse_map_size(char *str)1394static int parse_map_size(char *str)
@@ -1922,19 +1945,19 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, · 550 unmodified lines
1922 goto out; /* caller will populate */1945 goto out; /* caller will populate */
1923 1946
1924 if (flags & HIST_FIELD_FL_VAR_REF) {1947 if (flags & HIST_FIELD_FL_VAR_REF) {
1925 hist_field->fn = hist_field_var_ref;1948 hist_field->fn_num = HIST_FIELD_FN_VAR_REF;
1926 goto out;1949 goto out;
1927 }1950 }
1928 1951
1929 if (flags & HIST_FIELD_FL_HITCOUNT) {1952 if (flags & HIST_FIELD_FL_HITCOUNT) {
1930 hist_field->fn = hist_field_counter;1953 hist_field->fn_num = HIST_FIELD_FN_COUNTER;
1931 hist_field->size = sizeof(u64);1954 hist_field->size = sizeof(u64);
1932 hist_field->type = "u64";1955 hist_field->type = "u64";
1933 goto out;1956 goto out;
1934 }1957 }
1935 1958
1936 if (flags & HIST_FIELD_FL_CONST) {1959 if (flags & HIST_FIELD_FL_CONST) {
1937 hist_field->fn = hist_field_const;1960 hist_field->fn_num = HIST_FIELD_FN_CONST;
1938 hist_field->size = sizeof(u64);1961 hist_field->size = sizeof(u64);
1939 hist_field->type = kstrdup("u64", GFP_KERNEL);1962 hist_field->type = kstrdup("u64", GFP_KERNEL);
1940 if (!hist_field->type)1963 if (!hist_field->type)
@@ -1943,14 +1966,14 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, · 2 unmodified lines
1943 }1966 }
1944 1967
1945 if (flags & HIST_FIELD_FL_STACKTRACE) {1968 if (flags & HIST_FIELD_FL_STACKTRACE) {
1946 hist_field->fn = hist_field_none;1969 hist_field->fn_num = HIST_FIELD_FN_NOP;
1947 goto out;1970 goto out;
1948 }1971 }
1949 1972
1950 if (flags & (HIST_FIELD_FL_LOG2 | HIST_FIELD_FL_BUCKET)) {1973 if (flags & (HIST_FIELD_FL_LOG2 | HIST_FIELD_FL_BUCKET)) {
1951 unsigned long fl = flags & ~(HIST_FIELD_FL_LOG2 | HIST_FIELD_FL_BUCKET);1974 unsigned long fl = flags & ~(HIST_FIELD_FL_LOG2 | HIST_FIELD_FL_BUCKET);
1952 hist_field->fn = flags & HIST_FIELD_FL_LOG2 ? hist_field_log2 :1975 hist_field->fn_num = flags & HIST_FIELD_FL_LOG2 ? HIST_FIELD_FN_LOG2 :
1953 hist_field_bucket;1976 HIST_FIELD_FN_BUCKET;
1954 hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);1977 hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);
1955 hist_field->size = hist_field->operands[0]->size;1978 hist_field->size = hist_field->operands[0]->size;
1956 hist_field->type = kstrdup_const(hist_field->operands[0]->type, GFP_KERNEL);1979 hist_field->type = kstrdup_const(hist_field->operands[0]->type, GFP_KERNEL);
@@ -1960,14 +1983,14 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, · 3 unmodified lines
1960 }1983 }
1961 1984
1962 if (flags & HIST_FIELD_FL_TIMESTAMP) {1985 if (flags & HIST_FIELD_FL_TIMESTAMP) {
1963 hist_field->fn = hist_field_timestamp;1986 hist_field->fn_num = HIST_FIELD_FN_TIMESTAMP;
1964 hist_field->size = sizeof(u64);1987 hist_field->size = sizeof(u64);
1965 hist_field->type = "u64";1988 hist_field->type = "u64";
1966 goto out;1989 goto out;
1967 }1990 }
1968 1991
1969 if (flags & HIST_FIELD_FL_CPU) {1992 if (flags & HIST_FIELD_FL_CPU) {
1970 hist_field->fn = hist_field_cpu;1993 hist_field->fn_num = HIST_FIELD_FN_CPU;
1971 hist_field->size = sizeof(int);1994 hist_field->size = sizeof(int);
1972 hist_field->type = "unsigned int";1995 hist_field->type = "unsigned int";
1973 goto out;1996 goto out;
@@ -1987,14 +2010,14 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, · 13 unmodified lines
1987 goto free;2010 goto free;
1988 2011
1989 if (field->filter_type == FILTER_STATIC_STRING) {2012 if (field->filter_type == FILTER_STATIC_STRING) {
1990 hist_field->fn = hist_field_string;2013 hist_field->fn_num = HIST_FIELD_FN_STRING;
1991 hist_field->size = field->size;2014 hist_field->size = field->size;
1992 } else if (field->filter_type == FILTER_DYN_STRING) {2015 } else if (field->filter_type == FILTER_DYN_STRING) {
1993 hist_field->fn = hist_field_dynstring;2016 hist_field->fn_num = HIST_FIELD_FN_DYNSTRING;
1994 } else if (field->filter_type == FILTER_RDYN_STRING)2017 } else if (field->filter_type == FILTER_RDYN_STRING)
1995 hist_field->fn = hist_field_reldynstring;2018 hist_field->fn_num = HIST_FIELD_FN_RELDYNSTRING;
1996 else2019 else
1997 hist_field->fn = hist_field_pstring;2020 hist_field->fn_num = HIST_FIELD_FN_PSTRING;
1998 } else {2021 } else {
1999 hist_field->size = field->size;2022 hist_field->size = field->size;
2000 hist_field->is_signed = field->is_signed;2023 hist_field->is_signed = field->is_signed;
@@ -2002,9 +2025,9 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, · 1 unmodified line
2002 if (!hist_field->type)2025 if (!hist_field->type)
2003 goto free;2026 goto free;
2004 2027
2005 hist_field->fn = select_value_fn(field->size,2028 hist_field->fn_num = select_value_fn(field->size,
2006 field->is_signed);2029 field->is_signed);
2007 if (!hist_field->fn) {2030 if (hist_field->fn_num == HIST_FIELD_FN_NOP) {
2008 destroy_hist_field(hist_field, 0);2031 destroy_hist_field(hist_field, 0);
2009 return NULL;2032 return NULL;
2010 }2033 }
@@ -2340,7 +2363,7 @@ static struct hist_field *create_alias(struct hist_trigger_data *hist_data, · 329 unmodified lines
2340 if (!alias)2363 if (!alias)
2341 return NULL;2364 return NULL;
2342 2365
2343 alias->fn = var_ref->fn;2366 alias->fn_num = var_ref->fn_num;
2344 alias->operands[0] = var_ref;2367 alias->operands[0] = var_ref;
2345 2368
2346 if (init_var_ref(alias, var_ref, var_ref->system, var_ref->event_name)) {2369 if (init_var_ref(alias, var_ref, var_ref->system, var_ref->event_name)) {
@@ -2523,7 +2546,7 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, · 176 unmodified lines
2523 2546
2524 expr->flags |= operand1->flags &2547 expr->flags |= operand1->flags &
2525 (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);2548 (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
2526 expr->fn = hist_field_unary_minus;2549 expr->fn_num = HIST_FIELD_FN_UMINUS;
2527 expr->operands[0] = operand1;2550 expr->operands[0] = operand1;
2528 expr->size = operand1->size;2551 expr->size = operand1->size;
2529 expr->is_signed = operand1->is_signed;2552 expr->is_signed = operand1->is_signed;
@@ -2595,7 +2618,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, · 65 unmodified lines
2595 unsigned long operand_flags, operand2_flags;2618 unsigned long operand_flags, operand2_flags;
2596 int field_op, ret = -EINVAL;2619 int field_op, ret = -EINVAL;
2597 char *sep, *operand1_str;2620 char *sep, *operand1_str;
2598 hist_field_fn_t op_fn;2621 enum hist_field_fn op_fn;
2599 bool combine_consts;2622 bool combine_consts;
2600 2623
2601 if (*n_subexprs > 3) {2624 if (*n_subexprs > 3) {
@@ -2654,16 +2677,16 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, · 52 unmodified lines
2654 2677
2655 switch (field_op) {2678 switch (field_op) {
2656 case FIELD_OP_MINUS:2679 case FIELD_OP_MINUS:
2657 op_fn = hist_field_minus;2680 op_fn = HIST_FIELD_FN_MINUS;
2658 break;2681 break;
2659 case FIELD_OP_PLUS:2682 case FIELD_OP_PLUS:
2660 op_fn = hist_field_plus;2683 op_fn = HIST_FIELD_FN_PLUS;
2661 break;2684 break;
2662 case FIELD_OP_DIV:2685 case FIELD_OP_DIV:
2663 op_fn = hist_field_div;2686 op_fn = HIST_FIELD_FN_DIV;
2664 break;2687 break;
2665 case FIELD_OP_MULT:2688 case FIELD_OP_MULT:
2666 op_fn = hist_field_mult;2689 op_fn = HIST_FIELD_FN_MULT;
2667 break;2690 break;
2668 default:2691 default:
2669 ret = -EINVAL;2692 ret = -EINVAL;
@@ -2719,13 +2742,16 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, · 49 unmodified lines
2719 op_fn = hist_field_get_div_fn(operand2);2742 op_fn = hist_field_get_div_fn(operand2);
2720 }2743 }
2721 2744
2745 expr->fn_num = op_fn;
2746
2722 if (combine_consts) {2747 if (combine_consts) {
2723 if (var1)2748 if (var1)
2724 expr->operands[0] = var1;2749 expr->operands[0] = var1;
2725 if (var2)2750 if (var2)
2726 expr->operands[1] = var2;2751 expr->operands[1] = var2;
2727 2752
2728 expr->constant = op_fn(expr, NULL, NULL, NULL, NULL);2753 expr->constant = hist_fn_call(expr, NULL, NULL, NULL, NULL);
2754 expr->fn_num = HIST_FIELD_FN_CONST;
2729 2755
2730 expr->operands[0] = NULL;2756 expr->operands[0] = NULL;
2731 expr->operands[1] = NULL;2757 expr->operands[1] = NULL;
@@ -2739,8 +2765,6 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, · 7 unmodified lines
2739 2765
2740 expr->name = expr_str(expr, 0);2766 expr->name = expr_str(expr, 0);
2741 } else {2767 } else {
2742 expr->fn = op_fn;
2743
2744 /* The operand sizes should be the same, so just pick one */2768 /* The operand sizes should be the same, so just pick one */
2745 expr->size = operand1->size;2769 expr->size = operand1->size;
2746 expr->is_signed = operand1->is_signed;2770 expr->is_signed = operand1->is_signed;
@@ -3065,7 +3089,7 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, · 318 unmodified lines
3065 struct hist_field *var = field_var->var;3089 struct hist_field *var = field_var->var;
3066 struct hist_field *val = field_var->val;3090 struct hist_field *val = field_var->val;
3067 3091
3068 var_val = val->fn(val, elt, buffer, rbe, rec);3092 var_val = hist_fn_call(val, elt, buffer, rbe, rec);
3069 var_idx = var->var.idx;3093 var_idx = var->var.idx;
3070 3094
3071 if (val->flags & HIST_FIELD_FL_STRING) {3095 if (val->flags & HIST_FIELD_FL_STRING) {
@@ -4186,6 +4210,74 @@ static u64 hist_field_execname(struct hist_field *hist_field, · 1114 unmodified lines
4186 return (u64)(unsigned long)(elt_data->comm);4210 return (u64)(unsigned long)(elt_data->comm);
4187}4211}
4188 4212
4213static u64 hist_fn_call(struct hist_field *hist_field,
4214 struct tracing_map_elt *elt,
4215 struct trace_buffer *buffer,
4216 struct ring_buffer_event *rbe,
4217 void *event)
4218{
4219 switch (hist_field->fn_num) {
4220 case HIST_FIELD_FN_VAR_REF:
4221 return hist_field_var_ref(hist_field, elt, buffer, rbe, event);
4222 case HIST_FIELD_FN_COUNTER:
4223 return hist_field_counter(hist_field, elt, buffer, rbe, event);
4224 case HIST_FIELD_FN_CONST:
4225 return hist_field_const(hist_field, elt, buffer, rbe, event);
4226 case HIST_FIELD_FN_LOG2:
4227 return hist_field_log2(hist_field, elt, buffer, rbe, event);
4228 case HIST_FIELD_FN_BUCKET:
4229 return hist_field_bucket(hist_field, elt, buffer, rbe, event);
4230 case HIST_FIELD_FN_TIMESTAMP:
4231 return hist_field_timestamp(hist_field, elt, buffer, rbe, event);
4232 case HIST_FIELD_FN_CPU:
4233 return hist_field_cpu(hist_field, elt, buffer, rbe, event);
4234 case HIST_FIELD_FN_STRING:
4235 return hist_field_string(hist_field, elt, buffer, rbe, event);
4236 case HIST_FIELD_FN_DYNSTRING:
4237 return hist_field_dynstring(hist_field, elt, buffer, rbe, event);
4238 case HIST_FIELD_FN_RELDYNSTRING:
4239 return hist_field_reldynstring(hist_field, elt, buffer, rbe, event);
4240 case HIST_FIELD_FN_PSTRING:
4241 return hist_field_pstring(hist_field, elt, buffer, rbe, event);
4242 case HIST_FIELD_FN_S64:
4243 return hist_field_s64(hist_field, elt, buffer, rbe, event);
4244 case HIST_FIELD_FN_U64:
4245 return hist_field_u64(hist_field, elt, buffer, rbe, event);
4246 case HIST_FIELD_FN_S32:
4247 return hist_field_s32(hist_field, elt, buffer, rbe, event);
4248 case HIST_FIELD_FN_U32:
4249 return hist_field_u32(hist_field, elt, buffer, rbe, event);
4250 case HIST_FIELD_FN_S16:
4251 return hist_field_s16(hist_field, elt, buffer, rbe, event);
4252 case HIST_FIELD_FN_U16:
4253 return hist_field_u16(hist_field, elt, buffer, rbe, event);
4254 case HIST_FIELD_FN_S8:
4255 return hist_field_s8(hist_field, elt, buffer, rbe, event);
4256 case HIST_FIELD_FN_U8:
4257 return hist_field_u8(hist_field, elt, buffer, rbe, event);
4258 case HIST_FIELD_FN_UMINUS:
4259 return hist_field_unary_minus(hist_field, elt, buffer, rbe, event);
4260 case HIST_FIELD_FN_MINUS:
4261 return hist_field_minus(hist_field, elt, buffer, rbe, event);
4262 case HIST_FIELD_FN_PLUS:
4263 return hist_field_plus(hist_field, elt, buffer, rbe, event);
4264 case HIST_FIELD_FN_DIV:
4265 return hist_field_div(hist_field, elt, buffer, rbe, event);
4266 case HIST_FIELD_FN_MULT:
4267 return hist_field_mult(hist_field, elt, buffer, rbe, event);
4268 case HIST_FIELD_FN_DIV_POWER2:
4269 return div_by_power_of_two(hist_field, elt, buffer, rbe, event);
4270 case HIST_FIELD_FN_DIV_NOT_POWER2:
4271 return div_by_not_power_of_two(hist_field, elt, buffer, rbe, event);
4272 case HIST_FIELD_FN_DIV_MULT_SHIFT:
4273 return div_by_mult_and_shift(hist_field, elt, buffer, rbe, event);
4274 case HIST_FIELD_FN_EXECNAME:
4275 return hist_field_execname(hist_field, elt, buffer, rbe, event);
4276 default:
4277 return 0;
4278 }
4279}
4280
4189/* Convert a var that points to common_pid.execname to a string */4281/* Convert a var that points to common_pid.execname to a string */
4190static void update_var_execname(struct hist_field *hist_field)4282static void update_var_execname(struct hist_field *hist_field)
4191{4283{
@@ -4197,7 +4289,7 @@ static void update_var_execname(struct hist_field *hist_field) · 5 unmodified lines
4197 kfree_const(hist_field->type);4289 kfree_const(hist_field->type);
4198 hist_field->type = "char[]";4290 hist_field->type = "char[]";
4199 4291
4200 hist_field->fn = hist_field_execname;4292 hist_field->fn_num = HIST_FIELD_FN_EXECNAME;
4201}4293}
4202 4294
4203static int create_var_field(struct hist_trigger_data *hist_data,4295static int create_var_field(struct hist_trigger_data *hist_data,
@@ -4956,7 +5048,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, · 752 unmodified lines
4956 5048
4957 for_each_hist_val_field(i, hist_data) {5049 for_each_hist_val_field(i, hist_data) {
4958 hist_field = hist_data->fields[i];5050 hist_field = hist_data->fields[i];
4959 hist_val = hist_field->fn(hist_field, elt, buffer, rbe, rec);5051 hist_val = hist_fn_call(hist_field, elt, buffer, rbe, rec);
4960 if (hist_field->flags & HIST_FIELD_FL_VAR) {5052 if (hist_field->flags & HIST_FIELD_FL_VAR) {
4961 var_idx = hist_field->var.idx;5053 var_idx = hist_field->var.idx;
4962 5054
@@ -4987,7 +5079,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, · 24 unmodified lines
4987 for_each_hist_key_field(i, hist_data) {5079 for_each_hist_key_field(i, hist_data) {
4988 hist_field = hist_data->fields[i];5080 hist_field = hist_data->fields[i];
4989 if (hist_field->flags & HIST_FIELD_FL_VAR) {5081 if (hist_field->flags & HIST_FIELD_FL_VAR) {
4990 hist_val = hist_field->fn(hist_field, elt, buffer, rbe, rec);5082 hist_val = hist_fn_call(hist_field, elt, buffer, rbe, rec);
4991 var_idx = hist_field->var.idx;5083 var_idx = hist_field->var.idx;
4992 tracing_map_set_var(elt, var_idx, hist_val);5084 tracing_map_set_var(elt, var_idx, hist_val);
4993 }5085 }
@@ -5062,7 +5154,7 @@ static void event_hist_trigger(struct event_trigger_data *data, · 68 unmodified lines
5062 HIST_STACKTRACE_SKIP);5154 HIST_STACKTRACE_SKIP);
5063 key = entries;5155 key = entries;
5064 } else {5156 } else {
5065 field_contents = key_field->fn(key_field, elt, buffer, rbe, rec);5157 field_contents = hist_fn_call(key_field, elt, buffer, rbe, rec);
5066 if (key_field->flags & HIST_FIELD_FL_STRING) {5158 if (key_field->flags & HIST_FIELD_FL_STRING) {
5067 key = (void *)(unsigned long)field_contents;5159 key = (void *)(unsigned long)field_contents;
5068 use_compound_key = true;5160 use_compound_key = true;
kernel/trace/trace_events_user.c+426−142
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/uio.h>14#include <linux/uio.h>
15#include <linux/ioctl.h>15#include <linux/ioctl.h>
16#include <linux/jhash.h>16#include <linux/jhash.h>
17#include <linux/refcount.h>
17#include <linux/trace_events.h>18#include <linux/trace_events.h>
18#include <linux/tracefs.h>19#include <linux/tracefs.h>
19#include <linux/types.h>20#include <linux/types.h>
@@ -39,28 +40,69 @@ · 19 unmodified lines
39 */40 */
40#define MAX_PAGE_ORDER 041#define MAX_PAGE_ORDER 0
41#define MAX_PAGES (1 << MAX_PAGE_ORDER)42#define MAX_PAGES (1 << MAX_PAGE_ORDER)
42#define MAX_EVENTS (MAX_PAGES * PAGE_SIZE)43#define MAX_BYTES (MAX_PAGES * PAGE_SIZE)
44#define MAX_EVENTS (MAX_BYTES * 8)
43 45
44/* Limit how long of an event name plus args within the subsystem. */46/* Limit how long of an event name plus args within the subsystem. */
45#define MAX_EVENT_DESC 51247#define MAX_EVENT_DESC 512
46#define EVENT_NAME(user_event) ((user_event)->tracepoint.name)48#define EVENT_NAME(user_event) ((user_event)->tracepoint.name)
47#define MAX_FIELD_ARRAY_SIZE 102449#define MAX_FIELD_ARRAY_SIZE 1024
48#define MAX_FIELD_ARG_NAME 256
49 50
50static char *register_page_data;51/*
52 * The MAP_STATUS_* macros are used for taking a index and determining the
53 * appropriate byte and the bit in the byte to set/reset for an event.
54 *
55 * The lower 3 bits of the index decide which bit to set.
56 * The remaining upper bits of the index decide which byte to use for the bit.
57 *
58 * This is used when an event has a probe attached/removed to reflect live
59 * status of the event wanting tracing or not to user-programs via shared
60 * memory maps.
61 */
62#define MAP_STATUS_BYTE(index) ((index) >> 3)
63#define MAP_STATUS_MASK(index) BIT((index) & 7)
64
65/*
66 * Internal bits (kernel side only) to keep track of connected probes:
67 * These are used when status is requested in text form about an event. These
68 * bits are compared against an internal byte on the event to determine which
69 * probes to print out to the user.
70 *
71 * These do not reflect the mapped bytes between the user and kernel space.
72 */
73#define EVENT_STATUS_FTRACE BIT(0)
74#define EVENT_STATUS_PERF BIT(1)
75#define EVENT_STATUS_OTHER BIT(7)
76
77/*
78 * Stores the pages, tables, and locks for a group of events.
79 * Each logical grouping of events has its own group, with a
80 * matching page for status checks within user programs. This
81 * allows for isolation of events to user programs by various
82 * means.
83 */
84struct user_event_group {
85 struct page *pages;
86 char *register_page_data;
87 char *system_name;
88 struct hlist_node node;
89 struct mutex reg_mutex;
90 DECLARE_HASHTABLE(register_table, 8);
91 DECLARE_BITMAP(page_bitmap, MAX_EVENTS);
92};
51 93
52static DEFINE_MUTEX(reg_mutex);94/* Group for init_user_ns mapping, top-most group */
53static DEFINE_HASHTABLE(register_table, 4);95static struct user_event_group *init_group;
54static DECLARE_BITMAP(page_bitmap, MAX_EVENTS);
55 96
56/*97/*
57 * Stores per-event properties, as users register events98 * Stores per-event properties, as users register events
58 * within a file a user_event might be created if it does not99 * within a file a user_event might be created if it does not
59 * already exist. These are globally used and their lifetime100 * already exist. These are globally used and their lifetime
60 * is tied to the refcnt member. These cannot go away until the101 * is tied to the refcnt member. These cannot go away until the
61 * refcnt reaches zero.102 * refcnt reaches one.
62 */103 */
63struct user_event {104struct user_event {
105 struct user_event_group *group;
64 struct tracepoint tracepoint;106 struct tracepoint tracepoint;
65 struct trace_event_call call;107 struct trace_event_call call;
66 struct trace_event_class class;108 struct trace_event_class class;
@@ -68,10 +110,11 @@ struct user_event { · 1 unmodified line
68 struct hlist_node node;110 struct hlist_node node;
69 struct list_head fields;111 struct list_head fields;
70 struct list_head validators;112 struct list_head validators;
71 atomic_t refcnt;113 refcount_t refcnt;
72 int index;114 int index;
73 int flags;115 int flags;
74 int min_size;116 int min_size;
117 char status;
75};118};
76 119
77/*120/*
@@ -86,6 +129,11 @@ struct user_event_refs { · 8 unmodified lines
86 struct user_event *events[];129 struct user_event *events[];
87};130};
88 131
132struct user_event_file_info {
133 struct user_event_group *group;
134 struct user_event_refs *refs;
135};
136
89#define VALIDATOR_ENSURE_NULL (1 << 0)137#define VALIDATOR_ENSURE_NULL (1 << 0)
90#define VALIDATOR_REL (1 << 1)138#define VALIDATOR_REL (1 << 1)
91 139
@@ -98,7 +146,8 @@ struct user_event_validator { · 6 unmodified lines
98typedef void (*user_event_func_t) (struct user_event *user, struct iov_iter *i,146typedef void (*user_event_func_t) (struct user_event *user, struct iov_iter *i,
99 void *tpdata, bool *faulted);147 void *tpdata, bool *faulted);
100 148
101static int user_event_parse(char *name, char *args, char *flags,149static int user_event_parse(struct user_event_group *group, char *name,
150 char *args, char *flags,
102 struct user_event **newuser);151 struct user_event **newuser);
103 152
104static u32 user_event_key(char *name)153static u32 user_event_key(char *name)
@@ -106,6 +155,144 @@ static u32 user_event_key(char *name) · 1 unmodified line
106 return jhash(name, strlen(name), 0);155 return jhash(name, strlen(name), 0);
107}156}
108 157
158static void set_page_reservations(char *pages, bool set)
159{
160 int page;
161
162 for (page = 0; page < MAX_PAGES; ++page) {
163 void *addr = pages + (PAGE_SIZE * page);
164
165 if (set)
166 SetPageReserved(virt_to_page(addr));
167 else
168 ClearPageReserved(virt_to_page(addr));
169 }
170}
171
172static void user_event_group_destroy(struct user_event_group *group)
173{
174 if (group->register_page_data)
175 set_page_reservations(group->register_page_data, false);
176
177 if (group->pages)
178 __free_pages(group->pages, MAX_PAGE_ORDER);
179
180 kfree(group->system_name);
181 kfree(group);
182}
183
184static char *user_event_group_system_name(struct user_namespace *user_ns)
185{
186 char *system_name;
187 int len = sizeof(USER_EVENTS_SYSTEM) + 1;
188
189 if (user_ns != &init_user_ns) {
190 /*
191 * Unexpected at this point:
192 * We only currently support init_user_ns.
193 * When we enable more, this will trigger a failure so log.
194 */
195 pr_warn("user_events: Namespace other than init_user_ns!\n");
196 return NULL;
197 }
198
199 system_name = kmalloc(len, GFP_KERNEL);
200
201 if (!system_name)
202 return NULL;
203
204 snprintf(system_name, len, "%s", USER_EVENTS_SYSTEM);
205
206 return system_name;
207}
208
209static inline struct user_event_group
210*user_event_group_from_user_ns(struct user_namespace *user_ns)
211{
212 if (user_ns == &init_user_ns)
213 return init_group;
214
215 return NULL;
216}
217
218static struct user_event_group *current_user_event_group(void)
219{
220 struct user_namespace *user_ns = current_user_ns();
221 struct user_event_group *group = NULL;
222
223 while (user_ns) {
224 group = user_event_group_from_user_ns(user_ns);
225
226 if (group)
227 break;
228
229 user_ns = user_ns->parent;
230 }
231
232 return group;
233}
234
235static struct user_event_group
236*user_event_group_create(struct user_namespace *user_ns)
237{
238 struct user_event_group *group;
239
240 group = kzalloc(sizeof(*group), GFP_KERNEL);
241
242 if (!group)
243 return NULL;
244
245 group->system_name = user_event_group_system_name(user_ns);
246
247 if (!group->system_name)
248 goto error;
249
250 group->pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, MAX_PAGE_ORDER);
251
252 if (!group->pages)
253 goto error;
254
255 group->register_page_data = page_address(group->pages);
256
257 set_page_reservations(group->register_page_data, true);
258
259 /* Zero all bits beside 0 (which is reserved for failures) */
260 bitmap_zero(group->page_bitmap, MAX_EVENTS);
261 set_bit(0, group->page_bitmap);
262
263 mutex_init(&group->reg_mutex);
264 hash_init(group->register_table);
265
266 return group;
267error:
268 if (group)
269 user_event_group_destroy(group);
270
271 return NULL;
272};
273
274static __always_inline
275void user_event_register_set(struct user_event *user)
276{
277 int i = user->index;
278
279 user->group->register_page_data[MAP_STATUS_BYTE(i)] |= MAP_STATUS_MASK(i);
280}
281
282static __always_inline
283void user_event_register_clear(struct user_event *user)
284{
285 int i = user->index;
286
287 user->group->register_page_data[MAP_STATUS_BYTE(i)] &= ~MAP_STATUS_MASK(i);
288}
289
290static __always_inline __must_check
291bool user_event_last_ref(struct user_event *user)
292{
293 return refcount_read(&user->refcnt) == 1;
294}
295
109static __always_inline __must_check296static __always_inline __must_check
110size_t copy_nofault(void *addr, size_t bytes, struct iov_iter *i)297size_t copy_nofault(void *addr, size_t bytes, struct iov_iter *i)
111{298{
@@ -141,7 +328,8 @@ static struct list_head *user_event_get_fields(struct trace_event_call *call) · 29 unmodified lines
141 *328 *
142 * Upon success user_event has its ref count increased by 1.329 * Upon success user_event has its ref count increased by 1.
143 */330 */
144static int user_event_parse_cmd(char *raw_command, struct user_event **newuser)331static int user_event_parse_cmd(struct user_event_group *group,
332 char *raw_command, struct user_event **newuser)
145{333{
146 char *name = raw_command;334 char *name = raw_command;
147 char *args = strpbrk(name, " ");335 char *args = strpbrk(name, " ");
@@ -155,7 +343,7 @@ static int user_event_parse_cmd(char *raw_command, struct user_event **newuser) · 7 unmodified lines
155 if (flags)343 if (flags)
156 *flags++ = '\0';344 *flags++ = '\0';
157 345
158 return user_event_parse(name, args, flags, newuser);346 return user_event_parse(group, name, args, flags, newuser);
159}347}
160 348
161static int user_field_array_size(const char *type)349static int user_field_array_size(const char *type)
@@ -277,7 +465,7 @@ static int user_event_add_field(struct user_event *user, const char *type, · 115 unmodified lines
277 goto add_field;465 goto add_field;
278 466
279add_validator:467add_validator:
280 if (strstr(type, "char") != 0)468 if (strstr(type, "char") != NULL)
281 validator_flags |= VALIDATOR_ENSURE_NULL;469 validator_flags |= VALIDATOR_ENSURE_NULL;
282 470
283 validator = kmalloc(sizeof(*validator), GFP_KERNEL);471 validator = kmalloc(sizeof(*validator), GFP_KERNEL);
@@ -458,7 +646,7 @@ static const char *user_field_format(const char *type) · 174 unmodified lines
458 return "%d";646 return "%d";
459 if (strcmp(type, "unsigned char") == 0)647 if (strcmp(type, "unsigned char") == 0)
460 return "%u";648 return "%u";
461 if (strstr(type, "char[") != 0)649 if (strstr(type, "char[") != NULL)
462 return "%s";650 return "%s";
463 651
464 /* Unknown, likely struct, allowed treat as 64-bit */652 /* Unknown, likely struct, allowed treat as 64-bit */
@@ -479,10 +667,52 @@ static bool user_field_is_dyn_string(const char *type, const char **str_func) · 14 unmodified lines
479 667
480 return false;668 return false;
481check:669check:
482 return strstr(type, "char") != 0;670 return strstr(type, "char") != NULL;
483}671}
484 672
485#define LEN_OR_ZERO (len ? len - pos : 0)673#define LEN_OR_ZERO (len ? len - pos : 0)
674static int user_dyn_field_set_string(int argc, const char **argv, int *iout,
675 char *buf, int len, bool *colon)
676{
677 int pos = 0, i = *iout;
678
679 *colon = false;
680
681 for (; i < argc; ++i) {
682 if (i != *iout)
683 pos += snprintf(buf + pos, LEN_OR_ZERO, " ");
684
685 pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", argv[i]);
686
687 if (strchr(argv[i], ';')) {
688 ++i;
689 *colon = true;
690 break;
691 }
692 }
693
694 /* Actual set, advance i */
695 if (len != 0)
696 *iout = i;
697
698 return pos + 1;
699}
700
701static int user_field_set_string(struct ftrace_event_field *field,
702 char *buf, int len, bool colon)
703{
704 int pos = 0;
705
706 pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", field->type);
707 pos += snprintf(buf + pos, LEN_OR_ZERO, " ");
708 pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", field->name);
709
710 if (colon)
711 pos += snprintf(buf + pos, LEN_OR_ZERO, ";");
712
713 return pos + 1;
714}
715
486static int user_event_set_print_fmt(struct user_event *user, char *buf, int len)716static int user_event_set_print_fmt(struct user_event *user, char *buf, int len)
487{717{
488 struct ftrace_event_field *field, *next;718 struct ftrace_event_field *field, *next;
@@ -600,8 +830,8 @@ static int destroy_user_event(struct user_event *user) · 111 unmodified lines
600 830
601 dyn_event_remove(&user->devent);831 dyn_event_remove(&user->devent);
602 832
603 register_page_data[user->index] = 0;833 user_event_register_clear(user);
604 clear_bit(user->index, page_bitmap);834 clear_bit(user->index, user->group->page_bitmap);
605 hash_del(&user->node);835 hash_del(&user->node);
606 836
607 user_event_destroy_validators(user);837 user_event_destroy_validators(user);
@@ -612,16 +842,17 @@ static int destroy_user_event(struct user_event *user) · 4 unmodified lines
612 return ret;842 return ret;
613}843}
614 844
615static struct user_event *find_user_event(char *name, u32 *outkey)845static struct user_event *find_user_event(struct user_event_group *group,
846 char *name, u32 *outkey)
616{847{
617 struct user_event *user;848 struct user_event *user;
618 u32 key = user_event_key(name);849 u32 key = user_event_key(name);
619 850
620 *outkey = key;851 *outkey = key;
621 852
622 hash_for_each_possible(register_table, user, node, key)853 hash_for_each_possible(group->register_table, user, node, key)
623 if (!strcmp(EVENT_NAME(user), name)) {854 if (!strcmp(EVENT_NAME(user), name)) {
624 atomic_inc(&user->refcnt);855 refcount_inc(&user->refcnt);
625 return user;856 return user;
626 }857 }
627 858
@@ -779,7 +1010,12 @@ static void update_reg_page_for(struct user_event *user) · 151 unmodified lines
779 rcu_read_unlock_sched();1010 rcu_read_unlock_sched();
780 }1011 }
781 1012
782 register_page_data[user->index] = status;1013 if (status)
1014 user_event_register_set(user);
1015 else
1016 user_event_register_clear(user);
1017
1018 user->status = status;
783}1019}
784 1020
785/*1021/*
@@ -835,17 +1071,18 @@ static int user_event_reg(struct trace_event_call *call, · 49 unmodified lines
835 1071
836 return ret;1072 return ret;
837inc:1073inc:
838 atomic_inc(&user->refcnt);1074 refcount_inc(&user->refcnt);
839 update_reg_page_for(user);1075 update_reg_page_for(user);
840 return 0;1076 return 0;
841dec:1077dec:
842 update_reg_page_for(user);1078 update_reg_page_for(user);
843 atomic_dec(&user->refcnt);1079 refcount_dec(&user->refcnt);
844 return 0;1080 return 0;
845}1081}
846 1082
847static int user_event_create(const char *raw_command)1083static int user_event_create(const char *raw_command)
848{1084{
1085 struct user_event_group *group;
849 struct user_event *user;1086 struct user_event *user;
850 char *name;1087 char *name;
851 int ret;1088 int ret;
@@ -861,14 +1098,19 @@ static int user_event_create(const char *raw_command) · 9 unmodified lines
861 if (!name)1098 if (!name)
862 return -ENOMEM;1099 return -ENOMEM;
863 1100
864 mutex_lock(&reg_mutex);1101 group = current_user_event_group();
865 1102
866 ret = user_event_parse_cmd(name, &user);1103 if (!group)
1104 return -ENOENT;
1105
1106 mutex_lock(&group->reg_mutex);
1107
1108 ret = user_event_parse_cmd(group, name, &user);
867 1109
868 if (!ret)1110 if (!ret)
869 atomic_dec(&user->refcnt);1111 refcount_dec(&user->refcnt);
870 1112
871 mutex_unlock(&reg_mutex);1113 mutex_unlock(&group->reg_mutex);
872 1114
873 if (ret)1115 if (ret)
874 kfree(name);1116 kfree(name);
@@ -910,14 +1152,14 @@ static bool user_event_is_busy(struct dyn_event *ev) · 35 unmodified lines
910{1152{
911 struct user_event *user = container_of(ev, struct user_event, devent);1153 struct user_event *user = container_of(ev, struct user_event, devent);
912 1154
913 return atomic_read(&user->refcnt) != 0;1155 return !user_event_last_ref(user);
914}1156}
915 1157
916static int user_event_free(struct dyn_event *ev)1158static int user_event_free(struct dyn_event *ev)
917{1159{
918 struct user_event *user = container_of(ev, struct user_event, devent);1160 struct user_event *user = container_of(ev, struct user_event, devent);
919 1161
920 if (atomic_read(&user->refcnt) != 0)1162 if (!user_event_last_ref(user))
921 return -EBUSY;1163 return -EBUSY;
922 1164
923 return destroy_user_event(user);1165 return destroy_user_event(user);
@@ -926,49 +1168,35 @@ static int user_event_free(struct dyn_event *ev) · 2 unmodified lines
926static bool user_field_match(struct ftrace_event_field *field, int argc,1168static bool user_field_match(struct ftrace_event_field *field, int argc,
927 const char **argv, int *iout)1169 const char **argv, int *iout)
928{1170{
929 char *field_name, *arg_name;1171 char *field_name = NULL, *dyn_field_name = NULL;
930 int len, pos, i = *iout;
931 bool colon = false, match = false;1172 bool colon = false, match = false;
1173 int dyn_len, len;
932 1174
933 if (i >= argc)1175 if (*iout >= argc)
934 return false;1176 return false;
935 1177
936 len = MAX_FIELD_ARG_NAME;1178 dyn_len = user_dyn_field_set_string(argc, argv, iout, dyn_field_name,
937 field_name = kmalloc(len, GFP_KERNEL);1179 0, &colon);
938 arg_name = kmalloc(len, GFP_KERNEL);
939
940 if (!arg_name || !field_name)
941 goto out;
942
943 pos = 0;
944
945 for (; i < argc; ++i) {
946 if (i != *iout)
947 pos += snprintf(arg_name + pos, len - pos, " ");
948 1180
949 pos += snprintf(arg_name + pos, len - pos, argv[i]);1181 len = user_field_set_string(field, field_name, 0, colon);
950 1182
951 if (strchr(argv[i], ';')) {1183 if (dyn_len != len)
952 ++i;1184 return false;
953 colon = true;
954 break;
955 }
956 }
957 1185
958 pos = 0;1186 dyn_field_name = kmalloc(dyn_len, GFP_KERNEL);
1187 field_name = kmalloc(len, GFP_KERNEL);
959 1188
960 pos += snprintf(field_name + pos, len - pos, field->type);1189 if (!dyn_field_name || !field_name)
961 pos += snprintf(field_name + pos, len - pos, " ");1190 goto out;
962 pos += snprintf(field_name + pos, len - pos, field->name);
963 1191
964 if (colon)1192 user_dyn_field_set_string(argc, argv, iout, dyn_field_name,
965 pos += snprintf(field_name + pos, len - pos, ";");1193 dyn_len, &colon);
966 1194
967 *iout = i;1195 user_field_set_string(field, field_name, len, colon);
968 1196
969 match = strcmp(arg_name, field_name) == 0;1197 match = strcmp(dyn_field_name, field_name) == 0;
970out:1198out:
971 kfree(arg_name);1199 kfree(dyn_field_name);
972 kfree(field_name);1200 kfree(field_name);
973 1201
974 return match;1202 return match;
@@ -1036,7 +1264,8 @@ static int user_event_trace_register(struct user_event *user) · 61 unmodified lines
1036 * The name buffer lifetime is owned by this method for success cases only.1264 * The name buffer lifetime is owned by this method for success cases only.
1037 * Upon success the returned user_event has its ref count increased by 1.1265 * Upon success the returned user_event has its ref count increased by 1.
1038 */1266 */
1039static int user_event_parse(char *name, char *args, char *flags,1267static int user_event_parse(struct user_event_group *group, char *name,
1268 char *args, char *flags,
1040 struct user_event **newuser)1269 struct user_event **newuser)
1041{1270{
1042 int ret;1271 int ret;
@@ -1046,7 +1275,7 @@ static int user_event_parse(char *name, char *args, char *flags, · 3 unmodified lines
1046 1275
1047 /* Prevent dyn_event from racing */1276 /* Prevent dyn_event from racing */
1048 mutex_lock(&event_mutex);1277 mutex_lock(&event_mutex);
1049 user = find_user_event(name, &key);1278 user = find_user_event(group, name, &key);
1050 mutex_unlock(&event_mutex);1279 mutex_unlock(&event_mutex);
1051 1280
1052 if (user) {1281 if (user) {
@@ -1059,7 +1288,7 @@ static int user_event_parse(char *name, char *args, char *flags, · 6 unmodified lines
1059 return 0;1288 return 0;
1060 }1289 }
1061 1290
1062 index = find_first_zero_bit(page_bitmap, MAX_EVENTS);1291 index = find_first_zero_bit(group->page_bitmap, MAX_EVENTS);
1063 1292
1064 if (index == MAX_EVENTS)1293 if (index == MAX_EVENTS)
1065 return -EMFILE;1294 return -EMFILE;
@@ -1073,6 +1302,7 @@ static int user_event_parse(char *name, char *args, char *flags, · 7 unmodified lines
1073 INIT_LIST_HEAD(&user->fields);1302 INIT_LIST_HEAD(&user->fields);
1074 INIT_LIST_HEAD(&user->validators);1303 INIT_LIST_HEAD(&user->validators);
1075 1304
1305 user->group = group;
1076 user->tracepoint.name = name;1306 user->tracepoint.name = name;
1077 1307
1078 ret = user_event_parse_fields(user, args);1308 ret = user_event_parse_fields(user, args);
@@ -1091,8 +1321,8 @@ static int user_event_parse(char *name, char *args, char *flags, · 12 unmodified lines
1091 user->call.flags = TRACE_EVENT_FL_TRACEPOINT;1321 user->call.flags = TRACE_EVENT_FL_TRACEPOINT;
1092 user->call.tp = &user->tracepoint;1322 user->call.tp = &user->tracepoint;
1093 user->call.event.funcs = &user_event_funcs;1323 user->call.event.funcs = &user_event_funcs;
1324 user->class.system = group->system_name;
1094 1325
1095 user->class.system = USER_EVENTS_SYSTEM;
1096 user->class.fields_array = user_event_fields_array;1326 user->class.fields_array = user_event_fields_array;
1097 user->class.get_fields = user_event_get_fields;1327 user->class.get_fields = user_event_get_fields;
1098 user->class.reg = user_event_reg;1328 user->class.reg = user_event_reg;
@@ -1110,13 +1340,13 @@ static int user_event_parse(char *name, char *args, char *flags, · 11 unmodified lines
1110 1340
1111 user->index = index;1341 user->index = index;
1112 1342
1113 /* Ensure we track ref */1343 /* Ensure we track self ref and caller ref (2) */
1114 atomic_inc(&user->refcnt);1344 refcount_set(&user->refcnt, 2);
1115 1345
1116 dyn_event_init(&user->devent, &user_event_dops);1346 dyn_event_init(&user->devent, &user_event_dops);
1117 dyn_event_add(&user->devent, &user->call);1347 dyn_event_add(&user->devent, &user->call);
1118 set_bit(user->index, page_bitmap);1348 set_bit(user->index, group->page_bitmap);
1119 hash_add(register_table, &user->node, key);1349 hash_add(group->register_table, &user->node, key);
1120 1350
1121 mutex_unlock(&event_mutex);1351 mutex_unlock(&event_mutex);
1122 1352
@@ -1134,32 +1364,20 @@ put_user: · 11 unmodified lines
1134/*1364/*
1135 * Deletes a previously created event if it is no longer being used.1365 * Deletes a previously created event if it is no longer being used.
1136 */1366 */
1137static int delete_user_event(char *name)1367static int delete_user_event(struct user_event_group *group, char *name)
1138{1368{
1139 u32 key;1369 u32 key;
1140 int ret;1370 struct user_event *user = find_user_event(group, name, &key);
1141 struct user_event *user = find_user_event(name, &key);
1142 1371
1143 if (!user)1372 if (!user)
1144 return -ENOENT;1373 return -ENOENT;
1145 1374
1146 /* Ensure we are the last ref */1375 refcount_dec(&user->refcnt);
1147 if (atomic_read(&user->refcnt) != 1) {
1148 ret = -EBUSY;
1149 goto put_ref;
1150 }
1151
1152 ret = destroy_user_event(user);
1153
1154 if (ret)
1155 goto put_ref;
1156 1376
1157 return ret;1377 if (!user_event_last_ref(user))
1158put_ref:1378 return -EBUSY;
1159 /* No longer have this ref */
1160 atomic_dec(&user->refcnt);
1161 1379
1162 return ret;1380 return destroy_user_event(user);
1163}1381}
1164 1382
1165/*1383/*
@@ -1167,6 +1385,7 @@ put_ref: · 1 unmodified line
1167 */1385 */
1168static ssize_t user_events_write_core(struct file *file, struct iov_iter *i)1386static ssize_t user_events_write_core(struct file *file, struct iov_iter *i)
1169{1387{
1388 struct user_event_file_info *info = file->private_data;
1170 struct user_event_refs *refs;1389 struct user_event_refs *refs;
1171 struct user_event *user = NULL;1390 struct user_event *user = NULL;
1172 struct tracepoint *tp;1391 struct tracepoint *tp;
@@ -1178,7 +1397,7 @@ static ssize_t user_events_write_core(struct file *file, struct iov_iter *i) · 5 unmodified lines
1178 1397
1179 rcu_read_lock_sched();1398 rcu_read_lock_sched();
1180 1399
1181 refs = rcu_dereference_sched(file->private_data);1400 refs = rcu_dereference_sched(info->refs);
1182 1401
1183 /*1402 /*
1184 * The refs->events array is protected by RCU, and new items may be1403 * The refs->events array is protected by RCU, and new items may be
@@ -1236,6 +1455,28 @@ static ssize_t user_events_write_core(struct file *file, struct iov_iter *i) · 51 unmodified lines
1236 return ret;1455 return ret;
1237}1456}
1238 1457
1458static int user_events_open(struct inode *node, struct file *file)
1459{
1460 struct user_event_group *group;
1461 struct user_event_file_info *info;
1462
1463 group = current_user_event_group();
1464
1465 if (!group)
1466 return -ENOENT;
1467
1468 info = kzalloc(sizeof(*info), GFP_KERNEL);
1469
1470 if (!info)
1471 return -ENOMEM;
1472
1473 info->group = group;
1474
1475 file->private_data = info;
1476
1477 return 0;
1478}
1479
1239static ssize_t user_events_write(struct file *file, const char __user *ubuf,1480static ssize_t user_events_write(struct file *file, const char __user *ubuf,
1240 size_t count, loff_t *ppos)1481 size_t count, loff_t *ppos)
1241{1482{
@@ -1245,7 +1486,8 @@ static ssize_t user_events_write(struct file *file, const char __user *ubuf, · 3 unmodified lines
1245 if (unlikely(*ppos != 0))1486 if (unlikely(*ppos != 0))
1246 return -EFAULT;1487 return -EFAULT;
1247 1488
1248 if (unlikely(import_single_range(READ, (char *)ubuf, count, &iov, &i)))1489 if (unlikely(import_single_range(WRITE, (char __user *)ubuf,
1490 count, &iov, &i)))
1249 return -EFAULT;1491 return -EFAULT;
1250 1492
1251 return user_events_write_core(file, &i);1493 return user_events_write_core(file, &i);
@@ -1256,13 +1498,15 @@ static ssize_t user_events_write_iter(struct kiocb *kp, struct iov_iter *i) · 4 unmodified lines
1256 return user_events_write_core(kp->ki_filp, i);1498 return user_events_write_core(kp->ki_filp, i);
1257}1499}
1258 1500
1259static int user_events_ref_add(struct file *file, struct user_event *user)1501static int user_events_ref_add(struct user_event_file_info *info,
1502 struct user_event *user)
1260{1503{
1504 struct user_event_group *group = info->group;
1261 struct user_event_refs *refs, *new_refs;1505 struct user_event_refs *refs, *new_refs;
1262 int i, size, count = 0;1506 int i, size, count = 0;
1263 1507
1264 refs = rcu_dereference_protected(file->private_data,1508 refs = rcu_dereference_protected(info->refs,
1265 lockdep_is_held(&reg_mutex));1509 lockdep_is_held(&group->reg_mutex));
1266 1510
1267 if (refs) {1511 if (refs) {
1268 count = refs->count;1512 count = refs->count;
@@ -1286,9 +1530,9 @@ static int user_events_ref_add(struct file *file, struct user_event *user) · 17 unmodified lines
1286 1530
1287 new_refs->events[i] = user;1531 new_refs->events[i] = user;
1288 1532
1289 atomic_inc(&user->refcnt);1533 refcount_inc(&user->refcnt);
1290 1534
1291 rcu_assign_pointer(file->private_data, new_refs);1535 rcu_assign_pointer(info->refs, new_refs);
1292 1536
1293 if (refs)1537 if (refs)
1294 kfree_rcu(refs, rcu);1538 kfree_rcu(refs, rcu);
@@ -1309,13 +1553,24 @@ static long user_reg_get(struct user_reg __user *ureg, struct user_reg *kreg) · 14 unmodified lines
1309 if (size > PAGE_SIZE)1553 if (size > PAGE_SIZE)
1310 return -E2BIG;1554 return -E2BIG;
1311 1555
1312 return copy_struct_from_user(kreg, sizeof(*kreg), ureg, size);1556 if (size < offsetofend(struct user_reg, write_index))
1557 return -EINVAL;
1558
1559 ret = copy_struct_from_user(kreg, sizeof(*kreg), ureg, size);
1560
1561 if (ret)
1562 return ret;
1563
1564 kreg->size = size;
1565
1566 return 0;
1313}1567}
1314 1568
1315/*1569/*
1316 * Registers a user_event on behalf of a user process.1570 * Registers a user_event on behalf of a user process.
1317 */1571 */
1318static long user_events_ioctl_reg(struct file *file, unsigned long uarg)1572static long user_events_ioctl_reg(struct user_event_file_info *info,
1573 unsigned long uarg)
1319{1574{
1320 struct user_reg __user *ureg = (struct user_reg __user *)uarg;1575 struct user_reg __user *ureg = (struct user_reg __user *)uarg;
1321 struct user_reg reg;1576 struct user_reg reg;
@@ -1336,24 +1591,24 @@ static long user_events_ioctl_reg(struct file *file, unsigned long uarg) · 14 unmodified lines
1336 return ret;1591 return ret;
1337 }1592 }
1338 1593
1339 ret = user_event_parse_cmd(name, &user);1594 ret = user_event_parse_cmd(info->group, name, &user);
1340 1595
1341 if (ret) {1596 if (ret) {
1342 kfree(name);1597 kfree(name);
1343 return ret;1598 return ret;
1344 }1599 }
1345 1600
1346 ret = user_events_ref_add(file, user);1601 ret = user_events_ref_add(info, user);
1347 1602
1348 /* No longer need parse ref, ref_add either worked or not */1603 /* No longer need parse ref, ref_add either worked or not */
1349 atomic_dec(&user->refcnt);1604 refcount_dec(&user->refcnt);
1350 1605
1351 /* Positive number is index and valid */1606 /* Positive number is index and valid */
1352 if (ret < 0)1607 if (ret < 0)
1353 return ret;1608 return ret;
1354 1609
1355 put_user((u32)ret, &ureg->write_index);1610 put_user((u32)ret, &ureg->write_index);
1356 put_user(user->index, &ureg->status_index);1611 put_user(user->index, &ureg->status_bit);
1357 1612
1358 return 0;1613 return 0;
1359}1614}
@@ -1361,7 +1616,8 @@ static long user_events_ioctl_reg(struct file *file, unsigned long uarg) · 1 unmodified line
1361/*1616/*
1362 * Deletes a user_event on behalf of a user process.1617 * Deletes a user_event on behalf of a user process.
1363 */1618 */
1364static long user_events_ioctl_del(struct file *file, unsigned long uarg)1619static long user_events_ioctl_del(struct user_event_file_info *info,
1620 unsigned long uarg)
1365{1621{
1366 void __user *ubuf = (void __user *)uarg;1622 void __user *ubuf = (void __user *)uarg;
1367 char *name;1623 char *name;
@@ -1374,7 +1630,7 @@ static long user_events_ioctl_del(struct file *file, unsigned long uarg) · 6 unmodified lines
1374 1630
1375 /* event_mutex prevents dyn_event from racing */1631 /* event_mutex prevents dyn_event from racing */
1376 mutex_lock(&event_mutex);1632 mutex_lock(&event_mutex);
1377 ret = delete_user_event(name);1633 ret = delete_user_event(info->group, name);
1378 mutex_unlock(&event_mutex);1634 mutex_unlock(&event_mutex);
1379 1635
1380 kfree(name);1636 kfree(name);
@@ -1388,19 +1644,21 @@ static long user_events_ioctl_del(struct file *file, unsigned long uarg) · 7 unmodified lines
1388static long user_events_ioctl(struct file *file, unsigned int cmd,1644static long user_events_ioctl(struct file *file, unsigned int cmd,
1389 unsigned long uarg)1645 unsigned long uarg)
1390{1646{
1647 struct user_event_file_info *info = file->private_data;
1648 struct user_event_group *group = info->group;
1391 long ret = -ENOTTY;1649 long ret = -ENOTTY;
1392 1650
1393 switch (cmd) {1651 switch (cmd) {
1394 case DIAG_IOCSREG:1652 case DIAG_IOCSREG:
1395 mutex_lock(&reg_mutex);1653 mutex_lock(&group->reg_mutex);
1396 ret = user_events_ioctl_reg(file, uarg);1654 ret = user_events_ioctl_reg(info, uarg);
1397 mutex_unlock(&reg_mutex);1655 mutex_unlock(&group->reg_mutex);
1398 break;1656 break;
1399 1657
1400 case DIAG_IOCSDEL:1658 case DIAG_IOCSDEL:
1401 mutex_lock(&reg_mutex);1659 mutex_lock(&group->reg_mutex);
1402 ret = user_events_ioctl_del(file, uarg);1660 ret = user_events_ioctl_del(info, uarg);
1403 mutex_unlock(&reg_mutex);1661 mutex_unlock(&group->reg_mutex);
1404 break;1662 break;
1405 }1663 }
1406 1664
@@ -1412,17 +1670,24 @@ static long user_events_ioctl(struct file *file, unsigned int cmd, · 5 unmodified lines
1412 */1670 */
1413static int user_events_release(struct inode *node, struct file *file)1671static int user_events_release(struct inode *node, struct file *file)
1414{1672{
1673 struct user_event_file_info *info = file->private_data;
1674 struct user_event_group *group;
1415 struct user_event_refs *refs;1675 struct user_event_refs *refs;
1416 struct user_event *user;1676 struct user_event *user;
1417 int i;1677 int i;
1418 1678
1679 if (!info)
1680 return -EINVAL;
1681
1682 group = info->group;
1683
1419 /*1684 /*
1420 * Ensure refs cannot change under any situation by taking the1685 * Ensure refs cannot change under any situation by taking the
1421 * register mutex during the final freeing of the references.1686 * register mutex during the final freeing of the references.
1422 */1687 */
1423 mutex_lock(&reg_mutex);1688 mutex_lock(&group->reg_mutex);
1424 1689
1425 refs = file->private_data;1690 refs = info->refs;
1426 1691
1427 if (!refs)1692 if (!refs)
1428 goto out;1693 goto out;
@@ -1436,37 +1701,56 @@ static int user_events_release(struct inode *node, struct file *file) · 7 unmodified lines
1436 user = refs->events[i];1701 user = refs->events[i];
1437 1702
1438 if (user)1703 if (user)
1439 atomic_dec(&user->refcnt);1704 refcount_dec(&user->refcnt);
1440 }1705 }
1441out:1706out:
1442 file->private_data = NULL;1707 file->private_data = NULL;
1443 1708
1444 mutex_unlock(&reg_mutex);1709 mutex_unlock(&group->reg_mutex);
1445 1710
1446 kfree(refs);1711 kfree(refs);
1712 kfree(info);
1447 1713
1448 return 0;1714 return 0;
1449}1715}
1450 1716
1451static const struct file_operations user_data_fops = {1717static const struct file_operations user_data_fops = {
1718 .open = user_events_open,
1452 .write = user_events_write,1719 .write = user_events_write,
1453 .write_iter = user_events_write_iter,1720 .write_iter = user_events_write_iter,
1454 .unlocked_ioctl = user_events_ioctl,1721 .unlocked_ioctl = user_events_ioctl,
1455 .release = user_events_release,1722 .release = user_events_release,
1456};1723};
1457 1724
1725static struct user_event_group *user_status_group(struct file *file)
1726{
1727 struct seq_file *m = file->private_data;
1728
1729 if (!m)
1730 return NULL;
1731
1732 return m->private;
1733}
1734
1458/*1735/*
1459 * Maps the shared page into the user process for checking if event is enabled.1736 * Maps the shared page into the user process for checking if event is enabled.
1460 */1737 */
1461static int user_status_mmap(struct file *file, struct vm_area_struct *vma)1738static int user_status_mmap(struct file *file, struct vm_area_struct *vma)
1462{1739{
1740 char *pages;
1741 struct user_event_group *group = user_status_group(file);
1463 unsigned long size = vma->vm_end - vma->vm_start;1742 unsigned long size = vma->vm_end - vma->vm_start;
1464 1743
1465 if (size != MAX_EVENTS)1744 if (size != MAX_BYTES)
1745 return -EINVAL;
1746
1747 if (!group)
1466 return -EINVAL;1748 return -EINVAL;
1467 1749
1750 pages = group->register_page_data;
1751
1468 return remap_pfn_range(vma, vma->vm_start,1752 return remap_pfn_range(vma, vma->vm_start,
1469 virt_to_phys(register_page_data) >> PAGE_SHIFT,1753 virt_to_phys(pages) >> PAGE_SHIFT,
1470 size, vm_get_page_prot(VM_READ));1754 size, vm_get_page_prot(VM_READ));
1471}1755}
1472 1756
@@ -1490,14 +1774,18 @@ static void user_seq_stop(struct seq_file *m, void *p) · 17 unmodified lines
1490 1774
1491static int user_seq_show(struct seq_file *m, void *p)1775static int user_seq_show(struct seq_file *m, void *p)
1492{1776{
1777 struct user_event_group *group = m->private;
1493 struct user_event *user;1778 struct user_event *user;
1494 char status;1779 char status;
1495 int i, active = 0, busy = 0, flags;1780 int i, active = 0, busy = 0, flags;
1496 1781
1497 mutex_lock(&reg_mutex);1782 if (!group)
1783 return -EINVAL;
1784
1785 mutex_lock(&group->reg_mutex);
1498 1786
1499 hash_for_each(register_table, i, user, node) {1787 hash_for_each(group->register_table, i, user, node) {
1500 status = register_page_data[user->index];1788 status = user->status;
1501 flags = user->flags;1789 flags = user->flags;
1502 1790
1503 seq_printf(m, "%d:%s", user->index, EVENT_NAME(user));1791 seq_printf(m, "%d:%s", user->index, EVENT_NAME(user));
@@ -1520,7 +1808,7 @@ static int user_seq_show(struct seq_file *m, void *p) · 16 unmodified lines
1520 active++;1808 active++;
1521 }1809 }
1522 1810
1523 mutex_unlock(&reg_mutex);1811 mutex_unlock(&group->reg_mutex);
1524 1812
1525 seq_puts(m, "\n");1813 seq_puts(m, "\n");
1526 seq_printf(m, "Active: %d\n", active);1814 seq_printf(m, "Active: %d\n", active);
@@ -1539,7 +1827,24 @@ static const struct seq_operations user_seq_ops = { · 12 unmodified lines
1539 1827
1540static int user_status_open(struct inode *node, struct file *file)1828static int user_status_open(struct inode *node, struct file *file)
1541{1829{
1542 return seq_open(file, &user_seq_ops);1830 struct user_event_group *group;
1831 int ret;
1832
1833 group = current_user_event_group();
1834
1835 if (!group)
1836 return -ENOENT;
1837
1838 ret = seq_open(file, &user_seq_ops);
1839
1840 if (!ret) {
1841 /* Chain group to seq_file */
1842 struct seq_file *m = file->private_data;
1843
1844 m->private = group;
1845 }
1846
1847 return ret;
1543}1848}
1544 1849
1545static const struct file_operations user_status_fops = {1850static const struct file_operations user_status_fops = {
@@ -1580,42 +1885,21 @@ err: · 34 unmodified lines
1580 return -ENODEV;1885 return -ENODEV;
1581}1886}
1582 1887
1583static void set_page_reservations(bool set)
1584{
1585 int page;
1586
1587 for (page = 0; page < MAX_PAGES; ++page) {
1588 void *addr = register_page_data + (PAGE_SIZE * page);
1589
1590 if (set)
1591 SetPageReserved(virt_to_page(addr));
1592 else
1593 ClearPageReserved(virt_to_page(addr));
1594 }
1595}
1596
1597static int __init trace_events_user_init(void)1888static int __init trace_events_user_init(void)
1598{1889{
1599 struct page *pages;
1600 int ret;1890 int ret;
1601 1891
1602 /* Zero all bits beside 0 (which is reserved for failures) */1892 init_group = user_event_group_create(&init_user_ns);
1603 bitmap_zero(page_bitmap, MAX_EVENTS);
1604 set_bit(0, page_bitmap);
1605 1893
1606 pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, MAX_PAGE_ORDER);1894 if (!init_group)
1607 if (!pages)
1608 return -ENOMEM;1895 return -ENOMEM;
1609 register_page_data = page_address(pages);
1610
1611 set_page_reservations(true);
1612 1896
1613 ret = create_user_tracefs();1897 ret = create_user_tracefs();
1614 1898
1615 if (ret) {1899 if (ret) {
1616 pr_warn("user_events could not register with tracefs\n");1900 pr_warn("user_events could not register with tracefs\n");
1617 set_page_reservations(false);1901 user_event_group_destroy(init_group);
1618 __free_pages(pages, MAX_PAGE_ORDER);1902 init_group = NULL;
1619 return ret;1903 return ret;
1620 }1904 }
1621 1905
kernel/trace/trace_osnoise.c+2−1
@@ -1786,8 +1786,9 @@ static int start_per_cpu_kthreads(void) · 1785 unmodified lines
1786 for_each_cpu(cpu, current_mask) {1786 for_each_cpu(cpu, current_mask) {
1787 retval = start_kthread(cpu);1787 retval = start_kthread(cpu);
1788 if (retval) {1788 if (retval) {
1789 cpus_read_unlock();
1789 stop_per_cpu_kthreads();1790 stop_per_cpu_kthreads();
1790 break;1791 return retval;
1791 }1792 }
1792 }1793 }
1793 1794
kernel/trace/trace_probe.h+2−1
@@ -445,7 +445,8 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, · 444 unmodified lines
445 C(SAME_PROBE, "There is already the exact same probe event"),\445 C(SAME_PROBE, "There is already the exact same probe event"),\
446 C(NO_EVENT_INFO, "This requires both group and event name to attach"),\446 C(NO_EVENT_INFO, "This requires both group and event name to attach"),\
447 C(BAD_ATTACH_EVENT, "Attached event does not exist"),\447 C(BAD_ATTACH_EVENT, "Attached event does not exist"),\
448 C(BAD_ATTACH_ARG, "Attached event does not have this field"),448 C(BAD_ATTACH_ARG, "Attached event does not have this field"),\
449 C(NO_EP_FILTER, "No filter rule after 'if'"),
449 450
450#undef C451#undef C
451#define C(a, b) TP_ERR_##a452#define C(a, b) TP_ERR_##a
kernel/trace/tracing_map.c+2−3
@@ -961,7 +961,7 @@ create_sort_entry(void *key, struct tracing_map_elt *elt) · 960 unmodified lines
961static void detect_dups(struct tracing_map_sort_entry **sort_entries,961static void detect_dups(struct tracing_map_sort_entry **sort_entries,
962 int n_entries, unsigned int key_size)962 int n_entries, unsigned int key_size)
963{963{
964 unsigned int dups = 0, total_dups = 0;964 unsigned int total_dups = 0;
965 int i;965 int i;
966 void *key;966 void *key;
967 967
@@ -974,11 +974,10 @@ static void detect_dups(struct tracing_map_sort_entry **sort_entries, · 6 unmodified lines
974 key = sort_entries[0]->key;974 key = sort_entries[0]->key;
975 for (i = 1; i < n_entries; i++) {975 for (i = 1; i < n_entries; i++) {
976 if (!memcmp(sort_entries[i]->key, key, key_size)) {976 if (!memcmp(sort_entries[i]->key, key, key_size)) {
977 dups++; total_dups++;977 total_dups++;
978 continue;978 continue;
979 }979 }
980 key = sort_entries[i]->key;980 key = sort_entries[i]->key;
981 dups = 0;
982 }981 }
983 982
984 WARN_ONCE(total_dups > 0,983 WARN_ONCE(total_dups > 0,
kernel/tracepoint.c+6−8
@@ -640,7 +640,6 @@ static void tp_module_going_check_quiescent(struct tracepoint *tp, void *priv) · 639 unmodified lines
640static int tracepoint_module_coming(struct module *mod)640static int tracepoint_module_coming(struct module *mod)
641{641{
642 struct tp_module *tp_mod;642 struct tp_module *tp_mod;
643 int ret = 0;
644 643
645 if (!mod->num_tracepoints)644 if (!mod->num_tracepoints)
646 return 0;645 return 0;
@@ -652,19 +651,18 @@ static int tracepoint_module_coming(struct module *mod) · 5 unmodified lines
652 */651 */
653 if (trace_module_has_bad_taint(mod))652 if (trace_module_has_bad_taint(mod))
654 return 0;653 return 0;
655 mutex_lock(&tracepoint_module_list_mutex);654
656 tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL);655 tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL);
657 if (!tp_mod) {656 if (!tp_mod)
658 ret = -ENOMEM;657 return -ENOMEM;
659 goto end;
660 }
661 tp_mod->mod = mod;658 tp_mod->mod = mod;
659
660 mutex_lock(&tracepoint_module_list_mutex);
662 list_add_tail(&tp_mod->list, &tracepoint_module_list);661 list_add_tail(&tp_mod->list, &tracepoint_module_list);
663 blocking_notifier_call_chain(&tracepoint_notify_list,662 blocking_notifier_call_chain(&tracepoint_notify_list,
664 MODULE_STATE_COMING, tp_mod);663 MODULE_STATE_COMING, tp_mod);
665end:
666 mutex_unlock(&tracepoint_module_list_mutex);664 mutex_unlock(&tracepoint_module_list_mutex);
667 return ret;665 return 0;
668}666}
669 667
670static void tracepoint_module_going(struct module *mod)668static void tracepoint_module_going(struct module *mod)
samples/user_events/example.c+18−7
@@ -12,13 +12,21 @@ · 11 unmodified lines
12#include <fcntl.h>12#include <fcntl.h>
13#include <stdio.h>13#include <stdio.h>
14#include <unistd.h>14#include <unistd.h>
15#include <asm/bitsperlong.h>
16#include <endian.h>
15#include <linux/user_events.h>17#include <linux/user_events.h>
16 18
19#if __BITS_PER_LONG == 64
20#define endian_swap(x) htole64(x)
21#else
22#define endian_swap(x) htole32(x)
23#endif
24
17/* Assumes debugfs is mounted */25/* Assumes debugfs is mounted */
18const char *data_file = "/sys/kernel/debug/tracing/user_events_data";26const char *data_file = "/sys/kernel/debug/tracing/user_events_data";
19const char *status_file = "/sys/kernel/debug/tracing/user_events_status";27const char *status_file = "/sys/kernel/debug/tracing/user_events_status";
20 28
21static int event_status(char **status)29static int event_status(long **status)
22{30{
23 int fd = open(status_file, O_RDONLY);31 int fd = open(status_file, O_RDONLY);
24 32
@@ -33,7 +41,8 @@ static int event_status(char **status) · 8 unmodified lines
33 return 0;41 return 0;
34}42}
35 43
36static int event_reg(int fd, const char *command, int *status, int *write)44static int event_reg(int fd, const char *command, long *index, long *mask,
45 int *write)
37{46{
38 struct user_reg reg = {0};47 struct user_reg reg = {0};
39 48
@@ -43,7 +52,8 @@ static int event_reg(int fd, const char *command, int *status, int *write) · 3 unmodified lines
43 if (ioctl(fd, DIAG_IOCSREG, &reg) == -1)52 if (ioctl(fd, DIAG_IOCSREG, &reg) == -1)
44 return -1;53 return -1;
45 54
46 *status = reg.status_index;55 *index = reg.status_bit / __BITS_PER_LONG;
56 *mask = endian_swap(1L << (reg.status_bit % __BITS_PER_LONG));
47 *write = reg.write_index;57 *write = reg.write_index;
48 58
49 return 0;59 return 0;
@@ -51,8 +61,9 @@ static int event_reg(int fd, const char *command, int *status, int *write) · 1 unmodified line
51 61
52int main(int argc, char **argv)62int main(int argc, char **argv)
53{63{
54 int data_fd, status, write;64 int data_fd, write;
55 char *status_page;65 long index, mask;
66 long *status_page;
56 struct iovec io[2];67 struct iovec io[2];
57 __u32 count = 0;68 __u32 count = 0;
58 69
@@ -61,7 +72,7 @@ int main(int argc, char **argv) · 2 unmodified lines
61 72
62 data_fd = open(data_file, O_RDWR);73 data_fd = open(data_file, O_RDWR);
63 74
64 if (event_reg(data_fd, "test u32 count", &status, &write) == -1)75 if (event_reg(data_fd, "test u32 count", &index, &mask, &write) == -1)
65 return errno;76 return errno;
66 77
67 /* Setup iovec */78 /* Setup iovec */
@@ -75,7 +86,7 @@ ask: · 7 unmodified lines
75 getchar();86 getchar();
76 87
77 /* Check if anyone is listening */88 /* Check if anyone is listening */
78 if (status_page[status]) {89 if (status_page[index] & mask) {
79 /* Yep, trace out our data */90 /* Yep, trace out our data */
80 writev(data_fd, (const struct iovec *)io, 2);91 writev(data_fd, (const struct iovec *)io, 2);
81 92
tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc+27−0
@@ -0,0 +1,27 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# description: Event probe event parser error log check
4# requires: dynamic_events events/syscalls/sys_enter_openat "<attached-group>.<attached-event> [<args>]":README error_log
5
6check_error() { # command-with-error-pos-by-^
7 ftrace_errlog_check 'event_probe' "$1" 'dynamic_events'
8}
9
10check_error 'e ^a.' # NO_EVENT_INFO
11check_error 'e ^.b' # NO_EVENT_INFO
12check_error 'e ^a.b' # BAD_ATTACH_EVENT
13check_error 'e syscalls/sys_enter_openat ^foo' # BAD_ATTACH_ARG
14check_error 'e:^/bar syscalls/sys_enter_openat' # NO_GROUP_NAME
15check_error 'e:^12345678901234567890123456789012345678901234567890123456789012345/bar syscalls/sys_enter_openat' # GROUP_TOO_LONG
16
17check_error 'e:^foo.1/bar syscalls/sys_enter_openat' # BAD_GROUP_NAME
18check_error 'e:^ syscalls/sys_enter_openat' # NO_EVENT_NAME
19check_error 'e:foo/^12345678901234567890123456789012345678901234567890123456789012345 syscalls/sys_enter_openat' # EVENT_TOO_LONG
20check_error 'e:foo/^bar.1 syscalls/sys_enter_openat' # BAD_EVENT_NAME
21
22check_error 'e:foo/bar syscalls/sys_enter_openat arg=^dfd' # BAD_FETCH_ARG
23check_error 'e:foo/bar syscalls/sys_enter_openat ^arg=$foo' # BAD_ATTACH_ARG
24
25check_error 'e:foo/bar syscalls/sys_enter_openat if ^' # NO_EP_FILTER
26
27exit 0
tools/testing/selftests/user_events/ftrace_test.c+39−8
@@ -22,6 +22,11 @@ const char *enable_file = "/sys/kernel/debug/tracing/events/user_events/__test_e · 21 unmodified lines
22const char *trace_file = "/sys/kernel/debug/tracing/trace";22const char *trace_file = "/sys/kernel/debug/tracing/trace";
23const char *fmt_file = "/sys/kernel/debug/tracing/events/user_events/__test_event/format";23const char *fmt_file = "/sys/kernel/debug/tracing/events/user_events/__test_event/format";
24 24
25static inline int status_check(char *status_page, int status_bit)
26{
27 return status_page[status_bit >> 3] & (1 << (status_bit & 7));
28}
29
25static int trace_bytes(void)30static int trace_bytes(void)
26{31{
27 int fd = open(trace_file, O_RDONLY);32 int fd = open(trace_file, O_RDONLY);
@@ -197,12 +202,12 @@ TEST_F(user, register_events) { · 169 unmodified lines
197 /* Register should work */202 /* Register should work */
198 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));203 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
199 ASSERT_EQ(0, reg.write_index);204 ASSERT_EQ(0, reg.write_index);
200 ASSERT_NE(0, reg.status_index);205 ASSERT_NE(0, reg.status_bit);
201 206
202 /* Multiple registers should result in same index */207 /* Multiple registers should result in same index */
203 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));208 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
204 ASSERT_EQ(0, reg.write_index);209 ASSERT_EQ(0, reg.write_index);
205 ASSERT_NE(0, reg.status_index);210 ASSERT_NE(0, reg.status_bit);
206 211
207 /* Ensure disabled */212 /* Ensure disabled */
208 self->enable_fd = open(enable_file, O_RDWR);213 self->enable_fd = open(enable_file, O_RDWR);
@@ -212,15 +217,15 @@ TEST_F(user, register_events) { · 3 unmodified lines
212 /* MMAP should work and be zero'd */217 /* MMAP should work and be zero'd */
213 ASSERT_NE(MAP_FAILED, status_page);218 ASSERT_NE(MAP_FAILED, status_page);
214 ASSERT_NE(NULL, status_page);219 ASSERT_NE(NULL, status_page);
215 ASSERT_EQ(0, status_page[reg.status_index]);220 ASSERT_EQ(0, status_check(status_page, reg.status_bit));
216 221
217 /* Enable event and ensure bits updated in status */222 /* Enable event and ensure bits updated in status */
218 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))223 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))
219 ASSERT_EQ(EVENT_STATUS_FTRACE, status_page[reg.status_index]);224 ASSERT_NE(0, status_check(status_page, reg.status_bit));
220 225
221 /* Disable event and ensure bits updated in status */226 /* Disable event and ensure bits updated in status */
222 ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0")))227 ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0")))
223 ASSERT_EQ(0, status_page[reg.status_index]);228 ASSERT_EQ(0, status_check(status_page, reg.status_bit));
224 229
225 /* File still open should return -EBUSY for delete */230 /* File still open should return -EBUSY for delete */
226 ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event"));231 ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event"));
@@ -240,6 +245,8 @@ TEST_F(user, write_events) { · 13 unmodified lines
240 struct iovec io[3];245 struct iovec io[3];
241 __u32 field1, field2;246 __u32 field1, field2;
242 int before = 0, after = 0;247 int before = 0, after = 0;
248 int page_size = sysconf(_SC_PAGESIZE);
249 char *status_page;
243 250
244 reg.size = sizeof(reg);251 reg.size = sizeof(reg);
245 reg.name_args = (__u64)"__test_event u32 field1; u32 field2";252 reg.name_args = (__u64)"__test_event u32 field1; u32 field2";
@@ -254,10 +261,18 @@ TEST_F(user, write_events) { · 8 unmodified lines
254 io[2].iov_base = &field2;261 io[2].iov_base = &field2;
255 io[2].iov_len = sizeof(field2);262 io[2].iov_len = sizeof(field2);
256 263
264 status_page = mmap(NULL, page_size, PROT_READ, MAP_SHARED,
265 self->status_fd, 0);
266
257 /* Register should work */267 /* Register should work */
258 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));268 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
259 ASSERT_EQ(0, reg.write_index);269 ASSERT_EQ(0, reg.write_index);
260 ASSERT_NE(0, reg.status_index);270 ASSERT_NE(0, reg.status_bit);
271
272 /* MMAP should work and be zero'd */
273 ASSERT_NE(MAP_FAILED, status_page);
274 ASSERT_NE(NULL, status_page);
275 ASSERT_EQ(0, status_check(status_page, reg.status_bit));
261 276
262 /* Write should fail on invalid slot with ENOENT */277 /* Write should fail on invalid slot with ENOENT */
263 io[0].iov_base = &field2;278 io[0].iov_base = &field2;
@@ -271,6 +286,9 @@ TEST_F(user, write_events) { · 7 unmodified lines
271 self->enable_fd = open(enable_file, O_RDWR);286 self->enable_fd = open(enable_file, O_RDWR);
272 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))287 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))
273 288
289 /* Event should now be enabled */
290 ASSERT_NE(0, status_check(status_page, reg.status_bit));
291
274 /* Write should make it out to ftrace buffers */292 /* Write should make it out to ftrace buffers */
275 before = trace_bytes();293 before = trace_bytes();
276 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3));294 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3));
@@ -298,7 +316,7 @@ TEST_F(user, write_fault) { · 21 unmodified lines
298 /* Register should work */316 /* Register should work */
299 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));317 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
300 ASSERT_EQ(0, reg.write_index);318 ASSERT_EQ(0, reg.write_index);
301 ASSERT_NE(0, reg.status_index);319 ASSERT_NE(0, reg.status_bit);
302 320
303 /* Write should work normally */321 /* Write should work normally */
304 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2));322 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2));
@@ -315,6 +333,11 @@ TEST_F(user, write_validator) { · 10 unmodified lines
315 int loc, bytes;333 int loc, bytes;
316 char data[8];334 char data[8];
317 int before = 0, after = 0;335 int before = 0, after = 0;
336 int page_size = sysconf(_SC_PAGESIZE);
337 char *status_page;
338
339 status_page = mmap(NULL, page_size, PROT_READ, MAP_SHARED,
340 self->status_fd, 0);
318 341
319 reg.size = sizeof(reg);342 reg.size = sizeof(reg);
320 reg.name_args = (__u64)"__test_event __rel_loc char[] data";343 reg.name_args = (__u64)"__test_event __rel_loc char[] data";
@@ -322,7 +345,12 @@ TEST_F(user, write_validator) { · 1 unmodified line
322 /* Register should work */345 /* Register should work */
323 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));346 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
324 ASSERT_EQ(0, reg.write_index);347 ASSERT_EQ(0, reg.write_index);
325 ASSERT_NE(0, reg.status_index);348 ASSERT_NE(0, reg.status_bit);
349
350 /* MMAP should work and be zero'd */
351 ASSERT_NE(MAP_FAILED, status_page);
352 ASSERT_NE(NULL, status_page);
353 ASSERT_EQ(0, status_check(status_page, reg.status_bit));
326 354
327 io[0].iov_base = &reg.write_index;355 io[0].iov_base = &reg.write_index;
328 io[0].iov_len = sizeof(reg.write_index);356 io[0].iov_len = sizeof(reg.write_index);
@@ -340,6 +368,9 @@ TEST_F(user, write_validator) { · 11 unmodified lines
340 self->enable_fd = open(enable_file, O_RDWR);368 self->enable_fd = open(enable_file, O_RDWR);
341 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))369 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))
342 370
371 /* Event should now be enabled */
372 ASSERT_NE(0, status_check(status_page, reg.status_bit));
373
343 /* Full in-bounds write should work */374 /* Full in-bounds write should work */
344 before = trace_bytes();375 before = trace_bytes();
345 loc = DYN_LOC(0, bytes);376 loc = DYN_LOC(0, bytes);
tools/testing/selftests/user_events/perf_test.c+8−3
@@ -35,6 +35,11 @@ static long perf_event_open(struct perf_event_attr *pe, pid_t pid, · 34 unmodified lines
35 return syscall(__NR_perf_event_open, pe, pid, cpu, group_fd, flags);35 return syscall(__NR_perf_event_open, pe, pid, cpu, group_fd, flags);
36}36}
37 37
38static inline int status_check(char *status_page, int status_bit)
39{
40 return status_page[status_bit >> 3] & (1 << (status_bit & 7));
41}
42
38static int get_id(void)43static int get_id(void)
39{44{
40 FILE *fp = fopen(id_file, "r");45 FILE *fp = fopen(id_file, "r");
@@ -120,8 +125,8 @@ TEST_F(user, perf_write) { · 79 unmodified lines
120 /* Register should work */125 /* Register should work */
121 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));126 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
122 ASSERT_EQ(0, reg.write_index);127 ASSERT_EQ(0, reg.write_index);
123 ASSERT_NE(0, reg.status_index);128 ASSERT_NE(0, reg.status_bit);
124 ASSERT_EQ(0, status_page[reg.status_index]);129 ASSERT_EQ(0, status_check(status_page, reg.status_bit));
125 130
126 /* Id should be there */131 /* Id should be there */
127 id = get_id();132 id = get_id();
@@ -144,7 +149,7 @@ TEST_F(user, perf_write) { · 16 unmodified lines
144 ASSERT_NE(MAP_FAILED, perf_page);149 ASSERT_NE(MAP_FAILED, perf_page);
145 150
146 /* Status should be updated */151 /* Status should be updated */
147 ASSERT_EQ(EVENT_STATUS_PERF, status_page[reg.status_index]);152 ASSERT_NE(0, status_check(status_page, reg.status_bit));
148 153
149 event.index = reg.write_index;154 event.index = reg.write_index;
150 event.field1 = 0xc001;155 event.field1 = 0xc001;
tools/verification/dot2/dot2k_templates/main_global.c+4−4
@@ -27,7 +27,7 @@ · 26 unmodified lines
27 *27 *
28 * The rv monitor reference is needed for the monitor declaration.28 * The rv monitor reference is needed for the monitor declaration.
29 */29 */
30struct rv_monitor rv_MODEL_NAME;30static struct rv_monitor rv_MODEL_NAME;
31DECLARE_DA_MON_GLOBAL(MODEL_NAME, MIN_TYPE);31DECLARE_DA_MON_GLOBAL(MODEL_NAME, MIN_TYPE);
32 32
33/*33/*
@@ -63,7 +63,7 @@ TRACEPOINT_DETACH · 29 unmodified lines
63/*63/*
64 * This is the monitor register section.64 * This is the monitor register section.
65 */65 */
66struct rv_monitor rv_MODEL_NAME = {66static struct rv_monitor rv_MODEL_NAME = {
67 .name = "MODEL_NAME",67 .name = "MODEL_NAME",
68 .description = "auto-generated MODEL_NAME",68 .description = "auto-generated MODEL_NAME",
69 .enable = enable_MODEL_NAME,69 .enable = enable_MODEL_NAME,
@@ -72,13 +72,13 @@ struct rv_monitor rv_MODEL_NAME = { · 2 unmodified lines
72 .enabled = 0,72 .enabled = 0,
73};73};
74 74
75static int register_MODEL_NAME(void)75static int __init register_MODEL_NAME(void)
76{76{
77 rv_register_monitor(&rv_MODEL_NAME);77 rv_register_monitor(&rv_MODEL_NAME);
78 return 0;78 return 0;
79}79}
80 80
81static void unregister_MODEL_NAME(void)81static void __exit unregister_MODEL_NAME(void)
82{82{
83 rv_unregister_monitor(&rv_MODEL_NAME);83 rv_unregister_monitor(&rv_MODEL_NAME);
84}84}
tools/verification/dot2/dot2k_templates/main_per_cpu.c+4−4
@@ -27,7 +27,7 @@ · 26 unmodified lines
27 *27 *
28 * The rv monitor reference is needed for the monitor declaration.28 * The rv monitor reference is needed for the monitor declaration.
29 */29 */
30struct rv_monitor rv_MODEL_NAME;30static struct rv_monitor rv_MODEL_NAME;
31DECLARE_DA_MON_PER_CPU(MODEL_NAME, MIN_TYPE);31DECLARE_DA_MON_PER_CPU(MODEL_NAME, MIN_TYPE);
32 32
33/*33/*
@@ -63,7 +63,7 @@ TRACEPOINT_DETACH · 29 unmodified lines
63/*63/*
64 * This is the monitor register section.64 * This is the monitor register section.
65 */65 */
66struct rv_monitor rv_MODEL_NAME = {66static struct rv_monitor rv_MODEL_NAME = {
67 .name = "MODEL_NAME",67 .name = "MODEL_NAME",
68 .description = "auto-generated MODEL_NAME",68 .description = "auto-generated MODEL_NAME",
69 .enable = enable_MODEL_NAME,69 .enable = enable_MODEL_NAME,
@@ -72,13 +72,13 @@ struct rv_monitor rv_MODEL_NAME = { · 2 unmodified lines
72 .enabled = 0,72 .enabled = 0,
73};73};
74 74
75static int register_MODEL_NAME(void)75static int __init register_MODEL_NAME(void)
76{76{
77 rv_register_monitor(&rv_MODEL_NAME);77 rv_register_monitor(&rv_MODEL_NAME);
78 return 0;78 return 0;
79}79}
80 80
81static void unregister_MODEL_NAME(void)81static void __exit unregister_MODEL_NAME(void)
82{82{
83 rv_unregister_monitor(&rv_MODEL_NAME);83 rv_unregister_monitor(&rv_MODEL_NAME);
84}84}
tools/verification/dot2/dot2k_templates/main_per_task.c+4−4
@@ -27,7 +27,7 @@ · 26 unmodified lines
27 *27 *
28 * The rv monitor reference is needed for the monitor declaration.28 * The rv monitor reference is needed for the monitor declaration.
29 */29 */
30struct rv_monitor rv_MODEL_NAME;30static struct rv_monitor rv_MODEL_NAME;
31DECLARE_DA_MON_PER_TASK(MODEL_NAME, MIN_TYPE);31DECLARE_DA_MON_PER_TASK(MODEL_NAME, MIN_TYPE);
32 32
33/*33/*
@@ -63,7 +63,7 @@ TRACEPOINT_DETACH · 29 unmodified lines
63/*63/*
64 * This is the monitor register section.64 * This is the monitor register section.
65 */65 */
66struct rv_monitor rv_MODEL_NAME = {66static struct rv_monitor rv_MODEL_NAME = {
67 .name = "MODEL_NAME",67 .name = "MODEL_NAME",
68 .description = "auto-generated MODEL_NAME",68 .description = "auto-generated MODEL_NAME",
69 .enable = enable_MODEL_NAME,69 .enable = enable_MODEL_NAME,
@@ -72,13 +72,13 @@ struct rv_monitor rv_MODEL_NAME = { · 2 unmodified lines
72 .enabled = 0,72 .enabled = 0,
73};73};
74 74
75static int register_MODEL_NAME(void)75static int __init register_MODEL_NAME(void)
76{76{
77 rv_register_monitor(&rv_MODEL_NAME);77 rv_register_monitor(&rv_MODEL_NAME);
78 return 0;78 return 0;
79}79}
80 80
81static void unregister_MODEL_NAME(void)81static void __exit unregister_MODEL_NAME(void)
82{82{
83 rv_unregister_monitor(&rv_MODEL_NAME);83 rv_unregister_monitor(&rv_MODEL_NAME);
84}84}