diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
| -rw-r--r-- | tools/perf/builtin-script.c | 51 | 
1 files changed, 44 insertions, 7 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 7228d141a789..2f3ff69fc4e7 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -22,6 +22,7 @@  #include "util/thread_map.h"  #include "util/stat.h"  #include "util/thread-stack.h" +#include "util/time-utils.h"  #include <linux/bitmap.h>  #include <linux/stringify.h>  #include <linux/time64.h> @@ -66,6 +67,8 @@ enum perf_output_field {  	PERF_OUTPUT_WEIGHT	    = 1U << 18,  	PERF_OUTPUT_BPF_OUTPUT	    = 1U << 19,  	PERF_OUTPUT_CALLINDENT	    = 1U << 20, +	PERF_OUTPUT_INSN	    = 1U << 21, +	PERF_OUTPUT_INSNLEN	    = 1U << 22,  };  struct output_option { @@ -93,6 +96,8 @@ struct output_option {  	{.str = "weight",   .field = PERF_OUTPUT_WEIGHT},  	{.str = "bpf-output",   .field = PERF_OUTPUT_BPF_OUTPUT},  	{.str = "callindent", .field = PERF_OUTPUT_CALLINDENT}, +	{.str = "insn", .field = PERF_OUTPUT_INSN}, +	{.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},  };  /* default set to maintain compatibility with current format */ @@ -437,7 +442,6 @@ static void print_sample_start(struct perf_sample *sample,  {  	struct perf_event_attr *attr = &evsel->attr;  	unsigned long secs; -	unsigned long usecs;  	unsigned long long nsecs;  	if (PRINT_FIELD(COMM)) { @@ -467,11 +471,14 @@ static void print_sample_start(struct perf_sample *sample,  		nsecs = sample->time;  		secs = nsecs / NSEC_PER_SEC;  		nsecs -= secs * NSEC_PER_SEC; -		usecs = nsecs / NSEC_PER_USEC; +  		if (nanosecs)  			printf("%5lu.%09llu: ", secs, nsecs); -		else -			printf("%5lu.%06lu: ", secs, usecs); +		else { +			char sample_time[32]; +			timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time)); +			printf("%12s: ", sample_time); +		}  	}  } @@ -624,6 +631,20 @@ static void print_sample_callindent(struct perf_sample *sample,  		printf("%*s", spacing - len, "");  } +static void print_insn(struct perf_sample *sample, +		       struct perf_event_attr *attr) +{ +	if (PRINT_FIELD(INSNLEN)) +		printf(" ilen: %d", sample->insn_len); +	if (PRINT_FIELD(INSN)) { +		int i; + +		printf(" insn:"); +		for (i = 0; i < sample->insn_len; i++) +			printf(" %02x", (unsigned char)sample->insn[i]); +	} +} +  static void print_sample_bts(struct perf_sample *sample,  			     struct perf_evsel *evsel,  			     struct thread *thread, @@ -668,6 +689,8 @@ static void print_sample_bts(struct perf_sample *sample,  	if (print_srcline_last)  		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout); +	print_insn(sample, attr); +  	printf("\n");  } @@ -811,6 +834,8 @@ struct perf_script {  	struct cpu_map		*cpus;  	struct thread_map	*threads;  	int			name_width; +	const char              *time_str; +	struct perf_time_interval ptime;  };  static int perf_evlist__max_name_len(struct perf_evlist *evlist) @@ -911,7 +936,7 @@ static void process_event(struct perf_script *script,  	if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))  		print_sample_bpf_output(sample); - +	print_insn(sample, attr);  	printf("\n");  } @@ -992,6 +1017,9 @@ static int process_sample_event(struct perf_tool *tool,  	struct perf_script *scr = container_of(tool, struct perf_script, tool);  	struct addr_location al; +	if (perf_time__skip_sample(&scr->ptime, sample->time)) +		return 0; +  	if (debug_mode) {  		if (sample->time < last_timestamp) {  			pr_err("Samples misordered, previous: %" PRIu64 @@ -2124,11 +2152,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  		     "Valid types: hw,sw,trace,raw. "  		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"  		     "addr,symoff,period,iregs,brstack,brstacksym,flags," -		     "bpf-output,callindent", parse_output_fields), +		     "bpf-output,callindent,insn,insnlen", parse_output_fields),  	OPT_BOOLEAN('a', "all-cpus", &system_wide,  		    "system-wide collection from all CPUs"),  	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",  		   "only consider these symbols"), +	OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]", +		   "Stop display of callgraph at these symbols"),  	OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),  	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",  		   "only display events for these comms"), @@ -2162,7 +2192,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  			"Enable symbol demangling"),  	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,  			"Enable kernel symbol demangling"), - +	OPT_STRING(0, "time", &script.time_str, "str", +		   "Time span of interest (start,stop)"),  	OPT_END()  	};  	const char * const script_subcommands[] = { "record", "report", NULL }; @@ -2441,6 +2472,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  	if (err < 0)  		goto out_delete; +	/* needs to be parsed after looking up reference time */ +	if (perf_time__parse_str(&script.ptime, script.time_str) != 0) { +		pr_err("Invalid time string\n"); +		return -EINVAL; +	} +  	err = __cmd_script(&script);  	flush_scripting();  |