perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
#include <Python.h>
|
|
|
|
#include <structmember.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <poll.h>
|
|
|
|
#include "evlist.h"
|
|
|
|
#include "evsel.h"
|
|
|
|
#include "event.h"
|
|
|
|
#include "cpumap.h"
|
|
|
|
#include "thread_map.h"
|
|
|
|
|
2011-02-26 04:30:16 +08:00
|
|
|
/* Define PyVarObject_HEAD_INIT for python 2.5 */
|
|
|
|
#ifndef PyVarObject_HEAD_INIT
|
|
|
|
# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
|
|
|
|
#endif
|
|
|
|
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
struct throttle_event {
|
|
|
|
struct perf_event_header header;
|
|
|
|
u64 time;
|
|
|
|
u64 id;
|
|
|
|
u64 stream_id;
|
|
|
|
};
|
|
|
|
|
2011-02-01 06:56:27 +08:00
|
|
|
PyMODINIT_FUNC initperf(void);
|
|
|
|
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
#define member_def(type, member, ptype, help) \
|
|
|
|
{ #member, ptype, \
|
|
|
|
offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
|
|
|
|
0, help }
|
|
|
|
|
|
|
|
#define sample_member_def(name, member, ptype, help) \
|
|
|
|
{ #name, ptype, \
|
|
|
|
offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
|
|
|
|
0, help }
|
|
|
|
|
|
|
|
struct pyrf_event {
|
|
|
|
PyObject_HEAD
|
|
|
|
struct perf_sample sample;
|
|
|
|
union perf_event event;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define sample_members \
|
2011-02-01 06:56:27 +08:00
|
|
|
sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
sample_member_def(sample_pid, pid, T_INT, "event pid"), \
|
|
|
|
sample_member_def(sample_tid, tid, T_INT, "event tid"), \
|
2011-02-01 06:56:27 +08:00
|
|
|
sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
|
|
|
|
sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
|
|
|
|
sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
|
|
|
|
sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
|
|
|
|
sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
|
|
|
|
|
|
|
|
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(mmap_event, pid, T_UINT, "event pid"),
|
|
|
|
member_def(mmap_event, tid, T_UINT, "event tid"),
|
2011-02-01 06:56:27 +08:00
|
|
|
member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
|
|
|
|
member_def(mmap_event, len, T_ULONGLONG, "map length"),
|
|
|
|
member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
|
2011-02-01 06:56:27 +08:00
|
|
|
{ .name = NULL, },
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
|
|
|
|
{
|
|
|
|
PyObject *ret;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
|
|
|
|
"length: %#" PRIx64 ", offset: %#" PRIx64 ", "
|
|
|
|
"filename: %s }",
|
|
|
|
pevent->event.mmap.pid, pevent->event.mmap.tid,
|
|
|
|
pevent->event.mmap.start, pevent->event.mmap.len,
|
|
|
|
pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
|
|
|
|
ret = PyErr_NoMemory();
|
|
|
|
} else {
|
|
|
|
ret = PyString_FromString(s);
|
|
|
|
free(s);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_mmap_event__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.mmap_event",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_event),
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_doc = pyrf_mmap_event__doc,
|
|
|
|
.tp_members = pyrf_mmap_event__members,
|
|
|
|
.tp_repr = (reprfunc)pyrf_mmap_event__repr,
|
|
|
|
};
|
|
|
|
|
|
|
|
static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
|
|
|
|
|
|
|
|
static PyMemberDef pyrf_task_event__members[] = {
|
|
|
|
sample_members
|
|
|
|
member_def(perf_event_header, type, T_UINT, "event type"),
|
|
|
|
member_def(fork_event, pid, T_UINT, "event pid"),
|
|
|
|
member_def(fork_event, ppid, T_UINT, "event ppid"),
|
|
|
|
member_def(fork_event, tid, T_UINT, "event tid"),
|
|
|
|
member_def(fork_event, ptid, T_UINT, "event ptid"),
|
2011-02-01 06:56:27 +08:00
|
|
|
member_def(fork_event, time, T_ULONGLONG, "timestamp"),
|
|
|
|
{ .name = NULL, },
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
|
|
|
|
{
|
|
|
|
return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
|
|
|
|
"ptid: %u, time: %" PRIu64 "}",
|
|
|
|
pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
|
|
|
|
pevent->event.fork.pid,
|
|
|
|
pevent->event.fork.ppid,
|
|
|
|
pevent->event.fork.tid,
|
|
|
|
pevent->event.fork.ptid,
|
|
|
|
pevent->event.fork.time);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_task_event__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.task_event",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_event),
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_doc = pyrf_task_event__doc,
|
|
|
|
.tp_members = pyrf_task_event__members,
|
|
|
|
.tp_repr = (reprfunc)pyrf_task_event__repr,
|
|
|
|
};
|
|
|
|
|
|
|
|
static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
|
|
|
|
|
|
|
|
static PyMemberDef pyrf_comm_event__members[] = {
|
|
|
|
sample_members
|
|
|
|
member_def(perf_event_header, type, T_UINT, "event type"),
|
|
|
|
member_def(comm_event, pid, T_UINT, "event pid"),
|
|
|
|
member_def(comm_event, tid, T_UINT, "event tid"),
|
|
|
|
member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
|
2011-02-01 06:56:27 +08:00
|
|
|
{ .name = NULL, },
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
|
|
|
|
{
|
|
|
|
return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
|
|
|
|
pevent->event.comm.pid,
|
|
|
|
pevent->event.comm.tid,
|
|
|
|
pevent->event.comm.comm);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_comm_event__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.comm_event",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_event),
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_doc = pyrf_comm_event__doc,
|
|
|
|
.tp_members = pyrf_comm_event__members,
|
|
|
|
.tp_repr = (reprfunc)pyrf_comm_event__repr,
|
|
|
|
};
|
|
|
|
|
|
|
|
static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
|
|
|
|
|
|
|
|
static PyMemberDef pyrf_throttle_event__members[] = {
|
|
|
|
sample_members
|
|
|
|
member_def(perf_event_header, type, T_UINT, "event type"),
|
2011-02-01 06:56:27 +08:00
|
|
|
member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
|
|
|
|
member_def(throttle_event, id, T_ULONGLONG, "event id"),
|
|
|
|
member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
|
|
|
|
{ .name = NULL, },
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
|
|
|
|
{
|
|
|
|
struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
|
|
|
|
|
|
|
|
return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
|
|
|
|
", stream_id: %" PRIu64 " }",
|
|
|
|
pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
|
|
|
|
te->time, te->id, te->stream_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_throttle_event__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.throttle_event",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_event),
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_doc = pyrf_throttle_event__doc,
|
|
|
|
.tp_members = pyrf_throttle_event__members,
|
|
|
|
.tp_repr = (reprfunc)pyrf_throttle_event__repr,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_event__setup_types(void)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
pyrf_mmap_event__type.tp_new =
|
|
|
|
pyrf_task_event__type.tp_new =
|
|
|
|
pyrf_comm_event__type.tp_new =
|
|
|
|
pyrf_throttle_event__type.tp_new = PyType_GenericNew;
|
|
|
|
err = PyType_Ready(&pyrf_mmap_event__type);
|
|
|
|
if (err < 0)
|
|
|
|
goto out;
|
|
|
|
err = PyType_Ready(&pyrf_task_event__type);
|
|
|
|
if (err < 0)
|
|
|
|
goto out;
|
|
|
|
err = PyType_Ready(&pyrf_comm_event__type);
|
|
|
|
if (err < 0)
|
|
|
|
goto out;
|
|
|
|
err = PyType_Ready(&pyrf_throttle_event__type);
|
|
|
|
if (err < 0)
|
|
|
|
goto out;
|
|
|
|
out:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyTypeObject *pyrf_event__type[] = {
|
|
|
|
[PERF_RECORD_MMAP] = &pyrf_mmap_event__type,
|
|
|
|
[PERF_RECORD_LOST] = &pyrf_mmap_event__type,
|
|
|
|
[PERF_RECORD_COMM] = &pyrf_comm_event__type,
|
|
|
|
[PERF_RECORD_EXIT] = &pyrf_task_event__type,
|
|
|
|
[PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type,
|
|
|
|
[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
|
|
|
|
[PERF_RECORD_FORK] = &pyrf_task_event__type,
|
|
|
|
[PERF_RECORD_READ] = &pyrf_mmap_event__type,
|
|
|
|
[PERF_RECORD_SAMPLE] = &pyrf_mmap_event__type,
|
|
|
|
};
|
|
|
|
|
|
|
|
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)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
ptype = pyrf_event__type[event->header.type];
|
|
|
|
pevent = PyObject_New(struct pyrf_event, ptype);
|
|
|
|
if (pevent != NULL)
|
|
|
|
memcpy(&pevent->event, event, event->header.size);
|
|
|
|
return (PyObject *)pevent;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pyrf_cpu_map {
|
|
|
|
PyObject_HEAD
|
|
|
|
|
|
|
|
struct cpu_map *cpus;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
|
|
|
|
PyObject *args, PyObject *kwargs)
|
|
|
|
{
|
|
|
|
static char *kwlist[] = { "cpustr", NULL, NULL, };
|
|
|
|
char *cpustr = NULL;
|
|
|
|
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
|
|
|
|
kwlist, &cpustr))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
pcpus->cpus = cpu_map__new(cpustr);
|
|
|
|
if (pcpus->cpus == NULL)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
|
|
|
|
{
|
|
|
|
cpu_map__delete(pcpus->cpus);
|
|
|
|
pcpus->ob_type->tp_free((PyObject*)pcpus);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
|
|
|
|
{
|
|
|
|
struct pyrf_cpu_map *pcpus = (void *)obj;
|
|
|
|
|
|
|
|
return pcpus->cpus->nr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
|
|
|
|
{
|
|
|
|
struct pyrf_cpu_map *pcpus = (void *)obj;
|
|
|
|
|
|
|
|
if (i >= pcpus->cpus->nr)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return Py_BuildValue("i", pcpus->cpus->map[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PySequenceMethods pyrf_cpu_map__sequence_methods = {
|
|
|
|
.sq_length = pyrf_cpu_map__length,
|
|
|
|
.sq_item = pyrf_cpu_map__item,
|
|
|
|
};
|
|
|
|
|
|
|
|
static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_cpu_map__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.cpu_map",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_cpu_map),
|
|
|
|
.tp_dealloc = (destructor)pyrf_cpu_map__delete,
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_doc = pyrf_cpu_map__doc,
|
|
|
|
.tp_as_sequence = &pyrf_cpu_map__sequence_methods,
|
|
|
|
.tp_init = (initproc)pyrf_cpu_map__init,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_cpu_map__setup_types(void)
|
|
|
|
{
|
|
|
|
pyrf_cpu_map__type.tp_new = PyType_GenericNew;
|
|
|
|
return PyType_Ready(&pyrf_cpu_map__type);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pyrf_thread_map {
|
|
|
|
PyObject_HEAD
|
|
|
|
|
|
|
|
struct thread_map *threads;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
|
|
|
|
PyObject *args, PyObject *kwargs)
|
|
|
|
{
|
|
|
|
static char *kwlist[] = { "pid", "tid", NULL, NULL, };
|
|
|
|
int pid = -1, tid = -1;
|
|
|
|
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
|
|
|
|
kwlist, &pid, &tid))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
pthreads->threads = thread_map__new(pid, tid);
|
|
|
|
if (pthreads->threads == NULL)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
|
|
|
|
{
|
|
|
|
thread_map__delete(pthreads->threads);
|
|
|
|
pthreads->ob_type->tp_free((PyObject*)pthreads);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
|
|
|
|
{
|
|
|
|
struct pyrf_thread_map *pthreads = (void *)obj;
|
|
|
|
|
|
|
|
return pthreads->threads->nr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
|
|
|
|
{
|
|
|
|
struct pyrf_thread_map *pthreads = (void *)obj;
|
|
|
|
|
|
|
|
if (i >= pthreads->threads->nr)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return Py_BuildValue("i", pthreads->threads->map[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PySequenceMethods pyrf_thread_map__sequence_methods = {
|
|
|
|
.sq_length = pyrf_thread_map__length,
|
|
|
|
.sq_item = pyrf_thread_map__item,
|
|
|
|
};
|
|
|
|
|
|
|
|
static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_thread_map__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.thread_map",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_thread_map),
|
|
|
|
.tp_dealloc = (destructor)pyrf_thread_map__delete,
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_doc = pyrf_thread_map__doc,
|
|
|
|
.tp_as_sequence = &pyrf_thread_map__sequence_methods,
|
|
|
|
.tp_init = (initproc)pyrf_thread_map__init,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_thread_map__setup_types(void)
|
|
|
|
{
|
|
|
|
pyrf_thread_map__type.tp_new = PyType_GenericNew;
|
|
|
|
return PyType_Ready(&pyrf_thread_map__type);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pyrf_evsel {
|
|
|
|
PyObject_HEAD
|
|
|
|
|
|
|
|
struct perf_evsel evsel;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
|
|
|
|
PyObject *args, PyObject *kwargs)
|
|
|
|
{
|
|
|
|
struct perf_event_attr attr = {
|
|
|
|
.type = PERF_TYPE_HARDWARE,
|
|
|
|
.config = PERF_COUNT_HW_CPU_CYCLES,
|
|
|
|
.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
|
|
|
|
};
|
|
|
|
static char *kwlist[] = {
|
|
|
|
"type",
|
|
|
|
"config",
|
|
|
|
"sample_freq",
|
|
|
|
"sample_period",
|
|
|
|
"sample_type",
|
|
|
|
"read_format",
|
|
|
|
"disabled",
|
|
|
|
"inherit",
|
|
|
|
"pinned",
|
|
|
|
"exclusive",
|
|
|
|
"exclude_user",
|
|
|
|
"exclude_kernel",
|
|
|
|
"exclude_hv",
|
|
|
|
"exclude_idle",
|
|
|
|
"mmap",
|
|
|
|
"comm",
|
|
|
|
"freq",
|
|
|
|
"inherit_stat",
|
|
|
|
"enable_on_exec",
|
|
|
|
"task",
|
|
|
|
"watermark",
|
|
|
|
"precise_ip",
|
|
|
|
"mmap_data",
|
|
|
|
"sample_id_all",
|
|
|
|
"wakeup_events",
|
|
|
|
"bp_type",
|
|
|
|
"bp_addr",
|
|
|
|
"bp_len", NULL, NULL, };
|
|
|
|
u64 sample_period = 0;
|
|
|
|
u32 disabled = 0,
|
|
|
|
inherit = 0,
|
|
|
|
pinned = 0,
|
|
|
|
exclusive = 0,
|
|
|
|
exclude_user = 0,
|
|
|
|
exclude_kernel = 0,
|
|
|
|
exclude_hv = 0,
|
|
|
|
exclude_idle = 0,
|
|
|
|
mmap = 0,
|
|
|
|
comm = 0,
|
|
|
|
freq = 1,
|
|
|
|
inherit_stat = 0,
|
|
|
|
enable_on_exec = 0,
|
|
|
|
task = 0,
|
|
|
|
watermark = 0,
|
|
|
|
precise_ip = 0,
|
|
|
|
mmap_data = 0,
|
|
|
|
sample_id_all = 1;
|
|
|
|
int idx = 0;
|
|
|
|
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
|
|
|
"|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", 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,
|
|
|
|
&enable_on_exec, &task, &watermark,
|
|
|
|
&precise_ip, &mmap_data, &sample_id_all,
|
|
|
|
&attr.wakeup_events, &attr.bp_type,
|
|
|
|
&attr.bp_addr, &attr.bp_len, &idx))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* union... */
|
|
|
|
if (sample_period != 0) {
|
|
|
|
if (attr.sample_freq != 0)
|
|
|
|
return -1; /* FIXME: throw right exception */
|
|
|
|
attr.sample_period = sample_period;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bitfields */
|
|
|
|
attr.disabled = disabled;
|
|
|
|
attr.inherit = inherit;
|
|
|
|
attr.pinned = pinned;
|
|
|
|
attr.exclusive = exclusive;
|
|
|
|
attr.exclude_user = exclude_user;
|
|
|
|
attr.exclude_kernel = exclude_kernel;
|
|
|
|
attr.exclude_hv = exclude_hv;
|
|
|
|
attr.exclude_idle = exclude_idle;
|
|
|
|
attr.mmap = mmap;
|
|
|
|
attr.comm = comm;
|
|
|
|
attr.freq = freq;
|
|
|
|
attr.inherit_stat = inherit_stat;
|
|
|
|
attr.enable_on_exec = enable_on_exec;
|
|
|
|
attr.task = task;
|
|
|
|
attr.watermark = watermark;
|
|
|
|
attr.precise_ip = precise_ip;
|
|
|
|
attr.mmap_data = mmap_data;
|
|
|
|
attr.sample_id_all = sample_id_all;
|
|
|
|
|
|
|
|
perf_evsel__init(&pevsel->evsel, &attr, idx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
|
|
|
|
{
|
|
|
|
perf_evsel__exit(&pevsel->evsel);
|
|
|
|
pevsel->ob_type->tp_free((PyObject*)pevsel);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
|
|
|
|
PyObject *args, PyObject *kwargs)
|
|
|
|
{
|
|
|
|
struct perf_evsel *evsel = &pevsel->evsel;
|
|
|
|
struct cpu_map *cpus = NULL;
|
|
|
|
struct thread_map *threads = NULL;
|
|
|
|
PyObject *pcpus = NULL, *pthreads = NULL;
|
2011-04-14 22:20:14 +08:00
|
|
|
int group = 0, inherit = 0;
|
|
|
|
static char *kwlist[] = {"cpus", "threads", "group", "inherit", NULL, NULL};
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
|
2011-04-14 22:20:14 +08:00
|
|
|
&pcpus, &pthreads, &group, &inherit))
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (pthreads != NULL)
|
|
|
|
threads = ((struct pyrf_thread_map *)pthreads)->threads;
|
|
|
|
|
|
|
|
if (pcpus != NULL)
|
|
|
|
cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
|
|
|
|
|
2011-04-14 22:20:14 +08:00
|
|
|
evsel->attr.inherit = inherit;
|
|
|
|
if (perf_evsel__open(evsel, cpus, threads, group) < 0) {
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
PyErr_SetFromErrno(PyExc_OSError);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_INCREF(Py_None);
|
|
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyMethodDef pyrf_evsel__methods[] = {
|
|
|
|
{
|
|
|
|
.ml_name = "open",
|
|
|
|
.ml_meth = (PyCFunction)pyrf_evsel__open,
|
|
|
|
.ml_flags = METH_VARARGS | METH_KEYWORDS,
|
|
|
|
.ml_doc = PyDoc_STR("open the event selector file descriptor table.")
|
|
|
|
},
|
2011-02-01 06:56:27 +08:00
|
|
|
{ .ml_name = NULL, }
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_evsel__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.evsel",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_evsel),
|
|
|
|
.tp_dealloc = (destructor)pyrf_evsel__delete,
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_doc = pyrf_evsel__doc,
|
|
|
|
.tp_methods = pyrf_evsel__methods,
|
|
|
|
.tp_init = (initproc)pyrf_evsel__init,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_evsel__setup_types(void)
|
|
|
|
{
|
|
|
|
pyrf_evsel__type.tp_new = PyType_GenericNew;
|
|
|
|
return PyType_Ready(&pyrf_evsel__type);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pyrf_evlist {
|
|
|
|
PyObject_HEAD
|
|
|
|
|
|
|
|
struct perf_evlist evlist;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
|
2011-02-01 06:56:27 +08:00
|
|
|
PyObject *args, PyObject *kwargs __used)
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
{
|
2011-01-30 21:59:43 +08:00
|
|
|
PyObject *pcpus = NULL, *pthreads = NULL;
|
|
|
|
struct cpu_map *cpus;
|
|
|
|
struct thread_map *threads;
|
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
threads = ((struct pyrf_thread_map *)pthreads)->threads;
|
|
|
|
cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
|
|
|
|
perf_evlist__init(&pevlist->evlist, cpus, threads);
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
|
|
|
|
{
|
|
|
|
perf_evlist__exit(&pevlist->evlist);
|
|
|
|
pevlist->ob_type->tp_free((PyObject*)pevlist);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
|
|
|
|
PyObject *args, PyObject *kwargs)
|
|
|
|
{
|
|
|
|
struct perf_evlist *evlist = &pevlist->evlist;
|
2011-01-30 21:59:43 +08:00
|
|
|
static char *kwlist[] = {"pages", "overwrite",
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
NULL, NULL};
|
|
|
|
int pages = 128, overwrite = false;
|
|
|
|
|
2011-01-30 21:59:43 +08:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
|
|
|
|
&pages, &overwrite))
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
return NULL;
|
|
|
|
|
2011-01-30 21:59:43 +08:00
|
|
|
if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
PyErr_SetFromErrno(PyExc_OSError);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_INCREF(Py_None);
|
|
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
|
|
|
|
PyObject *args, PyObject *kwargs)
|
|
|
|
{
|
|
|
|
struct perf_evlist *evlist = &pevlist->evlist;
|
|
|
|
static char *kwlist[] = {"timeout", NULL, NULL};
|
|
|
|
int timeout = -1, n;
|
|
|
|
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
n = poll(evlist->pollfd, evlist->nr_fds, timeout);
|
|
|
|
if (n < 0) {
|
|
|
|
PyErr_SetFromErrno(PyExc_OSError);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Py_BuildValue("i", n);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
|
2011-02-01 06:56:27 +08:00
|
|
|
PyObject *args __used, PyObject *kwargs __used)
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
{
|
|
|
|
struct perf_evlist *evlist = &pevlist->evlist;
|
|
|
|
PyObject *list = PyList_New(0);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < evlist->nr_fds; ++i) {
|
|
|
|
PyObject *file;
|
|
|
|
FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
|
|
|
|
|
|
|
|
if (fp == NULL)
|
|
|
|
goto free_list;
|
|
|
|
|
|
|
|
file = PyFile_FromFile(fp, "perf", "r", NULL);
|
|
|
|
if (file == NULL)
|
|
|
|
goto free_list;
|
|
|
|
|
|
|
|
if (PyList_Append(list, file) != 0) {
|
|
|
|
Py_DECREF(file);
|
|
|
|
goto free_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_DECREF(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
free_list:
|
|
|
|
return PyErr_NoMemory();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
|
2011-02-01 06:56:27 +08:00
|
|
|
PyObject *args, PyObject *kwargs __used)
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
{
|
|
|
|
struct perf_evlist *evlist = &pevlist->evlist;
|
|
|
|
PyObject *pevsel;
|
|
|
|
struct perf_evsel *evsel;
|
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "O", &pevsel))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
Py_INCREF(pevsel);
|
|
|
|
evsel = &((struct pyrf_evsel *)pevsel)->evsel;
|
|
|
|
evsel->idx = evlist->nr_entries;
|
|
|
|
perf_evlist__add(evlist, evsel);
|
|
|
|
|
|
|
|
return Py_BuildValue("i", evlist->nr_entries);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
|
|
|
|
PyObject *args, PyObject *kwargs)
|
|
|
|
{
|
|
|
|
struct perf_evlist *evlist = &pevlist->evlist;
|
|
|
|
union perf_event *event;
|
|
|
|
int sample_id_all = 1, cpu;
|
|
|
|
static char *kwlist[] = {"sample_id_all", NULL, NULL};
|
2011-05-22 08:17:22 +08:00
|
|
|
int err;
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
|
|
|
|
&cpu, &sample_id_all))
|
|
|
|
return NULL;
|
|
|
|
|
perf evlist: Fix per thread mmap setup
The PERF_EVENT_IOC_SET_OUTPUT ioctl was returning -EINVAL when using
--pid when monitoring multithreaded apps, as we can only share a ring
buffer for events on the same thread if not doing per cpu.
Fix it by using per thread ring buffers.
Tested with:
[root@felicio ~]# tuna -t 26131 -CP | nl
1 thread ctxt_switches
2 pid SCHED_ rtpri affinity voluntary nonvoluntary cmd
3 26131 OTHER 0 0,1 10814276 2397830 chromium-browse
4 642 OTHER 0 0,1 14688 0 chromium-browse
5 26148 OTHER 0 0,1 713602 115479 chromium-browse
6 26149 OTHER 0 0,1 801958 2262 chromium-browse
7 26150 OTHER 0 0,1 1271128 248 chromium-browse
8 26151 OTHER 0 0,1 3 0 chromium-browse
9 27049 OTHER 0 0,1 36796 9 chromium-browse
10 618 OTHER 0 0,1 14711 0 chromium-browse
11 661 OTHER 0 0,1 14593 0 chromium-browse
12 29048 OTHER 0 0,1 28125 0 chromium-browse
13 26143 OTHER 0 0,1 2202789 781 chromium-browse
[root@felicio ~]#
So 11 threads under pid 26131, then:
[root@felicio ~]# perf record -F 50000 --pid 26131
[root@felicio ~]# grep perf_event /proc/`pidof perf`/maps | nl
1 7fa4a2538000-7fa4a25b9000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
2 7fa4a25b9000-7fa4a263a000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
3 7fa4a263a000-7fa4a26bb000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
4 7fa4a26bb000-7fa4a273c000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
5 7fa4a273c000-7fa4a27bd000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
6 7fa4a27bd000-7fa4a283e000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
7 7fa4a283e000-7fa4a28bf000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
8 7fa4a28bf000-7fa4a2940000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
9 7fa4a2940000-7fa4a29c1000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
10 7fa4a29c1000-7fa4a2a42000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
11 7fa4a2a42000-7fa4a2ac3000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
[root@felicio ~]#
11 mmaps, one per thread since we didn't specify any CPU list, so we need one
mmap per thread and:
[root@felicio ~]# perf record -F 50000 --pid 26131
^M
^C[ perf record: Woken up 79 times to write data ]
[ perf record: Captured and wrote 20.614 MB perf.data (~900639 samples) ]
[root@felicio ~]# perf report -D | grep PERF_RECORD_SAMPLE | cut -d/ -f2 | cut -d: -f1 | sort -n | uniq -c | sort -nr | nl
1 371310 26131
2 96516 26148
3 95694 26149
4 95203 26150
5 7291 26143
6 87 27049
7 76 661
8 60 29048
9 47 618
10 43 642
[root@felicio ~]#
Ok, one of the threads, 26151 was quiescent, so no samples there, but all the
others are there.
Then, if I specify one CPU:
[root@felicio ~]# perf record -F 50000 --pid 26131 --cpu 1
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.680 MB perf.data (~29730 samples) ]
[root@felicio ~]# perf report -D | grep PERF_RECORD_SAMPLE | cut -d/ -f2 | cut -d: -f1 | sort -n | uniq -c | sort -nr | nl
1 8444 26131
2 2584 26149
3 2518 26148
4 2324 26150
5 123 26143
6 9 661
7 9 29048
[root@felicio ~]#
This machine has two cores, so fewer threads appeared on the radar, and:
[root@felicio ~]# grep perf_event /proc/`pidof perf`/maps | nl
1 7f484b922000-7f484b9a3000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
[root@felicio ~]#
Just one mmap, as now we can use just one per-cpu buffer instead of the
per-thread needed in the previous case.
For global profiling:
[root@felicio ~]# perf record -F 50000 -a
^C[ perf record: Woken up 26 times to write data ]
[ perf record: Captured and wrote 7.128 MB perf.data (~311412 samples) ]
[root@felicio ~]# grep perf_event /proc/`pidof perf`/maps | nl
1 7fb49b435000-7fb49b4b6000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
2 7fb49b4b6000-7fb49b537000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
[root@felicio ~]#
It uses per-cpu buffers.
For just one thread:
[root@felicio ~]# perf record -F 50000 --tid 26148
^C[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.330 MB perf.data (~14426 samples) ]
[root@felicio ~]# perf report -D | grep PERF_RECORD_SAMPLE | cut -d/ -f2 | cut -d: -f1 | sort -n | uniq -c | sort -nr | nl
1 9969 26148
[root@felicio ~]#
[root@felicio ~]# grep perf_event /proc/`pidof perf`/maps | nl
1 7f286a51b000-7f286a59c000 rwxs 00000000 00:09 4064 anon_inode:[perf_event]
[root@felicio ~]#
Tested-by: David Ahern <dsahern@gmail.com>
Tested-by: Lin Ming <ming.m.lin@intel.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: http://lkml.kernel.org/r/20110426204401.GB1746@ghostprotocols.net
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-05-15 20:39:00 +08:00
|
|
|
event = perf_evlist__mmap_read(evlist, cpu);
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
if (event != NULL) {
|
|
|
|
struct perf_evsel *first;
|
|
|
|
PyObject *pyevent = pyrf_event__new(event);
|
|
|
|
struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
|
|
|
|
|
|
|
|
if (pyevent == NULL)
|
|
|
|
return PyErr_NoMemory();
|
|
|
|
|
|
|
|
first = list_entry(evlist->entries.next, struct perf_evsel, node);
|
2011-05-22 08:17:22 +08:00
|
|
|
err = perf_event__parse_sample(event, first->attr.sample_type,
|
2011-06-02 22:04:54 +08:00
|
|
|
perf_evsel__sample_size(first),
|
2011-05-22 08:17:22 +08:00
|
|
|
sample_id_all, &pevent->sample);
|
2011-06-02 21:55:10 +08:00
|
|
|
if (err)
|
|
|
|
return PyErr_Format(PyExc_OSError,
|
|
|
|
"perf: can't parse sample, err=%d", err);
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
return pyevent;
|
|
|
|
}
|
2011-06-02 21:55:10 +08:00
|
|
|
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
Py_INCREF(Py_None);
|
|
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyMethodDef pyrf_evlist__methods[] = {
|
|
|
|
{
|
|
|
|
.ml_name = "mmap",
|
|
|
|
.ml_meth = (PyCFunction)pyrf_evlist__mmap,
|
|
|
|
.ml_flags = METH_VARARGS | METH_KEYWORDS,
|
|
|
|
.ml_doc = PyDoc_STR("mmap the file descriptor table.")
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ml_name = "poll",
|
|
|
|
.ml_meth = (PyCFunction)pyrf_evlist__poll,
|
|
|
|
.ml_flags = METH_VARARGS | METH_KEYWORDS,
|
|
|
|
.ml_doc = PyDoc_STR("poll the file descriptor table.")
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ml_name = "get_pollfd",
|
|
|
|
.ml_meth = (PyCFunction)pyrf_evlist__get_pollfd,
|
|
|
|
.ml_flags = METH_VARARGS | METH_KEYWORDS,
|
|
|
|
.ml_doc = PyDoc_STR("get the poll file descriptor table.")
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ml_name = "add",
|
|
|
|
.ml_meth = (PyCFunction)pyrf_evlist__add,
|
|
|
|
.ml_flags = METH_VARARGS | METH_KEYWORDS,
|
|
|
|
.ml_doc = PyDoc_STR("adds an event selector to the list.")
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ml_name = "read_on_cpu",
|
|
|
|
.ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu,
|
|
|
|
.ml_flags = METH_VARARGS | METH_KEYWORDS,
|
|
|
|
.ml_doc = PyDoc_STR("reads an event.")
|
|
|
|
},
|
2011-02-01 06:56:27 +08:00
|
|
|
{ .ml_name = NULL, }
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static Py_ssize_t pyrf_evlist__length(PyObject *obj)
|
|
|
|
{
|
|
|
|
struct pyrf_evlist *pevlist = (void *)obj;
|
|
|
|
|
|
|
|
return pevlist->evlist.nr_entries;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
|
|
|
|
{
|
|
|
|
struct pyrf_evlist *pevlist = (void *)obj;
|
|
|
|
struct perf_evsel *pos;
|
|
|
|
|
|
|
|
if (i >= pevlist->evlist.nr_entries)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
list_for_each_entry(pos, &pevlist->evlist.entries, node)
|
|
|
|
if (i-- == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
|
|
|
|
}
|
|
|
|
|
|
|
|
static PySequenceMethods pyrf_evlist__sequence_methods = {
|
|
|
|
.sq_length = pyrf_evlist__length,
|
|
|
|
.sq_item = pyrf_evlist__item,
|
|
|
|
};
|
|
|
|
|
|
|
|
static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
|
|
|
|
|
|
|
|
static PyTypeObject pyrf_evlist__type = {
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
.tp_name = "perf.evlist",
|
|
|
|
.tp_basicsize = sizeof(struct pyrf_evlist),
|
|
|
|
.tp_dealloc = (destructor)pyrf_evlist__delete,
|
|
|
|
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
|
|
|
.tp_as_sequence = &pyrf_evlist__sequence_methods,
|
|
|
|
.tp_doc = pyrf_evlist__doc,
|
|
|
|
.tp_methods = pyrf_evlist__methods,
|
|
|
|
.tp_init = (initproc)pyrf_evlist__init,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pyrf_evlist__setup_types(void)
|
|
|
|
{
|
|
|
|
pyrf_evlist__type.tp_new = PyType_GenericNew;
|
|
|
|
return PyType_Ready(&pyrf_evlist__type);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
const char *name;
|
|
|
|
int value;
|
|
|
|
} perf__constants[] = {
|
|
|
|
{ "TYPE_HARDWARE", PERF_TYPE_HARDWARE },
|
|
|
|
{ "TYPE_SOFTWARE", PERF_TYPE_SOFTWARE },
|
|
|
|
{ "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT },
|
|
|
|
{ "TYPE_HW_CACHE", PERF_TYPE_HW_CACHE },
|
|
|
|
{ "TYPE_RAW", PERF_TYPE_RAW },
|
|
|
|
{ "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT },
|
|
|
|
|
|
|
|
{ "COUNT_HW_CPU_CYCLES", PERF_COUNT_HW_CPU_CYCLES },
|
|
|
|
{ "COUNT_HW_INSTRUCTIONS", PERF_COUNT_HW_INSTRUCTIONS },
|
|
|
|
{ "COUNT_HW_CACHE_REFERENCES", PERF_COUNT_HW_CACHE_REFERENCES },
|
|
|
|
{ "COUNT_HW_CACHE_MISSES", PERF_COUNT_HW_CACHE_MISSES },
|
|
|
|
{ "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
|
|
|
|
{ "COUNT_HW_BRANCH_MISSES", PERF_COUNT_HW_BRANCH_MISSES },
|
|
|
|
{ "COUNT_HW_BUS_CYCLES", PERF_COUNT_HW_BUS_CYCLES },
|
|
|
|
{ "COUNT_HW_CACHE_L1D", PERF_COUNT_HW_CACHE_L1D },
|
|
|
|
{ "COUNT_HW_CACHE_L1I", PERF_COUNT_HW_CACHE_L1I },
|
|
|
|
{ "COUNT_HW_CACHE_LL", PERF_COUNT_HW_CACHE_LL },
|
|
|
|
{ "COUNT_HW_CACHE_DTLB", PERF_COUNT_HW_CACHE_DTLB },
|
|
|
|
{ "COUNT_HW_CACHE_ITLB", PERF_COUNT_HW_CACHE_ITLB },
|
|
|
|
{ "COUNT_HW_CACHE_BPU", PERF_COUNT_HW_CACHE_BPU },
|
|
|
|
{ "COUNT_HW_CACHE_OP_READ", PERF_COUNT_HW_CACHE_OP_READ },
|
|
|
|
{ "COUNT_HW_CACHE_OP_WRITE", PERF_COUNT_HW_CACHE_OP_WRITE },
|
|
|
|
{ "COUNT_HW_CACHE_OP_PREFETCH", PERF_COUNT_HW_CACHE_OP_PREFETCH },
|
|
|
|
{ "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
|
|
|
|
{ "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS },
|
|
|
|
|
2011-04-29 20:41:28 +08:00
|
|
|
{ "COUNT_HW_STALLED_CYCLES_FRONTEND", PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
|
|
|
|
{ "COUNT_HW_STALLED_CYCLES_BACKEND", PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
|
|
|
|
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
{ "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK },
|
|
|
|
{ "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK },
|
|
|
|
{ "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS },
|
|
|
|
{ "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES },
|
|
|
|
{ "COUNT_SW_CPU_MIGRATIONS", PERF_COUNT_SW_CPU_MIGRATIONS },
|
|
|
|
{ "COUNT_SW_PAGE_FAULTS_MIN", PERF_COUNT_SW_PAGE_FAULTS_MIN },
|
|
|
|
{ "COUNT_SW_PAGE_FAULTS_MAJ", PERF_COUNT_SW_PAGE_FAULTS_MAJ },
|
|
|
|
{ "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS },
|
|
|
|
{ "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS },
|
|
|
|
|
|
|
|
{ "SAMPLE_IP", PERF_SAMPLE_IP },
|
|
|
|
{ "SAMPLE_TID", PERF_SAMPLE_TID },
|
|
|
|
{ "SAMPLE_TIME", PERF_SAMPLE_TIME },
|
|
|
|
{ "SAMPLE_ADDR", PERF_SAMPLE_ADDR },
|
|
|
|
{ "SAMPLE_READ", PERF_SAMPLE_READ },
|
|
|
|
{ "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN },
|
|
|
|
{ "SAMPLE_ID", PERF_SAMPLE_ID },
|
|
|
|
{ "SAMPLE_CPU", PERF_SAMPLE_CPU },
|
|
|
|
{ "SAMPLE_PERIOD", PERF_SAMPLE_PERIOD },
|
|
|
|
{ "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID },
|
|
|
|
{ "SAMPLE_RAW", PERF_SAMPLE_RAW },
|
|
|
|
|
|
|
|
{ "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED },
|
|
|
|
{ "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING },
|
|
|
|
{ "FORMAT_ID", PERF_FORMAT_ID },
|
|
|
|
{ "FORMAT_GROUP", PERF_FORMAT_GROUP },
|
|
|
|
|
|
|
|
{ "RECORD_MMAP", PERF_RECORD_MMAP },
|
|
|
|
{ "RECORD_LOST", PERF_RECORD_LOST },
|
|
|
|
{ "RECORD_COMM", PERF_RECORD_COMM },
|
|
|
|
{ "RECORD_EXIT", PERF_RECORD_EXIT },
|
|
|
|
{ "RECORD_THROTTLE", PERF_RECORD_THROTTLE },
|
|
|
|
{ "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE },
|
|
|
|
{ "RECORD_FORK", PERF_RECORD_FORK },
|
|
|
|
{ "RECORD_READ", PERF_RECORD_READ },
|
|
|
|
{ "RECORD_SAMPLE", PERF_RECORD_SAMPLE },
|
2011-02-01 06:56:27 +08:00
|
|
|
{ .name = NULL, },
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static PyMethodDef perf__methods[] = {
|
2011-02-01 06:56:27 +08:00
|
|
|
{ .ml_name = NULL, }
|
perf tools: Initial python binding
First clarifying that this kind of binding is not a replacement or an
equivalent to the 'perf script' way of using python with perf.
The 'perf script' way is to process events and look at a given script
for some python function that matches the events to pass each event for
processing.
This is a python module, i.e. everything is driven from the python
script, that merely uses "import perf" or "from perf import".
perf script is focused on tracepoints, this binding is focused on profiling as
an initial target. More work is needed to make available tracepoint specific
variables as event variables accessible via this binding.
There is one example of such usage model, in
tools/perf/python/twatch.py, a tool to watch "cycles" events together
with task (fork, exit) and comm perf events.
For now, due to me not being able to grok how python distutils cope with
building C extensions outside the sources dir the install target just
builds it, I'm using it as:
[root@emilia linux]# export PYTHONPATH=~acme/git/build/perf/lib.linux-x86_64-2.6/
[root@emilia linux]# tools/perf/python/twatch.py
cpu: 4, pid: 30126, tid: 30126 { type: mmap, pid: 30126, tid: 30126, start: 0x4, length: 0x82e9ca03, offset: 0, filename: }
cpu: 6, pid: 47, tid: 47 { type: mmap, pid: 47, tid: 47, start: 0x6, length: 0xbef87c36, offset: 0, filename: }
cpu: 1, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x1, length: 0x775d1904, offset: 0, filename: }
cpu: 7, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0x7, length: 0xc750aeb6, offset: 0, filename: }
cpu: 5, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x5, length: 0x76669635, offset: 0, filename: }
cpu: 0, pid: 0, tid: 0 { type: mmap, pid: 0, tid: 0, start: 0, length: 0x6422ef6b, offset: 0, filename: }
cpu: 2, pid: 2255, tid: 2255 { type: mmap, pid: 2255, tid: 2255, start: 0x2, length: 0xe078757a, offset: 0, filename: }
cpu: 1, pid: 5769, tid: 5769 { type: fork, pid: 30127, ppid: 5769, tid: 30127, ptid: 5769, time: 103893991270534}
cpu: 6, pid: 30127, tid: 30127 { type: comm, pid: 30127, tid: 30127, comm: ls }
cpu: 6, pid: 30127, tid: 30127 { type: exit, pid: 30127, ppid: 30127, tid: 30127, ptid: 30127, time: 103893993273024}
The first 8 mmap events in this 8 way machine are a mistery that is still being
investigated.
More of the tools/perf/util/ APIs will be exposed via this python binding as
the need arises. For now the focus is on creating events and processing them,
symbol resolution is an obvious next step, with tracepoint variables as a close
second step.
Cc: Clark Williams <williams@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-30 01:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
PyMODINIT_FUNC initperf(void)
|
|
|
|
{
|
|
|
|
PyObject *obj;
|
|
|
|
int i;
|
|
|
|
PyObject *dict, *module = Py_InitModule("perf", perf__methods);
|
|
|
|
|
|
|
|
if (module == NULL ||
|
|
|
|
pyrf_event__setup_types() < 0 ||
|
|
|
|
pyrf_evlist__setup_types() < 0 ||
|
|
|
|
pyrf_evsel__setup_types() < 0 ||
|
|
|
|
pyrf_thread_map__setup_types() < 0 ||
|
|
|
|
pyrf_cpu_map__setup_types() < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Py_INCREF(&pyrf_evlist__type);
|
|
|
|
PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
|
|
|
|
|
|
|
|
Py_INCREF(&pyrf_evsel__type);
|
|
|
|
PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
|
|
|
|
|
|
|
|
Py_INCREF(&pyrf_thread_map__type);
|
|
|
|
PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
|
|
|
|
|
|
|
|
Py_INCREF(&pyrf_cpu_map__type);
|
|
|
|
PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
|
|
|
|
|
|
|
|
dict = PyModule_GetDict(module);
|
|
|
|
if (dict == NULL)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
for (i = 0; perf__constants[i].name != NULL; i++) {
|
|
|
|
obj = PyInt_FromLong(perf__constants[i].value);
|
|
|
|
if (obj == NULL)
|
|
|
|
goto error;
|
|
|
|
PyDict_SetItemString(dict, perf__constants[i].name, obj);
|
|
|
|
Py_DECREF(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
|
|
|
|
}
|