Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc36f948 authored by Stephane Eranian's avatar Stephane Eranian Committed by Arnaldo Carvalho de Melo
Browse files

perf script: Enable printing of interrupted machine state



This patch adds the output of the interrupted machine state (iregs) to
perf script. It presents them  as NAME:VALUE so this is easy to parse
during post processing.

To capture the interrupted machine state:
   $ perf record -I ....

to display iregs, use the -F option:

   $ perf script -F ip,iregs
   40afc2   AX:0x6c5770    BX:0x1e    CX:0x5f4d80a    DX:0x101010101010101    SI:0x1

Signed-off-by: default avatarStephane Eranian <eranian@google.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1441039273-16260-2-git-send-email-eranian@google.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d988d5ee
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -116,7 +116,7 @@ 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, flags.
	srcline, period, iregs, flags.
        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 −1
Original line number Original line Diff line number Diff line
@@ -6,6 +6,7 @@
#include "util/exec_cmd.h"
#include "util/exec_cmd.h"
#include "util/header.h"
#include "util/header.h"
#include "util/parse-options.h"
#include "util/parse-options.h"
#include "util/perf_regs.h"
#include "util/session.h"
#include "util/session.h"
#include "util/tool.h"
#include "util/tool.h"
#include "util/symbol.h"
#include "util/symbol.h"
@@ -46,6 +47,7 @@ enum perf_output_field {
	PERF_OUTPUT_SYMOFFSET       = 1U << 11,
	PERF_OUTPUT_SYMOFFSET       = 1U << 11,
	PERF_OUTPUT_SRCLINE         = 1U << 12,
	PERF_OUTPUT_SRCLINE         = 1U << 12,
	PERF_OUTPUT_PERIOD          = 1U << 13,
	PERF_OUTPUT_PERIOD          = 1U << 13,
	PERF_OUTPUT_IREGS	    = 1U << 14,
};
};


struct output_option {
struct output_option {
@@ -66,6 +68,7 @@ struct output_option {
	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
	{.str = "period", .field = PERF_OUTPUT_PERIOD},
	{.str = "period", .field = PERF_OUTPUT_PERIOD},
	{.str = "iregs", .field = PERF_OUTPUT_IREGS},
};
};


/* default set to maintain compatibility with current format */
/* default set to maintain compatibility with current format */
@@ -255,6 +258,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
					PERF_OUTPUT_PERIOD))
					PERF_OUTPUT_PERIOD))
		return -EINVAL;
		return -EINVAL;


	if (PRINT_FIELD(IREGS) &&
		perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
					PERF_OUTPUT_IREGS))
		return -EINVAL;

	return 0;
	return 0;
}
}


@@ -352,6 +360,24 @@ static int perf_session__check_output_opt(struct perf_session *session)
	return 0;
	return 0;
}
}


static void print_sample_iregs(union perf_event *event __maybe_unused,
			  struct perf_sample *sample,
			  struct thread *thread __maybe_unused,
			  struct perf_event_attr *attr)
{
	struct regs_dump *regs = &sample->intr_regs;
	uint64_t mask = attr->sample_regs_intr;
	unsigned i = 0, r;

	if (!regs)
		return;

	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
		u64 val = regs->regs[i++];
		printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
	}
}

static void print_sample_start(struct perf_sample *sample,
static void print_sample_start(struct perf_sample *sample,
			       struct thread *thread,
			       struct thread *thread,
			       struct perf_evsel *evsel)
			       struct perf_evsel *evsel)
@@ -525,6 +551,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
				     PERF_MAX_STACK_DEPTH);
				     PERF_MAX_STACK_DEPTH);
	}
	}


	if (PRINT_FIELD(IREGS))
		print_sample_iregs(event, sample, thread, attr);

	printf("\n");
	printf("\n");
}
}


@@ -1643,7 +1672,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
		     "comma separated output fields prepend with 'type:'. "
		     "comma separated output fields prepend with 'type:'. "
		     "Valid types: hw,sw,trace,raw. "
		     "Valid types: hw,sw,trace,raw. "
		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
		     "addr,symoff,period,flags", parse_output_fields),
		     "addr,symoff,period,iregs,flags", 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"),
	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",