mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [GIT PULL] tracing: Fixes for 7.3
@ 2026-09-06 20:03 Steven Rostedt
  2026-09-06 21:50 ` pr-tracker-bot
  0 siblings, 1 reply; 4+ messages in thread
From: Steven Rostedt @ 2026-09-06 20:03 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: LKML, Masami Hiramatsu, Mathieu Desnoyers, Vincent Donnefort,
	Andrew Morton


Linus,

tracing fixes for v7.3:

- Fix several tracefs files that did not take the trace_array reference

  A trace instance can be created and destroyed in the tracefs "instances"
  directory via mkdir and rmdir respectively. The instance is represented by
  a trace_array descriptor. Most tracefs files pass the trace_array as the
  private data of the inode to the open/read/write functions. Since there is
  no locking between the time a task opens a file and the deletion of the
  instance (and the freeing of the trace_array), each open needs to get a
  reference to the trace_array and each close must remove it. A instance
  can't be removed if there's any reference taken on its trace_array. The
  open function uses trace_array_get() that takes a lock (preventing removal
  of instances) and iterates the list of all existing trace_arrays and if it
  finds a match, it takes the reference and releases the lock. If it doesn't
  find a match, it causes the open to return -ENODEV.

  There were some added files that did not take the trace_array reference
  on open that needed to be fixed. Sashiko also correctly pointed out that
  there were some files that took an address of an field or element of the
  trace_array which had a pointer back to the trace_array to take its
  reference on open. But this leaves a slight race between referencing this
  element to get the trace_array as the element itself could be freed. To
  solve this, some helper functions were created to look for trace_arrays
  with this field or element in the search so that the element did not have
  to be dereferenced before the trace_array's reference was taken.

- Add a lock around ftrace_ops initialization

  When a ftrace_ops is first used by ftrace, some internal initialization is
  performed on the ops. But if multiple tasks were calling functions that
  did this initialization, it could race and perform doing the
  initialization more than once, corrupting the internal data. Add a lock in
  the initialization code to prevent this from happening.

- Fix splice reads on mmapped buffers

  The logic in the ring buffer splice code for mmapped buffers is supposed
  to do a copy of the memory as the mapped buffers can't be given to splice.
  But there was an if statement within the copy code that would return a -1
  if a request for a full page was done and it wasn't a partial read. This
  is because this logic was written before mmapped buffers existed and this
  case didn't make sense at the time. For mmapped buffers it makes perfect
  sense and by returning early can drop a lot of pages unnecessarily.

- Have the persistent ring buffer validation check nr_subbufs

  Sashiko reported that the validation code was relying on the saved
  nr_subbufs to match the calculated nr_pages + 1 and if they were off, that
  the code could cause corruption. Sashiko is correct, and the saved
  nr_subbufs should be validated before assuming it is correct.

- Do not allow more than one instance with the same name on cmdline

  If an admin were to add more than one trace instances with the same name
  they all would be created, but only the first one would be accessible via
  tracefs. This used to not be allowed but some restructuring of code has
  since made it possible.

- Fix the race between subbuf resize and trace_pipe_raw readers

  If a task was reading trace_pipe_raw while another task was changing the
  ring buffer subbuf size, it could crash the reader. The trace_pipe_raw
  readers do get their own copy of the page from the buffer, but the code
  needs some restructuring to not have the resize of the subbuffers cause
  issues.

- Cap the size of the mapped (static) ring buffer nr_pages

  The meta data used for ring buffer mapped buffers is 32 bit in size. A
  normal ring buffer could (in theory) have more than 4 billion pages.
  But this is not allowed by mapped buffers, so enforce it.


Please pull the latest trace-v7.3-rc1 tree, which can be found at:


  git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
trace-v7.3-rc1

Tag SHA1: d878c05d090306c6cfb75b77ed73aad53677d59e
Head SHA1: d80e12156f1fd490adf29a8d28489725a3ac817a


Masami Hiramatsu (Google) (1):
      tracing: Fix to avoid creating trace instances with duplicate names

Steven Rostedt (7):
      tracing: Have show_event_filters/triggers files take trace array ref
      ftrace: Take trace_array reference before accessing its ftrace_ops
      ftrace: Synchronize the initialization of ftrace_ops
      tracing: Take trace_array reference when opening options file
      ring-buffer: Add checking nr_subbufs to persistent ring buffer validation
      tracing: Fix comment in tracing_buffers_splice_read()
      ring-buffer: Use a macro for static buffer bits

Vincent Donnefort (4):
      ring-buffer: Allow splice reads on static buffers
      tracing: Fix subbuf resize races with trace_pipe_raw readers
      ring-buffer: Cap static ring buffer nr_pages
      ring-buffer: Prevent truncation of nr_pages / nr_subbufs

----
 include/linux/ftrace.h               |   5 +-
 include/linux/ring_buffer.h          |   5 +-
 kernel/trace/ftrace.c                |  70 ++++++----
 kernel/trace/ring_buffer.c           | 239 +++++++++++++++++++++++------------
 kernel/trace/ring_buffer_benchmark.c |   6 +-
 kernel/trace/trace.c                 | 171 ++++++++++++++++---------
 kernel/trace/trace.h                 |  14 +-
 kernel/trace/trace_events.c          |  28 +++-
 kernel/trace/trace_functions.c       |   2 +-
 kernel/trace/trace_stack.c           |   2 +-
 10 files changed, 357 insertions(+), 185 deletions(-)
---------------------------

^ permalink raw reply	[flat|nested] 4+ messages in thread
* [GIT PULL] tracing: Fixes for 7.3
@ 2026-08-30  1:15 Steven Rostedt
  2026-08-30 17:23 ` pr-tracker-bot
  0 siblings, 1 reply; 4+ messages in thread
