Re: [PATCH v5 07/13] perf stat: Use affinity for closing file descriptors

From: Jiri Olsa
Date: Mon Nov 11 2019 - 08:31:03 EST


On Thu, Nov 07, 2019 at 10:16:40AM -0800, Andi Kleen wrote:
> From: Andi Kleen <ak@xxxxxxxxxxxxxxx>
>
> Closing a perf fd can also trigger an IPI to the target CPU.
> Use the same affinity technique as we use for reading/enabling events
> to closing to optimize the CPU transitions.
>
> Before on a large test case with 94 CPUs:
>
> % time seconds usecs/call calls errors syscall
> ------ ----------- ----------- --------- --------- ----------------
> 32.56 3.085463 50 61483 close
>
> After:
>
> 10.54 0.735704 11 61485 close
>
> Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
>
> ---
>
> v2: Use new iterator macros
> v3: Use new iterator macros
> Add missing affinity__cleanup
> v4:
> Update iterators again
> ---
> tools/perf/util/evlist.c | 27 +++++++++++++++++++++++++--
> 1 file changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index dae6e846b2f8..0dcea66329e2 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -18,6 +18,7 @@
> #include "debug.h"
> #include "units.h"
> #include <internal/lib.h> // page_size
> +#include "affinity.h"
> #include "../perf.h"
> #include "asm/bug.h"
> #include "bpf-event.h"
> @@ -1169,9 +1170,31 @@ void perf_evlist__set_selected(struct evlist *evlist,
> void evlist__close(struct evlist *evlist)
> {
> struct evsel *evsel;
> + struct affinity affinity;
> + int cpu, i;
>
> - evlist__for_each_entry_reverse(evlist, evsel)
> - evsel__close(evsel);
> + if (!evlist->core.cpus) {

should this be evlist->all_cpus?

jirka

> + evlist__for_each_entry_reverse(evlist, evsel)
> + evsel__close(evsel);
> + return;
> + }
> +
> + if (affinity__setup(&affinity) < 0)
> + return;
> + evlist__for_each_cpu (evlist, i, cpu) {
> + affinity__set(&affinity, cpu);
> +
> + evlist__for_each_entry_reverse(evlist, evsel) {
> + if (evsel__cpu_iter_skip(evsel, cpu))
> + continue;
> + perf_evsel__close_cpu(&evsel->core, evsel->cpu_iter - 1);
> + }
> + }
> + affinity__cleanup(&affinity);
> + evlist__for_each_entry_reverse(evlist, evsel) {
> + perf_evsel__free_fd(&evsel->core);
> + perf_evsel__free_id(&evsel->core);
> + }
> }
>
> static int perf_evlist__create_syswide_maps(struct evlist *evlist)
> --
> 2.23.0
>