From 739621f65702d532527aec124b0818d3a1521b5e Mon Sep 17 00:00:00 2001 From: Gautam Menghani Date: Mon, 19 May 2025 12:51:42 -0700 Subject: [PATCH] perf python: Add evsel read method Add the evsel read method to enable python to read counter data for the given evsel. Signed-off-by: Gautam Menghani Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Howard Chu Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/linux-perf-users/20250512055748.479786-1-gautam@linux.ibm.com/ Link: https://lore.kernel.org/r/20250519195148.1708988-6-irogers@google.com [ make the API take a CPU and thread then compute from these the appropriate indices. ] Signed-off-by: Ian Rogers Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/python.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 21e2da1ec0c6..3155efb0ed43 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -888,6 +888,37 @@ static PyObject *pyrf_evsel__threads(struct pyrf_evsel *pevsel) return (PyObject *)pthread_map; } +static PyObject *pyrf_evsel__read(struct pyrf_evsel *pevsel, + PyObject *args, PyObject *kwargs) +{ + struct evsel *evsel = &pevsel->evsel; + int cpu = 0, cpu_idx, thread = 0, thread_idx; + struct perf_counts_values counts; + struct pyrf_counts_values *count_values = PyObject_New(struct pyrf_counts_values, + &pyrf_counts_values__type); + + if (!count_values) + return NULL; + + if (!PyArg_ParseTuple(args, "ii", &cpu, &thread)) + return NULL; + + cpu_idx = perf_cpu_map__idx(evsel->core.cpus, (struct perf_cpu){.cpu = cpu}); + if (cpu_idx < 0) { + PyErr_Format(PyExc_TypeError, "CPU %d is not part of evsel's CPUs", cpu); + return NULL; + } + thread_idx = perf_thread_map__idx(evsel->core.threads, thread); + if (cpu_idx < 0) { + PyErr_Format(PyExc_TypeError, "Thread %d is not part of evsel's threads", + thread); + return NULL; + } + perf_evsel__read(&(evsel->core), cpu_idx, thread_idx, &counts); + count_values->values = counts; + return (PyObject *)count_values; +} + static PyObject *pyrf_evsel__str(PyObject *self) { struct pyrf_evsel *pevsel = (void *)self; @@ -918,6 +949,12 @@ static PyMethodDef pyrf_evsel__methods[] = { .ml_flags = METH_NOARGS, .ml_doc = PyDoc_STR("threads the event is to be used with.") }, + { + .ml_name = "read", + .ml_meth = (PyCFunction)pyrf_evsel__read, + .ml_flags = METH_VARARGS | METH_KEYWORDS, + .ml_doc = PyDoc_STR("read counters") + }, { .ml_name = NULL, } }; -- 2.25.1