From: Adrian Hunter <adrian.hunter@intel.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Andi Kleen <ak@linux.intel.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Ingo Molnar <mingo@kernel.org>,
linux-kernel@vger.kernel.org, Jiri Olsa <jolsa@redhat.com>,
Stephane Eranian <eranian@google.com>,
mathieu.poirier@linaro.org, Pawel Moll <pawel.moll@arm.com>
Subject: [PATCH V3 2/4] perf tools: Add new PERF_RECORD_SWITCH event
Date: Tue, 7 Jul 2015 11:36:40 +0300 [thread overview]
Message-ID: <1436258202-6540-3-git-send-email-adrian.hunter@intel.com> (raw)
In-Reply-To: <1436258202-6540-1-git-send-email-adrian.hunter@intel.com>
Support processing of PERF_RECORD_SWITCH events.
There is still no way to select them, though.
That is added in a subsequest patch.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/builtin-inject.c | 1 +
tools/perf/util/event.c | 26 ++++++++++++++++++++++++++
tools/perf/util/event.h | 12 ++++++++++++
tools/perf/util/evsel.c | 1 +
tools/perf/util/machine.c | 10 ++++++++++
tools/perf/util/machine.h | 2 ++
tools/perf/util/session.c | 16 ++++++++++++++++
tools/perf/util/tool.h | 1 +
8 files changed, 69 insertions(+)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 01b06492bd6a..f62c49b35be0 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -561,6 +561,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
.lost = perf_event__repipe,
.aux = perf_event__repipe,
.itrace_start = perf_event__repipe,
+ .context_switch = perf_event__repipe,
.read = perf_event__repipe_sample,
.throttle = perf_event__repipe,
.unthrottle = perf_event__repipe,
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 67a977e5d0ab..c61cc02932fa 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -26,6 +26,7 @@ static const char *perf_event__names[] = {
[PERF_RECORD_AUX] = "AUX",
[PERF_RECORD_ITRACE_START] = "ITRACE_START",
[PERF_RECORD_LOST_SAMPLES] = "LOST_SAMPLES",
+ [PERF_RECORD_SWITCH] = "SWITCH",
[PERF_RECORD_HEADER_ATTR] = "ATTR",
[PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE",
[PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA",
@@ -749,6 +750,14 @@ int perf_event__process_lost_samples(struct perf_tool *tool __maybe_unused,
return machine__process_lost_samples_event(machine, event, sample);
}
+int perf_event__process_switch(struct perf_tool *tool __maybe_unused,
+ union perf_event *event,
+ struct perf_sample *sample __maybe_unused,
+ struct machine *machine)
+{
+ return machine__process_switch_event(machine, event);
+}
+
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
{
return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n",
@@ -827,6 +836,20 @@ size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
event->itrace_start.pid, event->itrace_start.tid);
}
+size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp)
+{
+ bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
+ const char *in_out = out ? "OUT" : "IN ";
+
+ if (event->context_switch.next_prev_pid == (u32)-1)
+ return fprintf(fp, " %s\n", in_out);
+
+ return fprintf(fp, " %s %s pid/tid: %5u/%-5u\n",
+ in_out, out ? "next" : "prev",
+ event->context_switch.next_prev_pid,
+ event->context_switch.next_prev_tid);
+}
+
size_t perf_event__fprintf(union perf_event *event, FILE *fp)
{
size_t ret = fprintf(fp, "PERF_RECORD_%s",
@@ -852,6 +875,9 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
case PERF_RECORD_ITRACE_START:
ret += perf_event__fprintf_itrace_start(event, fp);
break;
+ case PERF_RECORD_SWITCH:
+ ret += perf_event__fprintf_switch(event, fp);
+ break;
default:
ret += fprintf(fp, "\n");
}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index c53f36384b64..4bb2ae894c78 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -348,6 +348,12 @@ struct itrace_start_event {
u32 pid, tid;
};
+struct context_switch_event {
+ struct perf_event_header header;
+ u32 next_prev_pid;
+ u32 next_prev_tid;
+};
+
union perf_event {
struct perf_event_header header;
struct mmap_event mmap;
@@ -369,6 +375,7 @@ union perf_event {
struct auxtrace_error_event auxtrace_error;
struct aux_event aux;
struct itrace_start_event itrace_start;
+ struct context_switch_event context_switch;
};
void perf_event__print_totals(void);
@@ -418,6 +425,10 @@ int perf_event__process_itrace_start(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct machine *machine);
+int perf_event__process_switch(struct perf_tool *tool,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct machine *machine);
int perf_event__process_mmap(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
@@ -480,6 +491,7 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_task(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);
+size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp);
size_t perf_event__fprintf(union perf_event *event, FILE *fp);
u64 kallsyms__get_function_start(const char *kallsyms_filename,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 83c08037e7e2..67d2b43dd500 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1126,6 +1126,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
PRINT_ATTRf(mmap2, p_unsigned);
PRINT_ATTRf(comm_exec, p_unsigned);
PRINT_ATTRf(use_clockid, p_unsigned);
+ PRINT_ATTRf(context_switch, p_unsigned);
PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned);
PRINT_ATTRf(bp_type, p_unsigned);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 7ff682770fdb..dfcd80df7cba 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -550,6 +550,14 @@ int machine__process_itrace_start_event(struct machine *machine __maybe_unused,
return 0;
}
+int machine__process_switch_event(struct machine *machine __maybe_unused,
+ union perf_event *event)
+{
+ if (dump_trace)
+ perf_event__fprintf_switch(event, stdout);
+ return 0;
+}
+
struct map *machine__findnew_module_map(struct machine *machine, u64 start,
const char *filename)
{
@@ -1451,6 +1459,8 @@ int machine__process_event(struct machine *machine, union perf_event *event,
ret = machine__process_itrace_start_event(machine, event); break;
case PERF_RECORD_LOST_SAMPLES:
ret = machine__process_lost_samples_event(machine, event, sample); break;
+ case PERF_RECORD_SWITCH:
+ ret = machine__process_switch_event(machine, event); break;
default:
ret = -1;
break;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 887798e511e9..f890697a4c9c 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -87,6 +87,8 @@ int machine__process_aux_event(struct machine *machine,
union perf_event *event);
int machine__process_itrace_start_event(struct machine *machine,
union perf_event *event);
+int machine__process_switch_event(struct machine *machine __maybe_unused,
+ union perf_event *event);
int machine__process_mmap_event(struct machine *machine, union perf_event *event,
struct perf_sample *sample);
int machine__process_mmap2_event(struct machine *machine, union perf_event *event,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ed9dc2555ec7..be6914a1c29d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -332,6 +332,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
tool->aux = perf_event__process_aux;
if (tool->itrace_start == NULL)
tool->itrace_start = perf_event__process_itrace_start;
+ if (tool->context_switch == NULL)
+ tool->context_switch = perf_event__process_switch;
if (tool->read == NULL)
tool->read = process_event_sample_stub;
if (tool->throttle == NULL)
@@ -470,6 +472,17 @@ static void perf_event__itrace_start_swap(union perf_event *event,
swap_sample_id_all(event, &event->itrace_start + 1);
}
+static void perf_event__switch_swap(union perf_event *event, bool sample_id_all)
+{
+ event->context_switch.next_prev_pid =
+ bswap_32(event->context_switch.next_prev_pid);
+ event->context_switch.next_prev_tid =
+ bswap_32(event->context_switch.next_prev_tid);
+
+ if (sample_id_all)
+ swap_sample_id_all(event, &event->context_switch + 1);
+}
+
static void perf_event__throttle_swap(union perf_event *event,
bool sample_id_all)
{
@@ -632,6 +645,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
[PERF_RECORD_AUX] = perf_event__aux_swap,
[PERF_RECORD_ITRACE_START] = perf_event__itrace_start_swap,
[PERF_RECORD_LOST_SAMPLES] = perf_event__all64_swap,
+ [PERF_RECORD_SWITCH] = perf_event__switch_swap,
[PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap,
[PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap,
[PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
@@ -1093,6 +1107,8 @@ static int machines__deliver_event(struct machines *machines,
return tool->aux(tool, event, sample, machine);
case PERF_RECORD_ITRACE_START:
return tool->itrace_start(tool, event, sample, machine);
+ case PERF_RECORD_SWITCH:
+ return tool->context_switch(tool, event, sample, machine);
default:
++evlist->stats.nr_unknown_events;
return -1;
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index c307dd438286..cab8cc24831b 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -46,6 +46,7 @@ struct perf_tool {
lost_samples,
aux,
itrace_start,
+ context_switch,
throttle,
unthrottle;
event_attr_op attr;
--
1.9.1
next prev parent reply other threads:[~2015-07-07 8:39 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-07 8:36 [PATCH V3 0/4] perf: Add PERF_RECORD_SWITCH to indicate context switches Adrian Hunter
2015-07-07 8:36 ` [PATCH V3 1/4] " Adrian Hunter
2015-07-07 13:25 ` Arnaldo Carvalho de Melo
2015-07-07 13:44 ` Arnaldo Carvalho de Melo
2015-07-07 15:36 ` Peter Zijlstra
2015-07-07 16:13 ` Arnaldo Carvalho de Melo
2015-07-07 22:52 ` Peter Zijlstra
2015-07-08 13:28 ` Arnaldo Carvalho de Melo
2015-07-08 13:42 ` Adrian Hunter
2015-07-08 14:56 ` Arnaldo Carvalho de Melo
2015-07-07 8:36 ` Adrian Hunter [this message]
2015-07-07 13:50 ` [PATCH V3 2/4] perf tools: Add new PERF_RECORD_SWITCH event Arnaldo Carvalho de Melo
2015-07-07 8:36 ` [PATCH V3 3/4] perf record: Add option --switch-events to select PERF_RECORD_SWITCH events Adrian Hunter
2015-07-07 13:53 ` Arnaldo Carvalho de Melo
2015-07-07 8:36 ` [PATCH V3 4/4] perf script: Add option --show-switch-events Adrian Hunter
2015-07-07 13:54 ` Arnaldo Carvalho de Melo
2015-07-07 9:06 ` [PATCH V3 0/4] perf: Add PERF_RECORD_SWITCH to indicate context switches Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1436258202-6540-3-git-send-email-adrian.hunter@intel.com \
--to=adrian.hunter@intel.com \
--cc=acme@kernel.org \
--cc=ak@linux.intel.com \
--cc=eranian@google.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.poirier@linaro.org \
--cc=mingo@kernel.org \
--cc=pawel.moll@arm.com \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.