Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1694015 > unrolled thread

[PATCH v2 0/5] perf script python: Provide sample dict to all handlers

Started byArun Kalyanasundaram <arunkaly@google.com>
First post2017-07-22 00:10 +0200
Last post2017-07-24 15:30 +0200
Articles 4 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/5] perf script python: Provide sample dict to all handlers Arun Kalyanasundaram <arunkaly@google.com> - 2017-07-22 00:10 +0200
    [PATCH v2 1/5] perf script python: Allocate memory only if handler exists Arun Kalyanasundaram <arunkaly@google.com> - 2017-07-22 00:10 +0200
      [tip:perf/core] perf script python: Allocate memory only if handler  exists tip-bot for Arun Kalyanasundaram <tipbot@zytor.com> - 2017-07-26 19:30 +0200
    Re: [PATCH v2 0/5] perf script python: Provide sample dict to all  handlers Jiri Olsa <jolsa@redhat.com> - 2017-07-24 15:30 +0200

#1694015 — [PATCH v2 0/5] perf script python: Provide sample dict to all handlers

FromArun Kalyanasundaram <arunkaly@google.com>
Date2017-07-22 00:10 +0200
Subject[PATCH v2 0/5] perf script python: Provide sample dict to all handlers
Message-ID<u5Ohr-20O-3@gated-at.bofh.it>
v2: - Add sample_read struct to the dict (in 3/5).
    - Increase reference count of callchain in process tracepoint to
      avoid unnecessary garbage collection (in 4/5).

The process_event python hook receives a dict with most perf_sample entries.

Other handlers (e.g. trace_unhandled, python_process_tracepoint) predate the introduction of this dict and do not receive it. This patch series adds the dict to all handlers, aiming to unify the information passed to them.

This change adds an additional argument to the affected handlers. To keep backwards compatibility (and avoid unnecessary work), do not pass the aforementioned dict if the number of arguments signals that handler version predates this change.

In addition, provide time_enabled, time_running and counter value in the perf_sample dict.

Initial Discussion: https://lkml.org/lkml/2017/7/1/108

Arun Kalyanasundaram (5):
  perf script python: Allocate memory only if handler exists
  perf script python: Refactor creation of perf sample dict
  perf script python: Add sample_read to dict
  perf script python: Add perf_sample dict to tracepoint handlers
  perf script python: Generate hooks with additional argument

 .../util/scripting-engines/trace-event-python.c    | 246 +++++++++++++++------
 1 file changed, 184 insertions(+), 62 deletions(-)

-- 
2.14.0.rc0.284.gd933b75aa4-goog

[toc] | [next] | [standalone]


#1694016 — [PATCH v2 1/5] perf script python: Allocate memory only if handler exists

FromArun Kalyanasundaram <arunkaly@google.com>
Date2017-07-22 00:10 +0200
Subject[PATCH v2 1/5] perf script python: Allocate memory only if handler exists
Message-ID<u5Ohs-20O-39@gated-at.bofh.it>
In reply to#1694015
Avoid allocating memory if hook handler is not available. This saves
unused memory allocation and simplifies error path.

Let handler in python_process_tracepoint point to either tracepoint
specific or trace_unhandled hook. Use dict to check if handler points to
trace_unhandled.

Remove the exit label in python_process_general_event and return when no
handler is available.

Signed-off-by: Arun Kalyanasundaram <arunkaly@google.com>
---
 .../util/scripting-engines/trace-event-python.c    | 38 +++++++++++++---------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 57b7a00e6f16..8a8f4829d3e2 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -407,10 +407,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
 	void *data = sample->raw_data;
 	unsigned long long nsecs = sample->time;
 	const char *comm = thread__comm_str(al->thread);
