From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752704AbcGMH2O (ORCPT ); Wed, 13 Jul 2016 03:28:14 -0400 Received: from terminus.zytor.com ([198.137.202.10]:42336 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752441AbcGMH2M (ORCPT ); Wed, 13 Jul 2016 03:28:12 -0400 Date: Wed, 13 Jul 2016 00:27:58 -0700 From: tip-bot for Jiri Olsa Message-ID: Cc: acme@redhat.com, tglx@linutronix.de, mingo@kernel.org, a.p.zijlstra@chello.nl, namhyung@kernel.org, jiri@mellanox.com, dsahern@gmail.com, jolsa@kernel.org, hpa@zytor.com, linux-kernel@vger.kernel.org Reply-To: hpa@zytor.com, linux-kernel@vger.kernel.org, jiri@mellanox.com, dsahern@gmail.com, jolsa@kernel.org, mingo@kernel.org, a.p.zijlstra@chello.nl, namhyung@kernel.org, acme@redhat.com, tglx@linutronix.de In-Reply-To: <1468148882-10362-9-git-send-email-jolsa@kernel.org> References: <1468148882-10362-9-git-send-email-jolsa@kernel.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] perf python: Add support to resolve tracepoint fields Git-Commit-ID: bae57e3825a3dded15f61cd20c6757d60ad6c712 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: bae57e3825a3dded15f61cd20c6757d60ad6c712 Gitweb: http://git.kernel.org/tip/bae57e3825a3dded15f61cd20c6757d60ad6c712 Author: Jiri Olsa AuthorDate: Sun, 10 Jul 2016 13:08:00 +0200 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 12 Jul 2016 16:19:16 -0300 perf python: Add support to resolve tracepoint fields Adding tp_getattro callback for sample event. It resolves tracepoint fields in runtime. It's now possible to access tracepoint fields in normal fashion like hardcoded ones (see the example in the next patch). Reported-and-Tested-by: Jiri Pirko Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1468148882-10362-9-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/python.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index dc7adaa..d32f970 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -290,6 +290,97 @@ static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) return ret; } +static bool is_tracepoint(struct pyrf_event *pevent) +{ + return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT; +} + +static int is_printable_array(char *p, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) { + if (!isprint(p[i]) && !isspace(p[i])) + return 0; + } + + return 1; +} + +static PyObject* +tracepoint_field(struct pyrf_event *pe, struct format_field *field) +{ + struct pevent *pevent = field->event->pevent; + void *data = pe->sample.raw_data; + PyObject *ret = NULL; + unsigned long long val; + unsigned int offset, len; + + if (field->flags & FIELD_IS_ARRAY) { + offset = field->offset; + len = field->size; + if (field->flags & FIELD_IS_DYNAMIC) { + val = pevent_read_number(pevent, data + offset, len); + offset = val; + len = offset >> 16; + offset &= 0xffff; + } + if (field->flags & FIELD_IS_STRING && + is_printable_array(data + offset, len)) { + ret = PyString_FromString((char *)data + offset); + } else { + ret = PyByteArray_FromStringAndSize((const char *) data + offset, len); + field->flags &= ~FIELD_IS_STRING; + } + } else { + val = pevent_read_number(pevent, data + field->offset, + field->size); + if (field->flags & FIELD_IS_POINTER) + ret = PyLong_FromUnsignedLong((unsigned long) val); + else if (field->flags & FIELD_IS_SIGNED) + ret = PyLong_FromLong((long) val); + else + ret = PyLong_FromUnsignedLong((unsigned long) val); + } + + return ret; +} + +static PyObject* +get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) +{ + const char *str = PyString_AsString(PyObject_Str(attr_name)); + struct perf_evsel *evsel = pevent->evsel; + struct format_field *field; + + if (!evsel->tp_format) { + struct event_format *tp_format; + + tp_format = trace_event__tp_format_id(evsel->attr.config); + if (!tp_format) + return NULL; + + evsel->tp_format = tp_format; + } + + field = pevent_find_any_field(evsel->tp_format, str); + if (!field) + return NULL; + + return tracepoint_field(pevent, field); +} + +static PyObject* +pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) +{ + PyObject *obj = NULL; + + if (is_tracepoint(pevent)) + obj = get_tracepoint_field(pevent, attr_name); + + return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name); +} + static PyTypeObject pyrf_sample_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.sample_event", @@ -298,6 +389,7 @@ static PyTypeObject pyrf_sample_event__type = { .tp_doc = pyrf_sample_event__doc, .tp_members = pyrf_sample_event__members, .tp_repr = (reprfunc)pyrf_sample_event__repr, + .tp_getattro = (getattrofunc) pyrf_sample_event__getattro, }; static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");