support PERF_SAMPLE_PHYS_ADDR (user)
cover support PERF_SAMPLE_PHYS_ADDR (user)
From: Kan Liang <[email protected]>
The patch series is to support PERF_SAMPLE_PHYS_ADDR in user perf tool. The kernel patch can be found here.
http://www.mail-archive.com/[email protected]/msg1472034.html
Kan Liang (5):
perf tools: add option to record sample physical address perf tools: add sort option phys_daddr
perf mem: support physical address
perf script: support physical addresses
perf test: add test case for PERF_SAMPLE_PHYS_ADDR
tools/include/uapi/linux/perf_event.h | 4 +- tools/perf/Documentation/perf-mem.txt | 4 ++ tools/perf/Documentation/perf-record.txt | 6 +- tools/perf/Documentation/perf-report.txt | 1 + tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-mem.c | 97 +++++++++++++++++++++++--------- tools/perf/builtin-record.c | 9 +++ tools/perf/builtin-script.c | 21 ++++++- tools/perf/perf.h | 1 + tools/perf/tests/sample-parsing.c | 6 +- tools/perf/util/event.h | 1 + tools/perf/util/evsel.c | 17 ++++++ tools/perf/util/hist.c | 3 + tools/perf/util/hist.h | 1 + tools/perf/util/machine.c | 7 ++- tools/perf/util/session.c | 3 + tools/perf/util/sort.c | 42 ++++++++++++++ tools/perf/util/sort.h | 1 + tools/perf/util/symbol.h | 1 + 19 files changed, 193 insertions(+), 34 deletions(-)
Signature · 1 line
2.4.3
PATCH 1/5 perf tools: add option to record sample physical address
From: Kan Liang <[email protected]>
Add new option --phys-data for perf record to record sample physical address. Once the option is applied, it implies that --data option is also applied to record sample virtual address.
--- tools/include/uapi/linux/perf_event.h | 4 +++- tools/perf/Documentation/perf-record.txt | 6 +++++- tools/perf/builtin-record.c | 9 +++++++++ tools/perf/perf.h | 1 + tools/perf/util/event.h | 1 + tools/perf/util/evsel.c | 17 +++++++++++++++++ tools/perf/util/session.c | 3 +++ 7 files changed, 39 insertions(+), 2 deletions(-)
tools/include/uapi/linux/perf_event.h +3 -1
@@ -139,8 +139,9 @@ enum perf_event_sample_format {PERF_SAMPLE_IDENTIFIER =1U <<16 ,PERF_SAMPLE_TRANSACTION =1U <<17 ,PERF_SAMPLE_REGS_INTR =1U <<18 , +PERF_SAMPLE_PHYS_ADDR =1U <<19 , - PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */ };/*
@@ -814,6 +815,7 @@ enum perf_event_type {* { u64 transaction; } && PERF_SAMPLE_TRANSACTION * { u64 abi; # enum perf_sample_regs_abi * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR +* { u64 phys_addr;} && PERF_SAMPLE_PHYS_ADDR * }; */ PERF_RECORD_SAMPLE = 9,
tools/perf/Documentation/perf-record.txt +5 -1
@@ -249,7 +249,11 @@ OPTIONS -d:: --data:: - Record the sample addresses. + Record the sample virtual addresses. + +--phys-data:: + Record the sample physical addresses which implies + the virtual address is also recorded. -T:: --timestamp::
tools/perf/builtin-record.c +9 -0
@@ -1604,6 +1604,8 @@ static struct option __record_options[] = {OPT_BOOLEAN ('s' ,"stat" , &record.opts.inherit_stat,"per thread counts" ),OPT_BOOLEAN ('d' ,"data" , &record.opts.sample_address,"Record the sample addresses" ), +OPT_BOOLEAN (0 ,"phys-data" , &record.opts.sample_phys_addr, +"Record the sample physical addresses" ),OPT_BOOLEAN (0 ,"sample-cpu" , &record.opts.sample_cpu,"Record the sample cpu" ), OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, &record.opts.sample_time_set,
@@ -1833,6 +1835,13 @@ int cmd_record(int argc, const char **argv) goto out; } +/* +* Record the sample physical addr which also implies +* the virtual addr is recorded. +*/ +if (rec->opts.sample_phys_addr) + rec->opts.sample_address = true; +if (rec->opts.target.tid && !rec->opts.no_inherit_set) rec->opts.no_inherit = true;
tools/perf/perf.h +1 -0
@@ -43,6 +43,7 @@ struct record_opts {bool no_samples;bool raw_samples;bool sample_address; +bool sample_phys_addr;bool sample_weight;bool sample_time;bool sample_time_set;
tools/perf/util/event.h +1 -0
@@ -200,6 +200,7 @@ struct perf_sample {u32 cpu;u32 raw_size;u64 data_src; +u64 phys_addr;u32 flags;u16 insn_len;u8 cpumode;
tools/perf/util/evsel.c +17 -0
@@ -950,6 +950,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,if (opts->sample_address)perf_evsel__set_sample_bit (evsel,DATA_SRC ); +if (opts->sample_phys_addr) +perf_evsel__set_sample_bit (evsel,PHYS_ADDR ); +if (opts->no_buffering) { attr->watermark =0 ; attr->wakeup_events =1 ;
@@ -2214,6 +2217,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, } } + data->phys_addr =0 ; +if (type &PERF_SAMPLE_PHYS_ADDR ) { + data->phys_addr = *array; + array++; + } +return 0 ; }
@@ -2319,6 +2328,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, } } +if (type &PERF_SAMPLE_PHYS_ADDR ) + result +=sizeof (u64); +return result; }
@@ -2508,6 +2520,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, } } +if (type &PERF_SAMPLE_PHYS_ADDR ) { + *array = sample->phys_addr; + array++; + } +return 0 ; }
tools/perf/util/session.c +3 -0
@@ -1120,6 +1120,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,if (sample_type &PERF_SAMPLE_DATA_SRC )printf (" . data_src: 0x%" PRIx64"\n" , sample->data_src); +if (sample_type &PERF_SAMPLE_PHYS_ADDR ) +printf (" .. phys_addr: 0x%" PRIx64"\n" , sample->phys_addr); +if (sample_type &PERF_SAMPLE_TRANSACTION )printf ("... transaction: %" PRIx64"\n" , sample->transaction);
Signature · 1 line
2.4.3
PATCH 2/5 perf tools: add sort option phys_daddr
In reply to [email protected]From: Kan Liang <[email protected]>
Add a new sort option phys_daddr for --mem-mode sort. With this option applied, perf can sort and report by sample's physical address.
--- tools/perf/Documentation/perf-report.txt | 1 + tools/perf/util/hist.c | 3 +++ tools/perf/util/hist.h | 1 + tools/perf/util/machine.c | 7 ++++-- tools/perf/util/sort.c | 42 ++++++++++++++++++++++++++++++++ tools/perf/util/sort.h | 1 + tools/perf/util/symbol.h | 1 + 7 files changed, 54 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-report.txt +1 -0
@@ -137,6 +137,7 @@ OPTIONS - mem: type of memory access for the data at the time of the sample - snoop: type of snoop (if any) for the data at the time of the sample - dcacheline: the cacheline the data address is on at the time of the sample + - phys_daddr: physical address of data being executed on at the time of sample And the default sort keys are changed to local_weight, mem, sym, dso, symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
tools/perf/util/hist.c +3 -0
@@ -167,6 +167,9 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) symlen = unresolved_col_width +4 +2 ;hists__set_unres_dso_col_len (hists,HISTC_MEM_DADDR_DSO ); } + +hists__new_col_len (hists,HISTC_MEM_PHYS_DADDR , unresolved_col_width +4 +2 ); + }else { symlen = unresolved_col_width +4 +2 ;hists__new_col_len (hists,HISTC_MEM_DADDR_SYMBOL , symlen);
tools/perf/util/hist.h +1 -0
@@ -47,6 +47,7 @@ enum hist_column {HISTC_GLOBAL_WEIGHT ,HISTC_MEM_DADDR_SYMBOL ,HISTC_MEM_DADDR_DSO , +HISTC_MEM_PHYS_DADDR ,HISTC_MEM_LOCKED ,HISTC_MEM_TLB , HISTC_MEM_LVL,
tools/perf/util/machine.c +5 -2
@@ -1635,10 +1635,12 @@ static void ip__resolve_ams(struct thread *thread, ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; + ams->phys_addr =0 ; }static void ip__resolve_data (struct thread *thread, -u8 m,struct addr_map_symbol *ams,u64 addr) +u8 m,struct addr_map_symbol *ams, +u64 addr,u64 phys_addr) {struct addr_location al;
@@ -1658,6 +1660,7 @@ static void ip__resolve_data(struct thread *thread, ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; + ams->phys_addr = phys_addr; } struct mem_info *sample__resolve_mem(struct perf_sample *sample,
@@ -1669,7 +1672,7 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,return NULL ;ip__resolve_ams (al->thread, &mi->iaddr, sample->ip); -ip__resolve_data (al->thread, al->cpumode, &mi->daddr, sample->addr); +ip__resolve_data (al->thread, al->cpumode, &mi->daddr, sample->addr, sample->phys_addr); mi->data_src.val = sample->data_src;return mi;
tools/perf/util/sort.c +42 -0
54 lines not on this page · raw message
tools/perf/util/sort.h +1 -0
@@ -245,6 +245,7 @@ enum sort_type {SORT_MEM_SNOOP ,SORT_MEM_DCACHELINE ,SORT_MEM_IADDR_SYMBOL , + SORT_MEM_PHYS_DADDR, };/*
tools/perf/util/symbol.h +1 -0
@@ -186,6 +186,7 @@ struct addr_map_symbol {struct symbol *sym;u64 addr;u64 al_addr; +u64 phys_addr; };struct branch_info {
Signature · 1 line
2.4.3
PATCH 3/5 perf mem: support physical address
In reply to [email protected]From: Kan Liang <[email protected]>
Add option phys-data in perf mem to record/report physical address. The default mem sort order for physical addresses is changed accordingly.
--- tools/perf/Documentation/perf-mem.txt | 4 ++ tools/perf/builtin-mem.c | 97 +++++++++++++++++++++++++---------- 2 files changed, 75 insertions(+), 26 deletions(-)
tools/perf/Documentation/perf-mem.txt +4 -0
@@ -59,6 +59,10 @@ OPTIONS --ldload:: Specify desired latency for loads event. +-p:: +--phys-data:: + Record/Report sample physical addresses + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-report[1]
tools/perf/builtin-mem.c +71 -26
135 lines not on this page · raw message
Signature · 1 line
2.4.3
PATCH 4/5 perf script: support physical addresses
In reply to [email protected]From: Kan Liang <[email protected]>
perf script print out physical addresses if phys_addr is applied in perf record.
Only display physical address when virtual address is selected.
--- tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-script.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-)
tools/perf/Documentation/perf-script.txt +1 -1
@@ -117,7 +117,7 @@ OPTIONS Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff, - callindent, insn, insnlen, synth. + callindent, insn, insnlen, synth, phys_addr. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
tools/perf/builtin-script.c +19 -2
@@ -87,6 +87,7 @@ enum perf_output_field {PERF_OUTPUT_BRSTACKINSN =1U <<23 ,PERF_OUTPUT_BRSTACKOFF =1U <<24 ,PERF_OUTPUT_SYNTH =1U <<25 , + PERF_OUTPUT_PHYS_ADDR = 1U << 26, }; struct output_option {
@@ -119,6 +120,7 @@ struct output_option { {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, {.str = "synth", .field = PERF_OUTPUT_SYNTH}, + {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, }; enum {
@@ -175,7 +177,8 @@ static struct {PERF_OUTPUT_EVNAME |PERF_OUTPUT_IP |PERF_OUTPUT_SYM |PERF_OUTPUT_DSO |PERF_OUTPUT_PERIOD |PERF_OUTPUT_ADDR | - PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT, +PERF_OUTPUT_DATA_SRC |PERF_OUTPUT_WEIGHT | + PERF_OUTPUT_PHYS_ADDR, .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, },
@@ -328,6 +331,12 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, PERF_OUTPUT_WEIGHT))return -EINVAL ; +if (PRINT_FIELD (PHYS_ADDR ) && !PRINT_FIELD (ADDR )) { +pr_err ("Display of sample physical address" +"but sample address is not selected.\n" ); +return -EINVAL ; + } +if (PRINT_FIELD (SYM ) && !PRINT_FIELD (IP ) && !PRINT_FIELD (ADDR )) {pr_err ("Display of symbols requested but neither sample IP nor " "sample address\nis selected. Hence, no addresses to convert "
@@ -382,6 +391,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, PERF_OUTPUT_IREGS))return -EINVAL ; +if (PRINT_FIELD (PHYS_ADDR ) && +perf_evsel__do_check_stype (evsel,PERF_SAMPLE_PHYS_ADDR ,"PHYS_ADDR" , +PERF_OUTPUT_PHYS_ADDR , allow_user_set)) +return -EINVAL ; +return 0 ; }
@@ -1446,6 +1460,9 @@ 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, thread, machine); + +if (PRINT_FIELD (PHYS_ADDR )) +printf ("%16" PRIx64, sample->phys_addr);printf ("\n" ); }
@@ -2729,7 +2746,7 @@ int cmd_script(int argc, const char **argv) "Valid types: hw,sw,trace,raw,synth. " "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," "addr,symoff,period,iregs,brstack,brstacksym,flags," - "bpf-output,callindent,insn,insnlen,brstackinsn,synth", + "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", parse_output_fields),OPT_BOOLEAN ('a' ,"all-cpus" , &system_wide, "system-wide collection from all CPUs"),
Signature · 1 line
2.4.3
PATCH 5/5 perf test: add test case for PERF_SAMPLE_PHYS_ADDR
In reply to [email protected]From: Kan Liang <[email protected]>
Extend sample-parsing test cases to support new sample type PERF_SAMPLE_PHYS_ADDR.
--- tools/perf/tests/sample-parsing.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
tools/perf/tests/sample-parsing.c +5 -1
@@ -141,6 +141,9 @@ static bool samples_same(const struct perf_sample *s1, } } +if (type &PERF_SAMPLE_PHYS_ADDR ) +COMP (phys_addr); +return true; }
@@ -206,6 +209,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) .mask = sample_regs, .regs = regs, }, + .phys_addr = 113, };struct sample_read_value values[] = {{1 ,5 }, {9 ,3 }, {2 ,7 }, {6 ,4 },};struct perf_sample sample_out;
@@ -305,7 +309,7 @@ int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_u* were added. Please actually update the test rather than just change * the condition below. */ -if (PERF_SAMPLE_MAX >PERF_SAMPLE_REGS_INTR <<1 ) { +if (PERF_SAMPLE_MAX >PERF_SAMPLE_PHYS_ADDR <<1 ) {pr_debug ("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n" );return -1 ; }
Signature · 1 line
2.4.3