Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp4900464rdb; Tue, 12 Dec 2023 12:27:41 -0800 (PST) X-Google-Smtp-Source: AGHT+IGcXprSLcbolT5VrQx1coNa0Qf8kgKcBwmrHl3FhxTJk40WYBK0Sh05LqUqBMy9YQP7GH/V X-Received: by 2002:a05:6358:3a1b:b0:170:c36a:a2ad with SMTP id g27-20020a0563583a1b00b00170c36aa2admr6400639rwe.36.1702412861458; Tue, 12 Dec 2023 12:27:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702412861; cv=none; d=google.com; s=arc-20160816; b=ixLmd8/zxBjokYWha3Gc6kdSrmudSA3NoNVMItxAfnAp9BK3rI1KL9KY2AbdMzvIuA CJiHxSCBvjSXS6VW07KSAQF+xWFrZhZLsEe8+W3tNHU+YBsx5fR1wIkanv0Q5c1AcIxv UihqVdrwJzXNwvVFtsu3085tl97tvTegYqG5c5Jd+bwrLYamfZrzWxMpOaoQKN+t69A4 Wz+seofFkLn5mtTtnzw5T/98Fq5x71PvGrhEbWjJgRGPLIQJx9VNUBqFkL3gDC5mIkom myhOD0AQqORb1eupJtDHB7c0AxlaWclhiAmFs2SZ79QMNnHnIUN439oeQR7toARWtspa LDQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=1r0l9UDH82X/QRijiq/v0dYWas+IVhPxoge2Q6dptEs=; fh=cbSbzzQTNzL0KNAuE9cxfEu5x6TvDttt6j2jrzuXqlE=; b=BES5qkkfklBBypc3ElxpJoW+ibQMx55ZlPahL62XUeOaNzmLfgUWQAi+G6lA7NL7wt dUdWtmrS10/c8waF4kfFVxSOqOqkilCEb9OO0fSBt5CcXE9RAsg75/SCN9PyhFAXqJun I8eYdxXdjgtuxVfYNNz6QFxy+xQd1nRE/QKpfNPYL/k1O6Ns1XAEWn1uYE2f/ThczmB7 SSJuCO4Hzn+buG7wzVCs2B7w2mgWCHK99MOJDme+BqiWTehPRj4yP0WEGnInNMYxatVC dcjgFG97eQ3IU/KOt5NKR/koaJ+xpS3W1DLYXp8NLwrpnzkqsIcvndBSBdWMDkZ74byD WVZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=XeI+ATa+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from howler.vger.email (howler.vger.email. [23.128.96.34]) by mx.google.com with ESMTPS id x4-20020a654544000000b005c6ec7ede9csi8114517pgr.866.2023.12.12.12.27.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 12:27:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) client-ip=23.128.96.34; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=XeI+ATa+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id 5C035802090F; Tue, 12 Dec 2023 12:27:38 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377293AbjLLU1W (ORCPT + 99 others); Tue, 12 Dec 2023 15:27:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230051AbjLLU1V (ORCPT ); Tue, 12 Dec 2023 15:27:21 -0500 Received: from mail-lf1-x131.google.com (mail-lf1-x131.google.com [IPv6:2a00:1450:4864:20::131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 702ECD5 for ; Tue, 12 Dec 2023 12:27:25 -0800 (PST) Received: by mail-lf1-x131.google.com with SMTP id 2adb3069b0e04-50bf1de91c6so770e87.1 for ; Tue, 12 Dec 2023 12:27:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1702412843; x=1703017643; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=1r0l9UDH82X/QRijiq/v0dYWas+IVhPxoge2Q6dptEs=; b=XeI+ATa+LdAkHqn1BjFTeJsitxU1zxpjBgkEu8WDKbZNjPhNQtcp57vQoaVKy0kVg8 EkFa9fjlHwGU3mvHzRftpGIcAG1ucOaUu6a3rukDYzYIQzBotRmViaGf5Dh2UmLcxSKZ HS38soueUWtlavoqmdkkl+Zm1h8x7D5LwKO5GCgp18xmtIBK7BtJxvYb0oxLzkLYQNXb ZdpeUxBGOA2uS6BrvctKMJKTMR9RVgx5qGmoZ/cN/9yEc3RjxC4KCSqyF2E6Q6z7tmKT ntSzFy0YlgAvbTSZ9SYl8Qqf5cyC1AzJGURXdWDOPnA0JP6FywFNJ4JWkdJ7MQtUU9LH dncg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702412843; x=1703017643; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1r0l9UDH82X/QRijiq/v0dYWas+IVhPxoge2Q6dptEs=; b=ihTKTblzU/kEzsL7Gq9h989IsdaVZD3MyacyJ1a6E7s3Bp749fv+dxLkj5sB6LypoR 7J7AO5a82GBu1CTHAyJXkx+Uwo7zrjOXH8y8ZWSWs7IVOKj8Mh4F/XqTuAyBY2EX/rKR zbOZPimYep/b7Y9muXjGBzqj6POdgNfotzHIgGQ7xEezhsI75SXvciTsRl0ExBzM0Lbw tGkmp8KBOuYTjHkLvCKf1xb6fQrsMsjPH/cjrOFvWnuYqC9zcvTQfm4ZN2dCZl7TYeIs BMm4fSHyRS4M5xaR0/gA5J1vCMjx42RTFbGsbQnMNrDjO6f3+4/X8tXKjlQjbd0QU2zb EKtQ== X-Gm-Message-State: AOJu0YxMHC3oPPqldlTaV5tS2JldKgiyQ23SCrLsoSOsjsk/t6inFAMR uIZFC+KbfMz6y8Dx42Jpc6RUDsqAuiOuajl66F7DuA== X-Received: by 2002:a19:4f07:0:b0:50b:fcb7:15af with SMTP id d7-20020a194f07000000b0050bfcb715afmr233274lfb.3.1702412843308; Tue, 12 Dec 2023 12:27:23 -0800 (PST) MIME-Version: 1.0 References: <20231129060211.1890454-1-irogers@google.com> <20231129060211.1890454-7-irogers@google.com> <94e3745c-8c2b-bdf3-f331-1cbe56574d48@arm.com> In-Reply-To: <94e3745c-8c2b-bdf3-f331-1cbe56574d48@arm.com> From: Ian Rogers Date: Tue, 12 Dec 2023 12:27:11 -0800 Message-ID: Subject: Re: [PATCH v1 06/14] libperf cpumap: Add any, empty and min helpers To: James Clark Cc: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Adrian Hunter , Suzuki K Poulose , Mike Leach , Leo Yan , John Garry , Will Deacon , Thomas Gleixner , Darren Hart , Davidlohr Bueso , =?UTF-8?Q?Andr=C3=A9_Almeida?= , Kan Liang , K Prateek Nayak , Sean Christopherson , Paolo Bonzini , Kajol Jain , Athira Rajeev , Andrew Jones , Alexandre Ghiti , Atish Patra , "Steinar H. Gunderson" , Yang Jihong , Yang Li , Changbin Du , Sandipan Das , Ravi Bangoria , Paran Lee , Nick Desaulniers , Huacai Chen , Yanteng Si , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, bpf@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Tue, 12 Dec 2023 12:27:38 -0800 (PST) On Tue, Dec 12, 2023 at 7:06=E2=80=AFAM James Clark w= rote: > > > > On 29/11/2023 06:02, Ian Rogers wrote: > > Additional helpers to better replace > > perf_cpu_map__has_any_cpu_or_is_empty. > > > > Signed-off-by: Ian Rogers > > --- > > tools/lib/perf/cpumap.c | 27 +++++++++++++++++++++++++++ > > tools/lib/perf/include/perf/cpumap.h | 16 ++++++++++++++++ > > tools/lib/perf/libperf.map | 4 ++++ > > 3 files changed, 47 insertions(+) > > > > diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c > > index 49fc98e16514..7403819da8fd 100644 > > --- a/tools/lib/perf/cpumap.c > > +++ b/tools/lib/perf/cpumap.c > > @@ -316,6 +316,19 @@ bool perf_cpu_map__has_any_cpu_or_is_empty(const s= truct perf_cpu_map *map) > > return map ? __perf_cpu_map__cpu(map, 0).cpu =3D=3D -1 : true; > > } > > > > +bool perf_cpu_map__is_any_cpu_or_is_empty(const struct perf_cpu_map *m= ap) > > +{ > > + if (!map) > > + return true; > > + > > + return __perf_cpu_map__nr(map) =3D=3D 1 && __perf_cpu_map__cpu(ma= p, 0).cpu =3D=3D -1; > > +} > > I'm struggling to understand the relevance of the difference between > has_any and is_any I see that there is a slight difference, but could it > not be refactored out so we only need one? Yep, that's what these changes are working toward. For has any the set {-1, 0, 1} would return true while is any will return false. Previously the has any behavior was called "empty" which I think is actively misleading. > Do you ever get an 'any' map that has more than 1 entry? It's quite a > subtle difference that is_any returns false if the first one is 'any' > but then there are subsequent entries. Whereas has_any would return > true. I'm not sure if future readers would be able to appreciate that. > > I see has_any is only used twice, both on evlist->all_cpus. Is there > something about that member that means it could have a map that has an > 'any' mixed with CPUs? Wouldn't that have the same result as a normal > 'any' anyway? The dummy event may be opened on any CPU but then a particular event may be opened on certain CPUs. We merge CPU maps in places like evlist so that we can iterate the appropriate CPUs for events and open/enable/disable/close all events on a certain CPU at the same time (we also set the affinity to that CPU to avoid IPIs). What I'm hoping to do in these changes is reduce the ambiguity, the corner cases are by their nature unusual. An example of a corner case is, uncore events often get opened just on CPU 0 but on a multi-socket system you may have a CPU 32 that also needs to open the event. Previous code treated the CPU map index and value it contained pretty interchangeably. This is often fine for the core PMU but is clearly wrong in this uncore case, {0, 32} has indexes 0 and 1 but those indexes don't match the CPU numbers. The case of -1 has often previously been called dummy but I'm trying to call it the "any CPU" case to match the perf_event_open man page (I'm hoping it also makes it less ambiguous with any CPU being used with a particular event like cycles, calling it dummy makes the event sound like it may have sideband data). The difference between "all CPUs" and "any CPU" is that an evsel for all CPUs would need the event opening individually on each CPU, while any CPU events are a single open call. Any CPU is only valid to perf_event_open if a PID is specified. Depending on the set up there could be overlaps in what they count but hopefully it is clearer what the distinction is. I believe the case of "any CPU" and specific CPU numbers is more common with aux buffers and Adrian has mentioned needing it for intel-pt. Thanks, Ian > > + > > +bool perf_cpu_map__is_empty(const struct perf_cpu_map *map) > > +{ > > + return map =3D=3D NULL; > > +} > > + > > int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu= cpu) > > { > > int low, high; > > @@ -372,6 +385,20 @@ bool perf_cpu_map__has_any_cpu(const struct perf_c= pu_map *map) > > return map && __perf_cpu_map__cpu(map, 0).cpu =3D=3D -1; > > } > > > > +struct perf_cpu perf_cpu_map__min(const struct perf_cpu_map *map) > > +{ > > + struct perf_cpu cpu, result =3D { > > + .cpu =3D -1 > > + }; > > + int idx; > > + > > + perf_cpu_map__for_each_cpu_skip_any(cpu, idx, map) { > > + result =3D cpu; > > + break; > > + } > > + return result; > > +} > > + > > struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map) > > { > > struct perf_cpu result =3D { > > diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/incl= ude/perf/cpumap.h > > index dbe0a7352b64..523e4348fc96 100644 > > --- a/tools/lib/perf/include/perf/cpumap.h > > +++ b/tools/lib/perf/include/perf/cpumap.h > > @@ -50,6 +50,22 @@ LIBPERF_API int perf_cpu_map__nr(const struct perf_c= pu_map *cpus); > > * perf_cpu_map__has_any_cpu_or_is_empty - is map either empty or has = the "any CPU"/dummy value. > > */ > > LIBPERF_API bool perf_cpu_map__has_any_cpu_or_is_empty(const struct pe= rf_cpu_map *map); > > +/** > > + * perf_cpu_map__is_any_cpu_or_is_empty - is map either empty or the "= any CPU"/dummy value. > > + */ > > +LIBPERF_API bool perf_cpu_map__is_any_cpu_or_is_empty(const struct per= f_cpu_map *map); > > +/** > > + * perf_cpu_map__is_empty - does the map contain no values and it does= n't > > + * contain the special "any CPU"/dummy value. > > + */ > > +LIBPERF_API bool perf_cpu_map__is_empty(const struct perf_cpu_map *map= ); > > +/** > > + * perf_cpu_map__min - the minimum CPU value or -1 if empty or just th= e "any CPU"/dummy value. > > + */ > > +LIBPERF_API struct perf_cpu perf_cpu_map__min(const struct perf_cpu_ma= p *map); > > +/** > > + * perf_cpu_map__max - the maximum CPU value or -1 if empty or just th= e "any CPU"/dummy value. > > + */ > > LIBPERF_API struct perf_cpu perf_cpu_map__max(const struct perf_cpu_ma= p *map); > > LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, str= uct perf_cpu cpu); > > LIBPERF_API bool perf_cpu_map__equal(const struct perf_cpu_map *lhs, > > diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map > > index 10b3f3722642..2aa79b696032 100644 > > --- a/tools/lib/perf/libperf.map > > +++ b/tools/lib/perf/libperf.map > > @@ -10,6 +10,10 @@ LIBPERF_0.0.1 { > > perf_cpu_map__nr; > > perf_cpu_map__cpu; > > perf_cpu_map__has_any_cpu_or_is_empty; > > + perf_cpu_map__is_any_cpu_or_is_empty; > > + perf_cpu_map__is_empty; > > + perf_cpu_map__has_any_cpu; > > + perf_cpu_map__min; > > perf_cpu_map__max; > > perf_cpu_map__has; > > perf_thread_map__new_array;