From: Steven Rostedt @ 2026-08-30  1:15 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: LKML, Masami Hiramatsu, Mathieu Desnoyers, Deepanshu Kartikey,
	Haotian Zhang, Hui Su, Ivan Immanuel Shaji,
	Jérémy Jean, Vincent Donnefort


Linus,

tracing fixes for v7.3:

- Fix error output of boot instance creation failure

  Currently if a boot instance creation fails, instead of printing out the
  name of the instance that failed, it prints "(null)". That is because it
  prints "cur_str" that had already been processed by strsep(). Print the
  saved name instead.

  While at it, print the error code of the failure.

- Fix use-after-free for same named historgrams

  Histograms can be named so that they can be used in multiple events. But
  if the named histogram has a variable attached, the second event that uses
  the named histogram which duplicates it and needs to free the original
  after duplication leaves the old variable in place and still visible. If
  another histogram uses than variable, it will use the stale one which will
  try to reference the freed duplicate histogram and crash the kernel.

  Free the duplicate variables along with the duplicated histogram data.

- Check return value of kthread_run() in event self test

  The events self tests uses a kthread for testing but does not check if it
  succeeded in creating a kthread. If the kthread creation were to fail, the
  code will still try to call kthread_stop() on the error returned.

- Fix race between reading trace_pipe and updating subbuffer size

  If a user is reading the trace_pipe file at the same time they update the
  ring buffer sub-buffer size, can cause the trace_pipe read to read stale
  data. Add trace_access_lock() around updating the ring buffer sub-buffer
  size.

- Fix eventfs_inode on failure path in creation of the events directory

  In the creation of the "events" directory, if after allocating the
  eventfs_inode a failure is detected, it calls cleanup_ei() which calls
  free_ei(). The free_ei() will test if eventfs_inode being freed has no
  children. It is a bug if it does. But on the failure case of the creation
  of the "events" directory, the children lists have not yet been
  initialized and the free will trigger a warning because list_empty() on an
  uninitialized list returns false.

  Move the initialization into init_ei() where it makes more sense and makes
  sure that a created eventfs_inode has its lists initialized upon creation.

- Check return value of kthread_run() in ftrace direct sample code

  The sample code that shows how to use the ftrace direct calls does not
  test the return of kthread_run() to see if it succeeds. Return a failure
  if the kthread_run() doesn't succeed.

- Clear user events state on fork in case of alloc failure

  On fork, the child gets a pointer to the parent's user events state. It
  makes a copy of it then updates the child's pointer to it. But if the
  allocation fails, the duplication function leaves the child with a pointer
  to its parent's descriptor. When the child cleans up its data, it will free
  the parent's descriptor while the parent is still using it.

  In the duplication function, set the child's user_event_mm to NULL before
  testing if the allocation succeeded, and when it exits it will not free
  the parent's descriptor.

- Fix retry exhaustion in simple ring buffer reader swap

  simple_ring_buffer_swap_reader_page() starts with retry set to 8 and
  post-decrements it only after a failed link replacement. On the final
  attempt, a successful replacement leaves retry at zero, while a failed
  replacement leaves it at -1.

  But the check for success expects the retry value to be non-zero and exits
  with an error on zero. This is the opposite result. Fix it.

- Fail nicely when the remote swap_reader_page() returns an error

  Currently, if the swap_reader_page() of a remote buffer fails, it triggers
  a WARN_ON_ONCE() and continues normally. Instead, have it exit with an
  error and a pr_warn() print instead of a full WARNING.


