Commit 28a0b398 authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo

perf script: Add support to display sample misc field

Adding support to display sample misc field in form
of letter for each bit:

  # perf script -F +misc ...
   sched-messaging  1414 K     28690.636582:       4590 cycles ...
   sched-messaging  1407 U     28690.636600:     325620 cycles ...
   sched-messaging  1414 K     28690.636608:      19473 cycles ...
  misc field  __________/

The misc bits are assigned to following letters:

  PERF_RECORD_MISC_KERNEL        K
  PERF_RECORD_MISC_USER          U
  PERF_RECORD_MISC_HYPERVISOR    H
  PERF_RECORD_MISC_GUEST_KERNEL  G
  PERF_RECORD_MISC_GUEST_USER    g
  PERF_RECORD_MISC_MMAP_DATA*    M
  PERF_RECORD_MISC_COMM_EXEC     E
  PERF_RECORD_MISC_SWITCH_OUT    S
Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180107160356.28203-9-jolsa@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 972c1488
...@@ -117,7 +117,7 @@ OPTIONS ...@@ -117,7 +117,7 @@ OPTIONS
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, brstackinsn,
brstackoff, callindent, insn, insnlen, synth, phys_addr, metric. brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc.
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
...@@ -225,6 +225,24 @@ OPTIONS ...@@ -225,6 +225,24 @@ OPTIONS
that the metric computed is averaged over the whole sampling that the metric computed is averaged over the whole sampling
period, not just for the sample point. period, not just for the sample point.
For sample events it's possible to display misc field with -F +misc option,
following letters are displayed for each bit:
PERF_RECORD_MISC_KERNEL K
PERF_RECORD_MISC_USER U
PERF_RECORD_MISC_HYPERVISOR H
PERF_RECORD_MISC_GUEST_KERNEL G
PERF_RECORD_MISC_GUEST_USER g
PERF_RECORD_MISC_MMAP_DATA* M
PERF_RECORD_MISC_COMM_EXEC E
PERF_RECORD_MISC_SWITCH_OUT S
$ perf script -F +misc ...
sched-messaging 1414 K 28690.636582: 4590 cycles ...
sched-messaging 1407 U 28690.636600: 325620 cycles ...
sched-messaging 1414 K 28690.636608: 19473 cycles ...
misc field ___________/
-k:: -k::
--vmlinux=<file>:: --vmlinux=<file>::
vmlinux pathname vmlinux pathname
......
...@@ -93,6 +93,7 @@ enum perf_output_field { ...@@ -93,6 +93,7 @@ enum perf_output_field {
PERF_OUTPUT_PHYS_ADDR = 1U << 26, PERF_OUTPUT_PHYS_ADDR = 1U << 26,
PERF_OUTPUT_UREGS = 1U << 27, PERF_OUTPUT_UREGS = 1U << 27,
PERF_OUTPUT_METRIC = 1U << 28, PERF_OUTPUT_METRIC = 1U << 28,
PERF_OUTPUT_MISC = 1U << 29,
}; };
struct output_option { struct output_option {
...@@ -128,6 +129,7 @@ struct output_option { ...@@ -128,6 +129,7 @@ struct output_option {
{.str = "synth", .field = PERF_OUTPUT_SYNTH}, {.str = "synth", .field = PERF_OUTPUT_SYNTH},
{.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
{.str = "metric", .field = PERF_OUTPUT_METRIC}, {.str = "metric", .field = PERF_OUTPUT_METRIC},
{.str = "misc", .field = PERF_OUTPUT_MISC},
}; };
enum { enum {
...@@ -594,7 +596,8 @@ static int perf_sample__fprintf_uregs(struct perf_sample *sample, ...@@ -594,7 +596,8 @@ static int perf_sample__fprintf_uregs(struct perf_sample *sample,
static int perf_sample__fprintf_start(struct perf_sample *sample, static int perf_sample__fprintf_start(struct perf_sample *sample,
struct thread *thread, struct thread *thread,
struct perf_evsel *evsel, FILE *fp) struct perf_evsel *evsel,
u32 type, FILE *fp)
{ {
struct perf_event_attr *attr = &evsel->attr; struct perf_event_attr *attr = &evsel->attr;
unsigned long secs; unsigned long secs;
...@@ -624,6 +627,47 @@ static int perf_sample__fprintf_start(struct perf_sample *sample, ...@@ -624,6 +627,47 @@ static int perf_sample__fprintf_start(struct perf_sample *sample,
printed += fprintf(fp, "[%03d] ", sample->cpu); printed += fprintf(fp, "[%03d] ", sample->cpu);
} }
if (PRINT_FIELD(MISC)) {
int ret = 0;
#define has(m) \
(sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m
if (has(KERNEL))
ret += fprintf(fp, "K");
if (has(USER))
ret += fprintf(fp, "U");
if (has(HYPERVISOR))
ret += fprintf(fp, "H");
if (has(GUEST_KERNEL))
ret += fprintf(fp, "G");
if (has(GUEST_USER))
ret += fprintf(fp, "g");
switch (type) {
case PERF_RECORD_MMAP:
case PERF_RECORD_MMAP2:
if (has(MMAP_DATA))
ret += fprintf(fp, "M");
break;
case PERF_RECORD_COMM:
if (has(COMM_EXEC))
ret += fprintf(fp, "E");
break;
case PERF_RECORD_SWITCH:
case PERF_RECORD_SWITCH_CPU_WIDE:
if (has(SWITCH_OUT))
ret += fprintf(fp, "S");
default:
break;
}
#undef has
ret += fprintf(fp, "%*s", 6 - ret, " ");
printed += ret;
}
if (PRINT_FIELD(TIME)) { if (PRINT_FIELD(TIME)) {
nsecs = sample->time; nsecs = sample->time;
secs = nsecs / NSEC_PER_SEC; secs = nsecs / NSEC_PER_SEC;
...@@ -1502,7 +1546,7 @@ static void script_print_metric(void *ctx, const char *color, ...@@ -1502,7 +1546,7 @@ static void script_print_metric(void *ctx, const char *color,
if (!fmt) if (!fmt)
return; return;
perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel, perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
mctx->fp); PERF_RECORD_SAMPLE, mctx->fp);
fputs("\tmetric: ", mctx->fp); fputs("\tmetric: ", mctx->fp);
if (color) if (color)
color_fprintf(mctx->fp, color, fmt, val); color_fprintf(mctx->fp, color, fmt, val);
...@@ -1516,7 +1560,7 @@ static void script_new_line(void *ctx) ...@@ -1516,7 +1560,7 @@ static void script_new_line(void *ctx)
struct metric_ctx *mctx = ctx; struct metric_ctx *mctx = ctx;
perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel, perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
mctx->fp); PERF_RECORD_SAMPLE, mctx->fp);
fputs("\tmetric: ", mctx->fp); fputs("\tmetric: ", mctx->fp);
} }
...@@ -1584,7 +1628,8 @@ static void process_event(struct perf_script *script, ...@@ -1584,7 +1628,8 @@ static void process_event(struct perf_script *script,
++es->samples; ++es->samples;
perf_sample__fprintf_start(sample, thread, evsel, fp); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_SAMPLE, fp);
if (PRINT_FIELD(PERIOD)) if (PRINT_FIELD(PERIOD))
fprintf(fp, "%10" PRIu64 " ", sample->period); fprintf(fp, "%10" PRIu64 " ", sample->period);
...@@ -1833,7 +1878,8 @@ static int process_comm_event(struct perf_tool *tool, ...@@ -1833,7 +1878,8 @@ static int process_comm_event(struct perf_tool *tool,
sample->tid = event->comm.tid; sample->tid = event->comm.tid;
sample->pid = event->comm.pid; sample->pid = event->comm.pid;
} }
perf_sample__fprintf_start(sample, thread, evsel, stdout); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_COMM, stdout);
perf_event__fprintf(event, stdout); perf_event__fprintf(event, stdout);
ret = 0; ret = 0;
out: out:
...@@ -1868,7 +1914,8 @@ static int process_namespaces_event(struct perf_tool *tool, ...@@ -1868,7 +1914,8 @@ static int process_namespaces_event(struct perf_tool *tool,
sample->tid = event->namespaces.tid; sample->tid = event->namespaces.tid;
sample->pid = event->namespaces.pid; sample->pid = event->namespaces.pid;
} }
perf_sample__fprintf_start(sample, thread, evsel, stdout); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_NAMESPACES, stdout);
perf_event__fprintf(event, stdout); perf_event__fprintf(event, stdout);
ret = 0; ret = 0;
out: out:
...@@ -1901,7 +1948,8 @@ static int process_fork_event(struct perf_tool *tool, ...@@ -1901,7 +1948,8 @@ static int process_fork_event(struct perf_tool *tool,
sample->tid = event->fork.tid; sample->tid = event->fork.tid;
sample->pid = event->fork.pid; sample->pid = event->fork.pid;
} }
perf_sample__fprintf_start(sample, thread, evsel, stdout); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_FORK, stdout);
perf_event__fprintf(event, stdout); perf_event__fprintf(event, stdout);
thread__put(thread); thread__put(thread);
...@@ -1930,7 +1978,8 @@ static int process_exit_event(struct perf_tool *tool, ...@@ -1930,7 +1978,8 @@ static int process_exit_event(struct perf_tool *tool,
sample->tid = event->fork.tid; sample->tid = event->fork.tid;
sample->pid = event->fork.pid; sample->pid = event->fork.pid;
} }
perf_sample__fprintf_start(sample, thread, evsel, stdout); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_EXIT, stdout);
perf_event__fprintf(event, stdout); perf_event__fprintf(event, stdout);
if (perf_event__process_exit(tool, event, sample, machine) < 0) if (perf_event__process_exit(tool, event, sample, machine) < 0)
...@@ -1965,7 +2014,8 @@ static int process_mmap_event(struct perf_tool *tool, ...@@ -1965,7 +2014,8 @@ static int process_mmap_event(struct perf_tool *tool,
sample->tid = event->mmap.tid; sample->tid = event->mmap.tid;
sample->pid = event->mmap.pid; sample->pid = event->mmap.pid;
} }
perf_sample__fprintf_start(sample, thread, evsel, stdout); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_MMAP, stdout);
perf_event__fprintf(event, stdout); perf_event__fprintf(event, stdout);
thread__put(thread); thread__put(thread);
return 0; return 0;
...@@ -1996,7 +2046,8 @@ static int process_mmap2_event(struct perf_tool *tool, ...@@ -1996,7 +2046,8 @@ static int process_mmap2_event(struct perf_tool *tool,
sample->tid = event->mmap2.tid; sample->tid = event->mmap2.tid;
sample->pid = event->mmap2.pid; sample->pid = event->mmap2.pid;
} }
perf_sample__fprintf_start(sample, thread, evsel, stdout); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_MMAP2, stdout);
perf_event__fprintf(event, stdout); perf_event__fprintf(event, stdout);
thread__put(thread); thread__put(thread);
return 0; return 0;
...@@ -2022,7 +2073,8 @@ static int process_switch_event(struct perf_tool *tool, ...@@ -2022,7 +2073,8 @@ static int process_switch_event(struct perf_tool *tool,
return -1; return -1;
} }
perf_sample__fprintf_start(sample, thread, evsel, stdout); perf_sample__fprintf_start(sample, thread, evsel,
PERF_RECORD_SWITCH, stdout);
perf_event__fprintf(event, stdout); perf_event__fprintf(event, stdout);
thread__put(thread); thread__put(thread);
return 0; return 0;
......
...@@ -205,6 +205,7 @@ struct perf_sample { ...@@ -205,6 +205,7 @@ struct perf_sample {
u32 flags; u32 flags;
u16 insn_len; u16 insn_len;
u8 cpumode; u8 cpumode;
u16 misc;
char insn[MAX_INSN]; char insn[MAX_INSN];
void *raw_data; void *raw_data;
struct ip_callchain *callchain; struct ip_callchain *callchain;
......
...@@ -2042,6 +2042,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, ...@@ -2042,6 +2042,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
data->stream_id = data->id = data->time = -1ULL; data->stream_id = data->id = data->time = -1ULL;
data->period = evsel->attr.sample_period; data->period = evsel->attr.sample_period;
data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
data->misc = event->header.misc;
data->id = -1ULL; data->id = -1ULL;
data->data_src = PERF_MEM_DATA_SRC_NONE; data->data_src = PERF_MEM_DATA_SRC_NONE;
......
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