Having one argument to the cpumap merge decremented but not the other leads to an inconsistent API. Don't decrement either argument. Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx> --- tools/lib/perf/cpumap.c | 11 +++-------- tools/lib/perf/evlist.c | 6 +++++- tools/perf/tests/cpumap.c | 1 + 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index 384d5e076ee4..95c56e17241b 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -342,9 +342,7 @@ bool perf_cpu_map__is_subset(const struct perf_cpu_map *a, const struct perf_cpu /* * Merge two cpumaps * - * orig either gets freed and replaced with a new map, or reused - * with no reference count change (similar to "realloc") - * other has its reference count increased. + * May reuse either orig or other bumping reference count accordingly. */ struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, @@ -356,11 +354,9 @@ struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, struct perf_cpu_map *merged; if (perf_cpu_map__is_subset(orig, other)) - return orig; - if (perf_cpu_map__is_subset(other, orig)) { - perf_cpu_map__put(orig); + return perf_cpu_map__get(orig); + if (perf_cpu_map__is_subset(other, orig)) return perf_cpu_map__get(other); - } tmp_len = orig->nr + other->nr; tmp_cpus = malloc(tmp_len * sizeof(struct perf_cpu)); @@ -387,6 +383,5 @@ struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, merged = cpu_map__trim_new(k, tmp_cpus); free(tmp_cpus); - perf_cpu_map__put(orig); return merged; } diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index 1b15ba13c477..b783249a038b 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -35,6 +35,8 @@ void perf_evlist__init(struct perf_evlist *evlist) static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, struct perf_evsel *evsel) { + struct perf_cpu_map *tmp; + /* * We already have cpus for evsel (via PMU sysfs) so * keep it, if there's no target cpu list defined. @@ -52,7 +54,9 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, perf_thread_map__put(evsel->threads); evsel->threads = perf_thread_map__get(evlist->threads); - evlist->all_cpus = perf_cpu_map__merge(evlist->all_cpus, evsel->cpus); + tmp = perf_cpu_map__merge(evlist->all_cpus, evsel->cpus); + perf_cpu_map__put(evlist->all_cpus); + evlist->all_cpus = tmp; } static void perf_evlist__propagate_maps(struct perf_evlist *evlist) diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index f94929ebb54b..cf205ed6b158 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -133,6 +133,7 @@ static int test__cpu_map_merge(struct test_suite *test __maybe_unused, int subte TEST_ASSERT_VAL("failed to merge map: bad nr", perf_cpu_map__nr(c) == 5); cpu_map__snprint(c, buf, sizeof(buf)); TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf, "1-2,4-5,7")); + perf_cpu_map__put(a); perf_cpu_map__put(b); perf_cpu_map__put(c); return 0; -- 2.35.1.1178.g4f1659d476-goog