mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	 00cf3d672a
			
		
	
	
		00cf3d672a
		
	
	
	
	
		
			
			Allow a stacktrace from one event to be displayed by the end event of a
synthetic event. This is very useful when looking for the longest latency
of a sleep or something blocked on I/O.
 # cd /sys/kernel/tracing/
 # echo 's:block_lat pid_t pid; u64 delta; unsigned long[] stack;' > dynamic_events
 # echo 'hist:keys=next_pid:ts=common_timestamp.usecs,st=stacktrace  if prev_state == 1||prev_state == 2' > events/sched/sched_switch/trigger
 # echo 'hist:keys=prev_pid:delta=common_timestamp.usecs-$ts,s=$st:onmax($delta).trace(block_lat,prev_pid,$delta,$s)' >> events/sched/sched_switch/trigger
The above creates a "block_lat" synthetic event that take the stacktrace of
when a task schedules out in either the interruptible or uninterruptible
states, and on a new per process max $delta (the time it was scheduled
out), will print the process id and the stacktrace.
  # echo 1 > events/synthetic/block_lat/enable
  # cat trace
 #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
 #              | |         |   |||||     |         |
    kworker/u16:0-767     [006] d..4.   560.645045: block_lat: pid=767 delta=66 stack=STACK:
 => __schedule
 => schedule
 => pipe_read
 => vfs_read
 => ksys_read
 => do_syscall_64
 => 0x966000aa
           <idle>-0       [003] d..4.   561.132117: block_lat: pid=0 delta=413787 stack=STACK:
 => __schedule
 => schedule
 => schedule_hrtimeout_range_clock
 => do_sys_poll
 => __x64_sys_poll
 => do_syscall_64
 => 0x966000aa
            <...>-153     [006] d..4.   562.068407: block_lat: pid=153 delta=54 stack=STACK:
 => __schedule
 => schedule
 => io_schedule
 => rq_qos_wait
 => wbt_wait
 => __rq_qos_throttle
 => blk_mq_submit_bio
 => submit_bio_noacct_nocheck
 => ext4_bio_write_page
 => mpage_submit_page
 => mpage_process_page_bufs
 => mpage_prepare_extent_to_map
 => ext4_do_writepages
 => ext4_writepages
 => do_writepages
 => __writeback_single_inode
Link: https://lkml.kernel.org/r/20230117152236.010941267@goodmis.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Tom Zanussi <zanussi@kernel.org>
Cc: Ross Zwisler <zwisler@google.com>
Cc: Ching-lin Yu <chinglinyu@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
		
	
			
		
			
				
	
	
		
			41 lines
		
	
	
	
		
			892 B
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			41 lines
		
	
	
	
		
			892 B
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| #ifndef __TRACE_SYNTH_H
 | |
| #define __TRACE_SYNTH_H
 | |
| 
 | |
| #include "trace_dynevent.h"
 | |
| 
 | |
| #define SYNTH_SYSTEM		"synthetic"
 | |
| #define SYNTH_FIELDS_MAX	64
 | |
| 
 | |
| #define STR_VAR_LEN_MAX		MAX_FILTER_STR_VAL /* must be multiple of sizeof(u64) */
 | |
| 
 | |
| struct synth_field {
 | |
| 	char *type;
 | |
| 	char *name;
 | |
| 	size_t size;
 | |
| 	unsigned int offset;
 | |
| 	unsigned int field_pos;
 | |
| 	bool is_signed;
 | |
| 	bool is_string;
 | |
| 	bool is_dynamic;
 | |
| 	bool is_stack;
 | |
| };
 | |
| 
 | |
| struct synth_event {
 | |
| 	struct dyn_event			devent;
 | |
| 	int					ref;
 | |
| 	char					*name;
 | |
| 	struct synth_field			**fields;
 | |
| 	unsigned int				n_fields;
 | |
| 	struct synth_field			**dynamic_fields;
 | |
| 	unsigned int				n_dynamic_fields;
 | |
| 	unsigned int				n_u64;
 | |
| 	struct trace_event_class		class;
 | |
| 	struct trace_event_call			call;
 | |
| 	struct tracepoint			*tp;
 | |
| 	struct module				*mod;
 | |
| };
 | |
| 
 | |
| extern struct synth_event *find_synth_event(const char *name);
 | |
| 
 | |
| #endif /* __TRACE_SYNTH_H */
 |