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

perf stat: Use affinity for enabling/disabling events

Restructure event enabling/disabling to use affinity, which
minimizes the number of IPIs needed.

Before on a large test case with 94 CPUs:

% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
54.65 1.899986 22 84812 660 ioctl

after:

39.21 0.930451 10 84796 644 ioctl

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lore.kernel.org/lkml/20191121001522.180827-13-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Andi Kleen and committed by
Arnaldo Carvalho de Melo
704e2f5b 363fb121

+37 -3
+37 -3
tools/perf/util/evlist.c
··· 378 378 void evlist__disable(struct evlist *evlist) 379 379 { 380 380 struct evsel *pos; 381 + struct affinity affinity; 382 + int cpu, i; 381 383 384 + if (affinity__setup(&affinity) < 0) 385 + return; 386 + 387 + evlist__for_each_cpu(evlist, i, cpu) { 388 + affinity__set(&affinity, cpu); 389 + 390 + evlist__for_each_entry(evlist, pos) { 391 + if (evsel__cpu_iter_skip(pos, cpu)) 392 + continue; 393 + if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->core.fd) 394 + continue; 395 + evsel__disable_cpu(pos, pos->cpu_iter - 1); 396 + } 397 + } 398 + affinity__cleanup(&affinity); 382 399 evlist__for_each_entry(evlist, pos) { 383 - if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->core.fd) 400 + if (!perf_evsel__is_group_leader(pos) || !pos->core.fd) 384 401 continue; 385 - evsel__disable(pos); 402 + pos->disabled = true; 386 403 } 387 404 388 405 evlist->enabled = false; ··· 408 391 void evlist__enable(struct evlist *evlist) 409 392 { 410 393 struct evsel *pos; 394 + struct affinity affinity; 395 + int cpu, i; 411 396 397 + if (affinity__setup(&affinity) < 0) 398 + return; 399 + 400 + evlist__for_each_cpu(evlist, i, cpu) { 401 + affinity__set(&affinity, cpu); 402 + 403 + evlist__for_each_entry(evlist, pos) { 404 + if (evsel__cpu_iter_skip(pos, cpu)) 405 + continue; 406 + if (!perf_evsel__is_group_leader(pos) || !pos->core.fd) 407 + continue; 408 + evsel__enable_cpu(pos, pos->cpu_iter - 1); 409 + } 410 + } 411 + affinity__cleanup(&affinity); 412 412 evlist__for_each_entry(evlist, pos) { 413 413 if (!perf_evsel__is_group_leader(pos) || !pos->core.fd) 414 414 continue; 415 - evsel__enable(pos); 415 + pos->disabled = false; 416 416 } 417 417 418 418 evlist->enabled = true;