Commit cb30bf881c5b for kernel

commit cb30bf881c5b4ee8b879558a2fce93d7de652955
Merge: c9e03d59483a 621a59d8fc67
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Fri Apr 17 09:43:12 2026 -0700

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

    Pull tracing updates from Steven Rostedt:

     - Fix printf format warning for bprintf

       sunrpc uses a trace_printk() that triggers a printf warning during
       the compile. Move the __printf() attribute around for when debugging
       is not enabled the warning will go away

     - Remove redundant check for EVENT_FILE_FL_FREED in
       event_filter_write()

       The FREED flag is checked in the call to event_file_file() and then
       checked again right afterward, which is unneeded

     - Clean up event_file_file() and event_file_data() helpers

       These helper functions played a different role in the past, but now
       with eventfs, the READ_ONCE() isn't needed. Simplify the code a bit
       and also add a warning to event_file_data() if the file or its data
       is not present

     - Remove updating file->private_data in tracing open

       All access to the file private data is handled by the helper
       functions, which do not use file->private_data. Stop updating it on
       open

     - Show ENUM names in function arguments via BTF in function tracing

       When showing the function arguments when func-args option is set for
       function tracing, if one of the arguments is found to be an enum,
       show the name of the enum instead of its number

     - Add new trace_call__##name() API for tracepoints

       Tracepoints are enabled via static_branch() blocks, where when not
       enabled, there's only a nop that is in the code where the execution
       will just skip over it. When tracing is enabled, the nop is converted
       to a direct jump to the tracepoint code. Sometimes more calculations
       are required to be performed to update the parameters of the
       tracepoint. In this case, trace_##name##_enabled() is called which is
       a static_branch() that gets enabled only when the tracepoint is
       enabled. This allows the extra calculations to also be skipped by the
       nop:

            if (trace_foo_enabled()) {
                    x = bar();
                    trace_foo(x);
            }

       Where the x=bar() is only performed when foo is enabled. The problem
       with this approach is that there's now two static_branch() calls. One
       for checking if the tracepoint is enabled, and then again to know if
       the tracepoint should be called. The second one is redundant

       Introduce trace_call__foo() that will call the foo() tracepoint
       directly without doing a static_branch():

            if (trace_foo_enabled()) {
                    x = bar();
                    trace_call__foo();
            }

     - Update various locations to use the new trace_call__##name() API

     - Move snapshot code out of trace.c

       Cleaning up trace.c to not be a "dump all", move the snapshot code
       out of it and into a new trace_snapshot.c file

     - Clean up some "%*.s" to "%*s"

     - Allow boot kernel command line options to be called multiple times

       Have options like:

            ftrace_filter=foo ftrace_filter=bar ftrace_filter=zoo

       Equal to:

            ftrace_filter=foo,bar,zoo

     - Fix ipi_raise event CPU field to be a CPU field

       The ipi_raise target_cpus field is defined as a __bitmask(). There is
       now a __cpumask() field definition. Update the field to use that

     - Have hist_field_name() use a snprintf() and not a series of strcat()

       It's safer to use snprintf() that a series of strcat()

     - Fix tracepoint regfunc balancing

       A tracepoint can define a "reg" and "unreg" function that gets called
       before the tracepoint is enabled, and after it is disabled
       respectively. But on error, after the "reg" func is called and the
       tracepoint is not enabled, the "unreg" function is not called to tear
       down what the "reg" function performed

     - Fix output that shows what histograms are enabled

       Event variables are displayed incorrectly in the histogram output

       Instead of "sched.sched_wakeup.$var", it is showing
       "$sched.sched_wakeup.var" where the '$' is in the incorrect location

     - Some other simple cleanups

    * tag 'trace-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: (24 commits)
      selftests/ftrace: Add test case for fully-qualified variable references
      tracing: Fix fully-qualified variable reference printing in histograms
      tracepoint: balance regfunc() on func_add() failure in tracepoint_add_func()
      tracing: Rebuild full_name on each hist_field_name() call
      tracing: Report ipi_raise target CPUs as cpumask
      tracing: Remove duplicate latency_fsnotify() stub
      tracing: Preserve repeated trace_trigger boot parameters
      tracing: Append repeated boot-time tracing parameters
      tracing: Remove spurious default precision from show_event_trigger/filter formats
      cpufreq: Use trace_call__##name() at guarded tracepoint call sites
      tracing: Remove tracing_alloc_snapshot() when snapshot isn't defined
      tracing: Move snapshot code out of trace.c and into trace_snapshot.c
      mm: damon: Use trace_call__##name() at guarded tracepoint call sites
      btrfs: Use trace_call__##name() at guarded tracepoint call sites
      spi: Use trace_call__##name() at guarded tracepoint call sites
      i2c: Use trace_call__##name() at guarded tracepoint call sites
      kernel: Use trace_call__##name() at guarded tracepoint call sites
      tracepoint: Add trace_call__##name() API
      tracing: trace_mmap.h: fix a kernel-doc warning
      tracing: Pretty-print enum parameters in function arguments
      ...

