History

Merge tag 'trace-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing updates from Steven Rostedt: - Remove a redundant IS_ERR() check trace_pipe_open() already checks for IS_ERR() and does it again in the return path. Remove the return check. - Export seq_buf_putmem_hex() to allow kunit tests against them To add Kunit tests on seq_buf_putmem_hex(), it needs to be exported. - Replace strcat() and strcpy() with seq_buf() logic The code for synthetic events uses a series of strcat() and strcpy() which can be error prone. Replace them with seq_buf() logic that does all the necessary bound checking. - Add a lockdep rcu_is_watching() to trace_##event##_enabled() call The trace_##event##_enabled() is a static branch that is true if the "event" is enabled. But this can hide bugs if this logic is in a location where RCU is disabled and not "watching". It would only trigger if lockdep is enabled and the event is enabled. Add a "rcu_is_watching()" warning if lockdep is enabled in that helper function to trigger regardless if the event is enabled or not. - Remove the local variable in the trace_printk() macro For name space integrity, remove the _______STR variable in the trace_printk() macro for using the sizeof() macro directly. - Use guard()s for the trace_recursion_record.c file - Fix typo in a comment of eventfs_callback() kerneldoc - Use trace_call__##event() in events within trace_##event##_enabled() A couple of events are called within an if block guarded by trace_##event##_enabled(). That is a static key that is only enabled when the event is enabled. The trace_call_##event() calls the tracepoint code directly without adding a redundant static key for that check. - Allow perf to read synthetic events Currently, perf does not have the ability to enable a synthetic event. If it does, it will either cause a kernel warning or error with "No such device". Synthetic events are not much different than kprobes and perf can handle fine with a few modifications. - Replace printk(KERN_WARNING ...) with pr_warn() - Replace krealloc() on an array with krealloc_array() - Fix README file path name for synthetic events - Change tracing_map tracing_map_array to use a flexible array Instead of allocating a separate pointer to hold the pages field of tracing_map_array, allocate the pages field as a flexible array when allocating the structure. - Fold trace_iterator_increment() into trace_find_next_entry_inc() The function trace_iterator_increment() was only used by trace_find_next_entry_inc(). It's not big enough to be a helper function for one user. Fold it into its caller. - Make field_var_str field a flexible array of hist_elt_data Instead of allocating a separate pointer for the field_var_str array of the hist_elt_data structure, allocate it as a flexible array when allocating the structure. - Disable KCOV for trace_irqsoff.c Like trace_preemptirq.c, trace_irqsoff.c has code that will crash when KCOV is enabled on ARM. The irqsoff tracing can be called on ARM because the irqsoff tracing code can be run from early interrupt code and produce coverage unrelated to syscall inputs. - Fix warning in __unregister_ftrace_function() called by perf Perf calls unregister_ftrace_function() without checking if its ftrace_ops has already been unregistered. There's an error path where on clean up it will unregister the ftrace_ops even if it wasn't registered and causes a warning. * tag 'trace-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: perf/ftrace: Fix WARNING in __unregister_ftrace_function tracing: Disable KCOV instrumentation for trace_irqsoff.o tracing: Turn hist_elt_data field_var_str into a flexible array tracing: Move trace_iterator_increment() into trace_find_next_entry_inc() tracing: Simplify pages allocation for tracing_map logic tracing: Fix README path for synthetic_events tracing: Use krealloc_array() for trace option array growth tracing/branch: Use pr_warn() instead of printk(KERN_WARNING) tracing: Allow perf to read synthetic events HID: Use trace_call__##name() at guarded tracepoint call sites cpufreq: amd-pstate: Use trace_call__##name() at guarded tracepoint call site tracefs: Fix typo in a comment of eventfs_callback() kerneldoc tracing: Switch trace_recursion_record.c code over to use guard() tracing: Remove local variable for argument detection from trace_printk() tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled() tracing: Bound synthetic-field strings with seq_buf seq_buf: Export seq_buf_putmem_hex() and add KUnit tests tracing: Remove redundant IS_ERR() check in trace_pipe_open()

