History

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

Pull tracing updates from Steven Rostedt: - Add function names as a way to filter function addresses - Add sample module to test ftrace ops and dynamic trampolines - Allow stack traces to be passed from beginning event to end event for synthetic events. This will allow seeing the stack trace of when a task is scheduled out and recorded when it gets scheduled back in. - Add trace event helper __get_buf() to use as a temporary buffer when printing out trace event output. - Add kernel command line to create trace instances on boot up. - Add enabling of events to instances created at boot up. - Add trace_array_puts() to write into instances. - Allow boot instances to take a snapshot at the end of boot up. - Allow live patch modules to include trace events - Minor fixes and clean ups * tag 'trace-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: (31 commits) tracing: Remove unnecessary NULL assignment tracepoint: Allow livepatch module add trace event tracing: Always use canonical ftrace path tracing/histogram: Fix stacktrace histogram Documententation tracing/histogram: Fix stacktrace key tracing/histogram: Fix a few problems with stacktrace variable printing tracing: Add BUILD_BUG() to make sure stacktrace fits in strings tracing/histogram: Don't use strlen to find length of stacktrace variables tracing: Allow boot instances to have snapshot buffers tracing: Add trace_array_puts() to write into instance tracing: Add enabling of events to boot instances tracing: Add creation of instances at boot command line tracing: Fix trace_event_raw_event_synth() if else statement samples: ftrace: Make some global variables static ftrace: sample: avoid open-coded 64-bit division samples: ftrace: Include the nospec-branch.h only for x86 tracing: Acquire buffer from temparary trace sequence tracing/histogram: Wrap remaining shell snippets in code blocks tracing/osnoise: No need for schedule_hrtimeout range bpf/tracing: Use stage6 of tracing to not duplicate macros ...

Linus Torvalds committed 3 years ago

Commit b72b5fe2 parents 9191423 7568a2142 files · +1113 −221Browse files

Showing the changes to kernel (14 of 42 files). Show all

Unified · Split

14 files
  1. kernel/trace/Kconfig +10 −10
  2. kernel/trace/kprobe_event_gen_test.c +1 −1
  3. kernel/trace/ring_buffer.c +7 −2
  4. kernel/trace/synth_event_gen_test.c +1 −1
  5. kernel/trace/trace.c +145 −19
  6. kernel/trace/trace.h +6 −0
  7. kernel/trace/trace_events.c +5 −8
  8. kernel/trace/trace_events_filter.c +92 −1
  9. kernel/trace/trace_events_hist.c +103 −23
  10. kernel/trace/trace_events_synth.c +86 −4
  11. kernel/trace/trace_osnoise.c +1 −1
  12. kernel/trace/trace_seq.c +23 −0
  13. kernel/trace/trace_synth.h +1 −0
  14. kernel/tracepoint.c +2 −2
