Commit 6b9bae63 authored by Kan Liang's avatar Kan Liang Committed by Arnaldo Carvalho de Melo

perf script: Support data page size

Display the data page size if it is available and asked by the user:

Can be configured by the user, for example:

  perf script --fields comm,event,phys_addr,data_page_size
            dtlb mem-loads:uP:        3fec82ea8 4K
            dtlb mem-loads:uP:        3fec82e90 4K
            dtlb mem-loads:uP:        3e23700a4 4K
            dtlb mem-loads:uP:        3fec82f20 4K
            dtlb mem-loads:uP:        3e23700a4 4K
            dtlb mem-loads:uP:        3b4211bec 4K
            dtlb mem-loads:uP:        382205dc0 2M
            dtlb mem-loads:uP:        36fa082c0 2M
            dtlb mem-loads:uP:        377607340 2M
            dtlb mem-loads:uP:        330010180 2M
            dtlb mem-loads:uP:        33200fd80 2M
            dtlb mem-loads:uP:        31b012b80 2M
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Acked-by: default avatarJiri Olsa <jolsa@redhat.com>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Stephane Eranian <eranian@google.com>
Cc: Will Deacon <will@kernel.org>
Link: http://lore.kernel.org/lkml/20201216185805.9981-2-kan.liang@linux.intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent b53d4872
...@@ -116,8 +116,9 @@ OPTIONS ...@@ -116,8 +116,9 @@ OPTIONS
--fields:: --fields::
Comma separated list of fields to print. Options are: Comma separated list of fields to print. Options are:
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output, brstackinsn, srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output,
brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc, srccode, ipc. brstackinsn, brstackoff, callindent, insn, insnlen, synth, phys_addr,
metric, misc, srccode, ipc, data_page_size.
Field list can be prepended with the type, trace, sw or hw, Field list can be prepended with the type, trace, sw or hw,
to indicate to which event type the field list applies. 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 e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "util/thread-stack.h" #include "util/thread-stack.h"
#include "util/time-utils.h" #include "util/time-utils.h"
#include "util/path.h" #include "util/path.h"
#include "util/event.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "print_binary.h" #include "print_binary.h"
#include "archinsn.h" #include "archinsn.h"
...@@ -115,6 +116,7 @@ enum perf_output_field { ...@@ -115,6 +116,7 @@ enum perf_output_field {
PERF_OUTPUT_SRCCODE = 1ULL << 30, PERF_OUTPUT_SRCCODE = 1ULL << 30,
PERF_OUTPUT_IPC = 1ULL << 31, PERF_OUTPUT_IPC = 1ULL << 31,
PERF_OUTPUT_TOD = 1ULL << 32, PERF_OUTPUT_TOD = 1ULL << 32,
PERF_OUTPUT_DATA_PAGE_SIZE = 1ULL << 33,
}; };
struct perf_script { struct perf_script {
...@@ -179,6 +181,7 @@ struct output_option { ...@@ -179,6 +181,7 @@ struct output_option {
{.str = "srccode", .field = PERF_OUTPUT_SRCCODE}, {.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
{.str = "ipc", .field = PERF_OUTPUT_IPC}, {.str = "ipc", .field = PERF_OUTPUT_IPC},
{.str = "tod", .field = PERF_OUTPUT_TOD}, {.str = "tod", .field = PERF_OUTPUT_TOD},
{.str = "data_page_size", .field = PERF_OUTPUT_DATA_PAGE_SIZE},
}; };
enum { enum {
...@@ -251,7 +254,8 @@ static struct { ...@@ -251,7 +254,8 @@ static struct {
PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD | PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR, PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR |
PERF_OUTPUT_DATA_PAGE_SIZE,
.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
}, },
...@@ -499,6 +503,10 @@ static int evsel__check_attr(struct evsel *evsel, struct perf_session *session) ...@@ -499,6 +503,10 @@ static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR)) evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR))
return -EINVAL; return -EINVAL;
if (PRINT_FIELD(DATA_PAGE_SIZE) &&
evsel__check_stype(evsel, PERF_SAMPLE_DATA_PAGE_SIZE, "DATA_PAGE_SIZE", PERF_OUTPUT_DATA_PAGE_SIZE))
return -EINVAL;
return 0; return 0;
} }
...@@ -1920,6 +1928,7 @@ static void process_event(struct perf_script *script, ...@@ -1920,6 +1928,7 @@ static void process_event(struct perf_script *script,
unsigned int type = output_type(attr->type); unsigned int type = output_type(attr->type);
struct evsel_script *es = evsel->priv; struct evsel_script *es = evsel->priv;
FILE *fp = es->fp; FILE *fp = es->fp;
char str[PAGE_SIZE_NAME_LEN];
if (output[type].fields == 0) if (output[type].fields == 0)
return; return;
...@@ -2008,6 +2017,9 @@ static void process_event(struct perf_script *script, ...@@ -2008,6 +2017,9 @@ static void process_event(struct perf_script *script,
if (PRINT_FIELD(PHYS_ADDR)) if (PRINT_FIELD(PHYS_ADDR))
fprintf(fp, "%16" PRIx64, sample->phys_addr); fprintf(fp, "%16" PRIx64, sample->phys_addr);
if (PRINT_FIELD(DATA_PAGE_SIZE))
fprintf(fp, " %s", get_page_size_name(sample->data_page_size, str));
perf_sample__fprintf_ipc(sample, attr, fp); perf_sample__fprintf_ipc(sample, attr, fp);
fprintf(fp, "\n"); fprintf(fp, "\n");
...@@ -3506,7 +3518,8 @@ int cmd_script(int argc, const char **argv) ...@@ -3506,7 +3518,8 @@ int cmd_script(int argc, const char **argv)
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
"addr,symoff,srcline,period,iregs,uregs,brstack," "addr,symoff,srcline,period,iregs,uregs,brstack,"
"brstacksym,flags,bpf-output,brstackinsn,brstackoff," "brstacksym,flags,bpf-output,brstackinsn,brstackoff,"
"callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc,tod", "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc,tod,"
"data_page_size",
parse_output_fields), parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide, OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"), "system-wide collection from all CPUs"),
......
...@@ -409,4 +409,7 @@ extern int sysctl_perf_event_max_stack; ...@@ -409,4 +409,7 @@ extern int sysctl_perf_event_max_stack;
extern int sysctl_perf_event_max_contexts_per_stack; extern int sysctl_perf_event_max_contexts_per_stack;
extern unsigned int proc_map_timeout; extern unsigned int proc_map_timeout;
#define PAGE_SIZE_NAME_LEN 32
char *get_page_size_name(u64 size, char *str);
#endif /* __PERF_RECORD_H */ #endif /* __PERF_RECORD_H */
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "ui/progress.h" #include "ui/progress.h"
#include "../perf.h" #include "../perf.h"
#include "arch/common.h" #include "arch/common.h"
#include "units.h"
#include <internal/lib.h> #include <internal/lib.h>
#ifdef HAVE_ZSTD_SUPPORT #ifdef HAVE_ZSTD_SUPPORT
...@@ -1258,10 +1259,19 @@ static void dump_event(struct evlist *evlist, union perf_event *event, ...@@ -1258,10 +1259,19 @@ static void dump_event(struct evlist *evlist, union perf_event *event,
event->header.size, perf_event__name(event->header.type)); event->header.size, perf_event__name(event->header.type));
} }
char *get_page_size_name(u64 size, char *str)
{
if (!size || !unit_number__scnprintf(str, PAGE_SIZE_NAME_LEN, size))
snprintf(str, PAGE_SIZE_NAME_LEN, "%s", "N/A");
return str;
}
static void dump_sample(struct evsel *evsel, union perf_event *event, static void dump_sample(struct evsel *evsel, union perf_event *event,
struct perf_sample *sample) struct perf_sample *sample)
{ {
u64 sample_type; u64 sample_type;
char str[PAGE_SIZE_NAME_LEN];
if (!dump_trace) if (!dump_trace)
return; return;
...@@ -1296,6 +1306,9 @@ static void dump_sample(struct evsel *evsel, union perf_event *event, ...@@ -1296,6 +1306,9 @@ static void dump_sample(struct evsel *evsel, union perf_event *event,
if (sample_type & PERF_SAMPLE_PHYS_ADDR) if (sample_type & PERF_SAMPLE_PHYS_ADDR)
printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr); printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr);
if (sample_type & PERF_SAMPLE_DATA_PAGE_SIZE)
printf(" .. data page size: %s\n", get_page_size_name(sample->data_page_size, str));
if (sample_type & PERF_SAMPLE_TRANSACTION) if (sample_type & PERF_SAMPLE_TRANSACTION)
printf("... transaction: %" PRIx64 "\n", sample->transaction); printf("... transaction: %" PRIx64 "\n", sample->transaction);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment