Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

libperf cpumap: Refactor perf_cpu_map__merge()

The perf_cpu_map__merge() function has two arguments, 'orig' and
'other'. The function definition might cause confusion as it could give
the impression that the CPU maps in the two arguments are copied into a
new allocated structure, which is then returned as the result.

The purpose of the function is to merge the CPU map 'other' into the CPU
map 'orig'. This commit changes the 'orig' argument to a pointer to
pointer, so the new result will be updated into 'orig'.

The return value is changed to an int type, as an error number or 0 for
success.

Update callers and tests for the new function definition.

Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20241107125308.41226-2-leo.yan@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Leo Yan and committed by
Arnaldo Carvalho de Melo
a9d22175 161c3402

+40 -33
+27 -22
tools/lib/perf/cpumap.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 + #include <errno.h> 2 3 #include <perf/cpumap.h> 3 4 #include <stdlib.h> 4 5 #include <linux/refcount.h> ··· 437 436 } 438 437 439 438 /* 440 - * Merge two cpumaps 439 + * Merge two cpumaps. 441 440 * 442 - * orig either gets freed and replaced with a new map, or reused 443 - * with no reference count change (similar to "realloc") 444 - * other has its reference count increased. 441 + * If 'other' is subset of '*orig', '*orig' keeps itself with no reference count 442 + * change (similar to "realloc"). 443 + * 444 + * If '*orig' is subset of 'other', '*orig' reuses 'other' with its reference 445 + * count increased. 446 + * 447 + * Otherwise, '*orig' gets freed and replaced with a new map. 445 448 */ 446 - 447 - struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, 448 - struct perf_cpu_map *other) 449 + int perf_cpu_map__merge(struct perf_cpu_map **orig, struct perf_cpu_map *other) 449 450 { 450 451 struct perf_cpu *tmp_cpus; 451 452 int tmp_len; 452 453 int i, j, k; 453 454 struct perf_cpu_map *merged; 454 455 455 - if (perf_cpu_map__is_subset(orig, other)) 456 - return orig; 457 - if (perf_cpu_map__is_subset(other, orig)) { 458 - perf_cpu_map__put(orig); 459 - return perf_cpu_map__get(other); 456 + if (perf_cpu_map__is_subset(*orig, other)) 457 + return 0; 458 + if (perf_cpu_map__is_subset(other, *orig)) { 459 + perf_cpu_map__put(*orig); 460 + *orig = perf_cpu_map__get(other); 461 + return 0; 460 462 } 461 463 462 - tmp_len = __perf_cpu_map__nr(orig) + __perf_cpu_map__nr(other); 464 + tmp_len = __perf_cpu_map__nr(*orig) + __perf_cpu_map__nr(other); 463 465 tmp_cpus = malloc(tmp_len * sizeof(struct perf_cpu)); 464 466 if (!tmp_cpus) 465 - return NULL; 467 + return -ENOMEM; 466 468 467 469 /* Standard merge algorithm from wikipedia */ 468 470 i = j = k = 0; 469 - while (i < __perf_cpu_map__nr(orig) && j < __perf_cpu_map__nr(other)) { 470 - if (__perf_cpu_map__cpu(orig, i).cpu <= __perf_cpu_map__cpu(other, j).cpu) { 471 - if (__perf_cpu_map__cpu(orig, i).cpu == __perf_cpu_map__cpu(other, j).cpu) 471 + while (i < __perf_cpu_map__nr(*orig) && j < __perf_cpu_map__nr(other)) { 472 + if (__perf_cpu_map__cpu(*orig, i).cpu <= __perf_cpu_map__cpu(other, j).cpu) { 473 + if (__perf_cpu_map__cpu(*orig, i).cpu == __perf_cpu_map__cpu(other, j).cpu) 472 474 j++; 473 - tmp_cpus[k++] = __perf_cpu_map__cpu(orig, i++); 475 + tmp_cpus[k++] = __perf_cpu_map__cpu(*orig, i++); 474 476 } else 475 477 tmp_cpus[k++] = __perf_cpu_map__cpu(other, j++); 476 478 } 477 479 478 - while (i < __perf_cpu_map__nr(orig)) 479 - tmp_cpus[k++] = __perf_cpu_map__cpu(orig, i++); 480 + while (i < __perf_cpu_map__nr(*orig)) 481 + tmp_cpus[k++] = __perf_cpu_map__cpu(*orig, i++); 480 482 481 483 while (j < __perf_cpu_map__nr(other)) 482 484 tmp_cpus[k++] = __perf_cpu_map__cpu(other, j++); ··· 487 483 488 484 merged = cpu_map__trim_new(k, tmp_cpus); 489 485 free(tmp_cpus); 490 - perf_cpu_map__put(orig); 491 - return merged; 486 + perf_cpu_map__put(*orig); 487 + *orig = merged; 488 + return 0; 492 489 } 493 490 494 491 struct perf_cpu_map *perf_cpu_map__intersect(struct perf_cpu_map *orig,
+1 -1
tools/lib/perf/evlist.c
··· 75 75 evsel->threads = perf_thread_map__get(evlist->threads); 76 76 } 77 77 78 - evlist->all_cpus = perf_cpu_map__merge(evlist->all_cpus, evsel->cpus); 78 + perf_cpu_map__merge(&evlist->all_cpus, evsel->cpus); 79 79 } 80 80 81 81 static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
+2 -2
tools/lib/perf/include/perf/cpumap.h
··· 39 39 LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); 40 40 LIBPERF_API struct perf_cpu_map *perf_cpu_map__read(FILE *file); 41 41 LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); 42 - LIBPERF_API struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, 43 - struct perf_cpu_map *other); 42 + LIBPERF_API int perf_cpu_map__merge(struct perf_cpu_map **orig, 43 + struct perf_cpu_map *other); 44 44 LIBPERF_API struct perf_cpu_map *perf_cpu_map__intersect(struct perf_cpu_map *orig, 45 45 struct perf_cpu_map *other); 46 46 LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map);
+6 -7
tools/perf/tests/cpumap.c
··· 160 160 { 161 161 struct perf_cpu_map *a = perf_cpu_map__new("4,2,1"); 162 162 struct perf_cpu_map *b = perf_cpu_map__new("4,5,7"); 163 - struct perf_cpu_map *c = perf_cpu_map__merge(a, b); 164 163 char buf[100]; 165 164 166 - TEST_ASSERT_VAL("failed to merge map: bad nr", perf_cpu_map__nr(c) == 5); 167 - cpu_map__snprint(c, buf, sizeof(buf)); 165 + perf_cpu_map__merge(&a, b); 166 + TEST_ASSERT_VAL("failed to merge map: bad nr", perf_cpu_map__nr(a) == 5); 167 + cpu_map__snprint(a, buf, sizeof(buf)); 168 168 TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf, "1-2,4-5,7")); 169 169 perf_cpu_map__put(b); 170 - perf_cpu_map__put(c); 170 + perf_cpu_map__put(a); 171 171 return 0; 172 172 } 173 173 ··· 233 233 } 234 234 235 235 /* Maps equal made maps. */ 236 - tmp = perf_cpu_map__merge(perf_cpu_map__get(one), two); 237 - TEST_ASSERT_VAL("pair", perf_cpu_map__equal(pair, tmp)); 238 - perf_cpu_map__put(tmp); 236 + perf_cpu_map__merge(&two, one); 237 + TEST_ASSERT_VAL("pair", perf_cpu_map__equal(pair, two)); 239 238 240 239 tmp = perf_cpu_map__intersect(pair, one); 241 240 TEST_ASSERT_VAL("one", perf_cpu_map__equal(one, tmp));
+4 -1
tools/perf/util/mem-events.c
··· 258 258 const char *s; 259 259 char *copy; 260 260 struct perf_cpu_map *cpu_map = NULL; 261 + int ret; 261 262 262 263 while ((pmu = perf_pmus__scan_mem(pmu)) != NULL) { 263 264 for (int j = 0; j < PERF_MEM_EVENTS__MAX; j++) { ··· 284 283 rec_argv[i++] = "-e"; 285 284 rec_argv[i++] = copy; 286 285 287 - cpu_map = perf_cpu_map__merge(cpu_map, pmu->cpus); 286 + ret = perf_cpu_map__merge(&cpu_map, pmu->cpus); 287 + if (ret < 0) 288 + return ret; 288 289 } 289 290 } 290 291