Commit b214ba8c authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Copy metric events properly when expand cgroups



The metricgroup__copy_metric_events() is to handle metrics events when
expanding event for cgroups.  As the metric events keep pointers to
evsel, it should be refreshed when events are cloned during the
operation.

The perf_stat__collect_metric_expr() is also called in case an event has
a metric directly.

During the copy, it references evsel by index as the evlist now has
cloned evsels for the given cgroup.

Also kernel test robot found an issue in the python module import so add
empty implementations of those two functions to fix it.

Reported-by: default avatarkernel test robot <rong.a.chen@intel.com>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Acked-by: default avatarJiri Olsa <jolsa@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20200924124455.336326-4-namhyung@kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d1c5a0e8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2234,7 +2234,8 @@ int cmd_stat(int argc, const char **argv)
			goto out;
		}

		if (evlist__expand_cgroup(evsel_list, stat_config.cgroup_list) < 0)
		if (evlist__expand_cgroup(evsel_list, stat_config.cgroup_list,
					  &stat_config.metric_events) < 0)
			goto out;
	}

+22 −1
Original line number Diff line number Diff line
@@ -3,6 +3,9 @@
#include "evsel.h"
#include "cgroup.h"
#include "evlist.h"
#include "rblist.h"
#include "metricgroup.h"
#include "stat.h"
#include <linux/zalloc.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -193,10 +196,12 @@ int parse_cgroups(const struct option *opt, const char *str,
	return 0;
}

int evlist__expand_cgroup(struct evlist *evlist, const char *str)
int evlist__expand_cgroup(struct evlist *evlist, const char *str,
			  struct rblist *metric_events)
{
	struct evlist *orig_list, *tmp_list;
	struct evsel *pos, *evsel, *leader;
	struct rblist orig_metric_events;
	struct cgroup *cgrp = NULL;
	const char *p, *e, *eos = str + strlen(str);
	int ret = -1;
@@ -217,6 +222,13 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str)
	perf_evlist__splice_list_tail(orig_list, &evlist->core.entries);
	evlist->core.nr_entries = 0;

	if (metric_events) {
		orig_metric_events = *metric_events;
		rblist__init(metric_events);
	} else {
		rblist__init(&orig_metric_events);
	}

	for (;;) {
		p = strchr(str, ',');
		e = p ? p : eos;
@@ -255,6 +267,14 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str)
		cgroup__put(cgrp);
		nr_cgroups++;

		if (metric_events) {
			perf_stat__collect_metric_expr(tmp_list);
			if (metricgroup__copy_metric_events(tmp_list, cgrp,
							    metric_events,
							    &orig_metric_events) < 0)
				break;
		}

		perf_evlist__splice_list_tail(evlist, &tmp_list->core.entries);
		tmp_list->core.nr_entries = 0;

@@ -268,6 +288,7 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str)
out_err:
	evlist__delete(orig_list);
	evlist__delete(tmp_list);
	rblist__exit(&orig_metric_events);

	return ret;
}
+3 −1
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@ struct cgroup *cgroup__get(struct cgroup *cgroup);
void cgroup__put(struct cgroup *cgroup);

struct evlist;
struct rblist;

struct cgroup *evlist__findnew_cgroup(struct evlist *evlist, const char *name);
int evlist__expand_cgroup(struct evlist *evlist, const char *cgroups);
int evlist__expand_cgroup(struct evlist *evlist, const char *cgroups,
			  struct rblist *metric_events);

void evlist__set_default_cgroup(struct evlist *evlist, struct cgroup *cgroup);

+11 −0
Original line number Diff line number Diff line
@@ -1969,3 +1969,14 @@ int evlist__ctlfd_process(struct evlist *evlist, enum evlist_ctl_cmd *cmd)

	return err;
}

struct evsel *evlist__find_evsel(struct evlist *evlist, int idx)
{
	struct evsel *evsel;

	evlist__for_each_entry(evlist, evsel) {
		if (evsel->idx == idx)
			return evsel;
	}
	return NULL;
}
+1 −0
Original line number Diff line number Diff line
@@ -386,4 +386,5 @@ int evlist__ctlfd_ack(struct evlist *evlist);
#define EVLIST_ENABLED_MSG "Events enabled\n"
#define EVLIST_DISABLED_MSG "Events disabled\n"

struct evsel *evlist__find_evsel(struct evlist *evlist, int idx);
#endif /* __PERF_EVLIST_H */
Loading