* [PATCH v5 1/5] perf script: Add general python handler to process non-tracepoint events
2012-08-08 9:57 [PATCH v5 0/5] perf script: Add general event support to event handler of python script Feng Tang
@ 2012-08-08 9:57 ` Feng Tang
2012-08-09 0:54 ` Namhyung Kim
2012-08-21 15:30 ` [tip:perf/core] " tip-bot for Feng Tang
2012-08-08 9:57 ` [PATCH v5 2/5] perf script: Replace "struct thread" with "struct addr_location" as a parameter for "process_event()" Feng Tang
` (3 subsequent siblings)
4 siblings, 2 replies; 19+ messages in thread
From: Feng Tang @ 2012-08-08 9:57 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel
Cc: Robert Richter, Andi Kleen, Stephane Eranian, Feng Tang,
David Ahern, Peter Zijlstra, Arnaldo Carvalho de Melo
This patch just follows Robert Richter's idea and the commit 37a058ea0
"perf script: Add generic perl handler to process events"
to similarly add a python handler for general events other than tracepoints.
For non-tracepoint events, this patch will try to find a function named
"process_event" in the python script, and pass the event attribute,
perf_sample, raw_data in format of raw string. And the python script can
use "struct" module's unpack function to disasemble the needed info and process.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
http://lkml.kernel.org/r/1339999839-14007-2-git-send-email-feng.tang@intel.com
[ committer note: Fixed up wrt da37896, i.e. pevent parm in script event handlers ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
.../util/scripting-engines/trace-event-python.c | 59 +++++++++++++++++++-
1 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index df7d33d..b9010d8 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -32,6 +32,7 @@
#include "../event.h"
#include "../thread.h"
#include "../trace-event.h"
+#include "../evsel.h"
PyMODINIT_FUNC initperf_trace_context(void);
@@ -220,7 +221,7 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
return event;
}
-static void python_process_event(union perf_event *perf_event __unused,
+static void python_process_tracepoint(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
@@ -337,6 +338,62 @@ static void python_process_event(union perf_event *perf_event __unused,
Py_DECREF(t);
}
+static void python_process_general_event(union perf_event *perf_event __unused,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine __unused,
+ struct thread *thread __unused)
+{
+ PyObject *handler, *retval, *t;
+ static char handler_name[64];
+ unsigned n = 0;
+ void *data = sample->raw_data;
+
+ t = PyTuple_New(MAX_FIELDS);
+ if (!t)
+ Py_FatalError("couldn't create Python tuple");
+
+ snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
+
+ handler = PyDict_GetItemString(main_dict, handler_name);
+ if (handler && !PyCallable_Check(handler)) {
+ handler = NULL;
+ goto exit;
+ }
+
+ /* Pass 3 parameters: event_attr, perf_sample, raw data */
+ PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
+ PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
+ PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
+
+ if (_PyTuple_Resize(&t, n) == -1)
+ Py_FatalError("error resizing Python tuple");
+
+ retval = PyObject_CallObject(handler, t);
+ if (retval == NULL)
+ handler_call_die(handler_name);
+exit:
+ Py_DECREF(t);
+}
+
+static void python_process_event(union perf_event *perf_event,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine,
+ struct thread *thread)
+{
+ switch (evsel->attr.type) {
+ case PERF_TYPE_TRACEPOINT:
+ python_process_tracepoint(perf_event, sample, evsel,
+ machine, thread);
+ break;
+ /* Reserve for future process_hw/sw/raw APIs */
+ default:
+ python_process_general_event(perf_event, sample, evsel,
+ machine, thread);
+ }
+}
+
static int run_start_sub(void)
{
PyObject *handler, *retval;
--
1.7.1
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v5 1/5] perf script: Add general python handler to process non-tracepoint events
2012-08-08 9:57 ` [PATCH v5 1/5] perf script: Add general python handler to process non-tracepoint events Feng Tang
@ 2012-08-09 0:54 ` Namhyung Kim
2012-08-21 15:30 ` [tip:perf/core] " tip-bot for Feng Tang
1 sibling, 0 replies; 19+ messages in thread
From: Namhyung Kim @ 2012-08-09 0:54 UTC (permalink / raw)
To: Feng Tang
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
Hi, Feng
On Wed, 8 Aug 2012 17:57:51 +0800, Feng Tang wrote:
> This patch just follows Robert Richter's idea and the commit 37a058ea0
> "perf script: Add generic perl handler to process events"
> to similarly add a python handler for general events other than tracepoints.
>
> For non-tracepoint events, this patch will try to find a function named
> "process_event" in the python script, and pass the event attribute,
> perf_sample, raw_data in format of raw string. And the python script can
> use "struct" module's unpack function to disasemble the needed info and process.
>
> Signed-off-by: Feng Tang <feng.tang@intel.com>
> Cc: Andi Kleen <andi@firstfloor.org>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Robert Richter <robert.richter@amd.com>
> Cc: Stephane Eranian <eranian@google.com>
> http://lkml.kernel.org/r/1339999839-14007-2-git-send-email-feng.tang@intel.com
> [ committer note: Fixed up wrt da37896, i.e. pevent parm in script event handlers ]
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> .../util/scripting-engines/trace-event-python.c | 59 +++++++++++++++++++-
> 1 files changed, 58 insertions(+), 1 deletions(-)
>
> diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
> index df7d33d..b9010d8 100644
> --- a/tools/perf/util/scripting-engines/trace-event-python.c
> +++ b/tools/perf/util/scripting-engines/trace-event-python.c
> @@ -32,6 +32,7 @@
> #include "../event.h"
> #include "../thread.h"
> #include "../trace-event.h"
> +#include "../evsel.h"
>
> PyMODINIT_FUNC initperf_trace_context(void);
>
> @@ -220,7 +221,7 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
> return event;
> }
>
> -static void python_process_event(union perf_event *perf_event __unused,
> +static void python_process_tracepoint(union perf_event *perf_event __unused,
> struct perf_sample *sample,
> struct perf_evsel *evsel,
> struct machine *machine __unused,
> @@ -337,6 +338,62 @@ static void python_process_event(union perf_event *perf_event __unused,
> Py_DECREF(t);
> }
>
> +static void python_process_general_event(union perf_event *perf_event __unused,
> + struct perf_sample *sample,
> + struct perf_evsel *evsel,
> + struct machine *machine __unused,
> + struct thread *thread __unused)
> +{
> + PyObject *handler, *retval, *t;
> + static char handler_name[64];
> + unsigned n = 0;
> + void *data = sample->raw_data;
> +
> + t = PyTuple_New(MAX_FIELDS);
> + if (!t)
> + Py_FatalError("couldn't create Python tuple");
> +
> + snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
> +
> + handler = PyDict_GetItemString(main_dict, handler_name);
> + if (handler && !PyCallable_Check(handler)) {
Shouldn't it be like below?
if (!handler || !PyCallable_Check(handler))
goto exit;
Otherwise we can end up calling PyObject_CallObject with NULL handler
if PyDict_GetItemString() returns NULL. And the handler won't be used
anymore so no need to set it to NULL (again).
Thanks,
Namhyung
> + handler = NULL;
> + goto exit;
> + }
> +
> + /* Pass 3 parameters: event_attr, perf_sample, raw data */
> + PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
> + PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
> + PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
> +
> + if (_PyTuple_Resize(&t, n) == -1)
> + Py_FatalError("error resizing Python tuple");
> +
> + retval = PyObject_CallObject(handler, t);
> + if (retval == NULL)
> + handler_call_die(handler_name);
> +exit:
> + Py_DECREF(t);
> +}
> +
> +static void python_process_event(union perf_event *perf_event,
> + struct perf_sample *sample,
> + struct perf_evsel *evsel,
> + struct machine *machine,
> + struct thread *thread)
> +{
> + switch (evsel->attr.type) {
> + case PERF_TYPE_TRACEPOINT:
> + python_process_tracepoint(perf_event, sample, evsel,
> + machine, thread);
> + break;
> + /* Reserve for future process_hw/sw/raw APIs */
> + default:
> + python_process_general_event(perf_event, sample, evsel,
> + machine, thread);
> + }
> +}
> +
> static int run_start_sub(void)
> {
> PyObject *handler, *retval;
^ permalink raw reply [flat|nested] 19+ messages in thread* [tip:perf/core] perf script: Add general python handler to process non-tracepoint events
2012-08-08 9:57 ` [PATCH v5 1/5] perf script: Add general python handler to process non-tracepoint events Feng Tang
2012-08-09 0:54 ` Namhyung Kim
@ 2012-08-21 15:30 ` tip-bot for Feng Tang
1 sibling, 0 replies; 19+ messages in thread
From: tip-bot for Feng Tang @ 2012-08-21 15:30 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, hpa, mingo, andi, peterz,
robert.richter, dsahern, tglx, feng.tang, mingo
Commit-ID: 6a6daec2ae9f097703c1da4925367f1c198c9492
Gitweb: http://git.kernel.org/tip/6a6daec2ae9f097703c1da4925367f1c198c9492
Author: Feng Tang <feng.tang@intel.com>
AuthorDate: Wed, 8 Aug 2012 17:57:51 +0800
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 8 Aug 2012 12:45:33 -0300
perf script: Add general python handler to process non-tracepoint events
This patch just follows Robert Richter's idea and the commit 37a058ea0
"perf script: Add generic perl handler to process events"
to similarly add a python handler for general events other than tracepoints.
For non-tracepoint events, this patch will try to find a function named
"process_event" in the python script, and pass the event attribute,
perf_sample, raw_data in format of raw string. And the python script can
use "struct" module's unpack function to disasemble the needed info and process.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1344419875-21665-2-git-send-email-feng.tang@intel.com
[ committer note: Fixed up wrt da37896, i.e. pevent parm in script event handlers ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
.../util/scripting-engines/trace-event-python.c | 59 +++++++++++++++++++-
1 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index df7d33d..b9010d8 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -32,6 +32,7 @@
#include "../event.h"
#include "../thread.h"
#include "../trace-event.h"
+#include "../evsel.h"
PyMODINIT_FUNC initperf_trace_context(void);
@@ -220,7 +221,7 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
return event;
}
-static void python_process_event(union perf_event *perf_event __unused,
+static void python_process_tracepoint(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
@@ -337,6 +338,62 @@ static void python_process_event(union perf_event *perf_event __unused,
Py_DECREF(t);
}
+static void python_process_general_event(union perf_event *perf_event __unused,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine __unused,
+ struct thread *thread __unused)
+{
+ PyObject *handler, *retval, *t;
+ static char handler_name[64];
+ unsigned n = 0;
+ void *data = sample->raw_data;
+
+ t = PyTuple_New(MAX_FIELDS);
+ if (!t)
+ Py_FatalError("couldn't create Python tuple");
+
+ snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
+
+ handler = PyDict_GetItemString(main_dict, handler_name);
+ if (handler && !PyCallable_Check(handler)) {
+ handler = NULL;
+ goto exit;
+ }
+
+ /* Pass 3 parameters: event_attr, perf_sample, raw data */
+ PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
+ PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
+ PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
+
+ if (_PyTuple_Resize(&t, n) == -1)
+ Py_FatalError("error resizing Python tuple");
+
+ retval = PyObject_CallObject(handler, t);
+ if (retval == NULL)
+ handler_call_die(handler_name);
+exit:
+ Py_DECREF(t);
+}
+
+static void python_process_event(union perf_event *perf_event,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine,
+ struct thread *thread)
+{
+ switch (evsel->attr.type) {
+ case PERF_TYPE_TRACEPOINT:
+ python_process_tracepoint(perf_event, sample, evsel,
+ machine, thread);
+ break;
+ /* Reserve for future process_hw/sw/raw APIs */
+ default:
+ python_process_general_event(perf_event, sample, evsel,
+ machine, thread);
+ }
+}
+
static int run_start_sub(void)
{
PyObject *handler, *retval;
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 2/5] perf script: Replace "struct thread" with "struct addr_location" as a parameter for "process_event()"
2012-08-08 9:57 [PATCH v5 0/5] perf script: Add general event support to event handler of python script Feng Tang
2012-08-08 9:57 ` [PATCH v5 1/5] perf script: Add general python handler to process non-tracepoint events Feng Tang
@ 2012-08-08 9:57 ` Feng Tang
2012-08-21 15:31 ` [tip:perf/core] perf script: Replace "struct thread" with " struct " tip-bot for Feng Tang
2012-08-08 9:57 ` [PATCH v5 3/5] perf script/python: Pass event/thread/dso name and symbol info to event handler in python Feng Tang
` (2 subsequent siblings)
4 siblings, 1 reply; 19+ messages in thread
From: Feng Tang @ 2012-08-08 9:57 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel
Cc: Robert Richter, Andi Kleen, Stephane Eranian, Feng Tang,
David Ahern, Peter Zijlstra, Arnaldo Carvalho de Melo
Both perl and python script start processing events other than trace
points, and it's useful to pass the resolved symbol and the dso info to
the event handler in script for better analysis and statistics.
Struct thread is already a member of struct addr_location, using
addr_location will keep the thread info, while providing additional
symbol and dso info if exist, so that the script itself doesn't need to
bother to do the symbol resolving and dso searching work.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Acked-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1339999839-14007-3-git-send-email-feng.tang@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-script.c | 5 +++--
.../perf/util/scripting-engines/trace-event-perl.c | 11 ++++++-----
.../util/scripting-engines/trace-event-python.c | 13 +++++++------
tools/perf/util/trace-event-scripting.c | 2 +-
tools/perf/util/trace-event.h | 5 +++--
5 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 6425612..30a9cb8 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -396,9 +396,10 @@ static void print_sample_bts(union perf_event *event,
static void process_event(union perf_event *event, struct perf_sample *sample,
struct perf_evsel *evsel, struct machine *machine,
- struct thread *thread)
+ struct addr_location *al)
{
struct perf_event_attr *attr = &evsel->attr;
+ struct thread *thread = al->thread;
if (output[attr->type].fields == 0)
return;
@@ -511,7 +512,7 @@ static int process_sample_event(struct perf_tool *tool __used,
if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
return 0;
- scripting_ops->process_event(event, sample, evsel, machine, thread);
+ scripting_ops->process_event(event, sample, evsel, machine, &al);
evsel->hists.stats.total_period += sample->period;
return 0;
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 20cefeb..1cde6aa 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -261,7 +261,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread)
+ struct addr_location *al)
{
struct format_field *field;
static char handler[256];
@@ -272,6 +272,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __unused,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
+ struct thread *thread = al->thread;
char *comm = thread->comm;
dSP;
@@ -349,7 +350,7 @@ static void perl_process_event_generic(union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread __unused)
+ struct addr_location *al __unused)
{
dSP;
@@ -375,10 +376,10 @@ static void perl_process_event(union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine,
- struct thread *thread)
+ struct addr_location *al)
{
- perl_process_tracepoint(event, sample, evsel, machine, thread);
- perl_process_event_generic(event, sample, evsel, machine, thread);
+ perl_process_tracepoint(event, sample, evsel, machine, al);
+ perl_process_event_generic(event, sample, evsel, machine, al);
}
static void run_start_sub(void)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index b9010d8..24711b3 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -225,7 +225,7 @@ static void python_process_tracepoint(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread)
+ struct addr_location *al)
{
PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
static char handler_name[256];
@@ -238,6 +238,7 @@ static void python_process_tracepoint(union perf_event *perf_event __unused,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
+ struct thread *thread = al->thread;
char *comm = thread->comm;
t = PyTuple_New(MAX_FIELDS);
@@ -342,7 +343,7 @@ static void python_process_general_event(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread __unused)
+ struct addr_location *al __unused)
{
PyObject *handler, *retval, *t;
static char handler_name[64];
@@ -361,7 +362,7 @@ static void python_process_general_event(union perf_event *perf_event __unused,
goto exit;
}
- /* Pass 3 parameters: event_attr, perf_sample, raw data */
+ /* Pass 4 parameters: event_attr, perf_sample, raw data, thread name */
PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
@@ -380,17 +381,17 @@ static void python_process_event(union perf_event *perf_event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine,
- struct thread *thread)
+ struct addr_location *al)
{
switch (evsel->attr.type) {
case PERF_TYPE_TRACEPOINT:
python_process_tracepoint(perf_event, sample, evsel,
- machine, thread);
+ machine, al);
break;
/* Reserve for future process_hw/sw/raw APIs */
default:
python_process_general_event(perf_event, sample, evsel,
- machine, thread);
+ machine, al);
}
}
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index aceb8ee..302ff26 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -39,7 +39,7 @@ static void process_event_unsupported(union perf_event *event __unused,
struct perf_sample *sample __unused,
struct perf_evsel *evsel __unused,
struct machine *machine __unused,
- struct thread *thread __unused)
+ struct addr_location *al __unused)
{
}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index cee1635..7575dfd 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -9,7 +9,6 @@ struct machine;
struct perf_sample;
union perf_event;
struct perf_tool;
-struct thread;
extern int header_page_size_size;
extern int header_page_ts_size;
@@ -76,6 +75,8 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
void tracing_data_put(struct tracing_data *tdata);
+struct addr_location;
+
struct scripting_ops {
const char *name;
int (*start_script) (const char *script, int argc, const char **argv);
@@ -84,7 +85,7 @@ struct scripting_ops {
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine,
- struct thread *thread);
+ struct addr_location *al);
int (*generate_script) (struct pevent *pevent, const char *outfile);
};
--
1.7.1
^ permalink raw reply related [flat|nested] 19+ messages in thread* [tip:perf/core] perf script: Replace "struct thread" with " struct addr_location" as a parameter for "process_event()"
2012-08-08 9:57 ` [PATCH v5 2/5] perf script: Replace "struct thread" with "struct addr_location" as a parameter for "process_event()" Feng Tang
@ 2012-08-21 15:31 ` tip-bot for Feng Tang
0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Feng Tang @ 2012-08-21 15:31 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, hpa, mingo, andi, peterz,
robert.richter, dsahern, tglx, feng.tang, mingo
Commit-ID: 73994dc158a24df4af77d0a76c9702f120f7a6ad
Gitweb: http://git.kernel.org/tip/73994dc158a24df4af77d0a76c9702f120f7a6ad
Author: Feng Tang <feng.tang@intel.com>
AuthorDate: Wed, 8 Aug 2012 17:57:52 +0800
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 8 Aug 2012 12:46:40 -0300
perf script: Replace "struct thread" with "struct addr_location" as a parameter for "process_event()"
Both perl and python script start processing events other than trace
points, and it's useful to pass the resolved symbol and the dso info to
the event handler in script for better analysis and statistics.
Struct thread is already a member of struct addr_location, using
addr_location will keep the thread info, while providing additional
symbol and dso info if exist, so that the script itself doesn't need to
bother to do the symbol resolving and dso searching work.
Tested-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Feng Tang <feng.tang@intel.com>
Acked-by: David Ahern <dsahern@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1344419875-21665-3-git-send-email-feng.tang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-script.c | 5 +++--
.../perf/util/scripting-engines/trace-event-perl.c | 11 ++++++-----
.../util/scripting-engines/trace-event-python.c | 13 +++++++------
tools/perf/util/trace-event-scripting.c | 2 +-
tools/perf/util/trace-event.h | 5 +++--
5 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 6425612..30a9cb8 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -396,9 +396,10 @@ static void print_sample_bts(union perf_event *event,
static void process_event(union perf_event *event, struct perf_sample *sample,
struct perf_evsel *evsel, struct machine *machine,
- struct thread *thread)
+ struct addr_location *al)
{
struct perf_event_attr *attr = &evsel->attr;
+ struct thread *thread = al->thread;
if (output[attr->type].fields == 0)
return;
@@ -511,7 +512,7 @@ static int process_sample_event(struct perf_tool *tool __used,
if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
return 0;
- scripting_ops->process_event(event, sample, evsel, machine, thread);
+ scripting_ops->process_event(event, sample, evsel, machine, &al);
evsel->hists.stats.total_period += sample->period;
return 0;
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 52580d0..d280010 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -261,7 +261,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread)
+ struct addr_location *al)
{
struct format_field *field;
static char handler[256];
@@ -272,6 +272,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __unused,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
+ struct thread *thread = al->thread;
char *comm = thread->comm;
dSP;
@@ -349,7 +350,7 @@ static void perl_process_event_generic(union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread __unused)
+ struct addr_location *al __unused)
{
dSP;
@@ -375,10 +376,10 @@ static void perl_process_event(union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine,
- struct thread *thread)
+ struct addr_location *al)
{
- perl_process_tracepoint(event, sample, evsel, machine, thread);
- perl_process_event_generic(event, sample, evsel, machine, thread);
+ perl_process_tracepoint(event, sample, evsel, machine, al);
+ perl_process_event_generic(event, sample, evsel, machine, al);
}
static void run_start_sub(void)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index b9010d8..24711b3 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -225,7 +225,7 @@ static void python_process_tracepoint(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread)
+ struct addr_location *al)
{
PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
static char handler_name[256];
@@ -238,6 +238,7 @@ static void python_process_tracepoint(union perf_event *perf_event __unused,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
+ struct thread *thread = al->thread;
char *comm = thread->comm;
t = PyTuple_New(MAX_FIELDS);
@@ -342,7 +343,7 @@ static void python_process_general_event(union perf_event *perf_event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine __unused,
- struct thread *thread __unused)
+ struct addr_location *al __unused)
{
PyObject *handler, *retval, *t;
static char handler_name[64];
@@ -361,7 +362,7 @@ static void python_process_general_event(union perf_event *perf_event __unused,
goto exit;
}
- /* Pass 3 parameters: event_attr, perf_sample, raw data */
+ /* Pass 4 parameters: event_attr, perf_sample, raw data, thread name */
PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
@@ -380,17 +381,17 @@ static void python_process_event(union perf_event *perf_event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine,
- struct thread *thread)
+ struct addr_location *al)
{
switch (evsel->attr.type) {
case PERF_TYPE_TRACEPOINT:
python_process_tracepoint(perf_event, sample, evsel,
- machine, thread);
+ machine, al);
break;
/* Reserve for future process_hw/sw/raw APIs */
default:
python_process_general_event(perf_event, sample, evsel,
- machine, thread);
+ machine, al);
}
}
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index aceb8ee..302ff26 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -39,7 +39,7 @@ static void process_event_unsupported(union perf_event *event __unused,
struct perf_sample *sample __unused,
struct perf_evsel *evsel __unused,
struct machine *machine __unused,
- struct thread *thread __unused)
+ struct addr_location *al __unused)
{
}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index cee1635..7575dfd 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -9,7 +9,6 @@ struct machine;
struct perf_sample;
union perf_event;
struct perf_tool;
-struct thread;
extern int header_page_size_size;
extern int header_page_ts_size;
@@ -76,6 +75,8 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
void tracing_data_put(struct tracing_data *tdata);
+struct addr_location;
+
struct scripting_ops {
const char *name;
int (*start_script) (const char *script, int argc, const char **argv);
@@ -84,7 +85,7 @@ struct scripting_ops {
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine,
- struct thread *thread);
+ struct addr_location *al);
int (*generate_script) (struct pevent *pevent, const char *outfile);
};
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 3/5] perf script/python: Pass event/thread/dso name and symbol info to event handler in python
2012-08-08 9:57 [PATCH v5 0/5] perf script: Add general event support to event handler of python script Feng Tang
2012-08-08 9:57 ` [PATCH v5 1/5] perf script: Add general python handler to process non-tracepoint events Feng Tang
2012-08-08 9:57 ` [PATCH v5 2/5] perf script: Replace "struct thread" with "struct addr_location" as a parameter for "process_event()" Feng Tang
@ 2012-08-08 9:57 ` Feng Tang
2012-08-09 1:06 ` Namhyung Kim
2012-08-21 15:32 ` [tip:perf/core] perf scripts python: Pass event/thread/ dso " tip-bot for Feng Tang
2012-08-08 9:57 ` [PATCH v5 4/5] perf script: Add a python library EventClass.py Feng Tang
2012-08-08 9:57 ` [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling Feng Tang
4 siblings, 2 replies; 19+ messages in thread
From: Feng Tang @ 2012-08-08 9:57 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel
Cc: Robert Richter, Andi Kleen, Stephane Eranian, Feng Tang,
David Ahern, Peter Zijlstra
Also as suggested by Arnaldo, pack all these parameters to a dictionary,
which is more expandable for adding new parameters while keeping the
compatibility for old scripts.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Stephane Eranian <eranian@google.com>
---
.../util/scripting-engines/trace-event-python.c | 35 ++++++++++++++++---
1 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 24711b3..7e3f576 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -345,15 +345,23 @@ static void python_process_general_event(union perf_event *perf_event __unused,
struct machine *machine __unused,
struct addr_location *al __unused)
{
- PyObject *handler, *retval, *t;
+ PyObject *handler, *retval, *t, *dict;
static char handler_name[64];
unsigned n = 0;
- void *data = sample->raw_data;
+ struct thread *thread = al->thread;
+ /*
+ * Use the MAX_FIELDS to make the function expandable, though
+ * currently there is only one itme for the tuple.
+ */
t = PyTuple_New(MAX_FIELDS);
if (!t)
Py_FatalError("couldn't create Python tuple");
+ dict = PyDict_New();
+ if (!dict)
+ Py_FatalError("couldn't create Python dictionary");
+
snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
handler = PyDict_GetItemString(main_dict, handler_name);
@@ -362,11 +370,25 @@ static void python_process_general_event(union perf_event *perf_event __unused,
goto exit;
}
- /* Pass 4 parameters: event_attr, perf_sample, raw data, thread name */
- PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
- PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
- PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
+ PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
+ PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize(
+ (const char *)&evsel->attr, sizeof(evsel->attr)));
+ PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize(
+ (const char *)sample, sizeof(*sample)));
+ PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize(
+ (const char *)sample->raw_data, sample->raw_size));
+ PyDict_SetItemString(dict, "comm",
+ PyString_FromString(thread->comm));
+ if (al->map) {
+ PyDict_SetItemString(dict, "dso",
+ PyString_FromString(al->map->dso->name));
+ }
+ if (al->sym) {
+ PyDict_SetItemString(dict, "symbol",
+ PyString_FromString(al->sym->name));
+ }
+ PyTuple_SetItem(t, n++, dict);
if (_PyTuple_Resize(&t, n) == -1)
Py_FatalError("error resizing Python tuple");
@@ -374,6 +396,7 @@ static void python_process_general_event(union perf_event *perf_event __unused,
if (retval == NULL)
handler_call_die(handler_name);
exit:
+ Py_DECREF(dict);
Py_DECREF(t);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v5 3/5] perf script/python: Pass event/thread/dso name and symbol info to event handler in python
2012-08-08 9:57 ` [PATCH v5 3/5] perf script/python: Pass event/thread/dso name and symbol info to event handler in python Feng Tang
@ 2012-08-09 1:06 ` Namhyung Kim
2012-08-21 15:32 ` [tip:perf/core] perf scripts python: Pass event/thread/ dso " tip-bot for Feng Tang
1 sibling, 0 replies; 19+ messages in thread
From: Namhyung Kim @ 2012-08-09 1:06 UTC (permalink / raw)
To: Feng Tang
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
On Wed, 8 Aug 2012 17:57:53 +0800, Feng Tang wrote:
> Also as suggested by Arnaldo, pack all these parameters to a dictionary,
> which is more expandable for adding new parameters while keeping the
> compatibility for old scripts.
>
Just minor nits.
> Signed-off-by: Feng Tang <feng.tang@intel.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Robert Richter <robert.richter@amd.com>
> Cc: Andi Kleen <andi@firstfloor.org>
> Cc: Stephane Eranian <eranian@google.com>
> ---
> .../util/scripting-engines/trace-event-python.c | 35 ++++++++++++++++---
> 1 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
> index 24711b3..7e3f576 100644
> --- a/tools/perf/util/scripting-engines/trace-event-python.c
> +++ b/tools/perf/util/scripting-engines/trace-event-python.c
> @@ -345,15 +345,23 @@ static void python_process_general_event(union perf_event *perf_event __unused,
> struct machine *machine __unused,
> struct addr_location *al __unused)
@al is used now.
> {
> - PyObject *handler, *retval, *t;
> + PyObject *handler, *retval, *t, *dict;
> static char handler_name[64];
> unsigned n = 0;
> - void *data = sample->raw_data;
> + struct thread *thread = al->thread;
>
> + /*
> + * Use the MAX_FIELDS to make the function expandable, though
> + * currently there is only one itme for the tuple.
s/itme/item/
Thanks,
Namhyung
> + */
> t = PyTuple_New(MAX_FIELDS);
> if (!t)
> Py_FatalError("couldn't create Python tuple");
>
> + dict = PyDict_New();
> + if (!dict)
> + Py_FatalError("couldn't create Python dictionary");
> +
> snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
>
> handler = PyDict_GetItemString(main_dict, handler_name);
> @@ -362,11 +370,25 @@ static void python_process_general_event(union perf_event *perf_event __unused,
> goto exit;
> }
>
> - /* Pass 4 parameters: event_attr, perf_sample, raw data, thread name */
> - PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
> - PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
> - PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
> + PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
> + PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize(
> + (const char *)&evsel->attr, sizeof(evsel->attr)));
> + PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize(
> + (const char *)sample, sizeof(*sample)));
> + PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize(
> + (const char *)sample->raw_data, sample->raw_size));
> + PyDict_SetItemString(dict, "comm",
> + PyString_FromString(thread->comm));
> + if (al->map) {
> + PyDict_SetItemString(dict, "dso",
> + PyString_FromString(al->map->dso->name));
> + }
> + if (al->sym) {
> + PyDict_SetItemString(dict, "symbol",
> + PyString_FromString(al->sym->name));
> + }
>
> + PyTuple_SetItem(t, n++, dict);
> if (_PyTuple_Resize(&t, n) == -1)
> Py_FatalError("error resizing Python tuple");
>
> @@ -374,6 +396,7 @@ static void python_process_general_event(union perf_event *perf_event __unused,
> if (retval == NULL)
> handler_call_die(handler_name);
> exit:
> + Py_DECREF(dict);
> Py_DECREF(t);
> }
^ permalink raw reply [flat|nested] 19+ messages in thread* [tip:perf/core] perf scripts python: Pass event/thread/ dso name and symbol info to event handler in python
2012-08-08 9:57 ` [PATCH v5 3/5] perf script/python: Pass event/thread/dso name and symbol info to event handler in python Feng Tang
2012-08-09 1:06 ` Namhyung Kim
@ 2012-08-21 15:32 ` tip-bot for Feng Tang
1 sibling, 0 replies; 19+ messages in thread
From: tip-bot for Feng Tang @ 2012-08-21 15:32 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, hpa, mingo, andi, peterz,
robert.richter, dsahern, tglx, feng.tang, mingo
Commit-ID: fd6b858a1e110c76e701cd9972a284ed2a7bcc33
Gitweb: http://git.kernel.org/tip/fd6b858a1e110c76e701cd9972a284ed2a7bcc33
Author: Feng Tang <feng.tang@intel.com>
AuthorDate: Wed, 8 Aug 2012 17:57:53 +0800
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 8 Aug 2012 12:48:02 -0300
perf scripts python: Pass event/thread/dso name and symbol info to event handler in python
Also as suggested by Arnaldo, pack all these parameters to a dictionary,
which is more expandable for adding new parameters while keeping the
compatibility for old scripts.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1344419875-21665-4-git-send-email-feng.tang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
.../util/scripting-engines/trace-event-python.c | 35 ++++++++++++++++---
1 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 24711b3..7e3f576 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -345,15 +345,23 @@ static void python_process_general_event(union perf_event *perf_event __unused,
struct machine *machine __unused,
struct addr_location *al __unused)
{
- PyObject *handler, *retval, *t;
+ PyObject *handler, *retval, *t, *dict;
static char handler_name[64];
unsigned n = 0;
- void *data = sample->raw_data;
+ struct thread *thread = al->thread;
+ /*
+ * Use the MAX_FIELDS to make the function expandable, though
+ * currently there is only one itme for the tuple.
+ */
t = PyTuple_New(MAX_FIELDS);
if (!t)
Py_FatalError("couldn't create Python tuple");
+ dict = PyDict_New();
+ if (!dict)
+ Py_FatalError("couldn't create Python dictionary");
+
snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
handler = PyDict_GetItemString(main_dict, handler_name);
@@ -362,11 +370,25 @@ static void python_process_general_event(union perf_event *perf_event __unused,
goto exit;
}
- /* Pass 4 parameters: event_attr, perf_sample, raw data, thread name */
- PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)&evsel->attr, sizeof(evsel->attr)));
- PyTuple_SetItem(t, n++, PyString_FromStringAndSize((void *)sample, sizeof(*sample)));
- PyTuple_SetItem(t, n++, PyString_FromStringAndSize(data, sample->raw_size));
+ PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
+ PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize(
+ (const char *)&evsel->attr, sizeof(evsel->attr)));
+ PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize(
+ (const char *)sample, sizeof(*sample)));
+ PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize(
+ (const char *)sample->raw_data, sample->raw_size));
+ PyDict_SetItemString(dict, "comm",
+ PyString_FromString(thread->comm));
+ if (al->map) {
+ PyDict_SetItemString(dict, "dso",
+ PyString_FromString(al->map->dso->name));
+ }
+ if (al->sym) {
+ PyDict_SetItemString(dict, "symbol",
+ PyString_FromString(al->sym->name));
+ }
+ PyTuple_SetItem(t, n++, dict);
if (_PyTuple_Resize(&t, n) == -1)
Py_FatalError("error resizing Python tuple");
@@ -374,6 +396,7 @@ static void python_process_general_event(union perf_event *perf_event __unused,
if (retval == NULL)
handler_call_die(handler_name);
exit:
+ Py_DECREF(dict);
Py_DECREF(t);
}
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 4/5] perf script: Add a python library EventClass.py
2012-08-08 9:57 [PATCH v5 0/5] perf script: Add general event support to event handler of python script Feng Tang
` (2 preceding siblings ...)
2012-08-08 9:57 ` [PATCH v5 3/5] perf script/python: Pass event/thread/dso name and symbol info to event handler in python Feng Tang
@ 2012-08-08 9:57 ` Feng Tang
2012-08-09 1:10 ` Namhyung Kim
2012-08-21 15:35 ` [tip:perf/core] perf scripts python: " tip-bot for Feng Tang
2012-08-08 9:57 ` [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling Feng Tang
4 siblings, 2 replies; 19+ messages in thread
From: Feng Tang @ 2012-08-08 9:57 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel
Cc: Robert Richter, Andi Kleen, Stephane Eranian, Feng Tang
This library defines several class types for perf events which could
help to better analyze the event samples. Currently there are just a
few classes, PerfEvent is the base class for all perf events, PebsEvent
is a HW base Intel x86 PEBS event, and user could add more SW/HW event
classes based on requriements.
Signed-off-by: Feng Tang <feng.tang@intel.com>
---
.../Perf-Trace-Util/lib/Perf/Trace/EventClass.py | 95 ++++++++++++++++++++
1 files changed, 95 insertions(+), 0 deletions(-)
create mode 100755 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
new file mode 100755
index 0000000..12cd773
--- /dev/null
+++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
@@ -0,0 +1,95 @@
+# EventClass.py
+#
+# This is a libray defining some events typs classes, which could
+# be used by other scripts to analyzing the perf samples.
+#
+# Currently there are just a few classes defined for examples,
+# PerfEvent is the base class for all perf event sample, PebsEvent
+# is a HW base Intel x86 PEBS event, and user could add more SW/HW
+# event classes based on requriements.
+
+import struct
+
+# Event types, user could add more here
+EVTYPE_GENERIC = 0
+EVTYPE_PEBS = 1 # Basic PEBS event
+EVTYPE_PEBS_LL = 2 # PEBS event with load latency info
+EVTYPE_IBS = 3
+
+#
+# Currently we don't have good way to tell the event type, but by
+# the size of raw buffer, raw PEBS event with load latency data's
+# size is 176 bytes, while the pure PEBS event's size is 144 bytes.
+#
+def create_event(name, comm, dso, symbol, raw_buf):
+ if (len(raw_buf) == 144):
+ event = PebsEvent(name, comm, dso, symbol, raw_buf)
+ elif (len(raw_buf) == 176):
+ event = PebsNHM(name, comm, dso, symbol, raw_buf)
+ else:
+ event = PerfEvent(name, comm, dso, symbol, raw_buf)
+
+ return event
+
+class PerfEvent(object):
+ event_num = 0
+ def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_GENERIC):
+ self.name = name
+ self.comm = comm
+ self.dso = dso
+ self.symbol = symbol
+ self.raw_buf = raw_buf
+ self.ev_type = ev_type
+ PerfEvent.event_num += 1
+
+ def show(self):
+ print "PMU event: name=%12s, symbol=%24s, comm=%8s, dso=%12s" % (self.name, self.symbol, self.comm, self.dso)
+
+#
+# Basic Intel PEBS (Precise Event-based Sampling) event, whose raw buffer
+# contains the context info when that event happened: the EFLAGS and
+# linear IP info, as well as all the registers.
+#
+class PebsEvent(PerfEvent):
+ pebs_num = 0
+ def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS):
+ tmp_buf=raw_buf[0:80]
+ flags, ip, ax, bx, cx, dx, si, di, bp, sp = struct.unpack('QQQQQQQQQQ', tmp_buf)
+ self.flags = flags
+ self.ip = ip
+ self.ax = ax
+ self.bx = bx
+ self.cx = cx
+ self.dx = dx
+ self.si = si
+ self.di = di
+ self.bp = bp
+ self.sp = sp
+
+ PerfEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
+ PebsEvent.pebs_num += 1
+ del tmp_buf
+
+#
+# Intel Nehalem and Westmere support PEBS plus Load Latency info which lie
+# in the four 64 bit words write after the PEBS data:
+# Status: records the IA32_PERF_GLOBAL_STATUS register value
+# DLA: Data Linear Address (EIP)
+# DSE: Data Source Encoding, where the latency happens, hit or miss
+# in L1/L2/L3 or IO operations
+# LAT: the actual latency in cycles
+#
+class PebsNHM(PebsEvent):
+ pebs_nhm_num = 0
+ def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS_LL):
+ tmp_buf=raw_buf[144:176]
+ status, dla, dse, lat = struct.unpack('QQQQ', tmp_buf)
+ self.status = status
+ self.dla = dla
+ self.dse = dse
+ self.lat = lat
+
+ PebsEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
+ PebsNHM.pebs_nhm_num += 1
+ del tmp_buf
+
--
1.7.1
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v5 4/5] perf script: Add a python library EventClass.py
2012-08-08 9:57 ` [PATCH v5 4/5] perf script: Add a python library EventClass.py Feng Tang
@ 2012-08-09 1:10 ` Namhyung Kim
2012-08-21 15:35 ` [tip:perf/core] perf scripts python: " tip-bot for Feng Tang
1 sibling, 0 replies; 19+ messages in thread
From: Namhyung Kim @ 2012-08-09 1:10 UTC (permalink / raw)
To: Feng Tang
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
On Wed, 8 Aug 2012 17:57:54 +0800, Feng Tang wrote:
> This library defines several class types for perf events which could
> help to better analyze the event samples. Currently there are just a
> few classes, PerfEvent is the base class for all perf events, PebsEvent
> is a HW base Intel x86 PEBS event, and user could add more SW/HW event
> classes based on requriements.
>
> Signed-off-by: Feng Tang <feng.tang@intel.com>
> ---
> .../Perf-Trace-Util/lib/Perf/Trace/EventClass.py | 95 ++++++++++++++++++++
> 1 files changed, 95 insertions(+), 0 deletions(-)
> create mode 100755 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
>
> diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
> new file mode 100755
> index 0000000..12cd773
> --- /dev/null
> +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
> @@ -0,0 +1,95 @@
> +# EventClass.py
> +#
> +# This is a libray defining some events typs classes, which could
s/typs/type/
> +# be used by other scripts to analyzing the perf samples.
> +#
> +# Currently there are just a few classes defined for examples,
> +# PerfEvent is the base class for all perf event sample, PebsEvent
> +# is a HW base Intel x86 PEBS event, and user could add more SW/HW
> +# event classes based on requriements.
s/requriements/requirements/
Thanks,
Namhyung
> +
> +import struct
> +
> +# Event types, user could add more here
> +EVTYPE_GENERIC = 0
> +EVTYPE_PEBS = 1 # Basic PEBS event
> +EVTYPE_PEBS_LL = 2 # PEBS event with load latency info
> +EVTYPE_IBS = 3
> +
> +#
> +# Currently we don't have good way to tell the event type, but by
> +# the size of raw buffer, raw PEBS event with load latency data's
> +# size is 176 bytes, while the pure PEBS event's size is 144 bytes.
> +#
> +def create_event(name, comm, dso, symbol, raw_buf):
> + if (len(raw_buf) == 144):
> + event = PebsEvent(name, comm, dso, symbol, raw_buf)
> + elif (len(raw_buf) == 176):
> + event = PebsNHM(name, comm, dso, symbol, raw_buf)
> + else:
> + event = PerfEvent(name, comm, dso, symbol, raw_buf)
> +
> + return event
> +
> +class PerfEvent(object):
> + event_num = 0
> + def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_GENERIC):
> + self.name = name
> + self.comm = comm
> + self.dso = dso
> + self.symbol = symbol
> + self.raw_buf = raw_buf
> + self.ev_type = ev_type
> + PerfEvent.event_num += 1
> +
> + def show(self):
> + print "PMU event: name=%12s, symbol=%24s, comm=%8s, dso=%12s" % (self.name, self.symbol, self.comm, self.dso)
> +
> +#
> +# Basic Intel PEBS (Precise Event-based Sampling) event, whose raw buffer
> +# contains the context info when that event happened: the EFLAGS and
> +# linear IP info, as well as all the registers.
> +#
> +class PebsEvent(PerfEvent):
> + pebs_num = 0
> + def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS):
> + tmp_buf=raw_buf[0:80]
> + flags, ip, ax, bx, cx, dx, si, di, bp, sp = struct.unpack('QQQQQQQQQQ', tmp_buf)
> + self.flags = flags
> + self.ip = ip
> + self.ax = ax
> + self.bx = bx
> + self.cx = cx
> + self.dx = dx
> + self.si = si
> + self.di = di
> + self.bp = bp
> + self.sp = sp
> +
> + PerfEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
> + PebsEvent.pebs_num += 1
> + del tmp_buf
> +
> +#
> +# Intel Nehalem and Westmere support PEBS plus Load Latency info which lie
> +# in the four 64 bit words write after the PEBS data:
> +# Status: records the IA32_PERF_GLOBAL_STATUS register value
> +# DLA: Data Linear Address (EIP)
> +# DSE: Data Source Encoding, where the latency happens, hit or miss
> +# in L1/L2/L3 or IO operations
> +# LAT: the actual latency in cycles
> +#
> +class PebsNHM(PebsEvent):
> + pebs_nhm_num = 0
> + def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS_LL):
> + tmp_buf=raw_buf[144:176]
> + status, dla, dse, lat = struct.unpack('QQQQ', tmp_buf)
> + self.status = status
> + self.dla = dla
> + self.dse = dse
> + self.lat = lat
> +
> + PebsEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
> + PebsNHM.pebs_nhm_num += 1
> + del tmp_buf
> +
^ permalink raw reply [flat|nested] 19+ messages in thread* [tip:perf/core] perf scripts python: Add a python library EventClass.py
2012-08-08 9:57 ` [PATCH v5 4/5] perf script: Add a python library EventClass.py Feng Tang
2012-08-09 1:10 ` Namhyung Kim
@ 2012-08-21 15:35 ` tip-bot for Feng Tang
1 sibling, 0 replies; 19+ messages in thread
From: tip-bot for Feng Tang @ 2012-08-21 15:35 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, hpa, mingo, andi, peterz,
robert.richter, dsahern, tglx, feng.tang, mingo
Commit-ID: 02f1c33f7d630183518ea42d45a6acf275541b08
Gitweb: http://git.kernel.org/tip/02f1c33f7d630183518ea42d45a6acf275541b08
Author: Feng Tang <feng.tang@intel.com>
AuthorDate: Wed, 8 Aug 2012 17:57:54 +0800
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 8 Aug 2012 12:53:08 -0300
perf scripts python: Add a python library EventClass.py
This library defines several class types for perf events which could
help to better analyze the event samples. Currently there are just a few
classes, PerfEvent is the base class for all perf events, PebsEvent is
a HW base Intel x86 PEBS event, and user could add more SW/HW event
classes based on requriements.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1344419875-21665-5-git-send-email-feng.tang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
.../Perf-Trace-Util/lib/Perf/Trace/EventClass.py | 94 ++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
new file mode 100755
index 0000000..6372431
--- /dev/null
+++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
@@ -0,0 +1,94 @@
+# EventClass.py
+#
+# This is a libray defining some events typs classes, which could
+# be used by other scripts to analyzing the perf samples.
+#
+# Currently there are just a few classes defined for examples,
+# PerfEvent is the base class for all perf event sample, PebsEvent
+# is a HW base Intel x86 PEBS event, and user could add more SW/HW
+# event classes based on requriements.
+
+import struct
+
+# Event types, user could add more here
+EVTYPE_GENERIC = 0
+EVTYPE_PEBS = 1 # Basic PEBS event
+EVTYPE_PEBS_LL = 2 # PEBS event with load latency info
+EVTYPE_IBS = 3
+
+#
+# Currently we don't have good way to tell the event type, but by
+# the size of raw buffer, raw PEBS event with load latency data's
+# size is 176 bytes, while the pure PEBS event's size is 144 bytes.
+#
+def create_event(name, comm, dso, symbol, raw_buf):
+ if (len(raw_buf) == 144):
+ event = PebsEvent(name, comm, dso, symbol, raw_buf)
+ elif (len(raw_buf) == 176):
+ event = PebsNHM(name, comm, dso, symbol, raw_buf)
+ else:
+ event = PerfEvent(name, comm, dso, symbol, raw_buf)
+
+ return event
+
+class PerfEvent(object):
+ event_num = 0
+ def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_GENERIC):
+ self.name = name
+ self.comm = comm
+ self.dso = dso
+ self.symbol = symbol
+ self.raw_buf = raw_buf
+ self.ev_type = ev_type
+ PerfEvent.event_num += 1
+
+ def show(self):
+ print "PMU event: name=%12s, symbol=%24s, comm=%8s, dso=%12s" % (self.name, self.symbol, self.comm, self.dso)
+
+#
+# Basic Intel PEBS (Precise Event-based Sampling) event, whose raw buffer
+# contains the context info when that event happened: the EFLAGS and
+# linear IP info, as well as all the registers.
+#
+class PebsEvent(PerfEvent):
+ pebs_num = 0
+ def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS):
+ tmp_buf=raw_buf[0:80]
+ flags, ip, ax, bx, cx, dx, si, di, bp, sp = struct.unpack('QQQQQQQQQQ', tmp_buf)
+ self.flags = flags
+ self.ip = ip
+ self.ax = ax
+ self.bx = bx
+ self.cx = cx
+ self.dx = dx
+ self.si = si
+ self.di = di
+ self.bp = bp
+ self.sp = sp
+
+ PerfEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
+ PebsEvent.pebs_num += 1
+ del tmp_buf
+
+#
+# Intel Nehalem and Westmere support PEBS plus Load Latency info which lie
+# in the four 64 bit words write after the PEBS data:
+# Status: records the IA32_PERF_GLOBAL_STATUS register value
+# DLA: Data Linear Address (EIP)
+# DSE: Data Source Encoding, where the latency happens, hit or miss
+# in L1/L2/L3 or IO operations
+# LAT: the actual latency in cycles
+#
+class PebsNHM(PebsEvent):
+ pebs_nhm_num = 0
+ def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS_LL):
+ tmp_buf=raw_buf[144:176]
+ status, dla, dse, lat = struct.unpack('QQQQ', tmp_buf)
+ self.status = status
+ self.dla = dla
+ self.dse = dse
+ self.lat = lat
+
+ PebsEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
+ PebsNHM.pebs_nhm_num += 1
+ del tmp_buf
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling
2012-08-08 9:57 [PATCH v5 0/5] perf script: Add general event support to event handler of python script Feng Tang
` (3 preceding siblings ...)
2012-08-08 9:57 ` [PATCH v5 4/5] perf script: Add a python library EventClass.py Feng Tang
@ 2012-08-08 9:57 ` Feng Tang
2012-08-09 1:30 ` Namhyung Kim
2012-08-21 15:36 ` [tip:perf/core] perf scripts python: Add event_analyzing_sample. py " tip-bot for Feng Tang
4 siblings, 2 replies; 19+ messages in thread
From: Feng Tang @ 2012-08-08 9:57 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel
Cc: Robert Richter, Andi Kleen, Stephane Eranian, Feng Tang
Currently only trace point events are supported in perf/python script,
the first 3 patches of this serie add the support for all types of
events. This script is just a simple sample to show how to gather the
basic information of the events and analyze them.
This script will create one object for each event sample and insert
them into a table in a database, then leverage the simple SQL commands
to sort/group them. User can modify or write their brand new functions
according to their specific requirment.
Here is the sample of how to use the script:
feng@feng-i7:/dev/shm$perf record -a tree
feng@feng-i7:/dev/shm$perf script -s process_event.py
---------------------------------
There is 100 records in gen_events table
Statistics about the general events grouped by thread/symbol/dso:
comm number histgram
==========================================
swapper 56 ######
tree 20 #####
perf 10 ####
sshd 8 ####
kworker/7:2 4 ###
ksoftirqd/7 1 #
plugin-containe 1 #
symbol number histgram
==========================================================
native_write_msr_safe 40 ######
__lock_acquire 8 ####
ftrace_graph_caller 4 ###
prepare_ftrace_return 4 ###
intel_idle 3 ##
native_sched_clock 3 ##
Unknown_symbol 2 ##
do_softirq 2 ##
lock_release 2 ##
lock_release_holdtime 2 ##
trace_graph_entry 2 ##
_IO_putc 1 #
__d_lookup_rcu 1 #
__do_fault 1 #
__schedule 1 #
_raw_spin_lock 1 #
delay_tsc 1 #
generic_exec_single 1 #
generic_fillattr 1 #
dso number histgram
==================================================================
[kernel.kallsyms] 95 #######
/lib/libc-2.12.1.so 5 ###
Signed-off-by: Feng Tang <feng.tang@intel.com>
---
.../perf/scripts/python/event_analyzing_sample.py | 193 ++++++++++++++++++++
1 files changed, 193 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/scripts/python/event_analyzing_sample.py
diff --git a/tools/perf/scripts/python/event_analyzing_sample.py b/tools/perf/scripts/python/event_analyzing_sample.py
new file mode 100644
index 0000000..46f05aa
--- /dev/null
+++ b/tools/perf/scripts/python/event_analyzing_sample.py
@@ -0,0 +1,193 @@
+# process_event.py: general event handler in python
+#
+# Current perf report is alreay very powerful with the anotation integrated,
+# and this script is not trying to be as powerful as perf report, but
+# providing end user/developer a flexible way to analyze the events other
+# than trace points.
+#
+# The 2 database related functions in this script just show how to gather
+# the basic information, and users can modify and write their own functions
+# according to their specific requirment.
+#
+# The first sample "show_general_events" just does a baisc grouping for all
+# generic events with the help of sqlite, and the 2nd one "show_pebs_ll" is
+# for a x86 HW PMU event: PEBS with load latency data.
+#
+
+import os
+import sys
+import math
+import struct
+import sqlite3
+
+sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+
+from perf_trace_context import *
+from EventClass import *
+
+#
+# If the perf.data has a big number of samples, then the insert operation
+# will be very time consuming (about 10+ minutes for 10000 samples) if the
+# .db database is on disk. Move the .db file to RAM based FS to speedup
+# the handling, which will cut the time down to several seconds.
+#
+con = sqlite3.connect("/dev/shm/perf.db")
+con.isolation_level = None
+
+def trace_begin():
+ print "In trace_begin:\n"
+
+ #
+ # Will create several tables at the start, pebs_ll is for PEBS data with
+ # load latency info, while gen_events is for general event.
+ #
+ con.execute("""
+ create table if not exists gen_events (
+ name text,
+ symbol text,
+ comm text,
+ dso text
+ );""")
+ con.execute("""
+ create table if not exists pebs_ll (
+ name text,
+ symbol text,
+ comm text,
+ dso text,
+ flags integer,
+ ip integer,
+ status integer,
+ dse integer,
+ dla integer,
+ lat integer
+ );""")
+
+#
+# Create and insert event object to a database so that user could
+# do more analysis with simple database commands.
+#
+def process_event(param_dict):
+ event_attr = param_dict["attr"]
+ sample = param_dict["sample"]
+ raw_buf = param_dict["raw_buf"]
+ comm = param_dict["comm"]
+ name = param_dict["ev_name"]
+
+ # Symbol and dso info are not always resolved
+ if (param_dict.has_key("dso")):
+ dso = param_dict["dso"]
+ else:
+ dso = "Unknown_dso"
+
+ if (param_dict.has_key("symbol")):
+ symbol = param_dict["symbol"]
+ else:
+ symbol = "Unknown_symbol"
+
+ # Creat the event object and insert it to the right table in database
+ event = create_event(name, comm, dso, symbol, raw_buf)
+ insert_db(event)
+
+def insert_db(event):
+ if event.ev_type == EVTYPE_GENERIC:
+ con.execute("insert into gen_events values(?, ?, ?, ?)",
+ (event.name, event.symbol, event.comm, event.dso))
+ elif event.ev_type == EVTYPE_PEBS_LL:
+ event.ip &= 0x7fffffffffffffff
+ event.dla &= 0x7fffffffffffffff
+ con.execute("insert into pebs_ll values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ (event.name, event.symbol, event.comm, event.dso, event.flags,
+ event.ip, event.status, event.dse, event.dla, event.lat))
+
+def trace_end():
+ print "In trace_end:\n"
+ # We show the basic info for the 2 type of event classes
+ show_general_events()
+ show_pebs_ll()
+ con.close()
+
+#
+# As the event number may be very big, so we can't use linear way
+# to show the histgram in real number, but use a log2 algorithm.
+#
+
+def num2sym(num):
+ # Each number will have at least one '#'
+ snum = '#' * (int)(math.log(num, 2) + 1)
+ return snum
+
+def show_general_events():
+
+ # Check the total record number in the table
+ count = con.execute("select count(*) from gen_events")
+ for t in count:
+ print "There is %d records in gen_events table" % t[0]
+ if t[0] == 0:
+ return
+
+ print "Statistics about the general events grouped by thread/symbol/dso: \n"
+
+ # Group by thread
+ commq = con.execute("select comm, count(comm) from gen_events group by comm order by -count(comm)")
+ print "\n%16s %8s %16s\n%s" % ("comm", "number", "histgram", "="*42)
+ for row in commq:
+ print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by symbol
+ print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histgram", "="*58)
+ symbolq = con.execute("select symbol, count(symbol) from gen_events group by symbol order by -count(symbol)")
+ for row in symbolq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by dso
+ print "\n%40s %8s %16s\n%s" % ("dso", "number", "histgram", "="*74)
+ dsoq = con.execute("select dso, count(dso) from gen_events group by dso order by -count(dso)")
+ for row in dsoq:
+ print "%40s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+#
+# This function just shows the basic info, and we could do more with the
+# data in the tables, like checking the function parameters when some
+# big latency events happen.
+#
+def show_pebs_ll():
+
+ count = con.execute("select count(*) from pebs_ll")
+ for t in count:
+ print "There is %d records in pebs_ll table" % t[0]
+ if t[0] == 0:
+ return
+
+ print "Statistics about the PEBS Load Latency events grouped by thread/symbol/dse/latency: \n"
+
+ # Group by thread
+ commq = con.execute("select comm, count(comm) from pebs_ll group by comm order by -count(comm)")
+ print "\n%16s %8s %16s\n%s" % ("comm", "number", "histgram", "="*42)
+ for row in commq:
+ print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by symbol
+ print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histgram", "="*58)
+ symbolq = con.execute("select symbol, count(symbol) from pebs_ll group by symbol order by -count(symbol)")
+ for row in symbolq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by dse
+ dseq = con.execute("select dse, count(dse) from pebs_ll group by dse order by -count(dse)")
+ print "\n%32s %8s %16s\n%s" % ("dse", "number", "histgram", "="*58)
+ for row in dseq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by latency
+ latq = con.execute("select lat, count(lat) from pebs_ll group by lat order by lat")
+ print "\n%32s %8s %16s\n%s" % ("latency", "number", "histgram", "="*58)
+ for row in latq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+def trace_unhandled(event_name, context, event_fields_dict):
+ print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
+
+def print_header(event_name, cpu, secs, nsecs, pid, comm):
+ print "%-20s %5u %05u.%09u %8u %-20s " % \
+ (event_name, cpu, secs, nsecs, pid, comm),
--
1.7.1
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling
2012-08-08 9:57 ` [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling Feng Tang
@ 2012-08-09 1:30 ` Namhyung Kim
2012-08-09 4:30 ` Feng Tang
2012-08-21 15:36 ` [tip:perf/core] perf scripts python: Add event_analyzing_sample. py " tip-bot for Feng Tang
1 sibling, 1 reply; 19+ messages in thread
From: Namhyung Kim @ 2012-08-09 1:30 UTC (permalink / raw)
To: Feng Tang
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
On Wed, 8 Aug 2012 17:57:55 +0800, Feng Tang wrote:
> Currently only trace point events are supported in perf/python script,
> the first 3 patches of this serie add the support for all types of
s/serie/series/
> events. This script is just a simple sample to show how to gather the
> basic information of the events and analyze them.
>
> This script will create one object for each event sample and insert
> them into a table in a database, then leverage the simple SQL commands
> to sort/group them. User can modify or write their brand new functions
> according to their specific requirment.
s/requirment/requirement/
>
> Here is the sample of how to use the script:
> feng@feng-i7:/dev/shm$perf record -a tree
> feng@feng-i7:/dev/shm$perf script -s process_event.py
s/process_event/event_analyzing_sample/
>
> ---------------------------------
> There is 100 records in gen_events table
> Statistics about the general events grouped by thread/symbol/dso:
>
> comm number histgram
> ==========================================
> swapper 56 ######
> tree 20 #####
> perf 10 ####
> sshd 8 ####
> kworker/7:2 4 ###
> ksoftirqd/7 1 #
> plugin-containe 1 #
>
> symbol number histgram
> ==========================================================
> native_write_msr_safe 40 ######
> __lock_acquire 8 ####
> ftrace_graph_caller 4 ###
> prepare_ftrace_return 4 ###
> intel_idle 3 ##
> native_sched_clock 3 ##
> Unknown_symbol 2 ##
> do_softirq 2 ##
> lock_release 2 ##
> lock_release_holdtime 2 ##
> trace_graph_entry 2 ##
> _IO_putc 1 #
> __d_lookup_rcu 1 #
> __do_fault 1 #
> __schedule 1 #
> _raw_spin_lock 1 #
> delay_tsc 1 #
> generic_exec_single 1 #
> generic_fillattr 1 #
>
> dso number histgram
> ==================================================================
> [kernel.kallsyms] 95 #######
> /lib/libc-2.12.1.so 5 ###
>
> Signed-off-by: Feng Tang <feng.tang@intel.com>
> ---
> .../perf/scripts/python/event_analyzing_sample.py | 193 ++++++++++++++++++++
> 1 files changed, 193 insertions(+), 0 deletions(-)
> create mode 100644 tools/perf/scripts/python/event_analyzing_sample.py
>
> diff --git a/tools/perf/scripts/python/event_analyzing_sample.py b/tools/perf/scripts/python/event_analyzing_sample.py
> new file mode 100644
> index 0000000..46f05aa
> --- /dev/null
> +++ b/tools/perf/scripts/python/event_analyzing_sample.py
> @@ -0,0 +1,193 @@
> +# process_event.py: general event handler in python
s/process_event/event_analyzing_sample/
> +#
> +# Current perf report is alreay very powerful with the anotation integrated,
s/alreay/already/ s/anotation/annotation/
> +# and this script is not trying to be as powerful as perf report, but
> +# providing end user/developer a flexible way to analyze the events other
> +# than trace points.
> +#
> +# The 2 database related functions in this script just show how to gather
> +# the basic information, and users can modify and write their own functions
> +# according to their specific requirment.
s/requirment/requirement/
> +#
> +# The first sample "show_general_events" just does a baisc grouping for all
s/sample/function/ s/baisc/basic/
> +# generic events with the help of sqlite, and the 2nd one "show_pebs_ll" is
> +# for a x86 HW PMU event: PEBS with load latency data.
> +#
> +
> +import os
> +import sys
> +import math
> +import struct
> +import sqlite3
> +
> +sys.path.append(os.environ['PERF_EXEC_PATH'] + \
> + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
> +
> +from perf_trace_context import *
> +from EventClass import *
> +
> +#
> +# If the perf.data has a big number of samples, then the insert operation
> +# will be very time consuming (about 10+ minutes for 10000 samples) if the
> +# .db database is on disk. Move the .db file to RAM based FS to speedup
> +# the handling, which will cut the time down to several seconds.
> +#
> +con = sqlite3.connect("/dev/shm/perf.db")
> +con.isolation_level = None
> +
> +def trace_begin():
> + print "In trace_begin:\n"
It seems it's not aligned with other statements, and even not needed at
all. Does it work?
> +
> + #
> + # Will create several tables at the start, pebs_ll is for PEBS data with
> + # load latency info, while gen_events is for general event.
> + #
> + con.execute("""
> + create table if not exists gen_events (
> + name text,
> + symbol text,
> + comm text,
> + dso text
> + );""")
> + con.execute("""
> + create table if not exists pebs_ll (
> + name text,
> + symbol text,
> + comm text,
> + dso text,
> + flags integer,
> + ip integer,
> + status integer,
> + dse integer,
> + dla integer,
> + lat integer
> + );""")
> +
> +#
> +# Create and insert event object to a database so that user could
> +# do more analysis with simple database commands.
> +#
> +def process_event(param_dict):
> + event_attr = param_dict["attr"]
> + sample = param_dict["sample"]
> + raw_buf = param_dict["raw_buf"]
> + comm = param_dict["comm"]
> + name = param_dict["ev_name"]
> +
> + # Symbol and dso info are not always resolved
> + if (param_dict.has_key("dso")):
> + dso = param_dict["dso"]
> + else:
> + dso = "Unknown_dso"
> +
> + if (param_dict.has_key("symbol")):
> + symbol = param_dict["symbol"]
> + else:
> + symbol = "Unknown_symbol"
> +
> + # Creat the event object and insert it to the right table in database
> + event = create_event(name, comm, dso, symbol, raw_buf)
> + insert_db(event)
> +
> +def insert_db(event):
> + if event.ev_type == EVTYPE_GENERIC:
> + con.execute("insert into gen_events values(?, ?, ?, ?)",
> + (event.name, event.symbol, event.comm, event.dso))
> + elif event.ev_type == EVTYPE_PEBS_LL:
> + event.ip &= 0x7fffffffffffffff
> + event.dla &= 0x7fffffffffffffff
> + con.execute("insert into pebs_ll values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
> + (event.name, event.symbol, event.comm, event.dso, event.flags,
> + event.ip, event.status, event.dse, event.dla, event.lat))
> +
> +def trace_end():
> + print "In trace_end:\n"
Ditto.
> + # We show the basic info for the 2 type of event classes
> + show_general_events()
> + show_pebs_ll()
> + con.close()
> +
> +#
> +# As the event number may be very big, so we can't use linear way
> +# to show the histgram in real number, but use a log2 algorithm.
> +#
> +
> +def num2sym(num):
> + # Each number will have at least one '#'
> + snum = '#' * (int)(math.log(num, 2) + 1)
> + return snum
> +
> +def show_general_events():
> +
> + # Check the total record number in the table
> + count = con.execute("select count(*) from gen_events")
> + for t in count:
> + print "There is %d records in gen_events table" % t[0]
> + if t[0] == 0:
> + return
> +
> + print "Statistics about the general events grouped by thread/symbol/dso: \n"
> +
> + # Group by thread
> + commq = con.execute("select comm, count(comm) from gen_events group by comm order by -count(comm)")
> + print "\n%16s %8s %16s\n%s" % ("comm", "number", "histgram", "="*42)
> + for row in commq:
> + print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
> +
> + # Group by symbol
> + print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histgram", "="*58)
> + symbolq = con.execute("select symbol, count(symbol) from gen_events group by symbol order by -count(symbol)")
> + for row in symbolq:
> + print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
> +
> + # Group by dso
> + print "\n%40s %8s %16s\n%s" % ("dso", "number", "histgram", "="*74)
> + dsoq = con.execute("select dso, count(dso) from gen_events group by dso order by -count(dso)")
> + for row in dsoq:
> + print "%40s %8d %s" % (row[0], row[1], num2sym(row[1]))
> +
> +#
> +# This function just shows the basic info, and we could do more with the
> +# data in the tables, like checking the function parameters when some
> +# big latency events happen.
> +#
> +def show_pebs_ll():
> +
> + count = con.execute("select count(*) from pebs_ll")
> + for t in count:
> + print "There is %d records in pebs_ll table" % t[0]
> + if t[0] == 0:
> + return
> +
> + print "Statistics about the PEBS Load Latency events grouped by thread/symbol/dse/latency: \n"
> +
> + # Group by thread
> + commq = con.execute("select comm, count(comm) from pebs_ll group by comm order by -count(comm)")
> + print "\n%16s %8s %16s\n%s" % ("comm", "number", "histgram", "="*42)
> + for row in commq:
> + print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
> +
> + # Group by symbol
> + print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histgram", "="*58)
> + symbolq = con.execute("select symbol, count(symbol) from pebs_ll group by symbol order by -count(symbol)")
> + for row in symbolq:
> + print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
> +
> + # Group by dse
> + dseq = con.execute("select dse, count(dse) from pebs_ll group by dse order by -count(dse)")
> + print "\n%32s %8s %16s\n%s" % ("dse", "number", "histgram", "="*58)
> + for row in dseq:
> + print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
> +
> + # Group by latency
> + latq = con.execute("select lat, count(lat) from pebs_ll group by lat order by lat")
> + print "\n%32s %8s %16s\n%s" % ("latency", "number", "histgram", "="*58)
> + for row in latq:
> + print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
> +
> +def trace_unhandled(event_name, context, event_fields_dict):
> + print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
> +
> +def print_header(event_name, cpu, secs, nsecs, pid, comm):
> + print "%-20s %5u %05u.%09u %8u %-20s " % \
> + (event_name, cpu, secs, nsecs, pid, comm),
It seems this function was not called anywhere.
Thanks,
Namhyung
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling
2012-08-09 1:30 ` Namhyung Kim
@ 2012-08-09 4:30 ` Feng Tang
2012-08-09 5:19 ` Namhyung Kim
0 siblings, 1 reply; 19+ messages in thread
From: Feng Tang @ 2012-08-09 4:30 UTC (permalink / raw)
To: Namhyung Kim
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
Hi Namhyung,
Many thanks for your valuable comments, I'll fold the fixes into an
incremental patch.
On Thu, 9 Aug 2012 10:30:34 +0900
Namhyung Kim <namhyung@kernel.org> wrote:
> On Wed, 8 Aug 2012 17:57:55 +0800, Feng Tang wrote:
> > Currently only trace point events are supported in perf/python script,
> > the first 3 patches of this serie add the support for all types of
>
> > +con = sqlite3.connect("/dev/shm/perf.db")
> > +con.isolation_level = None
> > +
> > +def trace_begin():
> > + print "In trace_begin:\n"
>
> It seems it's not aligned with other statements, and even not needed at
> all. Does it work?
trace_begin() is a must have for a python script, the <print "In trace_begin:\n">
is automatically generated from "perf script -g", I guess its intension is
to help developer debug their own patches. and same for the trace_end().
> > +def print_header(event_name, cpu, secs, nsecs, pid, comm):
> > + print "%-20s %5u %05u.%09u %8u %-20s " % \
> > + (event_name, cpu, secs, nsecs, pid, comm),
>
> It seems this function was not called anywhere.
It is auto-generated too, and you are right, it is not needed at all,
will remove it.
Thanks,
Feng
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling
2012-08-09 4:30 ` Feng Tang
@ 2012-08-09 5:19 ` Namhyung Kim
2012-08-09 5:28 ` Feng Tang
0 siblings, 1 reply; 19+ messages in thread
From: Namhyung Kim @ 2012-08-09 5:19 UTC (permalink / raw)
To: Feng Tang
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
Hi,
On Thu, 9 Aug 2012 12:30:07 +0800, Feng Tang wrote:
> Hi Namhyung,
>
> Many thanks for your valuable comments, I'll fold the fixes into an
> incremental patch.
>
> On Thu, 9 Aug 2012 10:30:34 +0900
> Namhyung Kim <namhyung@kernel.org> wrote:
>
>> On Wed, 8 Aug 2012 17:57:55 +0800, Feng Tang wrote:
>> > Currently only trace point events are supported in perf/python script,
>> > the first 3 patches of this serie add the support for all types of
>>
>
>> > +con = sqlite3.connect("/dev/shm/perf.db")
>> > +con.isolation_level = None
>> > +
>> > +def trace_begin():
>> > + print "In trace_begin:\n"
>>
>> It seems it's not aligned with other statements, and even not needed at
>> all. Does it work?
>
> trace_begin() is a must have for a python script, the <print "In trace_begin:\n">
> is automatically generated from "perf script -g", I guess its intension is
> to help developer debug their own patches. and same for the trace_end().
>
I meant the print statement not trace_begin function :)
Btw, by any chance do you plan to add support to callchains? I think
it's very nice to have.
Thanks,
Namhyung
>> > +def print_header(event_name, cpu, secs, nsecs, pid, comm):
>> > + print "%-20s %5u %05u.%09u %8u %-20s " % \
>> > + (event_name, cpu, secs, nsecs, pid, comm),
>>
>> It seems this function was not called anywhere.
>
> It is auto-generated too, and you are right, it is not needed at all,
> will remove it.
>
> Thanks,
> Feng
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling
2012-08-09 5:19 ` Namhyung Kim
@ 2012-08-09 5:28 ` Feng Tang
2012-08-09 5:46 ` Namhyung Kim
0 siblings, 1 reply; 19+ messages in thread
From: Feng Tang @ 2012-08-09 5:28 UTC (permalink / raw)
To: Namhyung Kim
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
On Thu, 9 Aug 2012 14:19:29 +0900
Namhyung Kim <namhyung@kernel.org> wrote:
> Hi,
>
> On Thu, 9 Aug 2012 12:30:07 +0800, Feng Tang wrote:
> > Hi Namhyung,
> >
> > Many thanks for your valuable comments, I'll fold the fixes into an
> > incremental patch.
> >
> > On Thu, 9 Aug 2012 10:30:34 +0900
> > Namhyung Kim <namhyung@kernel.org> wrote:
> >
> >> On Wed, 8 Aug 2012 17:57:55 +0800, Feng Tang wrote:
> >> > Currently only trace point events are supported in perf/python script,
> >> > the first 3 patches of this serie add the support for all types of
> >>
> >
> >> > +con = sqlite3.connect("/dev/shm/perf.db")
> >> > +con.isolation_level = None
> >> > +
> >> > +def trace_begin():
> >> > + print "In trace_begin:\n"
> >>
> >> It seems it's not aligned with other statements, and even not needed at
> >> all. Does it work?
> >
> > trace_begin() is a must have for a python script, the <print "In
> > trace_begin:\n"> is automatically generated from "perf script -g", I guess
> > its intension is to help developer debug their own patches. and same for
> > the trace_end().
> >
> I meant the print statement not trace_begin function :)
I see
>
> Btw, by any chance do you plan to add support to callchains? I think
> it's very nice to have.
No, it's not on the plan list :). My next plan is to integrate the perf
script to the perf report framework, so that users can directly call
perf script inside perf report browser like running the annotation.
Thanks,
Feng
>
> Thanks,
> Namhyung
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling
2012-08-09 5:28 ` Feng Tang
@ 2012-08-09 5:46 ` Namhyung Kim
0 siblings, 0 replies; 19+ messages in thread
From: Namhyung Kim @ 2012-08-09 5:46 UTC (permalink / raw)
To: Feng Tang
Cc: Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
Ingo Molnar, linux-kernel, Robert Richter, Andi Kleen,
Stephane Eranian
On Thu, 9 Aug 2012 13:28:43 +0800, Feng Tang wrote:
> On Thu, 9 Aug 2012 14:19:29 +0900
>> Btw, by any chance do you plan to add support to callchains? I think
>> it's very nice to have.
>
> No, it's not on the plan list :). My next plan is to integrate the perf
> script to the perf report framework, so that users can directly call
> perf script inside perf report browser like running the annotation.
>
Sounds cool!
Thanks,
Namhyung
^ permalink raw reply [flat|nested] 19+ messages in thread
* [tip:perf/core] perf scripts python: Add event_analyzing_sample. py as a sample for general event handling
2012-08-08 9:57 ` [PATCH v5 5/5] perf script: Add event_analyzing_sample.py as a sample for general event handling Feng Tang
2012-08-09 1:30 ` Namhyung Kim
@ 2012-08-21 15:36 ` tip-bot for Feng Tang
1 sibling, 0 replies; 19+ messages in thread
From: tip-bot for Feng Tang @ 2012-08-21 15:36 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, hpa, mingo, andi, peterz,
robert.richter, dsahern, tglx, feng.tang, mingo
Commit-ID: 0076d546b4f9b5c15121c6959d108a83fe43fa9a
Gitweb: http://git.kernel.org/tip/0076d546b4f9b5c15121c6959d108a83fe43fa9a
Author: Feng Tang <feng.tang@intel.com>
AuthorDate: Wed, 8 Aug 2012 17:57:55 +0800
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 8 Aug 2012 12:55:38 -0300
perf scripts python: Add event_analyzing_sample.py as a sample for general event handling
Currently only trace point events are supported in perf/python script,
the first 3 patches of this serie add the support for all types of
events. This script is just a simple sample to show how to gather the
basic information of the events and analyze them.
This script will create one object for each event sample and insert them
into a table in a database, then leverage the simple SQL commands to
sort/group them. User can modify or write their brand new functions
according to their specific requirment.
Here is the sample of how to use the script:
$ perf record -a tree
$ perf script -s process_event.py
There is 100 records in gen_events table
Statistics about the general events grouped by thread/symbol/dso:
comm number histgram
==========================================
swapper 56 ######
tree 20 #####
perf 10 ####
sshd 8 ####
kworker/7:2 4 ###
ksoftirqd/7 1 #
plugin-containe 1 #
symbol number histgram
==========================================================
native_write_msr_safe 40 ######
__lock_acquire 8 ####
ftrace_graph_caller 4 ###
prepare_ftrace_return 4 ###
intel_idle 3 ##
native_sched_clock 3 ##
Unknown_symbol 2 ##
do_softirq 2 ##
lock_release 2 ##
lock_release_holdtime 2 ##
trace_graph_entry 2 ##
_IO_putc 1 #
__d_lookup_rcu 1 #
__do_fault 1 #
__schedule 1 #
_raw_spin_lock 1 #
delay_tsc 1 #
generic_exec_single 1 #
generic_fillattr 1 #
dso number histgram
==================================================================
[kernel.kallsyms] 95 #######
/lib/libc-2.12.1.so 5 ###
Signed-off-by: Feng Tang <feng.tang@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1344419875-21665-6-git-send-email-feng.tang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
.../perf/scripts/python/event_analyzing_sample.py | 193 ++++++++++++++++++++
1 files changed, 193 insertions(+), 0 deletions(-)
diff --git a/tools/perf/scripts/python/event_analyzing_sample.py b/tools/perf/scripts/python/event_analyzing_sample.py
new file mode 100644
index 0000000..46f05aa
--- /dev/null
+++ b/tools/perf/scripts/python/event_analyzing_sample.py
@@ -0,0 +1,193 @@
+# process_event.py: general event handler in python
+#
+# Current perf report is alreay very powerful with the anotation integrated,
+# and this script is not trying to be as powerful as perf report, but
+# providing end user/developer a flexible way to analyze the events other
+# than trace points.
+#
+# The 2 database related functions in this script just show how to gather
+# the basic information, and users can modify and write their own functions
+# according to their specific requirment.
+#
+# The first sample "show_general_events" just does a baisc grouping for all
+# generic events with the help of sqlite, and the 2nd one "show_pebs_ll" is
+# for a x86 HW PMU event: PEBS with load latency data.
+#
+
+import os
+import sys
+import math
+import struct
+import sqlite3
+
+sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+
+from perf_trace_context import *
+from EventClass import *
+
+#
+# If the perf.data has a big number of samples, then the insert operation
+# will be very time consuming (about 10+ minutes for 10000 samples) if the
+# .db database is on disk. Move the .db file to RAM based FS to speedup
+# the handling, which will cut the time down to several seconds.
+#
+con = sqlite3.connect("/dev/shm/perf.db")
+con.isolation_level = None
+
+def trace_begin():
+ print "In trace_begin:\n"
+
+ #
+ # Will create several tables at the start, pebs_ll is for PEBS data with
+ # load latency info, while gen_events is for general event.
+ #
+ con.execute("""
+ create table if not exists gen_events (
+ name text,
+ symbol text,
+ comm text,
+ dso text
+ );""")
+ con.execute("""
+ create table if not exists pebs_ll (
+ name text,
+ symbol text,
+ comm text,
+ dso text,
+ flags integer,
+ ip integer,
+ status integer,
+ dse integer,
+ dla integer,
+ lat integer
+ );""")
+
+#
+# Create and insert event object to a database so that user could
+# do more analysis with simple database commands.
+#
+def process_event(param_dict):
+ event_attr = param_dict["attr"]
+ sample = param_dict["sample"]
+ raw_buf = param_dict["raw_buf"]
+ comm = param_dict["comm"]
+ name = param_dict["ev_name"]
+
+ # Symbol and dso info are not always resolved
+ if (param_dict.has_key("dso")):
+ dso = param_dict["dso"]
+ else:
+ dso = "Unknown_dso"
+
+ if (param_dict.has_key("symbol")):
+ symbol = param_dict["symbol"]
+ else:
+ symbol = "Unknown_symbol"
+
+ # Creat the event object and insert it to the right table in database
+ event = create_event(name, comm, dso, symbol, raw_buf)
+ insert_db(event)
+
+def insert_db(event):
+ if event.ev_type == EVTYPE_GENERIC:
+ con.execute("insert into gen_events values(?, ?, ?, ?)",
+ (event.name, event.symbol, event.comm, event.dso))
+ elif event.ev_type == EVTYPE_PEBS_LL:
+ event.ip &= 0x7fffffffffffffff
+ event.dla &= 0x7fffffffffffffff
+ con.execute("insert into pebs_ll values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ (event.name, event.symbol, event.comm, event.dso, event.flags,
+ event.ip, event.status, event.dse, event.dla, event.lat))
+
+def trace_end():
+ print "In trace_end:\n"
+ # We show the basic info for the 2 type of event classes
+ show_general_events()
+ show_pebs_ll()
+ con.close()
+
+#
+# As the event number may be very big, so we can't use linear way
+# to show the histgram in real number, but use a log2 algorithm.
+#
+
+def num2sym(num):
+ # Each number will have at least one '#'
+ snum = '#' * (int)(math.log(num, 2) + 1)
+ return snum
+
+def show_general_events():
+
+ # Check the total record number in the table
+ count = con.execute("select count(*) from gen_events")
+ for t in count:
+ print "There is %d records in gen_events table" % t[0]
+ if t[0] == 0:
+ return
+
+ print "Statistics about the general events grouped by thread/symbol/dso: \n"
+
+ # Group by thread
+ commq = con.execute("select comm, count(comm) from gen_events group by comm order by -count(comm)")
+ print "\n%16s %8s %16s\n%s" % ("comm", "number", "histgram", "="*42)
+ for row in commq:
+ print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by symbol
+ print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histgram", "="*58)
+ symbolq = con.execute("select symbol, count(symbol) from gen_events group by symbol order by -count(symbol)")
+ for row in symbolq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by dso
+ print "\n%40s %8s %16s\n%s" % ("dso", "number", "histgram", "="*74)
+ dsoq = con.execute("select dso, count(dso) from gen_events group by dso order by -count(dso)")
+ for row in dsoq:
+ print "%40s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+#
+# This function just shows the basic info, and we could do more with the
+# data in the tables, like checking the function parameters when some
+# big latency events happen.
+#
+def show_pebs_ll():
+
+ count = con.execute("select count(*) from pebs_ll")
+ for t in count:
+ print "There is %d records in pebs_ll table" % t[0]
+ if t[0] == 0:
+ return
+
+ print "Statistics about the PEBS Load Latency events grouped by thread/symbol/dse/latency: \n"
+
+ # Group by thread
+ commq = con.execute("select comm, count(comm) from pebs_ll group by comm order by -count(comm)")
+ print "\n%16s %8s %16s\n%s" % ("comm", "number", "histgram", "="*42)
+ for row in commq:
+ print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by symbol
+ print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histgram", "="*58)
+ symbolq = con.execute("select symbol, count(symbol) from pebs_ll group by symbol order by -count(symbol)")
+ for row in symbolq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by dse
+ dseq = con.execute("select dse, count(dse) from pebs_ll group by dse order by -count(dse)")
+ print "\n%32s %8s %16s\n%s" % ("dse", "number", "histgram", "="*58)
+ for row in dseq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ # Group by latency
+ latq = con.execute("select lat, count(lat) from pebs_ll group by lat order by lat")
+ print "\n%32s %8s %16s\n%s" % ("latency", "number", "histgram", "="*58)
+ for row in latq:
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+def trace_unhandled(event_name, context, event_fields_dict):
+ print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
+
+def print_header(event_name, cpu, secs, nsecs, pid, comm):
+ print "%-20s %5u %05u.%09u %8u %-20s " % \
+ (event_name, cpu, secs, nsecs, pid, comm),
^ permalink raw reply related [flat|nested] 19+ messages in thread