Linus Torvalds committed 4 months ago

Commit 23b5d042 parents 8c13415 958112317 files · +222 −113Browse files

Unified · Split

17 files
  1. drivers/cpufreq/amd-pstate.c +2 −1
  2. drivers/hid/intel-ish-hid/ipc/pci-ish.c +1 −1
  3. include/linux/trace_printk.h +1 −2
  4. include/linux/tracefs.h +1 −1
  5. include/linux/tracepoint.h +4 −0
  6. kernel/trace/Makefile +3 −2
  7. kernel/trace/trace.c +11 −14
  8. kernel/trace/trace_branch.c +3 −6
  9. kernel/trace/trace_event_perf.c +11 −1
  10. kernel/trace/trace_events_hist.c +40 −32
  11. kernel/trace/trace_events_synth.c +94 −27
  12. kernel/trace/trace_recursion_record.c +3 −5
  13. kernel/trace/trace_remote.c +1 −1
  14. kernel/trace/tracing_map.c +11 −19
  15. kernel/trace/tracing_map.h +1 −1
  16. lib/seq_buf.c +1 −0
  17. lib/tests/seq_buf_kunit.c +34 −0
drivers/cpufreq/amd-pstate.c+2−1
@@ -361,7 +361,8 @@ static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf) · 360 unmodified lines
361361
362362 out_trace:
363363 if (trace_amd_pstate_cppc_req2_enabled())
364− trace_amd_pstate_cppc_req2(cpudata->cpu, perf, changed, ret);
364+ trace_call__amd_pstate_cppc_req2(cpudata->cpu, perf, changed,
365+ ret);
365366 return ret;
366367 }
367368
drivers/hid/intel-ish-hid/ipc/pci-ish.c+1−1
@@ -110,7 +110,7 @@ void ish_event_tracer(struct ishtp_device *dev, const char *format, ...) · 109 unmodified lines
110110 vsnprintf(tmp_buf, sizeof(tmp_buf), format, args);
111111 va_end(args);
112112
113− trace_ishtp_dump(tmp_buf);
113+ trace_call__ishtp_dump(tmp_buf);
114114 }
115115 }
116116
include/linux/trace_printk.h+1−2
@@ -86,8 +86,7 @@ do { \ · 85 unmodified lines
8686
8787 #define trace_printk(fmt, ...) \
8888 do { \
89− char _______STR[] = __stringify((__VA_ARGS__)); \
90− if (sizeof(_______STR) > 3) \
89+ if (sizeof __stringify((__VA_ARGS__)) > 3) \
9190 do_trace_printk(fmt, ##__VA_ARGS__); \
9291 else \
9392 trace_puts(fmt); \
include/linux/tracefs.h+1−1
@@ -30,7 +30,7 @@ struct eventfs_file; · 29 unmodified lines
3030 * @data: data to pass to the created file ops
3131 * @fops: the file operations of the created file
3232 *
33− * The evetnfs files are dynamically created. The struct eventfs_entry array
33+ * The eventfs files are dynamically created. The struct eventfs_entry array
3434 * is passed to eventfs_create_dir() or eventfs_create_events_dir() that will
3535 * be used to create the files within those directories. When a lookup
3636 * or access to a file within the directory is made, the struct eventfs_entry
include/linux/tracepoint.h+4−0
@@ -294,6 +294,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) · 293 unmodified lines
294294 static inline bool \
295295 trace_##name##_enabled(void) \
296296 { \
297+ if (IS_ENABLED(CONFIG_LOCKDEP)) { \
298+ WARN_ONCE(!rcu_is_watching(), \
299+ "RCU not watching for tracepoint"); \
300+ } \
297301 return static_branch_unlikely(&__tracepoint_##name.key);\
298302 }
299303
kernel/trace/Makefile+3−2
@@ -48,9 +48,10 @@ ifdef CONFIG_GCOV_PROFILE_FTRACE · 47 unmodified lines
4848 GCOV_PROFILE := y
4949 endif
5050
51−# Functions in this file could be invoked from early interrupt
52−# code and produce random code coverage.
51+# Functions in these files can run from IRQ entry before hardirq context
52+# is visible to KCOV, and produce coverage unrelated to syscall inputs.
5353 KCOV_INSTRUMENT_trace_preemptirq.o := n
54+KCOV_INSTRUMENT_trace_irqsoff.o := n
5455
5556 CFLAGS_bpf_trace.o := -I$(src)
5657
kernel/trace/trace.c+11−14
@@ -2338,15 +2338,6 @@ void trace_last_func_repeats(struct trace_array *tr, · 2337 unmodified lines
23382338 __buffer_unlock_commit(buffer, event);
23392339 }
23402340
2341−static void trace_iterator_increment(struct trace_iterator *iter)
2342−{
2343− struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu);
2344−
2345− iter->idx++;
2346− if (buf_iter)
2347− ring_buffer_iter_advance(buf_iter);
2348−}
2349−
23502341 static struct trace_entry *
23512342 peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
23522343 unsigned long *lost_events)
@@ -2676,11 +2667,17 @@ struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, · 323 unmodified lines
26762667 /* Find the next real entry, and increment the iterator to the next entry */
26772668 void *trace_find_next_entry_inc(struct trace_iterator *iter)
26782669 {
2670+ struct ring_buffer_iter *buf_iter;
2671+
26792672 iter->ent = __find_next_entry(iter, &iter->cpu,
26802673 &iter->lost_events, &iter->ts);
26812674
2682− if (iter->ent)
2683− trace_iterator_increment(iter);
2675+ if (iter->ent) {
2676+ iter->idx++;
2677+ buf_iter = trace_buffer_iter(iter, iter->cpu);
2678+ if (buf_iter)
2679+ ring_buffer_iter_advance(buf_iter);
2680+ }
26842681
26852682 return iter->ent ? iter : NULL;
26862683 }
@@ -4474,7 +4471,7 @@ static const char readme_msg[] = · 1787 unmodified lines
44744471 "\t snapshot() - snapshot the trace buffer\n\n"
44754472 #endif
44764473 #ifdef CONFIG_SYNTH_EVENTS
4477− " events/synthetic_events\t- Create/append/remove/show synthetic events\n"
4474+ " synthetic_events\t- Create/append/remove/show synthetic events\n"
44784475 "\t Write into this file to define/undefine new synthetic events.\n"
44794476 "\t example: echo 'myevent u64 lat; char name[]; long[] stack' >> synthetic_events\n"
44804477 #endif
@@ -7928,8 +7925,8 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer, · 3447 unmodified lines
79287925 if (!topts)
79297926 return 0;
79307927
7931− tr_topts = krealloc(tr->topts, sizeof(*tr->topts) * (tr->nr_topts + 1),
7932− GFP_KERNEL);
7928+ tr_topts = krealloc_array(tr->topts, tr->nr_topts + 1, sizeof(*tr->topts),
7929+ GFP_KERNEL);
79337930 if (!tr_topts) {
79347931 kfree(topts);
79357932 return -ENOMEM;
kernel/trace/trace_branch.c+3−6
@@ -181,8 +181,7 @@ __init static int init_branch_tracer(void) · 180 unmodified lines
181181
182182 ret = register_trace_event(&trace_branch_event);
183183 if (!ret) {
184− printk(KERN_WARNING "Warning: could not register "
185− "branch events\n");
184+ pr_warn("Warning: could not register branch events\n");
186185 return 1;
187186 }
188187 return register_tracer(&branch_trace);
@@ -374,8 +373,7 @@ __init static int init_annotated_branch_stats(void) · 185 unmodified lines
374373
375374 ret = register_stat_tracer(&annotated_branch_stats);
376375 if (ret) {
377− printk(KERN_WARNING "Warning: could not register "
378− "annotated branches stats\n");
376+ pr_warn("Warning: could not register annotated branches stats\n");
379377 return ret;
380378 }
381379 return 0;
@@ -439,8 +437,7 @@ __init static int all_annotated_branch_stats(void) · 57 unmodified lines
439437
440438 ret = register_stat_tracer(&all_branch_stats);
441439 if (ret) {
442− printk(KERN_WARNING "Warning: could not register "
443− "all branches stats\n");
440+ pr_warn("Warning: could not register all branches stats\n");
444441 return ret;
445442 }
446443 return 0;
kernel/trace/trace_event_perf.c+11−1
@@ -497,7 +497,17 @@ static int perf_ftrace_function_register(struct perf_event *event) · 496 unmodified lines
497497 static int perf_ftrace_function_unregister(struct perf_event *event)
498498 {
499499 struct ftrace_ops *ops = &event->ftrace_ops;
500− int ret = unregister_ftrace_function(ops);
500+ int ret = 0;
501+
502+ /*
503+ * Perf will call this unconditionally even if the ops is not
504+ * enabled. The unregister_ftrace_function() will warn if called
505+ * when not enabled. Just bypass the unregistering if ops isn't
506+ * enabled here.
507+ */
508+ if (ops->flags & FTRACE_OPS_FL_ENABLED)
509+ ret = unregister_ftrace_function(ops);
510+
501511 ftrace_free_filter(ops);
502512 return ret;
503513 }
kernel/trace/trace_events_hist.c+40−32
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/module.h>
99 #include <linux/kallsyms.h>
1010 #include <linux/security.h>
11+#include <linux/seq_buf.h>
1112 #include <linux/mutex.h>
1213 #include <linux/slab.h>
1314 #include <linux/stacktrace.h>
@@ -682,8 +683,8 @@ struct track_data { · 668 unmodified lines
682683 struct hist_elt_data {
683684 char *comm;
684685 u64 *var_ref_vals;
685− char **field_var_str;
686686 int n_field_var_str;
687+ char *field_var_str[] __counted_by(n_field_var_str);
687688 };
688689
689690 struct snapshot_context {
@@ -1628,8 +1629,6 @@ static void hist_elt_data_free(struct hist_elt_data *elt_data) · 938 unmodified lines
16281629 for (i = 0; i < elt_data->n_field_var_str; i++)
16291630 kfree(elt_data->field_var_str[i]);
16301631
1631− kfree(elt_data->field_var_str);
1632−
16331632 kfree(elt_data->comm);
16341633 kfree(elt_data);
16351634 }
@@ -1649,10 +1648,19 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt) · 13 unmodified lines
16491648 struct hist_field *hist_field;
16501649 unsigned int i, n_str;
16511650
1652− elt_data = kzalloc_obj(*elt_data);
1651+ BUILD_BUG_ON(STR_VAR_LEN_MAX & (sizeof(u64) - 1));
1652+
1653+ n_str = hist_data->n_field_var_str + hist_data->n_save_var_str +
1654+ hist_data->n_var_str;
1655+ if (n_str > SYNTH_FIELDS_MAX)
1656+ return -EINVAL;
1657+
1658+ elt_data = kzalloc_flex(*elt_data, field_var_str, n_str);
16531659 if (!elt_data)
16541660 return -ENOMEM;
16551661
1662+ elt_data->n_field_var_str = n_str;
1663+
16561664 for_each_hist_field(i, hist_data) {
16571665 hist_field = hist_data->fields[i];
16581666
@@ -1666,24 +1674,8 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt) · 7 unmodified lines
16661674 }
16671675 }
16681676
1669− n_str = hist_data->n_field_var_str + hist_data->n_save_var_str +
1670− hist_data->n_var_str;
1671− if (n_str > SYNTH_FIELDS_MAX) {
1672− hist_elt_data_free(elt_data);
1673− return -EINVAL;
1674− }
1675−
1676− BUILD_BUG_ON(STR_VAR_LEN_MAX & (sizeof(u64) - 1));
1677−
16781677 size = STR_VAR_LEN_MAX;
16791678
1680− elt_data->field_var_str = kcalloc(n_str, sizeof(char *), GFP_KERNEL);
1681− if (!elt_data->field_var_str) {
1682− hist_elt_data_free(elt_data);
1683− return -EINVAL;
1684− }
1685− elt_data->n_field_var_str = n_str;
1686−
16871679 for (i = 0; i < n_str; i++) {
16881680 elt_data->field_var_str[i] = kzalloc(size, GFP_KERNEL);
16891681 if (!elt_data->field_var_str[i]) {
@@ -2967,13 +2959,22 @@ find_synthetic_field_var(struct hist_trigger_data *target_hist_data, · 1277 unmodified lines
29672959 {
29682960 struct hist_field *event_var;
29692961 char *synthetic_name;
2962+ struct seq_buf s;
29702963
29712964 synthetic_name = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
29722965 if (!synthetic_name)
29732966 return ERR_PTR(-ENOMEM);
29742967
2975− strcpy(synthetic_name, "synthetic_");
2976− strcat(synthetic_name, field_name);
2968+ seq_buf_init(&s, synthetic_name, MAX_FILTER_STR_VAL);
2969+ seq_buf_printf(&s, "synthetic_%s", field_name);
2970+
2971+ /* Terminate synthetic_name with a NUL. */
2972+ seq_buf_str(&s);
2973+
2974+ if (seq_buf_has_overflowed(&s)) {
2975+ kfree(synthetic_name);
2976+ return ERR_PTR(-E2BIG);
2977+ }
29772978
29782979 event_var = find_event_var(target_hist_data, system, event_name, synthetic_name);
29792980
@@ -3019,6 +3020,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, · 39 unmodified lines
30193020 struct hist_field *key_field;
30203021 struct hist_field *event_var;
30213022 char *saved_filter;
3023+ struct seq_buf s;
30223024 char *cmd;
30233025 int ret;
30243026
@@ -3063,28 +3065,34 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, · 38 unmodified lines
30633065 return ERR_PTR(-ENOMEM);
30643066 }
30653067
3068+ seq_buf_init(&s, cmd, MAX_FILTER_STR_VAL);
3069+
30663070 /* Use the same keys as the compatible histogram */
3067− strcat(cmd, "keys=");
3071+ seq_buf_puts(&s, "keys=");
30683072
30693073 for_each_hist_key_field(i, hist_data) {
30703074 key_field = hist_data->fields[i];
30713075 if (!first)
3072− strcat(cmd, ",");
3073− strcat(cmd, key_field->field->name);
3076+ seq_buf_putc(&s, ',');
3077+ seq_buf_puts(&s, key_field->field->name);
30743078 first = false;
30753079 }
30763080
30773081 /* Create the synthetic field variable specification */
3078− strcat(cmd, ":synthetic_");
3079− strcat(cmd, field_name);
3080− strcat(cmd, "=");
3081− strcat(cmd, field_name);
3082+ seq_buf_printf(&s, ":synthetic_%s=%s", field_name, field_name);
30823083
30833084 /* Use the same filter as the compatible histogram */
30843085 saved_filter = find_trigger_filter(hist_data, file);
3085− if (saved_filter) {
3086− strcat(cmd, " if ");
3087− strcat(cmd, saved_filter);
3086+ if (saved_filter)
3087+ seq_buf_printf(&s, " if %s", saved_filter);
3088+
3089+ /* Terminate cmd with a NUL. */
3090+ seq_buf_str(&s);
3091+
3092+ if (seq_buf_has_overflowed(&s)) {
3093+ kfree(cmd);
3094+ kfree(var_hist);
3095+ return ERR_PTR(-E2BIG);
30883096 }
30893097
30903098 var_hist->cmd = kstrdup(cmd, GFP_KERNEL);
kernel/trace/trace_events_synth.c+94−27
@@ -499,28 +499,19 @@ static unsigned int trace_stack(struct synth_trace_event *entry, · 498 unmodified lines
499499 return len;
500500 }
501501
502−static void trace_event_raw_event_synth(void *__data,
503− u64 *var_ref_vals,
504− unsigned int *var_ref_idx)
502+static __always_inline int get_field_size(struct synth_event *event,
503+ u64 *var_ref_vals,
504+ unsigned int *var_ref_idx)
505505 {
506− unsigned int i, n_u64, val_idx, len, data_size = 0;
507− struct trace_event_file *trace_file = __data;
508− struct synth_trace_event *entry;
509− struct trace_event_buffer fbuffer;
510− struct trace_buffer *buffer;
511− struct synth_event *event;
512− int fields_size = 0;
513−
514− event = trace_file->event_call->data;
515−
516− if (trace_trigger_soft_disabled(trace_file))
517− return;
506+ int fields_size;
518507
519508 fields_size = event->n_u64 * sizeof(u64);
520509
521− for (i = 0; i < event->n_dynamic_fields; i++) {
510+ for (int i = 0; i < event->n_dynamic_fields; i++) {
522511 unsigned int field_pos = event->dynamic_fields[i]->field_pos;
523512 char *str_val;
513+ int val_idx;
514+ int len;
524515
525516 val_idx = var_ref_idx[field_pos];
526517 str_val = (char *)(long)var_ref_vals[val_idx];
@@ -535,18 +526,18 @@ static void trace_event_raw_event_synth(void *__data, · 8 unmodified lines
535526
536527 fields_size += len;
537528 }
529+ return fields_size;
530+}
538531
539− /*
540− * Avoid ring buffer recursion detection, as this event
541− * is being performed within another event.
542− */
543− buffer = trace_file->tr->array_buffer.buffer;
544− guard(ring_buffer_nest)(buffer);
545−
546− entry = trace_event_buffer_reserve(&fbuffer, trace_file,
547− sizeof(*entry) + fields_size);
548− if (!entry)
549− return;
532+static __always_inline void write_synth_entry(struct synth_event *event,
533+ struct synth_trace_event *entry,
534+ u64 *var_ref_vals,
535+ unsigned int *var_ref_idx)
536+{
537+ int data_size = 0;
538+ int i, n_u64;
539+ int val_idx;
540+ int len;
550541
551542 for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
552543 val_idx = var_ref_idx[i];
@@ -587,10 +578,83 @@ static void trace_event_raw_event_synth(void *__data, · 34 unmodified lines
587578 n_u64++;
588579 }
589580 }
581+}
582+
583+static void trace_event_raw_event_synth(void *__data,
584+ u64 *var_ref_vals,
585+ unsigned int *var_ref_idx)
586+{
587+ struct trace_event_file *trace_file = __data;
588+ struct synth_trace_event *entry;
589+ struct trace_event_buffer fbuffer;
590+ struct trace_buffer *buffer;
591+ struct synth_event *event;
592+ int fields_size;
593+
594+ event = trace_file->event_call->data;
595+
596+ if (trace_trigger_soft_disabled(trace_file))
597+ return;
598+
599+ fields_size = get_field_size(event, var_ref_vals, var_ref_idx);
600+
601+ /*
602+ * Avoid ring buffer recursion detection, as this event
603+ * is being performed within another event.
604+ */
605+ buffer = trace_file->tr->array_buffer.buffer;
606+ guard(ring_buffer_nest)(buffer);
607+
608+ entry = trace_event_buffer_reserve(&fbuffer, trace_file,
609+ sizeof(*entry) + fields_size);
610+ if (!entry)
611+ return;
612+
613+ write_synth_entry(event, entry, var_ref_vals, var_ref_idx);
590614
591615 trace_event_buffer_commit(&fbuffer);
592616 }
593617
618+#ifdef CONFIG_PERF_EVENTS
619+static void perf_event_raw_event_synth(void *__data,
620+ u64 *var_ref_vals,
621+ unsigned int *var_ref_idx)
622+{
623+ struct trace_event_call *call = __data;
624+ struct synth_trace_event *entry;
625+ struct hlist_head *perf_head;
626+ struct synth_event *event;
627+ struct pt_regs *regs;
628+ int fields_size;
629+ size_t size;
630+ int context;
631+
632+ event = call->data;
633+
634+ perf_head = this_cpu_ptr(call->perf_events);
635+
636+ if (!perf_head || hlist_empty(perf_head))
637+ return;
638+
639+ fields_size = get_field_size(event, var_ref_vals, var_ref_idx);
640+
641+ size = ALIGN(sizeof(*entry) + fields_size, 8);
642+
643+ entry = perf_trace_buf_alloc(size, &regs, &context);
644+
645+ if (unlikely(!entry))
646+ return;
647+
648+ write_synth_entry(event, entry, var_ref_vals, var_ref_idx);
649+
650+ perf_fetch_caller_regs(regs);
651+
652+ perf_trace_buf_submit(entry, size, context,
653+ call->event.type, 1, regs,
654+ perf_head, NULL);
655+}
656+#endif
657+
594658 static void free_synth_event_print_fmt(struct trace_event_call *call)
595659 {
596660 if (call) {
@@ -917,6 +981,9 @@ static int register_synth_event(struct synth_event *event) · 320 unmodified lines
917981 call->flags = TRACE_EVENT_FL_TRACEPOINT;
918982 call->class->reg = synth_event_reg;
919983 call->class->probe = trace_event_raw_event_synth;
984+#ifdef CONFIG_PERF_EVENTS
985+ call->class->perf_probe = perf_event_raw_event_synth;
986+#endif
920987 call->data = event;
921988 call->tp = event->tp;
922989
kernel/trace/trace_recursion_record.c+3−5
@@ -180,9 +180,8 @@ static const struct seq_operations recursed_function_seq_ops = { · 179 unmodified lines
180180
181181 static int recursed_function_open(struct inode *inode, struct file *file)
182182 {
183− int ret = 0;
183+ guard(mutex)(&recursed_function_lock);
184184
185− mutex_lock(&recursed_function_lock);
186185 /* If this file was opened for write, then erase contents */
187186 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
188187 /* disable updating records */
@@ -194,10 +193,9 @@ static int recursed_function_open(struct inode *inode, struct file *file) · 5 unmodified lines
194193 atomic_set(&nr_records, 0);
195194 }
196195 if (file->f_mode & FMODE_READ)
197− ret = seq_open(file, &recursed_function_seq_ops);
198− mutex_unlock(&recursed_function_lock);
196+ return seq_open(file, &recursed_function_seq_ops);
199197
200− return ret;
198+ return 0;
201199 }
202200
203201 static ssize_t recursed_function_write(struct file *file,
kernel/trace/trace_remote.c+1−1
@@ -602,7 +602,7 @@ static int trace_pipe_open(struct inode *inode, struct file *filp) · 601 unmodified lines
602602
603603 filp->private_data = iter;
604604
605− return IS_ERR(iter) ? PTR_ERR(iter) : 0;
605+ return 0;
606606 }
607607
608608 static int trace_pipe_release(struct inode *inode, struct file *filp)
kernel/trace/tracing_map.c+11−19
@@ -288,9 +288,6 @@ static void tracing_map_array_clear(struct tracing_map_array *a) · 287 unmodified lines
288288 {
289289 unsigned int i;
290290
291− if (!a->pages)
292− return;
293−
294291 for (i = 0; i < a->n_pages; i++)
295292 memset(a->pages[i], 0, PAGE_SIZE);
296293 }
@@ -302,9 +299,6 @@ static void tracing_map_array_free(struct tracing_map_array *a) · 5 unmodified lines
302299 if (!a)
303300 return;
304301
305− if (!a->pages)
306− goto free;
307−
308302 for (i = 0; i < a->n_pages; i++) {
309303 if (!a->pages[i])
310304 break;
@@ -312,9 +306,6 @@ static void tracing_map_array_free(struct tracing_map_array *a) · 1 unmodified line
312306 free_page((unsigned long)a->pages[i]);
313307 }
314308
315− kfree(a->pages);
316−
317− free:
318309 kfree(a);
319310 }
320311
@@ -322,24 +313,25 @@ static struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts, · 1 unmodified line
322313 unsigned int entry_size)
323314 {
324315 struct tracing_map_array *a;
316+ unsigned int entry_size_shift;
317+ unsigned int entries_per_page;
318+ unsigned int n_pages;
325319 unsigned int i;
326320
327− a = kzalloc_obj(*a);
321+ entry_size_shift = fls(roundup_pow_of_two(entry_size) - 1);
322+ entries_per_page = PAGE_SIZE / (1 << entry_size_shift);
323+ n_pages = max(1, n_elts / entries_per_page);
324+
325+ a = kzalloc_flex(*a, pages, n_pages);
328326 if (!a)
329327 return NULL;
330328
331− a->entry_size_shift = fls(roundup_pow_of_two(entry_size) - 1);
332− a->entries_per_page = PAGE_SIZE / (1 << a->entry_size_shift);
333− a->n_pages = n_elts / a->entries_per_page;
334− if (!a->n_pages)
335− a->n_pages = 1;
329+ a->entry_size_shift = entry_size_shift;
330+ a->entries_per_page = entries_per_page;
331+ a->n_pages = n_pages;
336332 a->entry_shift = fls(a->entries_per_page) - 1;
337333 a->entry_mask = (1 << a->entry_shift) - 1;
338334
339− a->pages = kcalloc(a->n_pages, sizeof(void *), GFP_KERNEL);
340− if (!a->pages)
341− goto free;
342−
343335 for (i = 0; i < a->n_pages; i++) {
344336 a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL);
345337 if (!a->pages[i])
kernel/trace/tracing_map.h+1−1
@@ -167,7 +167,7 @@ struct tracing_map_array { · 166 unmodified lines
167167 unsigned int entry_shift;
168168 unsigned int entry_mask;
169169 unsigned int n_pages;
170− void **pages;
170+ void *pages[] __counted_by(n_pages);
171171 };
172172
173173 #define TRACING_MAP_ARRAY_ELT(array, idx) \
lib/seq_buf.c+1−0
@@ -298,6 +298,7 @@ int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, · 297 unmodified lines
298298 }
299299 return 0;
300300 }
301+EXPORT_SYMBOL_GPL(seq_buf_putmem_hex);
301302
302303 /**
303304 * seq_buf_path - copy a path into the sequence buffer
lib/tests/seq_buf_kunit.c+34−0
@@ -184,6 +184,38 @@ static void seq_buf_get_buf_commit_test(struct kunit *test) · 183 unmodified lines
184184 KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
185185 }
186186
187+static void seq_buf_putmem_hex_test(struct kunit *test)
188+{
189+ DECLARE_SEQ_BUF(s, 24);
190+ const u8 data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
191+#ifdef __BIG_ENDIAN
192+ const char *expected = "0001020304050607 0809 ";
193+#else
194+ const char *expected = "0706050403020100 0908 ";
195+#endif
196+
197+ KUNIT_EXPECT_EQ(test, seq_buf_putmem_hex(&s, data, sizeof(data)), 0);
198+ KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
199+ KUNIT_EXPECT_EQ(test, seq_buf_used(&s), strlen(expected));
200+ KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), expected);
201+}
202+
203+static void seq_buf_putmem_hex_overflow_test(struct kunit *test)
204+{
205+ DECLARE_SEQ_BUF(s, 20);
206+ const u8 data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
207+#ifdef __BIG_ENDIAN
208+ const char *expected = "0001020304050607 ";
209+#else
210+ const char *expected = "0706050403020100 ";
211+#endif
212+
213+ KUNIT_EXPECT_EQ(test, seq_buf_putmem_hex(&s, data, sizeof(data)), -1);
214+ KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
215+ KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 20);
216+ KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), expected);
217+}
218+
187219 static struct kunit_case seq_buf_test_cases[] = {
188220 KUNIT_CASE(seq_buf_init_test),
189221 KUNIT_CASE(seq_buf_declare_test),
@@ -194,6 +226,8 @@ static struct kunit_case seq_buf_test_cases[] = { · 4 unmodified lines
194226 KUNIT_CASE(seq_buf_printf_test),
195227 KUNIT_CASE(seq_buf_printf_overflow_test),
196228 KUNIT_CASE(seq_buf_get_buf_commit_test),
229+ KUNIT_CASE(seq_buf_putmem_hex_test),
230+ KUNIT_CASE(seq_buf_putmem_hex_overflow_test),
197231 {}
198232 };
199233