tracing: Updates for v6.17
cover tracing: Updates for v6.17
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
trace/for-next
Head SHA1: 9ba817fb7c6afd3c86a6d4c3b822924b87ef0348
Arnd Bergmann (1):
kernel: trace: preemptirq_delay_test: use offstack cpu mask
Nam Cao (1):
tracing: Remove pointless memory barriers
Ricardo Neri (1):
tracing/sched: Remove obsolete comment on suffixes
Steven Rostedt (4):
tracing: Use queue_rcu_work() to free filters
tracing: Remove EVENT_FILE_FL_SOFT_MODE flag
tracing: Fix comment in trace_module_remove_events()
tracing: Deprecate auto-mounting tracefs in debugfs
Yury Norov (1):
tracing: Replace opencoded cpumask_next_wrap() in move_to_next_cpu()
----
.../ABI/obsolete/automount-tracefs-debugfs | 20 ++++++++++++++++ include/linux/trace_events.h | 3 --- include/trace/events/sched.h | 2 -- kernel/trace/Kconfig | 13 ++++++++++ kernel/trace/preemptirq_delay_test.c | 13 ++++++---- kernel/trace/rv/rv.c | 6 ----- kernel/trace/trace.c | 21 ++++++++-------- kernel/trace/trace_events.c | 26 ++++++++++---------- kernel/trace/trace_events_filter.c | 28 +++++++++++++++------- kernel/trace/trace_hwlat.c | 5 +--- 10 files changed, 86 insertions(+), 51 deletions(-) create mode 100644 Documentation/ABI/obsolete/automount-tracefs-debugfs
PATCH 1/8 tracing: Replace opencoded cpumask_next_wrap() in move_to_next_cpu()
From: Yury Norov <[email protected]>
The dedicated cpumask_next_wrap() is more verbose and effective than cpumask_next() followed by cpumask_first().
--- kernel/trace/trace_hwlat.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
kernel/trace/trace_hwlat.c +1 -4
@@ -325,12 +325,9 @@ static void move_to_next_cpu(void)cpus_read_lock ();cpumask_and (current_mask, cpu_online_mask, tr->tracing_cpumask); - next_cpu =cpumask_next (raw_smp_processor_id (), current_mask); + next_cpu =cpumask_next_wrap (raw_smp_processor_id (), current_mask);cpus_read_unlock (); -if (next_cpu >= nr_cpu_ids) - next_cpu =cpumask_first (current_mask); -if (next_cpu >= nr_cpu_ids)/* Shouldn't happen! */ goto change_mode;
Signature · 1 line
2.47.2
PATCH 2/8 tracing: Use queue_rcu_work() to free filters
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Freeing of filters requires to wait for both an RCU grace period as well as a RCU task trace wait period after they have been detached from their lists. The trace task period can be quite large so the freeing of the filters was moved to use the call_rcu*() routines. The problem with that is that the callback functions of call_rcu*() is done from a soft irq and can cause latencies if the callback takes a bit of time.
The filters are freed per event in a system and the syscalls system contains an event per system call, which can be over 700 events. Freeing 700 filters in a bottom half is undesirable.
Instead, move the freeing to use queue_rcu_work() which is done in task context.
--- kernel/trace/trace_events_filter.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
kernel/trace/trace_events_filter.c +20 -8
@@ -1344,13 +1344,14 @@ struct filter_list {struct filter_head {struct list_head list; -struct rcu_head rcu; +union { +struct rcu_head rcu; +struct rcu_work rwork; + }; }; - -static void free_filter_list (struct rcu_head *rhp) +static void free_filter_list (struct filter_head *filter_list) { - struct filter_head *filter_list = container_of(rhp, struct filter_head, rcu);struct filter_list *filter_item, *tmp;list_for_each_entry_safe (filter_item, tmp, &filter_list->list, list) {
@@ -1361,9 +1362,20 @@ static void free_filter_list(struct rcu_head *rhp)kfree (filter_list); } +static void free_filter_list_work (struct work_struct *work) +{ +struct filter_head *filter_list; + + filter_list = container_of(to_rcu_work(work), struct filter_head, rwork); +free_filter_list (filter_list); +} +static void free_filter_list_tasks (struct rcu_head *rhp) { -call_rcu (rhp, free_filter_list); + struct filter_head *filter_list = container_of(rhp, struct filter_head, rcu); + +INIT_RCU_WORK (&filter_list->rwork, free_filter_list_work); +queue_rcu_work (system_wq, &filter_list->rwork); }/*
@@ -1460,7 +1472,7 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir,tracepoint_synchronize_unregister ();if (head) -free_filter_list (&head->rcu); +free_filter_list (head);list_for_each_entry (file, &tr->events, list) {if (file->system != dir || !file->filter)
@@ -2305,7 +2317,7 @@ static int process_system_preds(struct trace_subsystem_dir *dir,return 0 ; fail:/* No call succeeded */ -free_filter_list (&filter_list->rcu); +free_filter_list (filter_list);parse_error (pe,FILT_ERR_BAD_SUBSYS_FILTER ,0 );return -EINVAL ; fail_mem:
@@ -2315,7 +2327,7 @@ static int process_system_preds(struct trace_subsystem_dir *dir,if (!fail)delay_free_filter (filter_list);else -free_filter_list (&filter_list->rcu); +free_filter_list (filter_list);return -ENOMEM ; }
Signature · 1 line
2.47.2
PATCH 3/8 kernel: trace: preemptirq_delay_test: use offstack cpu mask
In reply to Steven RostedtFrom: Arnd Bergmann <[email protected]>
A CPU mask on the stack is broken for large values of CONFIG_NR_CPUS:
kernel/trace/preemptirq_delay_test.c: In function ‘preemptirq_delay_run’:kernel/trace/preemptirq_delay_test.c:143:1: error: the frame size of 8512 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
Fall back to dynamic allocation here.
--- kernel/trace/preemptirq_delay_test.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
kernel/trace/preemptirq_delay_test.c +9 -4
@@ -117,12 +117,15 @@ static int preemptirq_delay_run(void *data) {int i;int s =MIN (burst_size,NR_TEST_FUNCS ); -struct cpumask cpu_mask; +cpumask_var_t cpu_mask; + +if (!alloc_cpumask_var (&cpu_mask,GFP_KERNEL )) +return -ENOMEM ;if (cpu_affinity >-1 ) { -cpumask_clear (&cpu_mask); -cpumask_set_cpu (cpu_affinity, &cpu_mask); -if (set_cpus_allowed_ptr (current, &cpu_mask)) +cpumask_clear (cpu_mask); +cpumask_set_cpu (cpu_affinity, cpu_mask); +if (set_cpus_allowed_ptr (current, cpu_mask))pr_err ("cpu_affinity:%d, failed\n" , cpu_affinity); }
@@ -139,6 +142,8 @@ static int preemptirq_delay_run(void *data)__set_current_state (TASK_RUNNING ); +free_cpumask_var (cpu_mask); +return 0 ; }
Signature · 1 line
2.47.2
PATCH 4/8 tracing/sched: Remove obsolete comment on suffixes
In reply to Steven RostedtFrom: Ricardo Neri <[email protected]>
Commit ac01fa73f530 ("tracepoint: Have tracepoints created with DECLARE_ TRACE() have _tp suffix") makes it unnecessary to manually add a suffix.
Remove a now obsolete comment.
--- include/trace/events/sched.h | 2 -- 1 file changed, 2 deletions(-)
include/trace/events/sched.h +0 -2
@@ -829,8 +829,6 @@ TRACE_EVENT(sched_wake_idle_without_ipi,/* * Following tracepoints are not exported in tracefs and provide hooking * mechanisms only for testing and debugging purposes. -* -* Postfixed with _tp to make them easily identifiable in the code. */ DECLARE_TRACE(pelt_cfs, TP_PROTO(struct cfs_rq *cfs_rq),
Signature · 1 line
2.47.2
PATCH 5/8 tracing: Remove pointless memory barriers
In reply to Steven RostedtFrom: Nam Cao <[email protected]>
Memory barriers are useful to ensure memory accesses from one CPU appear in the original order as seen by other CPUs.
Some smp_rmb() and smp_wmb() are used, but they are not ordering multiple memory accesses.
Remove them.
--- kernel/trace/rv/rv.c | 6 ------ kernel/trace/trace.c | 7 ------- 2 files changed, 13 deletions(-)
kernel/trace/rv/rv.c +0 -6
@@ -675,8 +675,6 @@ static bool __read_mostly monitoring_on;*/ bool rv_monitoring_on (void ) { -/* Ensures that concurrent monitors read consistent monitoring_on */ -smp_rmb ();return READ_ONCE (monitoring_on); }
@@ -696,8 +694,6 @@ static ssize_t monitoring_on_read_data(struct file *filp, char __user *user_buf,static void turn_monitoring_off (void ) {WRITE_ONCE (monitoring_on, false); -/* Ensures that concurrent monitors read consistent monitoring_on */ -smp_wmb (); }static void reset_all_monitors (void )
@@ -713,8 +709,6 @@ static void reset_all_monitors(void)static void turn_monitoring_on (void ) {WRITE_ONCE (monitoring_on, true); -/* Ensures that concurrent monitors read consistent monitoring_on */ -smp_wmb (); }static void turn_monitoring_on_with_reset (void )
kernel/trace/trace.c +0 -7
@@ -936,7 +936,6 @@ int tracing_is_enabled(void)* return the mirror variable of the state of the ring buffer. * It's a little racy, but we don't really care. */ -smp_rmb ();return !global_trace.buffer_disabled; }
@@ -1107,8 +1106,6 @@ void tracer_tracing_on(struct trace_array *tr)* important to be fast than accurate. */ tr->buffer_disabled =0 ; -/* Make the flag seen by readers */ -smp_wmb (); }/**
@@ -1640,8 +1637,6 @@ void tracer_tracing_off(struct trace_array *tr)* important to be fast than accurate. */ tr->buffer_disabled =1 ; -/* Make the flag seen by readers */ -smp_wmb (); }/**
@@ -2710,8 +2705,6 @@ void trace_buffered_event_enable(void)static void enable_trace_buffered_event (void *data) { -/* Probably not needed, but do it anyway */ -smp_rmb ();this_cpu_dec (trace_buffered_event_cnt); }
Signature · 1 line
2.47.2
PATCH 6/8 tracing: Remove EVENT_FILE_FL_SOFT_MODE flag
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
When soft disabling of trace events was first created, it needed to have a way to know if a file had a user that was using it with soft disabled (for triggers that need to enable or disable events from a context that can not really enable or disable the event, it would set SOFT_DISABLED to state it is disabled). The flag SOFT_MODE was used to denote that an event had a user that would enable or disable it via the SOFT_DISABLED flag.
Commit 1cf4c0732db3c ("tracing: Modify soft-mode only if there's no other referrer") fixed a bug where if two users were using the SOFT_DISABLED flag the accounting would get messed up as the SOFT_MODE flag could only handle one user. That commit added the sm_ref counter which kept track of how many users were using the event in "soft mode". This made the SOFT_MODE flag redundant as it should only be set if the sm_ref counter is non zero.
Remove the SOFT_MODE flag and just use the sm_ref counter to know the event is in soft mode or not. This makes the code a bit simpler.
--- include/linux/trace_events.h | 3 --- kernel/trace/trace_events.c | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 15 deletions(-)
include/linux/trace_events.h +0 -3
@@ -480,7 +480,6 @@ enum {EVENT_FILE_FL_RECORDED_TGID_BIT ,EVENT_FILE_FL_FILTERED_BIT ,EVENT_FILE_FL_NO_SET_FILTER_BIT , -EVENT_FILE_FL_SOFT_MODE_BIT ,EVENT_FILE_FL_SOFT_DISABLED_BIT ,EVENT_FILE_FL_TRIGGER_MODE_BIT , EVENT_FILE_FL_TRIGGER_COND_BIT,
@@ -618,7 +617,6 @@ extern int __kprobe_event_add_fields(struct dynevent_cmd *cmd, ...);* RECORDED_TGID - The tgids should be recorded at sched_switch * FILTERED - The event has a filter attached * NO_SET_FILTER - Set when filter has error and is to be ignored -* SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED * SOFT_DISABLED - When set, do not trace the event (even though its * tracepoint may be enabled) * TRIGGER_MODE - When set, invoke the triggers associated with the event
@@ -633,7 +631,6 @@ enum {EVENT_FILE_FL_RECORDED_TGID = (1 <<EVENT_FILE_FL_RECORDED_TGID_BIT ),EVENT_FILE_FL_FILTERED = (1 <<EVENT_FILE_FL_FILTERED_BIT ),EVENT_FILE_FL_NO_SET_FILTER = (1 <<EVENT_FILE_FL_NO_SET_FILTER_BIT ), -EVENT_FILE_FL_SOFT_MODE = (1 <<EVENT_FILE_FL_SOFT_MODE_BIT ),EVENT_FILE_FL_SOFT_DISABLED = (1 <<EVENT_FILE_FL_SOFT_DISABLED_BIT ),EVENT_FILE_FL_TRIGGER_MODE = (1 <<EVENT_FILE_FL_TRIGGER_MODE_BIT ), EVENT_FILE_FL_TRIGGER_COND = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT),
kernel/trace/trace_events.c +12 -12
@@ -768,6 +768,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, {struct trace_event_call *call = file->event_call;struct trace_array *tr = file->tr; +bool soft_mode =atomic_read (&file->sm_ref) !=0 ;int ret =0 ;int disable;
@@ -782,7 +783,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,* is set we do not want the event to be enabled before we * clear the bit. * -* When soft_disable is not set but the SOFT_MODE flag is, +* When soft_disable is not set but the soft_mode is, * we do nothing. Do not disable the tracepoint, otherwise * "soft enable"s (clearing the SOFT_DISABLED bit) wont work. */
@@ -790,11 +791,11 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,if (atomic_dec_return (&file->sm_ref) >0 )break ; disable = file->flags &EVENT_FILE_FL_SOFT_DISABLED ; -clear_bit (EVENT_FILE_FL_SOFT_MODE_BIT , &file->flags); + soft_mode = false;/* Disable use of trace_buffered_event */ trace_buffered_event_disable (); }else - disable = !(file->flags &EVENT_FILE_FL_SOFT_MODE ); + disable = !soft_mode;if (disable && (file->flags &EVENT_FILE_FL_ENABLED )) {clear_bit (EVENT_FILE_FL_ENABLED_BIT , &file->flags);
@@ -812,8 +813,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,WARN_ON_ONCE (ret); } -/* If in SOFT_MODE, just set the SOFT_DISABLE_BIT, else clear it */ -if (file->flags &EVENT_FILE_FL_SOFT_MODE ) +/* If in soft mode, just set the SOFT_DISABLE_BIT, else clear it */ +if (soft_mode)set_bit (EVENT_FILE_FL_SOFT_DISABLED_BIT , &file->flags);else clear_bit (EVENT_FILE_FL_SOFT_DISABLED_BIT , &file->flags);
@@ -823,7 +824,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,* When soft_disable is set and enable is set, we want to * register the tracepoint for the event, but leave the event * as is. That means, if the event was already enabled, we do -* nothing (but set SOFT_MODE). If the event is disabled, we +* nothing (but set soft_mode). If the event is disabled, we * set SOFT_DISABLED before enabling the event tracepoint, so * it still seems to be disabled. */
@@ -832,7 +833,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,else {if (atomic_inc_return (&file->sm_ref) >1 )break ; -set_bit (EVENT_FILE_FL_SOFT_MODE_BIT , &file->flags); + soft_mode = true;/* Enable use of trace_buffered_event */ trace_buffered_event_enable (); }
@@ -840,7 +841,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,if (!(file->flags &EVENT_FILE_FL_ENABLED )) {bool cmd = false, tgid = false; -/* Keep the event disabled, when going to SOFT_MODE. */ +/* Keep the event disabled, when going to soft mode. */ if (soft_disable)set_bit (EVENT_FILE_FL_SOFT_DISABLED_BIT , &file->flags);
@@ -1792,8 +1793,7 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, !(flags & EVENT_FILE_FL_SOFT_DISABLED))strcpy (buf,"1" ); -if (flags &EVENT_FILE_FL_SOFT_DISABLED || - flags &EVENT_FILE_FL_SOFT_MODE ) +if (atomic_read (&file->sm_ref) !=0 )strcat (buf,"*" );strcat (buf,"\n" );
@@ -3584,7 +3584,7 @@ static int probe_remove_event_call(struct trace_event_call *call)continue ;/* * We can't rely on ftrace_event_enable_disable(enable => 0) -* we are going to do, EVENT_FILE_FL_SOFT_MODE can suppress +* we are going to do, soft mode can suppress * TRACE_REG_UNREGISTER. */ if (file->flags &EVENT_FILE_FL_ENABLED )
@@ -3997,7 +3997,7 @@ static int free_probe_data(void *data) edata->ref--;if (!edata->ref) { -/* Remove the SOFT_MODE flag */ +/* Remove soft mode */ __ftrace_event_enable_disable (edata->file,0 ,1 );trace_event_put_ref (edata->file->event_call);kfree (edata);
Signature · 1 line
2.47.2
PATCH 7/8 tracing: Fix comment in trace_module_remove_events()
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Fix typo "allocade" -> "allocated".
--- kernel/trace/trace_events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_events.c +1 -1
@@ -3695,7 +3695,7 @@ static void trace_module_remove_events(struct module *mod)if (call->module == mod)__trace_remove_event_call (call); } -/* Check for any strings allocade for this module */ +/* Check for any strings allocated for this module */ list_for_each_entry_safe (modstr, m, &module_strings, next) {if (modstr->module != mod)continue ;
Signature · 1 line
2.47.2
PATCH 8/8 tracing: Deprecate auto-mounting tracefs in debugfs
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
In January 2015, tracefs was created to allow access to the tracing infrastructure without needing to compile in debugfs. When tracefs is configured, the directory /sys/kernel/tracing will exist and tooling is expected to use that path to access the tracing infrastructure.
To allow backward compatibility, when debugfs is mounted, it would automount tracefs in its "tracing" directory so that tooling that had hard coded /sys/kernel/debug/tracing would still work.
It has been over 10 years since the new interface was introduced, and all tooling should now be using it. Start the process of deprecating the old path so that it doesn't need to be maintained anymore.
A new config is added to allow distributions to disable automounting of tracefs on debugfs.
If /sys/kernel/debug/tracing is accessed, a pr_warn() will trigger stating:
"NOTICE: Automounting of tracing to debugfs is deprecated and will be removed in 2030"
Expect to remove this feature in 5 years (2030).
--- .../ABI/obsolete/automount-tracefs-debugfs | 20 +++++++++++++++++++ kernel/trace/Kconfig | 13 ++++++++++++ kernel/trace/trace.c | 14 +++++++++---- 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 Documentation/ABI/obsolete/automount-tracefs-debugfs
Documentation/ABI/obsolete/automount-tracefs-debugfs new file +20 -0
@@ -0,0 +1,20 @@ +What: /sys/kernel/debug/tracing +Date: May 2008 +KernelVersion: 2.6.27 +Contact: [email protected] +Description: + + The ftrace was first added to the kernel, its interface was placed + into the debugfs file system under the "tracing" directory. Access + to the files were in /sys/kernel/debug/tracing. As systems wanted + access to the tracing interface without having to enable debugfs, a + new interface was created called "tracefs". This was a stand alone + file system and was usually mounted in /sys/kernel/tracing. + + To allow older tooling to continue to operate, when mounting + debugfs, the tracefs file system would automatically get mounted in + the "tracing" directory of debugfs. The tracefs interface was added + in January 2015 in the v4.1 kernel. + + All tooling should now be using tracefs directly and the "tracing" + directory in debugfs should be removed by January 2030.
kernel/trace/Kconfig +13 -0
@@ -199,6 +199,19 @@ menuconfig FTRACE if FTRACE +config TRACEFS_AUTOMOUNT_DEPRECATED + bool "Automount tracefs on debugfs [DEPRECATED]" + depends on TRACING + default y + help + The tracing interface was moved from /sys/kernel/debug/tracing + to /sys/kernel/tracing in 2015, but the tracing file system + was still automounted in /sys/kernel/debug for backward + compatibility with tooling. + + The new interface has been around for more than 10 years and + the old debug mount will soon be removed. + config BOOTTIME_TRACING bool "Boot-time Tracing support" depends on TRACING
kernel/trace/trace.c +10 -4
@@ -6296,7 +6296,7 @@ static bool tracer_options_updated;static void add_tracer_options (struct trace_array *tr,struct tracer *t) {/* Only enable if the directory has been created already. */ -if (!tr->dir) +if (!tr->dir && !(tr->flags &TRACE_ARRAY_FL_GLOBAL ))return ;/* Only create trace option files after update_tracer_options finish */
@@ -8977,13 +8977,13 @@ static inline __init int register_snapshot_cmd(void) { return 0; }static struct dentry *tracing_get_dentry (struct trace_array *tr) { -if (WARN_ON (!tr->dir)) -return ERR_PTR (-ENODEV ); -/* Top directory uses NULL as the parent */ if (tr->flags &TRACE_ARRAY_FL_GLOBAL )return NULL ; +if (WARN_ON (!tr->dir)) +return ERR_PTR (-ENODEV ); +/* All sub buffers have a descriptor */ return tr->dir; }
@@ -10249,6 +10249,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)ftrace_init_tracefs (tr, d_tracer); } +#ifdef CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED static struct vfsmount *trace_automount (struct dentry *mntpt,void *ingore) {struct vfsmount *mnt;
@@ -10270,6 +10271,8 @@ static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore)if (IS_ERR (fc))return ERR_CAST (fc); +pr_warn ("NOTICE: Automounting of tracing to debugfs is deprecated and will be removed in 2030\n" ); + ret =vfs_parse_fs_string (fc,"source" ,"tracefs" ,strlen ("tracefs" ));if (!ret)
@@ -10280,6 +10283,7 @@ static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore)put_fs_context (fc); return mnt; } +#endif /** * tracing_init_dentry - initialize top level trace array
@@ -10304,6 +10308,7 @@ int tracing_init_dentry(void)if (WARN_ON (!tracefs_initialized ()))return -ENODEV ; +#ifdef CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED /* * As there may still be users that expect the tracing * files to exist in debugfs/tracing, we must automount
@@ -10312,6 +10317,7 @@ int tracing_init_dentry(void)*/ tr->dir =debugfs_create_automount ("tracing" ,NULL , trace_automount,NULL ); +#endif return 0 ; }
Signature · 1 line
2.47.2