-
-	t = PyTuple_New(MAX_FIELDS);
-	if (!t)
-		Py_FatalError("couldn't create Python tuple");
+	const char *default_handler_name = "trace_unhandled";
 
 	if (!event) {
 		snprintf(handler_name, sizeof(handler_name),
@@ -427,10 +424,19 @@ static void python_process_tracepoint(struct perf_sample *sample,
 
 	handler = get_handler(handler_name);
 	if (!handler) {
+		handler = get_handler(default_handler_name);
+		if (!handler)
+			return;
 		dict = PyDict_New();
 		if (!dict)
 			Py_FatalError("couldn't create Python dict");
 	}
+
+	t = PyTuple_New(MAX_FIELDS);
+	if (!t)
+		Py_FatalError("couldn't create Python tuple");
+
+
 	s = nsecs / NSEC_PER_SEC;
 	ns = nsecs - s * NSEC_PER_SEC;
 
@@ -445,7 +451,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
 	/* ip unwinding */
 	callchain = python_process_callchain(sample, evsel, al);
 
-	if (handler) {
+	if (!dict) {
 		PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
 		PyTuple_SetItem(t, n++, PyInt_FromLong(s));
 		PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
@@ -484,23 +490,23 @@ static void python_process_tracepoint(struct perf_sample *sample,
 		} else { /* FIELD_IS_NUMERIC */
 			obj = get_field_numeric_entry(event, field, data);
 		}
-		if (handler)
+		if (!dict)
 			PyTuple_SetItem(t, n++, obj);
 		else
 			pydict_set_item_string_decref(dict, field->name, obj);
 
 	}
 
-	if (!handler)
+	if (dict)
 		PyTuple_SetItem(t, n++, dict);
 
 	if (_PyTuple_Resize(&t, n) == -1)
 		Py_FatalError("error resizing Python tuple");
 
-	if (handler) {
+	if (!dict) {
 		call_object(handler, t, handler_name);
 	} else {
-		try_call_object("trace_unhandled", t);
+		call_object(handler, t, default_handler_name);
 		Py_DECREF(dict);
 	}
 
@@ -799,6 +805,12 @@ static void python_process_general_event(struct perf_sample *sample,
 	static char handler_name[64];
 	unsigned n = 0;
 
+	snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
+
+	handler = get_handler(handler_name);
+	if (!handler)
+		return;
+
 	/*
 	 * Use the MAX_FIELDS to make the function expandable, though
 	 * currently there is only one item for the tuple.
@@ -815,12 +827,6 @@ static void python_process_general_event(struct perf_sample *sample,
 	if (!dict_sample)
 		Py_FatalError("couldn't create Python dictionary");
 
-	snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
-
-	handler = get_handler(handler_name);
-	if (!handler)
-		goto exit;
-
 	pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
 	pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
 			(const char *)&evsel->attr, sizeof(evsel->attr)));
@@ -861,7 +867,7 @@ static void python_process_general_event(struct perf_sample *sample,
 		Py_FatalError("error resizing Python tuple");
 
 	call_object(handler, t, handler_name);
-exit:
+
 	Py_DECREF(dict);
 	Py_DECREF(t);
 }
-- 
2.14.0.rc0.284.gd933b75aa4-goog

[toc] | [prev] | [next] | [standalone]


#1697429 — [tip:perf/core] perf script python: Allocate memory only if handler exists

Fromtip-bot for Arun Kalyanasundaram <tipbot@zytor.com>
Date2017-07-26 19:30 +0200
Subject[tip:perf/core] perf script python: Allocate memory only if handler exists
Message-ID<u7yig-3eE-51@gated-at.bofh.it>
In reply to#1694016
Commit-ID:  e9f9a9ca8588e58dc0800b44adc41d32f6fc813a
Gitweb:     http://git.kernel.org/tip/e9f9a9ca8588e58dc0800b44adc41d32f6fc813a
Author:     Arun Kalyanasundaram <arunkaly@google.com>
AuthorDate: Fri, 21 Jul 2017 15:04:18 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 25 Jul 2017 22:43:18 -0300

perf script python: Allocate memory only if handler exists

Avoid allocating memory if hook handler is not available. This saves
unused memory allocation and simplifies error path.

Let handler in python_process_tracepoint point to either tracepoint
specific or trace_unhandled hook. Use dict to check if handler points to
trace_unhandled.

Remove the exit label in python_process_general_event and return when no
handler is available.

Signed-off-by: Arun Kalyanasundaram <arunkaly@google.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Carrillo-Cisneros <davidcc@google.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Seongjae Park <sj38.park@gmail.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/20170721220422.63962-2-arunkaly@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 .../util/scripting-engines/trace-event-python.c    | 38 +++++++++++++---------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 57b7a00..8a8f482 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -407,10 +407,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
 	void *data = sample->raw_data;
 	unsigned long long nsecs = sample->time;
 	const char *comm = thread__comm_str(al->thread);
-
-	t = PyTuple_New(MAX_FIELDS);
-	if (!t)
-		Py_FatalError("couldn't create Python tuple");
+	const char *default_handler_name = "trace_unhandled";
 
 	if (!event) {
 		snprintf(handler_name, sizeof(handler_name),
@@ -427,10 +424,19 @@ static void python_process_tracepoint(struct perf_sample *sample,
 
 	handler = get_handler(handler_name);
 	if (!handler) {
+		handler = get_handler(default_handler_name);
+		if (!handler)
+			return;
 		dict = PyDict_New();
 		if (!dict)
 			Py_FatalError("couldn't create Python dict");
 	}
+
+	t = PyTuple_New(MAX_FIELDS);
+	if (!t)
+		Py_FatalError("couldn't create Python tuple");
+
+
 	s = nsecs / NSEC_PER_SEC;
 	ns = nsecs - s * NSEC_PER_SEC;
 
@@ -445,7 +451,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
 	/* ip unwinding */
 	callchain = python_process_callchain(sample, evsel, al);
 
-	if (handler) {
+	if (!dict) {
 		PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
 		PyTuple_SetItem(t, n++, PyInt_FromLong(s));
 		PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
@@ -484,23 +490,23 @@ static void python_process_tracepoint(struct perf_sample *sample,
 		} else { /* FIELD_IS_NUMERIC */
 			obj = get_field_numeric_entry(event, field, data);
 		}
-		if (handler)
+		if (!dict)
 			PyTuple_SetItem(t, n++, obj);
 		else
 			pydict_set_item_string_decref(dict, field->name, obj);
 
 	}
 
-	if (!handler)
+	if (dict)
 		PyTuple_SetItem(t, n++, dict);
 
 	if (_PyTuple_Resize(&t, n) == -1)
 		Py_FatalError("error resizing Python tuple");
 
-	if (handler) {
+	if (!dict) {
 		call_object(handler, t, handler_name);
 	} else {
-		try_call_object("trace_unhandled", t);
+		call_object(handler, t, default_handler_name);
 		Py_DECREF(dict);
 	}
 
@@ -799,6 +805,12 @@ static void python_process_general_event(struct perf_sample *sample,
 	static char handler_name[64];
 	unsigned n = 0;
 
+	snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
+
+	handler = get_handler(handler_name);
+	if (!handler)
+		return;
+
 	/*
 	 * Use the MAX_FIELDS to make the function expandable, though
 	 * currently there is only one item for the tuple.
@@ -815,12 +827,6 @@ static void python_process_general_event(struct perf_sample *sample,
 	if (!dict_sample)
 		Py_FatalError("couldn't create Python dictionary");
 
-	snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
-
-	handler = get_handler(handler_name);
-	if (!handler)
-		goto exit;
-
 	pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
 	pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
 			(const char *)&evsel->attr, sizeof(evsel->attr)));
@@ -861,7 +867,7 @@ static void python_process_general_event(struct perf_sample *sample,
 		Py_FatalError("error resizing Python tuple");
 
 	call_object(handler, t, handler_name);
-exit:
+
 	Py_DECREF(dict);
 	Py_DECREF(t);
 }

[toc] | [prev] | [next] | [standalone]


#1694709 — Re: [PATCH v2 0/5] perf script python: Provide sample dict to all handlers

FromJiri Olsa <jolsa@redhat.com>
Date2017-07-24 15:30 +0200
SubjectRe: [PATCH v2 0/5] perf script python: Provide sample dict to all handlers
Message-ID<u6LAS-5qf-21@gated-at.bofh.it>
In reply to#1694015
On Fri, Jul 21, 2017 at 03:04:17PM -0700, Arun Kalyanasundaram wrote:
> v2: - Add sample_read struct to the dict (in 3/5).
>     - Increase reference count of callchain in process tracepoint to
>       avoid unnecessary garbage collection (in 4/5).
> 
> The process_event python hook receives a dict with most perf_sample entries.
> 
> Other handlers (e.g. trace_unhandled, python_process_tracepoint) predate the introduction of this dict and do not receive it. This patch series adds the dict to all handlers, aiming to unify the information passed to them.
> 
> This change adds an additional argument to the affected handlers. To keep backwards compatibility (and avoid unnecessary work), do not pass the aforementioned dict if the number of arguments signals that handler version predates this change.
> 
> In addition, provide time_enabled, time_running and counter value in the perf_sample dict.
> 
> Initial Discussion: https://lkml.org/lkml/2017/7/1/108
> 
> Arun Kalyanasundaram (5):
>   perf script python: Allocate memory only if handler exists
>   perf script python: Refactor creation of perf sample dict
>   perf script python: Add sample_read to dict
>   perf script python: Add perf_sample dict to tracepoint handlers
>   perf script python: Generate hooks with additional argument
> 

looks good,

Acked-by: Jiri Olsa <jolsa@kernel.org>

thanks,
jirka

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web