Please pull the latest trace-v7.3-2 tree, which can be found at:


  git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
trace-v7.3-2

Tag SHA1: dc1be90a7091efc5769819e7f333d2f1fe08a1a1
Head SHA1: 5eab74874d11160725c42ab676ba97a797a362eb


Deepanshu Kartikey (2):
      tracing: Fix use-after-free in trace_pipe read on sub-buffer order change
      eventfs: Initialize ei->children and ei->list in init_ei()

Haotian Zhang (2):
      samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify
      samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify

Hui Su (2):
      tracing: Fix use-after-free with same-name named triggers
      tracing: Fix crash passing ERR_PTR to kthread_stop()

Ivan Immanuel Shaji (2):
      tracing: Fix retry exhaustion in simple ring buffer reader swap
      ring-buffer: Stop remote reader update when page swap fails

Jérémy Jean (1):
      tracing/user_events: Clear copied tracing state before fork duplication

Vincent Donnefort (1):
      tracing: Fix logged instance name on creation failure

----
 fs/tracefs/event_inode.c                    |  7 ++-----
 kernel/trace/ring_buffer.c                  |  7 +++++--
 kernel/trace/simple_ring_buffer.c           |  4 ++--
 kernel/trace/trace.c                        |  6 +++++-
 kernel/trace/trace_events.c                 |  2 ++
 kernel/trace/trace_events_hist.c            |  4 +++-
 kernel/trace/trace_events_user.c            |  3 +++
 samples/ftrace/ftrace-direct-modify.c       | 12 +++++++++---
 samples/ftrace/ftrace-direct-multi-modify.c | 12 +++++++++---
 9 files changed, 40 insertions(+), 17 deletions(-)
---------------------------
diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 604ba3e841d2..6e3513b13cfa 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -438,6 +438,8 @@ static inline struct eventfs_inode *init_ei(struct eventfs_inode *ei, const char
 	if (!ei->name)
 		return NULL;
 	kref_init(&ei->kref);
+	INIT_LIST_HEAD(&ei->children);
+	INIT_LIST_HEAD(&ei->list);
 	return ei;
 }
 
@@ -729,8 +731,6 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode
 	ei->entries = entries;
 	ei->nr_entries = size;
 	ei->data = data;
-	INIT_LIST_HEAD(&ei->children);
-	INIT_LIST_HEAD(&ei->list);
 
 	scoped_guard(mutex, &eventfs_mutex) {
 		if (!parent->is_freed)
@@ -802,9 +802,6 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
 	ei->attr.uid = uid;
 	ei->attr.gid = gid;
 
-	INIT_LIST_HEAD(&ei->children);
-	INIT_LIST_HEAD(&ei->list);
-
 	ti = get_tracefs(inode);
 	ti->flags |= TRACEFS_EVENT_INODE;
 	ti->private = ei;
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 5fc009edc1ec..b7d076b6edcf 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -5805,8 +5805,11 @@ __rb_get_reader_page_from_remote(struct ring_buffer_per_cpu *cpu_buffer)
 
 	prev_reader = cpu_buffer->subbuf_ids[cpu_buffer->meta_page->reader.id];
 
-	WARN_ON_ONCE(cpu_buffer->remote->swap_reader_page(cpu_buffer->cpu,
-							  cpu_buffer->remote->priv));
+	if (cpu_buffer->remote->swap_reader_page(cpu_buffer->cpu,
+						 cpu_buffer->remote->priv)) {
+		pr_warn_ratelimited("Remote reader page swap failed\n");
+		return NULL;
+	}
 	/* nr_pages doesn't include the reader page */
 	if (WARN_ON_ONCE(cpu_buffer->meta_page->reader.id > cpu_buffer->nr_pages))
 		return NULL;
diff --git a/kernel/trace/simple_ring_buffer.c b/kernel/trace/simple_ring_buffer.c
index f4642f5adda3..49913bb0057a 100644
--- a/kernel/trace/simple_ring_buffer.c
+++ b/kernel/trace/simple_ring_buffer.c
@@ -160,8 +160,8 @@ int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buffer)
 		overrun = cpu_buffer->meta->overrun;
 	} while (!simple_bpage_unset_head_link(last, reader, SIMPLE_RB_LINK_NORMAL) && retry--);
 