diff --cc kernel/trace/trace.c
index e9455d46ec16,284f813a61f8..6eb4d3097a4d
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@@ -7299,52 -6464,9 +6529,14 @@@ static int tracing_clock_open(struct in
  	if (ret)
  		return ret;

- 	switch (val) {
- 	case 0:
- 		if (iter->cpu_file != RING_BUFFER_ALL_CPUS)
- 			return -EINVAL;
- 		if (tr->allocated_snapshot)
- 			free_snapshot(tr);
- 		break;
- 	case 1:
- /* Only allow per-cpu swap if the ring buffer supports it */
- #ifndef CONFIG_RING_BUFFER_ALLOW_SWAP
- 		if (iter->cpu_file != RING_BUFFER_ALL_CPUS)
- 			return -EINVAL;
- #endif
- 		if (tr->allocated_snapshot)
- 			ret = resize_buffer_duplicate_size(&tr->snapshot_buffer,
- 					&tr->array_buffer, iter->cpu_file);
-
- 		ret = tracing_arm_snapshot_locked(tr);
- 		if (ret)
- 			return ret;
-
- 		/* Now, we're going to swap */
- 		if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
- 			local_irq_disable();
- 			update_max_tr(tr, current, smp_processor_id(), NULL);
- 			local_irq_enable();
- 		} else {
- 			smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer,
- 						 (void *)tr, 1);
- 		}
- 		tracing_disarm_snapshot(tr);
- 		break;
- 	default:
- 		if (tr->allocated_snapshot) {
- 			if (iter->cpu_file == RING_BUFFER_ALL_CPUS)
- 				tracing_reset_online_cpus(&tr->snapshot_buffer);
- 			else
- 				tracing_reset_cpu(&tr->snapshot_buffer, iter->cpu_file);
- 		}
- 		break;
++	if ((file->f_mode & FMODE_WRITE) && trace_array_is_readonly(tr)) {
++		trace_array_put(tr);
++		return -EACCES;
 +	}
 +
- 	if (ret >= 0) {
- 		*ppos += cnt;
- 		ret = cnt;
- 	}
+ 	ret = single_open(file, tracing_clock_show, inode->i_private);
+ 	if (ret < 0)
+ 		trace_array_put(tr);

  	return ret;
  }
diff --cc kernel/trace/trace.h
index e68f9c2027eb,90d67f4432f5..80fe152af1dd
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@@ -705,14 -693,42 +709,48 @@@ struct dentry *trace_create_file(const
  				 struct dentry *parent,
  				 void *data,
  				 const struct file_operations *fops);
 +struct dentry *trace_create_cpu_file(const char *name,
 +				     umode_t mode,
 +				     struct dentry *parent,
 +				     void *data,
 +				     long cpu,
 +				     const struct file_operations *fops);
- int tracing_get_cpu(struct inode *inode);

+ struct trace_iterator *__tracing_open(struct inode *inode, struct file *file,
+ 				      bool snapshot);
+ int tracing_buffers_open(struct inode *inode, struct file *filp);
+ ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf,
+ 			     size_t count, loff_t *ppos);
+ int tracing_buffers_release(struct inode *inode, struct file *file);
+ ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos,
+ 		   struct pipe_inode_info *pipe, size_t len, unsigned int flags);
+
+ ssize_t tracing_nsecs_read(unsigned long *ptr, char __user *ubuf,
+ 			   size_t cnt, loff_t *ppos);
+ ssize_t tracing_nsecs_write(unsigned long *ptr, const char __user *ubuf,
+ 			    size_t cnt, loff_t *ppos);
+
+ void trace_set_buffer_entries(struct array_buffer *buf, unsigned long val);
+
+ /*
+  * Should be used after trace_array_get(), trace_types_lock
+  * ensures that i_cdev was already initialized.
+  */
+ static inline int tracing_get_cpu(struct inode *inode)
+ {
+ 	if (inode->i_cdev) /* See trace_create_cpu_file() */
+ 		return (long)inode->i_cdev - 1;
+ 	return RING_BUFFER_ALL_CPUS;
+ }
+ void tracing_reset_cpu(struct array_buffer *buf, int cpu);
+
+ struct ftrace_buffer_info {
+ 	struct trace_iterator	iter;
+ 	void			*spare;
+ 	unsigned int		spare_cpu;
+ 	unsigned int		spare_size;
+ 	unsigned int		read;
+ };

  /**
   * tracer_tracing_is_on_cpu - show real state of ring buffer enabled on for a cpu