kernel/trace/Kconfig+10−10
@@ -242,7 +242,7 @@ config DYNAMIC_FTRACE · 241 unmodified lines
242242 enabled, and the functions not enabled will not affect
243243 performance of the system.
244244
245− See the files in /sys/kernel/debug/tracing:
245+ See the files in /sys/kernel/tracing:
246246 available_filter_functions
247247 set_ftrace_filter
248248 set_ftrace_notrace
@@ -306,7 +306,7 @@ config STACK_TRACER · 57 unmodified lines
306306 select KALLSYMS
307307 help
308308 This special tracer records the maximum stack footprint of the
309− kernel and displays it in /sys/kernel/debug/tracing/stack_trace.
309+ kernel and displays it in /sys/kernel/tracing/stack_trace.
310310
311311 This tracer works by hooking into every function call that the
312312 kernel executes, and keeping a maximum stack depth value and
@@ -346,7 +346,7 @@ config IRQSOFF_TRACER · 33 unmodified lines
346346 disabled by default and can be runtime (re-)started
347347 via:
348348
349− echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
349+ echo 0 > /sys/kernel/tracing/tracing_max_latency
350350
351351 (Note that kernel size and overhead increase with this option
352352 enabled. This option and the preempt-off timing option can be
@@ -370,7 +370,7 @@ config PREEMPT_TRACER · 17 unmodified lines
370370 disabled by default and can be runtime (re-)started
371371 via:
372372
373− echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
373+ echo 0 > /sys/kernel/tracing/tracing_max_latency
374374
375375 (Note that kernel size and overhead increase with this option
376376 enabled. This option and the irqs-off timing option can be
@@ -522,7 +522,7 @@ config TRACER_SNAPSHOT · 145 unmodified lines
522522 Allow tracing users to take snapshot of the current buffer using the
523523 ftrace interface, e.g.:
524524
525− echo 1 > /sys/kernel/debug/tracing/snapshot
525+ echo 1 > /sys/kernel/tracing/snapshot
526526 cat snapshot
527527
528528 config TRACER_SNAPSHOT_PER_CPU_SWAP
@@ -534,7 +534,7 @@ config TRACER_SNAPSHOT_PER_CPU_SWAP · 5 unmodified lines
534534 full swap (all buffers). If this is set, then the following is
535535 allowed:
536536
537− echo 1 > /sys/kernel/debug/tracing/per_cpu/cpu2/snapshot
537+ echo 1 > /sys/kernel/tracing/per_cpu/cpu2/snapshot
538538
539539 After which, only the tracing buffer for CPU 2 was swapped with
540540 the main tracing buffer, and the other CPU buffers remain the same.
@@ -581,7 +581,7 @@ config PROFILE_ANNOTATED_BRANCHES · 40 unmodified lines
581581 This tracer profiles all likely and unlikely macros
582582 in the kernel. It will display the results in:
583583
584− /sys/kernel/debug/tracing/trace_stat/branch_annotated
584+ /sys/kernel/tracing/trace_stat/branch_annotated
585585
586586 Note: this will add a significant overhead; only turn this
587587 on if you need to profile the system's use of these macros.
@@ -594,7 +594,7 @@ config PROFILE_ALL_BRANCHES · 6 unmodified lines
594594 taken in the kernel is recorded whether it hit or miss.
595595 The results will be displayed in:
596596
597− /sys/kernel/debug/tracing/trace_stat/branch_all
597+ /sys/kernel/tracing/trace_stat/branch_all
598598
599599 This option also enables the likely/unlikely profiler.
600600
@@ -645,8 +645,8 @@ config BLK_DEV_IO_TRACE · 44 unmodified lines
645645 Tracing also is possible using the ftrace interface, e.g.:
646646
647647 echo 1 > /sys/block/sda/sda1/trace/enable
648− echo blk > /sys/kernel/debug/tracing/current_tracer
649− cat /sys/kernel/debug/tracing/trace_pipe
648+ echo blk > /sys/kernel/tracing/current_tracer
649+ cat /sys/kernel/tracing/trace_pipe
650650
651651 If unsure, say N.
652652
kernel/trace/kprobe_event_gen_test.c+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
2121 * Then:
2222 *
2323 * # insmod kernel/trace/kprobe_event_gen_test.ko
24− * # cat /sys/kernel/debug/tracing/trace
24+ * # cat /sys/kernel/tracing/trace
2525 *
2626 * You should see many instances of the "gen_kprobe_test" and
2727 * "gen_kretprobe_test" events in the trace buffer.
kernel/trace/ring_buffer.c+7−2
@@ -2864,7 +2864,7 @@ rb_check_timestamp(struct ring_buffer_per_cpu *cpu_buffer, · 2863 unmodified lines
28642864 sched_clock_stable() ? "" :
28652865 "If you just came from a suspend/resume,\n"
28662866 "please switch to the trace global clock:\n"
2867− " echo global > /sys/kernel/debug/tracing/trace_clock\n"
2867+ " echo global > /sys/kernel/tracing/trace_clock\n"
28682868 "or add trace_clock=global to the kernel command line\n");
28692869 }
28702870
@@ -5604,11 +5604,16 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page); · 2733 unmodified lines
56045604 */
56055605 void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu, void *data)
56065606 {
5607− struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
5607+ struct ring_buffer_per_cpu *cpu_buffer;
56085608 struct buffer_data_page *bpage = data;
56095609 struct page *page = virt_to_page(bpage);
56105610 unsigned long flags;
56115611
5612+ if (!buffer || !buffer->buffers || !buffer->buffers[cpu])
5613+ return;
5614+
5615+ cpu_buffer = buffer->buffers[cpu];
5616+
56125617 /* If the page is still in use someplace else, we can't reuse it */
56135618 if (page_ref_count(page) > 1)
56145619 goto out;
kernel/trace/synth_event_gen_test.c+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 * Then:
2323 *
2424 * # insmod kernel/trace/synth_event_gen_test.ko
25− * # cat /sys/kernel/debug/tracing/trace
25+ * # cat /sys/kernel/tracing/trace
2626 *
2727 * You should see several events in the trace buffer -
2828 * "create_synth_test", "empty_synth_test", and several instances of
kernel/trace/trace.c+145−19
@@ -49,6 +49,8 @@ · 48 unmodified lines
4949 #include <linux/irq_work.h>
5050 #include <linux/workqueue.h>
5151
52+#include <asm/setup.h> /* COMMAND_LINE_SIZE */
53+
5254 #include "trace.h"
5355 #include "trace_output.h"
5456
@@ -186,6 +188,12 @@ static char *default_bootup_tracer; · 131 unmodified lines
186188 static bool allocate_snapshot;
187189 static bool snapshot_at_boot;
188190
191+static char boot_instance_info[COMMAND_LINE_SIZE] __initdata;
192+static int boot_instance_index;
193+
194+static char boot_snapshot_info[COMMAND_LINE_SIZE] __initdata;
195+static int boot_snapshot_index;
196+
189197 static int __init set_cmdline_ftrace(char *str)
190198 {
191199 strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);
@@ -222,9 +230,22 @@ __setup("traceoff_on_warning", stop_trace_on_warning); · 30 unmodified lines
222230
223231 static int __init boot_alloc_snapshot(char *str)
224232 {
225− allocate_snapshot = true;
226− /* We also need the main ring buffer expanded */
227− ring_buffer_expanded = true;
233+ char *slot = boot_snapshot_info + boot_snapshot_index;
234+ int left = sizeof(boot_snapshot_info) - boot_snapshot_index;
235+ int ret;
236+
237+ if (str[0] == '=') {
238+ str++;
239+ if (strlen(str) >= left)
240+ return -1;
241+
242+ ret = snprintf(slot, left, "%s\t", str);
243+ boot_snapshot_index += ret;
244+ } else {
245+ allocate_snapshot = true;
246+ /* We also need the main ring buffer expanded */
247+ ring_buffer_expanded = true;
248+ }
228249 return 1;
229250 }
230251 __setup("alloc_snapshot", boot_alloc_snapshot);
@@ -239,6 +260,23 @@ static int __init boot_snapshot(char *str) · 8 unmodified lines
239260 __setup("ftrace_boot_snapshot", boot_snapshot);
240261
241262
263+static int __init boot_instance(char *str)
264+{
265+ char *slot = boot_instance_info + boot_instance_index;
266+ int left = sizeof(boot_instance_info) - boot_instance_index;
267+ int ret;
268+
269+ if (strlen(str) >= left)
270+ return -1;
271+
272+ ret = snprintf(slot, left, "%s\t", str);
273+ boot_instance_index += ret;
274+
275+ return 1;
276+}
277+__setup("trace_instance=", boot_instance);
278+
279+
242280 static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata;
243281
244282 static int __init set_trace_boot_options(char *str)
@@ -1001,13 +1039,8 @@ __buffer_unlock_commit(struct trace_buffer *buffer, struct ring_buffer_event *ev · 756 unmodified lines
10011039 ring_buffer_unlock_commit(buffer);
10021040 }
10031041
1004−/**
1005− * __trace_puts - write a constant string into the trace buffer.
1006− * @ip: The address of the caller
1007− * @str: The constant string to write
1008− * @size: The size of the string.
1009− */
1010−int __trace_puts(unsigned long ip, const char *str, int size)
1042+int __trace_array_puts(struct trace_array *tr, unsigned long ip,
1043+ const char *str, int size)
10111044 {
10121045 struct ring_buffer_event *event;
10131046 struct trace_buffer *buffer;
@@ -1015,7 +1048,7 @@ int __trace_puts(unsigned long ip, const char *str, int size) · 1 unmodified line
10151048 unsigned int trace_ctx;
10161049 int alloc;
10171050
1018− if (!(global_trace.trace_flags & TRACE_ITER_PRINTK))
1051+ if (!(tr->trace_flags & TRACE_ITER_PRINTK))
10191052 return 0;
10201053
10211054 if (unlikely(tracing_selftest_running || tracing_disabled))
@@ -1024,7 +1057,7 @@ int __trace_puts(unsigned long ip, const char *str, int size) · 2 unmodified lines
10241057 alloc = sizeof(*entry) + size + 2; /* possible \n added */
10251058
10261059 trace_ctx = tracing_gen_ctx();
1027− buffer = global_trace.array_buffer.buffer;
1060+ buffer = tr->array_buffer.buffer;
10281061 ring_buffer_nest_start(buffer);
10291062 event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc,
10301063 trace_ctx);
@@ -1046,11 +1079,23 @@ int __trace_puts(unsigned long ip, const char *str, int size) · 15 unmodified lines
10461079 entry->buf[size] = '\0';
10471080
10481081 __buffer_unlock_commit(buffer, event);
1049− ftrace_trace_stack(&global_trace, buffer, trace_ctx, 4, NULL);
1082+ ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL);
10501083 out:
10511084 ring_buffer_nest_end(buffer);
10521085 return size;
10531086 }
1087+EXPORT_SYMBOL_GPL(__trace_array_puts);
1088+
1089+/**
1090+ * __trace_puts - write a constant string into the trace buffer.
1091+ * @ip: The address of the caller
1092+ * @str: The constant string to write
1093+ * @size: The size of the string.
1094+ */
1095+int __trace_puts(unsigned long ip, const char *str, int size)
1096+{
1097+ return __trace_array_puts(&global_trace, ip, str, size);
1098+}
10541099 EXPORT_SYMBOL_GPL(__trace_puts);
10551100
10561101 /**
@@ -1142,7 +1187,7 @@ void tracing_snapshot_instance(struct trace_array *tr) · 85 unmodified lines
11421187 *
11431188 * Note, make sure to allocate the snapshot with either
11441189 * a tracing_snapshot_alloc(), or by doing it manually
1145− * with: echo 1 > /sys/kernel/debug/tracing/snapshot
1190+ * with: echo 1 > /sys/kernel/tracing/snapshot
11461191 *
11471192 * If the snapshot buffer is not allocated, it will stop tracing.
11481193 * Basically making a permanent snapshot.
@@ -5760,7 +5805,7 @@ static const char readme_msg[] = · 4611 unmodified lines
57605805 #ifdef CONFIG_SYNTH_EVENTS
57615806 " events/synthetic_events\t- Create/append/remove/show synthetic events\n"
57625807 "\t Write into this file to define/undefine new synthetic events.\n"
5763− "\t example: echo 'myevent u64 lat; char name[]' >> synthetic_events\n"
5808+ "\t example: echo 'myevent u64 lat; char name[]; long[] stack' >> synthetic_events\n"
57645809 #endif
57655810 #endif
57665811 ;
@@ -9225,10 +9270,6 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) · 3458 unmodified lines
92259270 }
92269271 tr->allocated_snapshot = allocate_snapshot;
92279272
9228− /*
9229− * Only the top level trace array gets its snapshot allocated
9230− * from the kernel command line.
9231− */
92329273 allocate_snapshot = false;
92339274 #endif
92349275
@@ -10144,6 +10185,79 @@ out: · 909 unmodified lines
1014410185 return ret;
1014510186 }
1014610187
10188+#ifdef CONFIG_TRACER_MAX_TRACE
10189+__init static bool tr_needs_alloc_snapshot(const char *name)
10190+{
10191+ char *test;
10192+ int len = strlen(name);
10193+ bool ret;
10194+
10195+ if (!boot_snapshot_index)
10196+ return false;
10197+
10198+ if (strncmp(name, boot_snapshot_info, len) == 0 &&
10199+ boot_snapshot_info[len] == '\t')
10200+ return true;
10201+
10202+ test = kmalloc(strlen(name) + 3, GFP_KERNEL);
10203+ if (!test)
10204+ return false;
10205+
10206+ sprintf(test, "\t%s\t", name);
10207+ ret = strstr(boot_snapshot_info, test) == NULL;
10208+ kfree(test);
10209+ return ret;
10210+}
10211+
10212+__init static void do_allocate_snapshot(const char *name)
10213+{
10214+ if (!tr_needs_alloc_snapshot(name))
10215+ return;
10216+
10217+ /*
10218+ * When allocate_snapshot is set, the next call to
10219+ * allocate_trace_buffers() (called by trace_array_get_by_name())
10220+ * will allocate the snapshot buffer. That will alse clear
10221+ * this flag.
10222+ */
10223+ allocate_snapshot = true;
10224+}
10225+#else
10226+static inline void do_allocate_snapshot(const char *name) { }
10227+#endif
10228+
10229+__init static void enable_instances(void)
10230+{
10231+ struct trace_array *tr;
10232+ char *curr_str;
10233+ char *str;
10234+ char *tok;
10235+
10236+ /* A tab is always appended */
10237+ boot_instance_info[boot_instance_index - 1] = '\0';
10238+ str = boot_instance_info;
10239+
10240+ while ((curr_str = strsep(&str, "\t"))) {
10241+
10242+ tok = strsep(&curr_str, ",");
10243+
10244+ if (IS_ENABLED(CONFIG_TRACER_MAX_TRACE))
10245+ do_allocate_snapshot(tok);
10246+
10247+ tr = trace_array_get_by_name(tok);
10248+ if (!tr) {
10249+ pr_warn("Failed to create instance buffer %s\n", curr_str);
10250+ continue;
10251+ }
10252+ /* Allow user space to delete it */
10253+ trace_array_put(tr);
10254+
10255+ while ((tok = strsep(&curr_str, ","))) {
10256+ early_enable_events(tr, tok, true);
10257+ }
10258+ }
10259+}
10260+
1014710261 __init static int tracer_alloc_buffers(void)
1014810262 {
1014910263 int ring_buf_size;
@@ -10277,10 +10391,19 @@ out: · 127 unmodified lines
1027710391
1027810392 void __init ftrace_boot_snapshot(void)
1027910393 {
10394+ struct trace_array *tr;
10395+
1028010396 if (snapshot_at_boot) {
1028110397 tracing_snapshot();
1028210398 internal_trace_puts("** Boot snapshot taken **\n");
1028310399 }
10400+
10401+ list_for_each_entry(tr, &ftrace_trace_arrays, list) {
10402+ if (tr == &global_trace)
10403+ continue;
10404+ trace_array_puts(tr, "** Boot snapshot taken **\n");
10405+ tracing_snapshot_instance(tr);
10406+ }
1028410407 }
1028510408
1028610409 void __init early_trace_init(void)
@@ -10302,6 +10425,9 @@ void __init early_trace_init(void) · 15 unmodified lines
1030210425 void __init trace_init(void)
1030310426 {
1030410427 trace_event_init();
10428+
10429+ if (boot_instance_index)
10430+ enable_instances();
1030510431 }
1030610432
1030710433 __init static void clear_boot_tracer(void)
kernel/trace/trace.h+6−0
@@ -113,6 +113,10 @@ enum trace_type { · 112 unmodified lines
113113 #define MEM_FAIL(condition, fmt, ...) \
114114 DO_ONCE_LITE_IF(condition, pr_err, "ERROR: " fmt, ##__VA_ARGS__)
115115
116+#define HIST_STACKTRACE_DEPTH 16
117+#define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
118+#define HIST_STACKTRACE_SKIP 5
119+
116120 /*
117121 * syscalls are special, and need special handling, this is why
118122 * they are not included in trace_entries.h
@@ -1331,6 +1335,8 @@ DECLARE_PER_CPU(int, trace_buffered_event_cnt); · 1212 unmodified lines
13311335 void trace_buffered_event_disable(void);
13321336 void trace_buffered_event_enable(void);
13331337
1338+void early_enable_events(struct trace_array *tr, char *buf, bool disable_first);
1339+
13341340 static inline void
13351341 __trace_event_discard_commit(struct trace_buffer *buffer,
13361342 struct ring_buffer_event *event)
kernel/trace/trace_events.c+5−8
@@ -2281,8 +2281,6 @@ create_new_subsystem(const char *name) · 2280 unmodified lines
22812281 if (!system->name)
22822282 goto out_free;
22832283
2284− system->filter = NULL;
2285−
22862284 system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL);
22872285 if (!system->filter)
22882286 goto out_free;
@@ -2843,7 +2841,7 @@ static __init int setup_trace_triggers(char *str) · 554 unmodified lines
28432841 if (!trigger)
28442842 break;
28452843 bootup_triggers[i].event = strsep(&trigger, ".");
2846− bootup_triggers[i].trigger = strsep(&trigger, ".");
2844+ bootup_triggers[i].trigger = trigger;
28472845 if (!bootup_triggers[i].trigger)
28482846 break;
28492847 }
@@ -3771,10 +3769,9 @@ static __init int event_trace_memsetup(void) · 921 unmodified lines
37713769 return 0;
37723770 }
37733771
3774−static __init void
3775−early_enable_events(struct trace_array *tr, bool disable_first)
3772+__init void
3773+early_enable_events(struct trace_array *tr, char *buf, bool disable_first)
37763774 {
3777− char *buf = bootup_event_buf;
37783775 char *token;
37793776 int ret;
37803777
@@ -3827,7 +3824,7 @@ static __init int event_trace_enable(void) · 46 unmodified lines
38273824 */
38283825 __trace_early_add_events(tr);
38293826
3830− early_enable_events(tr, false);
3827+ early_enable_events(tr, bootup_event_buf, false);
38313828
38323829 trace_printk_start_comm();
38333830
@@ -3855,7 +3852,7 @@ static __init int event_trace_enable_again(void) · 21 unmodified lines
38553852 if (!tr)
38563853 return -ENODEV;
38573854
3858− early_enable_events(tr, true);
3855+ early_enable_events(tr, bootup_event_buf, true);
38593856
38603857 return 0;
38613858 }
kernel/trace/trace_events_filter.c+92−1
@@ -64,6 +64,7 @@ enum filter_pred_fn { · 63 unmodified lines
6464 FILTER_PRED_FN_PCHAR_USER,
6565 FILTER_PRED_FN_PCHAR,
6666 FILTER_PRED_FN_CPU,
67+ FILTER_PRED_FN_FUNCTION,
6768 FILTER_PRED_FN_,
6869 FILTER_PRED_TEST_VISITED,
6970 };
@@ -71,6 +72,7 @@ enum filter_pred_fn { · 1 unmodified line
7172 struct filter_pred {
7273 enum filter_pred_fn fn_num;
7374 u64 val;
75+ u64 val2;
7476 struct regex regex;
7577 unsigned short *ops;
7678 struct ftrace_event_field *field;
@@ -103,6 +105,7 @@ struct filter_pred { · 26 unmodified lines
103105 C(INVALID_FILTER, "Meaningless filter expression"), \
104106 C(IP_FIELD_ONLY, "Only 'ip' field is supported for function trace"), \
105107 C(INVALID_VALUE, "Invalid value (did you forget quotes)?"), \
108+ C(NO_FUNCTION, "Function not found"), \
106109 C(ERRNO, "Error"), \
107110 C(NO_FILTER, "No filter found")
108111
@@ -876,6 +879,17 @@ static int filter_pred_comm(struct filter_pred *pred, void *event) · 767 unmodified lines
876879 return cmp ^ pred->not;
877880 }
878881
882+/* Filter predicate for functions. */
883+static int filter_pred_function(struct filter_pred *pred, void *event)
884+{
885+ unsigned long *addr = (unsigned long *)(event + pred->offset);
886+ unsigned long start = (unsigned long)pred->val;
887+ unsigned long end = (unsigned long)pred->val2;
888+ int ret = *addr >= start && *addr < end;
889+
890+ return pred->op == OP_EQ ? ret : !ret;
891+}
892+
879893 /*
880894 * regex_match_foo - Basic regex callbacks
881895 *
@@ -1335,6 +1349,8 @@ static int filter_pred_fn_call(struct filter_pred *pred, void *event) · 453 unmodified lines
13351349 return filter_pred_pchar(pred, event);
13361350 case FILTER_PRED_FN_CPU:
13371351 return filter_pred_cpu(pred, event);
1352+ case FILTER_PRED_FN_FUNCTION:
1353+ return filter_pred_function(pred, event);
13381354 case FILTER_PRED_TEST_VISITED:
13391355 return test_pred_visited_fn(pred, event);
13401356 default:
@@ -1350,8 +1366,13 @@ static int parse_pred(const char *str, void *data, · 9 unmodified lines
13501366 struct trace_event_call *call = data;
13511367 struct ftrace_event_field *field;
13521368 struct filter_pred *pred = NULL;
1369+ unsigned long offset;
1370+ unsigned long size;
1371+ unsigned long ip;
13531372 char num_buf[24]; /* Big enough to hold an address */
13541373 char *field_name;
1374+ char *name;
1375+ bool function = false;
13551376 bool ustring = false;
13561377 char q;
13571378 u64 val;
@@ -1393,6 +1414,12 @@ static int parse_pred(const char *str, void *data, · 35 unmodified lines
13931414 i += len;
13941415 }
13951416
1417+ /* See if the field is a kernel function name */
1418+ if ((len = str_has_prefix(str + i, ".function"))) {
1419+ function = true;
1420+ i += len;
1421+ }
1422+
13961423 while (isspace(str[i]))
13971424 i++;
13981425
@@ -1423,7 +1450,71 @@ static int parse_pred(const char *str, void *data, · 24 unmodified lines
14231450 pred->offset = field->offset;
14241451 pred->op = op;
14251452
1426− if (ftrace_event_is_function(call)) {
1453+ if (function) {
1454+ /* The field must be the same size as long */
1455+ if (field->size != sizeof(long)) {
1456+ parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + i);
1457+ goto err_free;
1458+ }
1459+
1460+ /* Function only works with '==' or '!=' and an unquoted string */
1461+ switch (op) {
1462+ case OP_NE:
1463+ case OP_EQ:
1464+ break;
1465+ default:
1466+ parse_error(pe, FILT_ERR_INVALID_OP, pos + i);
1467+ goto err_free;
1468+ }
1469+
1470+ if (isdigit(str[i])) {
1471+ /* We allow 0xDEADBEEF */
1472+ while (isalnum(str[i]))
1473+ i++;
1474+
1475+ len = i - s;
1476+ /* 0xfeedfacedeadbeef is 18 chars max */
1477+ if (len >= sizeof(num_buf)) {
1478+ parse_error(pe, FILT_ERR_OPERAND_TOO_LONG, pos + i);
1479+ goto err_free;
1480+ }
1481+
1482+ strncpy(num_buf, str + s, len);
1483+ num_buf[len] = 0;
1484+
1485+ ret = kstrtoul(num_buf, 0, &ip);
1486+ if (ret) {
1487+ parse_error(pe, FILT_ERR_INVALID_VALUE, pos + i);
1488+ goto err_free;
1489+ }
1490+ } else {
1491+ s = i;
1492+ for (; str[i] && !isspace(str[i]); i++)
1493+ ;
1494+
1495+ len = i - s;
1496+ name = kmemdup_nul(str + s, len, GFP_KERNEL);
1497+ if (!name)
1498+ goto err_mem;
1499+ ip = kallsyms_lookup_name(name);
1500+ kfree(name);
1501+ if (!ip) {
1502+ parse_error(pe, FILT_ERR_NO_FUNCTION, pos + i);
1503+ goto err_free;
1504+ }
1505+ }
1506+
1507+ /* Now find the function start and end address */
1508+ if (!kallsyms_lookup_size_offset(ip, &size, &offset)) {
1509+ parse_error(pe, FILT_ERR_NO_FUNCTION, pos + i);
1510+ goto err_free;
1511+ }
1512+
1513+ pred->fn_num = FILTER_PRED_FN_FUNCTION;
1514+ pred->val = ip - offset;
1515+ pred->val2 = pred->val + size;
1516+
1517+ } else if (ftrace_event_is_function(call)) {
14271518 /*
14281519 * Perf does things different with function events.
14291520 * It only allows an "ip" field, and expects a string.
kernel/trace/trace_events_hist.c+103−23
@@ -135,6 +135,7 @@ enum hist_field_fn { · 134 unmodified lines
135135 HIST_FIELD_FN_DIV_NOT_POWER2,
136136 HIST_FIELD_FN_DIV_MULT_SHIFT,
137137 HIST_FIELD_FN_EXECNAME,
138+ HIST_FIELD_FN_STACK,
138139 };
139140
140141 /*
@@ -480,10 +481,6 @@ DEFINE_HIST_FIELD_FN(u8); · 339 unmodified lines
480481 #define for_each_hist_key_field(i, hist_data) \
481482 for ((i) = (hist_data)->n_vals; (i) < (hist_data)->n_fields; (i)++)
482483
483−#define HIST_STACKTRACE_DEPTH 16
484−#define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
485−#define HIST_STACKTRACE_SKIP 5
486−
487484 #define HITCOUNT_IDX 0
488485 #define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE)
489486
@@ -1360,7 +1357,12 @@ static const char *hist_field_name(struct hist_field *field, · 870 unmodified lines
13601357 field_name = field->name;
13611358 } else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
13621359 field_name = "common_timestamp";
1363− else if (field->flags & HIST_FIELD_FL_HITCOUNT)
1360+ else if (field->flags & HIST_FIELD_FL_STACKTRACE) {
1361+ if (field->field)
1362+ field_name = field->field->name;
1363+ else
1364+ field_name = "stacktrace";
1365+ } else if (field->flags & HIST_FIELD_FL_HITCOUNT)
13641366 field_name = "hitcount";
13651367
13661368 if (field_name == NULL)
@@ -1718,6 +1720,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) · 351 unmodified lines
17181720 flags_str = "percent";
17191721 else if (hist_field->flags & HIST_FIELD_FL_GRAPH)
17201722 flags_str = "graph";
1723+ else if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
1724+ flags_str = "stacktrace";
17211725
17221726 return flags_str;
17231727 }
@@ -1979,7 +1983,14 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, · 255 unmodified lines
19791983 }
19801984
19811985 if (flags & HIST_FIELD_FL_STACKTRACE) {
1982− hist_field->fn_num = HIST_FIELD_FN_NOP;
1986+ if (field)
1987+ hist_field->fn_num = HIST_FIELD_FN_STACK;
1988+ else
1989+ hist_field->fn_num = HIST_FIELD_FN_NOP;
1990+ hist_field->size = HIST_STACKTRACE_SIZE;
1991+ hist_field->type = kstrdup_const("unsigned long[]", GFP_KERNEL);
1992+ if (!hist_field->type)
1993+ goto free;
19831994 goto out;
19841995 }
19851996
@@ -2312,6 +2323,8 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, · 326 unmodified lines
23122323 *flags |= HIST_FIELD_FL_EXECNAME;
23132324 else if (strcmp(modifier, "syscall") == 0)
23142325 *flags |= HIST_FIELD_FL_SYSCALL;
2326+ else if (strcmp(modifier, "stacktrace") == 0)
2327+ *flags |= HIST_FIELD_FL_STACKTRACE;
23152328 else if (strcmp(modifier, "log2") == 0)
23162329 *flags |= HIST_FIELD_FL_LOG2;
23172330 else if (strcmp(modifier, "usecs") == 0)
@@ -2351,6 +2364,8 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, · 33 unmodified lines
23512364 hist_data->enable_timestamps = true;
23522365 if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS)
23532366 hist_data->attrs->ts_in_usecs = true;
2367+ } else if (strcmp(field_name, "stacktrace") == 0) {
2368+ *flags |= HIST_FIELD_FL_STACKTRACE;
23542369 } else if (strcmp(field_name, "common_cpu") == 0)
23552370 *flags |= HIST_FIELD_FL_CPU;
23562371 else if (strcmp(field_name, "hitcount") == 0)
@@ -3111,6 +3126,9 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, · 754 unmodified lines
31113126 unsigned int i, j, var_idx;
31123127 u64 var_val;
31133128
3129+ /* Make sure stacktrace can fit in the string variable length */
3130+ BUILD_BUG_ON((HIST_STACKTRACE_DEPTH + 1) * sizeof(long) >= STR_VAR_LEN_MAX);
3131+
31143132 for (i = 0, j = field_var_str_start; i < n_field_vars; i++) {
31153133 struct field_var *field_var = field_vars[i];
31163134 struct hist_field *var = field_var->var;
@@ -3119,13 +3137,26 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, · 2 unmodified lines
31193137 var_val = hist_fn_call(val, elt, buffer, rbe, rec);
31203138 var_idx = var->var.idx;
31213139
3122− if (val->flags & HIST_FIELD_FL_STRING) {
3140+ if (val->flags & (HIST_FIELD_FL_STRING |
3141+ HIST_FIELD_FL_STACKTRACE)) {
31233142 char *str = elt_data->field_var_str[j++];
31243143 char *val_str = (char *)(uintptr_t)var_val;
31253144 unsigned int size;
31263145
3127− size = min(val->size, STR_VAR_LEN_MAX);
3128− strscpy(str, val_str, size);
3146+ if (val->flags & HIST_FIELD_FL_STRING) {
3147+ size = min(val->size, STR_VAR_LEN_MAX);
3148+ strscpy(str, val_str, size);
3149+ } else {
3150+ char *stack_start = str + sizeof(unsigned long);
3151+ int e;
3152+
3153+ e = stack_trace_save((void *)stack_start,
3154+ HIST_STACKTRACE_DEPTH,
3155+ HIST_STACKTRACE_SKIP);
3156+ if (e < HIST_STACKTRACE_DEPTH - 1)
3157+ ((unsigned long *)stack_start)[e] = 0;
3158+ *((unsigned long *)str) = e;
3159+ }
31293160 var_val = (u64)(uintptr_t)str;
31303161 }
31313162 tracing_map_set_var(elt, var_idx, var_val);
@@ -3824,7 +3855,8 @@ static void save_field_var(struct hist_trigger_data *hist_data, · 692 unmodified lines
38243855 {
38253856 hist_data->field_vars[hist_data->n_field_vars++] = field_var;
38263857
3827− if (field_var->val->flags & HIST_FIELD_FL_STRING)
3858+ /* Stack traces are saved in the string storage too */
3859+ if (field_var->val->flags & (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE))
38283860 hist_data->n_field_var_str++;
38293861 }
38303862
@@ -3849,6 +3881,9 @@ static int check_synth_field(struct synth_event *event, · 18 unmodified lines
38493881 && field->is_dynamic)
38503882 return 0;
38513883
3884+ if (strstr(hist_field->type, "long[") && field->is_stack)
3885+ return 0;
3886+
38523887 if (strcmp(field->type, hist_field->type) != 0) {
38533888 if (field->size != hist_field->size ||
38543889 (!field->is_string && field->is_signed != hist_field->is_signed))
@@ -4103,7 +4138,8 @@ static int action_create(struct hist_trigger_data *hist_data, · 248 unmodified lines
41034138 }
41044139
41054140 hist_data->save_vars[hist_data->n_save_vars++] = field_var;
4106− if (field_var->val->flags & HIST_FIELD_FL_STRING)
4141+ if (field_var->val->flags &
4142+ (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE))
41074143 hist_data->n_save_var_str++;
41084144 kfree(param);
41094145 }
@@ -4242,6 +4278,19 @@ static u64 hist_field_execname(struct hist_field *hist_field, · 132 unmodified lines
42424278 return (u64)(unsigned long)(elt_data->comm);
42434279 }
42444280
4281+static u64 hist_field_stack(struct hist_field *hist_field,
4282+ struct tracing_map_elt *elt,
4283+ struct trace_buffer *buffer,
4284+ struct ring_buffer_event *rbe,
4285+ void *event)
4286+{
4287+ u32 str_item = *(u32 *)(event + hist_field->field->offset);
4288+ int str_loc = str_item & 0xffff;
4289+ char *addr = (char *)(event + str_loc);
4290+
4291+ return (u64)(unsigned long)addr;
4292+}
4293+
42454294 static u64 hist_fn_call(struct hist_field *hist_field,
42464295 struct tracing_map_elt *elt,
42474296 struct trace_buffer *buffer,
@@ -4305,6 +4354,8 @@ static u64 hist_fn_call(struct hist_field *hist_field, · 57 unmodified lines
43054354 return div_by_mult_and_shift(hist_field, elt, buffer, rbe, event);
43064355 case HIST_FIELD_FN_EXECNAME:
43074356 return hist_field_execname(hist_field, elt, buffer, rbe, event);
4357+ case HIST_FIELD_FN_STACK:
4358+ return hist_field_stack(hist_field, elt, buffer, rbe, event);
43084359 default:
43094360 return 0;
43104361 }
@@ -4351,7 +4402,8 @@ static int create_var_field(struct hist_trigger_data *hist_data, · 40 unmodified lines
43514402 if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_EXECNAME)
43524403 update_var_execname(hist_data->fields[val_idx]);
43534404
4354− if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_STRING)
4405+ if (!ret && hist_data->fields[val_idx]->flags &
4406+ (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE))
43554407 hist_data->fields[val_idx]->var_str_idx = hist_data->n_var_str++;
43564408
43574409 return ret;
@@ -5092,7 +5144,8 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, · 734 unmodified lines
50925144 if (hist_field->flags & HIST_FIELD_FL_VAR) {
50935145 var_idx = hist_field->var.idx;
50945146
5095− if (hist_field->flags & HIST_FIELD_FL_STRING) {
5147+ if (hist_field->flags &
5148+ (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE)) {
50965149 unsigned int str_start, var_str_idx, idx;
50975150 char *str, *val_str;
50985151 unsigned int size;
@@ -5105,9 +5158,20 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, · 6 unmodified lines
51055158 str = elt_data->field_var_str[idx];
51065159 val_str = (char *)(uintptr_t)hist_val;
51075160
5108− size = min(hist_field->size, STR_VAR_LEN_MAX);
5109− strscpy(str, val_str, size);
5110−
5161+ if (hist_field->flags & HIST_FIELD_FL_STRING) {
5162+ size = min(hist_field->size, STR_VAR_LEN_MAX);
5163+ strscpy(str, val_str, size);
5164+ } else {
5165+ char *stack_start = str + sizeof(unsigned long);
5166+ int e;
5167+
5168+ e = stack_trace_save((void *)stack_start,
5169+ HIST_STACKTRACE_DEPTH,
5170+ HIST_STACKTRACE_SKIP);
5171+ if (e < HIST_STACKTRACE_DEPTH - 1)
5172+ ((unsigned long *)stack_start)[e] = 0;
5173+ *((unsigned long *)str) = e;
5174+ }
51115175 hist_val = (u64)(uintptr_t)str;
51125176 }
51135177 tracing_map_set_var(elt, var_idx, hist_val);
@@ -5193,8 +5257,17 @@ static void event_hist_trigger(struct event_trigger_data *data, · 79 unmodified lines
51935257
51945258 if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
51955259 memset(entries, 0, HIST_STACKTRACE_SIZE);
5196− stack_trace_save(entries, HIST_STACKTRACE_DEPTH,
5197− HIST_STACKTRACE_SKIP);
5260+ if (key_field->field) {
5261+ unsigned long *stack, n_entries;
5262+
5263+ field_contents = hist_fn_call(key_field, elt, buffer, rbe, rec);
5264+ stack = (unsigned long *)(long)field_contents;
5265+ n_entries = *stack;
5266+ memcpy(entries, ++stack, n_entries * sizeof(unsigned long));
5267+ } else {
5268+ stack_trace_save(entries, HIST_STACKTRACE_DEPTH,
5269+ HIST_STACKTRACE_SKIP);
5270+ }
51985271 key = entries;
51995272 } else {
52005273 field_contents = hist_fn_call(key_field, elt, buffer, rbe, rec);
@@ -5297,7 +5370,10 @@ static void hist_trigger_print_key(struct seq_file *m, · 96 unmodified lines
52975370 seq_printf(m, "%s: %-30s[%3llu]", field_name,
52985371 syscall_name, uval);
52995372 } else if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
5300− seq_puts(m, "stacktrace:\n");
5373+ if (key_field->field)
5374+ seq_printf(m, "%s.stacktrace", key_field->field->name);
5375+ else
5376+ seq_puts(m, "stacktrace:\n");
53015377 hist_trigger_stacktrace_print(m,
53025378 key + key_field->offset,
53035379 HIST_STACKTRACE_DEPTH);
@@ -5842,7 +5918,8 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) · 538 unmodified lines
58425918
58435919 if (hist_field->flags) {
58445920 if (!(hist_field->flags & HIST_FIELD_FL_VAR_REF) &&
5845− !(hist_field->flags & HIST_FIELD_FL_EXPR)) {
5921+ !(hist_field->flags & HIST_FIELD_FL_EXPR) &&
5922+ !(hist_field->flags & HIST_FIELD_FL_STACKTRACE)) {
58465923 const char *flags = get_hist_field_flags(hist_field);
58475924
58485925 if (flags)
@@ -5875,9 +5952,12 @@ static int event_hist_trigger_print(struct seq_file *m, · 26 unmodified lines
58755952 if (i > hist_data->n_vals)
58765953 seq_puts(m, ",");
58775954
5878− if (field->flags & HIST_FIELD_FL_STACKTRACE)
5879− seq_puts(m, "stacktrace");
5880− else
5955+ if (field->flags & HIST_FIELD_FL_STACKTRACE) {
5956+ if (field->field)
5957+ seq_printf(m, "%s.stacktrace", field->field->name);
5958+ else
5959+ seq_puts(m, "stacktrace");
5960+ } else
58815961 hist_field_print(m, field);
58825962 }
58835963
kernel/trace/trace_events_synth.c+86−4
@@ -173,6 +173,14 @@ static int synth_field_is_string(char *type) · 172 unmodified lines
173173 return false;
174174 }
175175
176+static int synth_field_is_stack(char *type)
177+{
178+ if (strstr(type, "long[") != NULL)
179+ return true;
180+
181+ return false;
182+}
183+
176184 static int synth_field_string_size(char *type)
177185 {
178186 char buf[4], *end, *start;
@@ -248,6 +256,8 @@ static int synth_field_size(char *type) · 69 unmodified lines
248256 size = sizeof(gfp_t);
249257 else if (synth_field_is_string(type))
250258 size = synth_field_string_size(type);
259+ else if (synth_field_is_stack(type))
260+ size = 0;
251261
252262 return size;
253263 }
@@ -292,6 +302,8 @@ static const char *synth_field_fmt(char *type) · 38 unmodified lines
292302 fmt = "%x";
293303 else if (synth_field_is_string(type))
294304 fmt = "%.*s";
305+ else if (synth_field_is_stack(type))
306+ fmt = "%s";
295307
296308 return fmt;
297309 }
@@ -371,6 +383,23 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter, · 73 unmodified lines
371383 i == se->n_fields - 1 ? "" : " ");
372384 n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
373385 }
386+ } else if (se->fields[i]->is_stack) {
387+ u32 offset, data_offset, len;
388+ unsigned long *p, *end;
389+
390+ offset = (u32)entry->fields[n_u64];
391+ data_offset = offset & 0xffff;
392+ len = offset >> 16;
393+
394+ p = (void *)entry + data_offset;
395+ end = (void *)p + len - (sizeof(long) - 1);
396+
397+ trace_seq_printf(s, "%s=STACK:\n", se->fields[i]->name);
398+
399+ for (; *p && p < end; p++)
400+ trace_seq_printf(s, "=> %pS\n", (void *)*p);
401+ n_u64++;
402+
374403 } else {
375404 struct trace_print_flags __flags[] = {
376405 __def_gfpflag_names, {-1, NULL} };
@@ -416,8 +445,7 @@ static unsigned int trace_string(struct synth_trace_event *entry, · 39 unmodified lines
416445 if (is_dynamic) {
417446 u32 data_offset;
418447
419− data_offset = offsetof(typeof(*entry), fields);
420− data_offset += event->n_u64 * sizeof(u64);
448+ data_offset = struct_size(entry, fields, event->n_u64);
421449 data_offset += data_size;
422450
423451 len = kern_fetch_store_strlen((unsigned long)str_val);
@@ -447,6 +475,43 @@ static unsigned int trace_string(struct synth_trace_event *entry, · 23 unmodified lines
447475 return len;
448476 }
449477
478+static unsigned int trace_stack(struct synth_trace_event *entry,
479+ struct synth_event *event,
480+ long *stack,
481+ unsigned int data_size,
482+ unsigned int *n_u64)
483+{
484+ unsigned int len;
485+ u32 data_offset;
486+ void *data_loc;
487+
488+ data_offset = struct_size(entry, fields, event->n_u64);
489+ data_offset += data_size;
490+
491+ for (len = 0; len < HIST_STACKTRACE_DEPTH; len++) {
492+ if (!stack[len])
493+ break;
494+ }
495+
496+ /* Include the zero'd element if it fits */
497+ if (len < HIST_STACKTRACE_DEPTH)
498+ len++;
499+
500+ len *= sizeof(long);
501+
502+ /* Find the dynamic section to copy the stack into. */
503+ data_loc = (void *)entry + data_offset;
504+ memcpy(data_loc, stack, len);
505+
506+ /* Fill in the field that holds the offset/len combo */
507+ data_offset |= len << 16;
508+ *(u32 *)&entry->fields[*n_u64] = data_offset;
509+
510+ (*n_u64)++;
511+
512+ return len;
513+}
514+
450515 static notrace void trace_event_raw_event_synth(void *__data,
451516 u64 *var_ref_vals,
452517 unsigned int *var_ref_idx)
@@ -473,7 +538,12 @@ static notrace void trace_event_raw_event_synth(void *__data, · 20 unmodified lines
473538 val_idx = var_ref_idx[field_pos];
474539 str_val = (char *)(long)var_ref_vals[val_idx];
475540
476− len = kern_fetch_store_strlen((unsigned long)str_val);
541+ if (event->dynamic_fields[i]->is_stack) {
542+ len = *((unsigned long *)str_val);
543+ len *= sizeof(unsigned long);
544+ } else {
545+ len = kern_fetch_store_strlen((unsigned long)str_val);
546+ }
477547
478548 fields_size += len;
479549 }
@@ -499,6 +569,12 @@ static notrace void trace_event_raw_event_synth(void *__data, · 19 unmodified lines
499569 event->fields[i]->is_dynamic,
500570 data_size, &n_u64);
501571 data_size += len; /* only dynamic string increments */
572+ } else if (event->fields[i]->is_stack) {
573+ long *stack = (long *)(long)var_ref_vals[val_idx];
574+
575+ len = trace_stack(entry, event, stack,
576+ data_size, &n_u64);
577+ data_size += len;
502578 } else {
503579 struct synth_field *field = event->fields[i];
504580 u64 val = var_ref_vals[val_idx];
@@ -561,6 +637,9 @@ static int __set_synth_event_print_fmt(struct synth_event *event, · 56 unmodified lines
561637 event->fields[i]->is_dynamic)
562638 pos += snprintf(buf + pos, LEN_OR_ZERO,
563639 ", __get_str(%s)", event->fields[i]->name);
640+ else if (event->fields[i]->is_stack)
641+ pos += snprintf(buf + pos, LEN_OR_ZERO,
642+ ", __get_stacktrace(%s)", event->fields[i]->name);
564643 else
565644 pos += snprintf(buf + pos, LEN_OR_ZERO,
566645 ", REC->%s", event->fields[i]->name);
@@ -697,7 +776,8 @@ static struct synth_field *parse_synth_field(int argc, char **argv, · 130 unmodified lines
697776 ret = -EINVAL;
698777 goto free;
699778 } else if (size == 0) {
700− if (synth_field_is_string(field->type)) {
779+ if (synth_field_is_string(field->type) ||
780+ synth_field_is_stack(field->type)) {
701781 char *type;
702782
703783 len = sizeof("__data_loc ") + strlen(field->type) + 1;
@@ -728,6 +808,8 @@ static struct synth_field *parse_synth_field(int argc, char **argv, · 24 unmodified lines
728808
729809 if (synth_field_is_string(field->type))
730810 field->is_string = true;
811+ else if (synth_field_is_stack(field->type))
812+ field->is_stack = true;
731813
732814 field->is_signed = synth_field_signed(field->type);
733815 out:
kernel/trace/trace_osnoise.c+1−1
@@ -1539,7 +1539,7 @@ static void osnoise_sleep(void) · 1538 unmodified lines
15391539 wake_time = ktime_add_us(ktime_get(), interval);
15401540 __set_current_state(TASK_INTERRUPTIBLE);
15411541
1542− while (schedule_hrtimeout_range(&wake_time, 0, HRTIMER_MODE_ABS)) {
1542+ while (schedule_hrtimeout(&wake_time, HRTIMER_MODE_ABS)) {
15431543 if (kthread_should_stop())
15441544 break;
15451545 }
kernel/trace/trace_seq.c+23−0
@@ -403,3 +403,26 @@ int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, · 402 unmodified lines
403403 return 1;
404404 }
405405 EXPORT_SYMBOL(trace_seq_hex_dump);
406+
407+/*
408+ * trace_seq_acquire - acquire seq buffer with size len
409+ * @s: trace sequence descriptor
410+ * @len: size of buffer to be acquired
411+ *
412+ * acquire buffer with size of @len from trace_seq for output usage,
413+ * user can fill string into that buffer.
414+ *
415+ * Returns start address of acquired buffer.
416+ *
417+ * it allow multiple usage in one trace output function call.
418+ */
419+char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
420+{
421+ char *ret = trace_seq_buffer_ptr(s);
422+
423+ if (!WARN_ON_ONCE(seq_buf_buffer_left(&s->seq) < len))
424+ seq_buf_commit(&s->seq, len);
425+
426+ return ret;
427+}
428+EXPORT_SYMBOL(trace_seq_acquire);
kernel/trace/trace_synth.h+1−0
@@ -18,6 +18,7 @@ struct synth_field { · 17 unmodified lines
1818 bool is_signed;
1919 bool is_string;
2020 bool is_dynamic;
21+ bool is_stack;
2122 };
2223
2324 struct synth_event {
kernel/tracepoint.c+2−2
@@ -571,8 +571,8 @@ static void for_each_tracepoint_range( · 570 unmodified lines
571571 bool trace_module_has_bad_taint(struct module *mod)
572572 {
573573 return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP) |
574− (1 << TAINT_UNSIGNED_MODULE) |
575− (1 << TAINT_TEST));
574+ (1 << TAINT_UNSIGNED_MODULE) | (1 << TAINT_TEST) |
575+ (1 << TAINT_LIVEPATCH));
576576 }
577577
578578 static BLOCKING_NOTIFIER_HEAD(tracepoint_notify_list);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t