Skip to content

Commit 9cd2640

Browse files
captain5050gregkh
authored andcommitted
perf python: Add parse_events function
[ Upstream commit f081def ] Add basic parse_events function that takes a string and returns an evlist. As the python evlist is embedded in a pyrf_evlist, and the evsels are embedded in pyrf_evsels, copy the parsed data into those structs and update evsel__clone to enable this. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Cc: Colin Ian King <colin.i.king@gmail.com> Cc: Dapeng Mi <dapeng1.mi@linux.intel.com> Cc: Howard Chu <howardchu95@gmail.com> Cc: Ilya Leoshkevich <iii@linux.ibm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Veronika Molnarova <vmolnaro@redhat.com> Cc: Weilin Wang <weilin.wang@intel.com> Link: https://lore.kernel.org/r/20241119011644.971342-20-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Stable-dep-of: c9ef786 ("perf cgroup: Update metric leader in evlist__expand_cgroup") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 7cfcd01 commit 9cd2640

4 files changed

Lines changed: 75 additions & 9 deletions

File tree

tools/perf/util/cgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str,
473473

474474
leader = NULL;
475475
evlist__for_each_entry(orig_list, pos) {
476-
evsel = evsel__clone(pos);
476+
evsel = evsel__clone(/*dest=*/NULL, pos);
477477
if (evsel == NULL)
478478
goto out_err;
479479

tools/perf/util/evsel.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ static int evsel__copy_config_terms(struct evsel *dst, struct evsel *src)
332332
* The assumption is that @orig is not configured nor opened yet.
333333
* So we only care about the attributes that can be set while it's parsed.
334334
*/
335-
struct evsel *evsel__clone(struct evsel *orig)
335+
struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig)
336336
{
337337
struct evsel *evsel;
338338

@@ -345,7 +345,11 @@ struct evsel *evsel__clone(struct evsel *orig)
345345
if (orig->bpf_obj)
346346
return NULL;
347347

348-
evsel = evsel__new(&orig->core.attr);
348+
if (dest)
349+
evsel = dest;
350+
else
351+
evsel = evsel__new(&orig->core.attr);
352+
349353
if (evsel == NULL)
350354
return NULL;
351355

@@ -395,11 +399,12 @@ struct evsel *evsel__clone(struct evsel *orig)
395399
evsel->core.leader = orig->core.leader;
396400

397401
evsel->max_events = orig->max_events;
398-
free((char *)evsel->unit);
399-
evsel->unit = strdup(orig->unit);
400-
if (evsel->unit == NULL)
401-
goto out_err;
402-
402+
zfree(&evsel->unit);
403+
if (orig->unit) {
404+
evsel->unit = strdup(orig->unit);
405+
if (evsel->unit == NULL)
406+
goto out_err;
407+
}
403408
evsel->scale = orig->scale;
404409
evsel->snapshot = orig->snapshot;
405410
evsel->per_pkg = orig->per_pkg;

tools/perf/util/evsel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static inline struct evsel *evsel__new(struct perf_event_attr *attr)
241241
return evsel__new_idx(attr, 0);
242242
}
243243

244-
struct evsel *evsel__clone(struct evsel *orig);
244+
struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig);
245245

246246
int copy_config_terms(struct list_head *dst, struct list_head *src);
247247
void free_config_terms(struct list_head *config_terms);

tools/perf/util/python.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "evsel.h"
1414
#include "event.h"
1515
#include "print_binary.h"
16+
#include "strbuf.h"
1617
#include "thread_map.h"
1718
#include "trace-event.h"
1819
#include "mmap.h"
@@ -1247,13 +1248,73 @@ static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
12471248
#endif // HAVE_LIBTRACEEVENT
12481249
}
12491250

1251+
static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel)
1252+
{
1253+
struct pyrf_evsel *pevsel = PyObject_New(struct pyrf_evsel, &pyrf_evsel__type);
1254+
1255+
if (!pevsel)
1256+
return NULL;
1257+
1258+
memset(&pevsel->evsel, 0, sizeof(pevsel->evsel));
1259+
evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx);
1260+
1261+
evsel__clone(&pevsel->evsel, evsel);
1262+
return (PyObject *)pevsel;
1263+
}
1264+
1265+
static PyObject *pyrf_evlist__from_evlist(struct evlist *evlist)
1266+
{
1267+
struct pyrf_evlist *pevlist = PyObject_New(struct pyrf_evlist, &pyrf_evlist__type);
1268+
struct evsel *pos;
1269+
1270+
if (!pevlist)
1271+
return NULL;
1272+
1273+
memset(&pevlist->evlist, 0, sizeof(pevlist->evlist));
1274+
evlist__init(&pevlist->evlist, evlist->core.all_cpus, evlist->core.threads);
1275+
evlist__for_each_entry(evlist, pos) {
1276+
struct pyrf_evsel *pevsel = (void *)pyrf_evsel__from_evsel(pos);
1277+
1278+
evlist__add(&pevlist->evlist, &pevsel->evsel);
1279+
}
1280+
return (PyObject *)pevlist;
1281+
}
1282+
1283+
static PyObject *pyrf__parse_events(PyObject *self, PyObject *args)
1284+
{
1285+
const char *input;
1286+
struct evlist evlist = {};
1287+
struct parse_events_error err;
1288+
PyObject *result;
1289+
1290+
if (!PyArg_ParseTuple(args, "s", &input))
1291+
return NULL;
1292+
1293+
parse_events_error__init(&err);
1294+
evlist__init(&evlist, NULL, NULL);
1295+
if (parse_events(&evlist, input, &err)) {
1296+
parse_events_error__print(&err, input);
1297+
PyErr_SetFromErrno(PyExc_OSError);
1298+
return NULL;
1299+
}
1300+
result = pyrf_evlist__from_evlist(&evlist);
1301+
evlist__exit(&evlist);
1302+
return result;
1303+
}
1304+
12501305
static PyMethodDef perf__methods[] = {
12511306
{
12521307
.ml_name = "tracepoint",
12531308
.ml_meth = (PyCFunction) pyrf__tracepoint,
12541309
.ml_flags = METH_VARARGS | METH_KEYWORDS,
12551310
.ml_doc = PyDoc_STR("Get tracepoint config.")
12561311
},
1312+
{
1313+
.ml_name = "parse_events",
1314+
.ml_meth = (PyCFunction) pyrf__parse_events,
1315+
.ml_flags = METH_VARARGS,
1316+
.ml_doc = PyDoc_STR("Parse a string of events and return an evlist.")
1317+
},
12571318
{ .ml_name = NULL, }
12581319
};
12591320

0 commit comments

Comments
 (0)