From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Borislav Petkov <bp@suse.de>, David Ahern <dsahern@gmail.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Guy Streeter <streeter@redhat.com>, Jiri Olsa <jolsa@redhat.com>,
Namhyung Kim <namhyung@kernel.org>,
Stephane Eranian <eranian@google.com>,
Wang Nan <wangnan0@huawei.com>
Subject: [PATCH 5/5] perf python: Support the PERF_RECORD_SWITCH
Date: Wed, 7 Oct 2015 19:45:17 -0300 [thread overview]
Message-ID: <1444257917-24527-6-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1444257917-24527-1-git-send-email-acme@kernel.org>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
To test it check tools/perf/python/twatch.py, after following the
instructions there to enable context_switch, output looks like:
[root@zoo linux]# tools/perf/python/twatch.py
cpu: 1, pid: 31463, tid: 31463 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31463, switch_out: 0 }
cpu: 2, pid: 31463, tid: 31496 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31496, switch_out: 0 }
cpu: 2, pid: 31463, tid: 31496 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31496, switch_out: 1 }
cpu: 3, pid: 31463, tid: 31527 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31527, switch_out: 0 }
cpu: 1, pid: 31463, tid: 31463 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31463, switch_out: 1 }
cpu: 3, pid: 31463, tid: 31527 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31527, switch_out: 1 }
cpu: 1, pid: 31463, tid: 31463 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31463, switch_out: 0 }
^CTraceback (most recent call last):
File "tools/perf/python/twatch.py", line 67, in <module>
main(context_switch = 1, thread = 31463)
File "tools/perf/python/twatch.py", line 40, in main
evlist.poll(timeout = -1)
KeyboardInterrupt
[root@zoo linux]#
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Guy Streeter <streeter@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-1ukistmpamc5z717k80ctcp2@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/python/twatch.py | 23 +++++++++++++++---
tools/perf/util/python.c | 59 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/tools/perf/python/twatch.py b/tools/perf/python/twatch.py
index b9d508336ae6..c235c22b107a 100755
--- a/tools/perf/python/twatch.py
+++ b/tools/perf/python/twatch.py
@@ -15,14 +15,14 @@
import perf
-def main():
+def main(context_switch = 0, thread = -1):
cpus = perf.cpu_map()
- threads = perf.thread_map()
+ threads = perf.thread_map(thread)
evsel = perf.evsel(type = perf.TYPE_SOFTWARE,
config = perf.COUNT_SW_DUMMY,
task = 1, comm = 1, mmap = 0, freq = 0,
wakeup_events = 1, watermark = 1,
- sample_id_all = 1,
+ sample_id_all = 1, context_switch = context_switch,
sample_type = perf.SAMPLE_PERIOD | perf.SAMPLE_TID | perf.SAMPLE_CPU)
"""What we want are just the PERF_RECORD_ lifetime events for threads,
@@ -48,4 +48,21 @@ def main():
print event
if __name__ == '__main__':
+ """
+ To test the PERF_RECORD_SWITCH record, pick a pid and replace
+ in the following line.
+
+ Example output:
+
+cpu: 3, pid: 31463, tid: 31593 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31593, switch_out: 1 }
+cpu: 1, pid: 31463, tid: 31489 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31489, switch_out: 1 }
+cpu: 2, pid: 31463, tid: 31496 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31496, switch_out: 1 }
+cpu: 3, pid: 31463, tid: 31491 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31491, switch_out: 0 }
+
+ It is possible as well to use event.misc & perf.PERF_RECORD_MISC_SWITCH_OUT
+ to figure out if this is a context switch in or out of the monitored threads.
+
+ If bored, please add command line option parsing support for these options :-)
+ """
+ # main(context_switch = 1, thread = 31463)
main()
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 6324fe6b161e..98f127abfa42 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -67,6 +67,7 @@ static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
static PyMemberDef pyrf_mmap_event__members[] = {
sample_members
member_def(perf_event_header, type, T_UINT, "event type"),
+ member_def(perf_event_header, misc, T_UINT, "event misc"),
member_def(mmap_event, pid, T_UINT, "event pid"),
member_def(mmap_event, tid, T_UINT, "event tid"),
member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
@@ -297,6 +298,43 @@ static PyTypeObject pyrf_sample_event__type = {
.tp_repr = (reprfunc)pyrf_sample_event__repr,
};
+static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
+
+static PyMemberDef pyrf_context_switch_event__members[] = {
+ sample_members
+ member_def(perf_event_header, type, T_UINT, "event type"),
+ member_def(context_switch_event, next_prev_pid, T_UINT, "next/prev pid"),
+ member_def(context_switch_event, next_prev_tid, T_UINT, "next/prev tid"),
+ { .name = NULL, },
+};
+
+static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent)
+{
+ PyObject *ret;
+ char *s;
+
+ if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
+ pevent->event.context_switch.next_prev_pid,
+ pevent->event.context_switch.next_prev_tid,
+ !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
+ ret = PyErr_NoMemory();
+ } else {
+ ret = PyString_FromString(s);
+ free(s);
+ }
+ return ret;
+}
+
+static PyTypeObject pyrf_context_switch_event__type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "perf.context_switch_event",
+ .tp_basicsize = sizeof(struct pyrf_event),
+ .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+ .tp_doc = pyrf_context_switch_event__doc,
+ .tp_members = pyrf_context_switch_event__members,
+ .tp_repr = (reprfunc)pyrf_context_switch_event__repr,
+};
+
static int pyrf_event__setup_types(void)
{
int err;
@@ -306,6 +344,7 @@ static int pyrf_event__setup_types(void)
pyrf_lost_event__type.tp_new =
pyrf_read_event__type.tp_new =
pyrf_sample_event__type.tp_new =
+ pyrf_context_switch_event__type.tp_new =
pyrf_throttle_event__type.tp_new = PyType_GenericNew;
err = PyType_Ready(&pyrf_mmap_event__type);
if (err < 0)
@@ -328,6 +367,9 @@ static int pyrf_event__setup_types(void)
err = PyType_Ready(&pyrf_sample_event__type);
if (err < 0)
goto out;
+ err = PyType_Ready(&pyrf_context_switch_event__type);
+ if (err < 0)
+ goto out;
out:
return err;
}
@@ -342,6 +384,8 @@ static PyTypeObject *pyrf_event__type[] = {
[PERF_RECORD_FORK] = &pyrf_task_event__type,
[PERF_RECORD_READ] = &pyrf_read_event__type,
[PERF_RECORD_SAMPLE] = &pyrf_sample_event__type,
+ [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type,
+ [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type,
};
static PyObject *pyrf_event__new(union perf_event *event)
@@ -349,8 +393,10 @@ static PyObject *pyrf_event__new(union perf_event *event)
struct pyrf_event *pevent;
PyTypeObject *ptype;
- if (event->header.type < PERF_RECORD_MMAP ||
- event->header.type > PERF_RECORD_SAMPLE)
+ if ((event->header.type < PERF_RECORD_MMAP ||
+ event->header.type > PERF_RECORD_SAMPLE) &&
+ !(event->header.type == PERF_RECORD_SWITCH ||
+ event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
return NULL;
ptype = pyrf_event__type[event->header.type];
@@ -528,6 +574,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
"exclude_hv",
"exclude_idle",
"mmap",
+ "context_switch",
"comm",
"freq",
"inherit_stat",
@@ -553,6 +600,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
exclude_hv = 0,
exclude_idle = 0,
mmap = 0,
+ context_switch = 0,
comm = 0,
freq = 1,
inherit_stat = 0,
@@ -565,13 +613,13 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
int idx = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
+ "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
&attr.type, &attr.config, &attr.sample_freq,
&sample_period, &attr.sample_type,
&attr.read_format, &disabled, &inherit,
&pinned, &exclusive, &exclude_user,
&exclude_kernel, &exclude_hv, &exclude_idle,
- &mmap, &comm, &freq, &inherit_stat,
+ &mmap, &context_switch, &comm, &freq, &inherit_stat,
&enable_on_exec, &task, &watermark,
&precise_ip, &mmap_data, &sample_id_all,
&attr.wakeup_events, &attr.bp_type,
@@ -595,6 +643,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
attr.exclude_hv = exclude_hv;
attr.exclude_idle = exclude_idle;
attr.mmap = mmap;
+ attr.context_switch = context_switch;
attr.comm = comm;
attr.freq = freq;
attr.inherit_stat = inherit_stat;
@@ -1019,6 +1068,8 @@ static struct {
PERF_CONST(RECORD_LOST_SAMPLES),
PERF_CONST(RECORD_SWITCH),
PERF_CONST(RECORD_SWITCH_CPU_WIDE),
+
+ PERF_CONST(RECORD_MISC_SWITCH_OUT),
{ .name = NULL, },
};
--
2.1.0
prev parent reply other threads:[~2015-10-07 22:45 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-07 22:45 [GIT PULL 0/5] perf/core improvements and fixes Arnaldo Carvalho de Melo
2015-10-07 22:45 ` Arnaldo Carvalho de Melo
2015-10-07 22:45 ` [PATCH 1/5] perf tools: Get rid of superfluos call to reset_dimensions Arnaldo Carvalho de Melo
2015-10-07 22:45 ` [PATCH 2/5] perf tools: Introduce hpp_dimension__add_output function Arnaldo Carvalho de Melo
2015-10-07 22:45 ` [PATCH 3/5] perf tools: Use hpp_dimension__add_output to register hpp columns Arnaldo Carvalho de Melo
2015-10-07 22:45 ` [PATCH 4/5] perf tools: Fix handling read result using a signed variable Arnaldo Carvalho de Melo
2015-10-07 22:45 ` Arnaldo Carvalho de Melo
2015-10-07 22:45 ` Arnaldo Carvalho de Melo [this message]
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=1444257917-24527-6-git-send-email-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=bp@suse.de \
--cc=dsahern@gmail.com \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=streeter@redhat.com \
--cc=wangnan0@huawei.com \
/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.