-	if (!retry)
-		return -EINVAL;
+	if (retry < 0)
+		return -EBUSY;
 
 	cpu_buffer->head_page = simple_bpage_from_link(reader->link.next);
 	cpu_buffer->head_page->link.prev = &reader->link;
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 89dc1c0ebb90..60c87977f1e3 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8214,6 +8214,8 @@ buffer_subbuf_size_write(struct file *filp, const char __user *ubuf,
 	/* Do not allow tracing while changing the order of the ring buffer */
 	tracing_stop_tr(tr);
 
+	trace_access_lock(RING_BUFFER_ALL_CPUS);
+
 	old_order = ring_buffer_subbuf_order_get(tr->array_buffer.buffer);
 	if (old_order == order)
 		goto out;
@@ -8253,6 +8255,7 @@ buffer_subbuf_size_write(struct file *filp, const char __user *ubuf,
 #endif
 	(*ppos)++;
  out:
+	trace_access_unlock(RING_BUFFER_ALL_CPUS);
 	if (ret)
 		cnt = ret;
 	tracing_start_tr(tr);
@@ -9726,7 +9729,8 @@ __init static void enable_instances(void)
 
 		tr = trace_array_create_systems(name, NULL, addr, size);
 		if (IS_ERR(tr)) {
-			pr_warn("Tracing: Failed to create instance buffer %s\n", curr_str);
+			pr_warn("Tracing: Failed to create instance buffer '%s' (%ld)\n", name,
+				PTR_ERR(tr));
 			continue;
 		}
 
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 9f8f2d02276c..1d39eaf6a0f7 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -5019,6 +5019,8 @@ static __init void event_test_stuff(void)
 	struct task_struct *test_thread;
 
 	test_thread = kthread_run(event_test_thread, NULL, "test-events");
+	if (WARN_ON(IS_ERR(test_thread)))
+		return;
 	msleep(1);
 	kthread_stop(test_thread);
 }
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 893bd8b0e48a..963e0d6b61fd 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6661,8 +6661,10 @@ static int hist_register_trigger(char *glob,
 		tracing_set_filter_buffering(file->tr, true);
 	}
 
-	if (named_data)
+	if (named_data) {
+		remove_hist_vars(hist_data);
 		destroy_hist_data(hist_data);
+	}
  out:
 	return ret;
 }
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index 2bbc89d4a266..93cda2f6f269 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -868,6 +868,9 @@ void user_event_mm_dup(struct task_struct *t, struct user_event_mm *old_mm)
 	struct user_event_mm *mm = user_event_mm_alloc(t);
 	struct user_event_enabler *enabler;
 
+	/* On failure, do not free parent's copy */
+	t->user_event_mm = NULL;
+
 	if (!mm)
 		return;
 
diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-direct-modify.c
index 1ba1927b548e..164d9dd6fd92 100644
--- a/samples/ftrace/ftrace-direct-modify.c
+++ b/samples/ftrace/ftrace-direct-modify.c
@@ -320,9 +320,15 @@ static int __init ftrace_direct_init(void)
 	ftrace_set_filter_ip(&direct, (unsigned long) my_ip, 0, 0);
 	ret = register_ftrace_direct(&direct, my_tramp);
 
-	if (!ret)
-		simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn");
-	return ret;
+	if (ret)
+		return ret;
+	simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn");
+	if (IS_ERR(simple_tsk)) {
+		unregister_ftrace_direct(&direct, my_tramp, true);
+		return PTR_ERR(simple_tsk);
+	}
+
+	return 0;
 }
 
 static void __exit ftrace_direct_exit(void)
diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/ftrace-direct-multi-modify.c
index 7a7822dfeb50..b03766c6217b 100644
--- a/samples/ftrace/ftrace-direct-multi-modify.c
+++ b/samples/ftrace/ftrace-direct-multi-modify.c
@@ -364,9 +364,15 @@ static int __init ftrace_direct_multi_init(void)
 
 	ret = register_ftrace_direct(&direct, my_tramp);
 
-	if (!ret)
-		simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn");
-	return ret;
+	if (ret)
+		return ret;
+	simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn");
+	if (IS_ERR(simple_tsk)) {
+		unregister_ftrace_direct(&direct, my_tramp, true);
+		return PTR_ERR(simple_tsk);
+	}
+
+	return 0;
 }
 
 static void __exit ftrace_direct_multi_exit(void)

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-06 21:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-06 20:03 [GIT PULL] tracing: Fixes for 7.3 Steven Rostedt
2026-09-06 21:50 ` pr-tracker-bot
  -- strict thread matches above, loose matches on Subject: below --
2026-08-30  1:15 Steven Rostedt
2026-08-30 17:23 ` pr-tracker-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®