From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67F73C00144 for ; Fri, 29 Jul 2022 07:44:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234953AbiG2HoI (ORCPT ); Fri, 29 Jul 2022 03:44:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234154AbiG2HoF (ORCPT ); Fri, 29 Jul 2022 03:44:05 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F39A465809 for ; Fri, 29 Jul 2022 00:44:04 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id y13-20020a5b09cd000000b0067114eb5b50so3287354ybq.17 for ; Fri, 29 Jul 2022 00:44:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=gJpUpfYLbWgWjOwgXjGO+9lnopmpvExo4+EzC9HEZTY=; b=dGCDlxqp0N92i8FI8IxZI0RMts2CVs6exeUrA29GDqYZd2sk37RGoacdGjeaGAaPEl veyYOZBOQmOc24vq5FT0+v67NmYoZPupwBcSbyu/TNItgl51jakqAeFTk7FmNHcuwF5s pyIEjbOqMtfjIMC0SNfrA/UQR/Pr/nXMZCMoS2MA3Tz7jvRTZwt4bIihGAMsFxtssia9 seAGqe9IhHByUB8BHUkgIW6PmueRB80GtUkYVRFSbRtaBOL1aiIn8a/sQ1FGp59m7yT7 JqR4pii4eZKYpIEeR1WUkTYi/kra01qzW5F6bRMrxFc4RW5XMmwU+T37ESVmuzmhsVCX WIqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=gJpUpfYLbWgWjOwgXjGO+9lnopmpvExo4+EzC9HEZTY=; b=VZK6sTwo1VbeYywkK/KbxdC2GnidrKvhx2biUFKS9TLp7oxsci93UOAnSvjbOJ/CwS zvuo6t/PIOKoFyzgtrR46rOgRqFA76RPiyb8gxEqsKwBWLNNVgwAC1O2xp1jtJZBhXiM +SPlUURLW8PQS5TIFOUGTeo1U2MH3tcNpTmtqp26zmBEkqjnANozi1BrGx3B5aGtClGa lAy1+UNfei4tHWDqDFBDsbe+U/cicue1qE0t9oBIe7fFDNldS+B+yVq9Ziy33eChWsB+ wMdgQZCWL0AQWJvlmmciL+6PFm3Stcc+KW7kMY6SceTLtrpKPXzFKtTmvR3v5R+KVs5e Fg+w== X-Gm-Message-State: ACgBeo3G45o1Fq13sC1lB3+vCU/+PQ3OEC7n9YK1h601pdYp9VX+4XAt hsEqoaotmzq1UFaHtHaHp5SHEre4ti4w X-Google-Smtp-Source: AA6agR4xDcMfnB3k6eIsa+YSBZau3gw42uQA+UFZp9uzUXHPo8lYPYIQ1NrBgvJdmk8BPuBm/TWyurtIPhKV X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a05:6902:70c:b0:670:bb85:766e with SMTP id k12-20020a056902070c00b00670bb85766emr1640653ybt.428.1659080644298; Fri, 29 Jul 2022 00:44:04 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:35 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-2-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 01/17] perf jevents: Clean up pytype warnings From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Improve type hints to clean up pytype warnings. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 83e0dcbeac9a..5b72048d50da 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -6,8 +6,7 @@ import csv import json import os import sys -from typing import Callable -from typing import Sequence +from typing import (Callable, Optional, Sequence) =20 # Global command line arguments. _args =3D None @@ -57,7 +56,7 @@ class JsonEvent: '. '), '.').replace('\n', '\\n').re= place( '\"', '\\"').replace('\r', '\\r= ') =20 - def convert_aggr_mode(aggr_mode: str) -> str: + def convert_aggr_mode(aggr_mode: str) -> Optional[str]: """Returns the aggr_mode_class enum value associated with the JSON s= tring.""" if not aggr_mode: return None @@ -67,7 +66,7 @@ class JsonEvent: } return aggr_mode_to_enum[aggr_mode] =20 - def lookup_msr(num: str) -> str: + def lookup_msr(num: str) -> Optional[str]: """Converts the msr number, or first in a list to the appropriate ev= ent field.""" if not num: return None @@ -79,7 +78,7 @@ class JsonEvent: } return msrmap[int(num.split(',', 1)[0], 0)] =20 - def real_event(name: str, event: str) -> str: + def real_event(name: str, event: str) -> Optional[str]: """Convert well known event names to an event string otherwise use t= he event argument.""" fixed =3D { 'inst_retired.any': 'event=3D0xc0,period=3D2000003', @@ -95,7 +94,7 @@ class JsonEvent: return fixed[name.lower()] return event =20 - def unit_to_pmu(unit: str) -> str: + def unit_to_pmu(unit: str) -> Optional[str]: """Convert a JSON Unit to Linux PMU name.""" if not unit: return None @@ -154,7 +153,7 @@ class JsonEvent: if self.metric_expr: self.metric_expr =3D self.metric_expr.replace('\\', '\\\\') arch_std =3D jd.get('ArchStdEvent') - if precise and self.desc and not '(Precise Event)' in self.desc: + if precise and self.desc and '(Precise Event)' not in self.desc: extra_desc +=3D ' (Must be precise)' if precise =3D=3D '2' else (' (= Precise ' 'event)') event =3D f'config=3D{llx(configcode)}' if configcode is not None else= f'event=3D{llx(eventcode)}' --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1BC2C19F2B for ; Fri, 29 Jul 2022 07:44:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234980AbiG2HoM (ORCPT ); Fri, 29 Jul 2022 03:44:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234946AbiG2HoI (ORCPT ); Fri, 29 Jul 2022 03:44:08 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD1D37B37E for ; Fri, 29 Jul 2022 00:44:07 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id j4-20020a5b0304000000b00676ba2ed7e9so323155ybp.23 for ; Fri, 29 Jul 2022 00:44:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=envuPbzzq2H54VKr3RstW6kg8N0kUvXDq8KS/IJYJi4=; b=oRwQiy17hOjBg79amu8cXv0HG3YS23fNp9hgX4XS6A3pX3ZvRQVEU3+98y70aFyWbQ 3knxj5i78Ot4CR/NK5LytuHU6ia5SqlDgp4WKLsoyqk2HV3YMNCadVKE0aGhmW9Klgsz WT7Ozg6cYj4AAr5pD4BASrxxeA36XGonvNb4Hq6IA7XLE2uhUtQ3xprXG+MOXXRn+uon wlxC8z6+D640QlNVWRHrAlCeZA0aw3W5TGUUL199sGO8Rg0Ew4PyTFReek2ogfesAZ0f /9zKy6CsSJDOe7vqxxRNl7IBxDDYepJJkVmm77pUlaYFiPC/hDLDPoT5Ub0jRQvocfZg uakA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=envuPbzzq2H54VKr3RstW6kg8N0kUvXDq8KS/IJYJi4=; b=rR23rwr9rlE0uNcyNjw7k0ry+9MG54LsgrVqcOD8crcQm5UQsTHmpSzNgbDzNZZIUr 2WBdT+5gcof/Sv98CqhySpE+mCYyQcW5vfgLgYG+pHfrtten5jppzL5gZRQhmljkc8wD AyQnHf9sT5Yqzo0a3Cbbdxhgd8dSdXI2gTJD6cl6l5ZJKKgOkWzOF00W8kUwhGd76xIh m0UNZ0cUCtikHjdMSbmaI/c3ycOrO9iGu/FvIMNyGtJtJzVw3anEjUXQWaKisD3V5KIy N/hqViMAbQzuYCx/C3pS1tM3DZ7az8lIezsXNhY+R2StZslcMTCLR9qlgNzVAncv38VN mwgA== X-Gm-Message-State: ACgBeo3pjd/yKwVEyEDUnuOkTJrcS5qTYah+YIqJcgA3VfcMPZKVb0Q2 8GqEC2HDYM8R7FneePiepbzjpNTYFCCa X-Google-Smtp-Source: AA6agR4cBEhcuit+eTvxeDSrr/fqU2sZZsNPKXEiBrGn3UWxvMJCZdiwO7Liknsg7sbmU0z0rRHmeY40o8Kh X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a25:c1c6:0:b0:66f:5acc:7fb8 with SMTP id r189-20020a25c1c6000000b0066f5acc7fb8mr1570670ybf.634.1659080647103; Fri, 29 Jul 2022 00:44:07 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:36 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-3-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 02/17] perf jevents: Simplify generation of C-string From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Previous implementation wanted variable order and '(null)' string output to match the C implementation. The '(null)' string output was a quirk/bug and so there is no need to carry it forward. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 5b72048d50da..cdfa4e0e7557 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -203,7 +203,7 @@ class JsonEvent: """Representation of the event as a C struct initializer.""" =20 def attr_string(attr: str, value: str) -> str: - return '\t.%s =3D \"%s\",\n' % (attr, value) + return f'\t.{attr} =3D \"{value}\",\n' =20 def str_if_present(self, attr: str) -> str: if not getattr(self, attr): @@ -211,17 +211,11 @@ class JsonEvent: return attr_string(attr, getattr(self, attr)) =20 s =3D '{\n' - for attr in ['name', 'event']: - s +=3D str_if_present(self, attr) - if self.desc is not None: - s +=3D attr_string('desc', self.desc) - else: - s +=3D attr_string('desc', '(null)') - s +=3D str_if_present(self, 'compat') s +=3D f'\t.topic =3D "{topic_local}",\n' for attr in [ - 'long_desc', 'pmu', 'unit', 'perpkg', 'aggr_mode', 'metric_expr', - 'metric_name', 'metric_group', 'deprecated', 'metric_constraint' + 'aggr_mode', 'compat', 'deprecated', 'desc', 'event', 'long_desc', + 'metric_constraint', 'metric_expr', 'metric_group', 'metric_name', + 'name', 'perpkg', 'pmu', 'unit' ]: s +=3D str_if_present(self, attr) s +=3D '},\n' --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3081DC19F2A for ; Fri, 29 Jul 2022 07:44:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235056AbiG2HoU (ORCPT ); Fri, 29 Jul 2022 03:44:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234942AbiG2HoL (ORCPT ); Fri, 29 Jul 2022 03:44:11 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5965965666 for ; Fri, 29 Jul 2022 00:44:10 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id m123-20020a253f81000000b0066ff6484995so3298778yba.22 for ; Fri, 29 Jul 2022 00:44:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=n6t/pfc0M41ToUc5HflmTh98LQ2xLoF6/7gvlW5ZK2Q=; b=RmaMHRM7ZCMs2/Sqd/a9cdMCmqaHieNXVHN4Vuvjr+TsV/F8AClPvTIRagoDGDteWP JtTrLV93NxFRO9qxISgnIVfKmNRq7AhrSL9eH75+iyu2fez+WJO0lxUj+jqV/oKCfe3i nuyp1wAIJyjwZvdYgpNF0Ol7SaSvyWX3/OmBZc8xGOSfwNMMDJu83rG8aYZjNa9VjNGX 68nHrV2nLH2zt4bKDZntZlSECtedzjURSUOIwFLvjqkwwAKOEq7Zao1TaGUi05MPmxbF xOeW23WnznBfPNyM8bDBJvTUDbitnImpHaGkGAe9c5bPYLuz2XRTTC+A6k5lQej39y3d o5Sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=n6t/pfc0M41ToUc5HflmTh98LQ2xLoF6/7gvlW5ZK2Q=; b=FHkmyE6B/1Dh187i8Fpq6O+gcPB/BtFXXCN4zHKQv216t00PlhO3noSPz0TYyaSS87 JhIZV0NTn9JtlhtrhBrAR2Fq1m7RBUsEjGlAuk1qc5+pU6RO8ah8yK4bxBeLbdmniXej IkU9oYlcaCTTdhO98TjOsZ0uVGVF2rnBt+rhRpfvC85rXOrVbnVlbae8mRYx6wgnz5i/ Mj2YWPwAqsrqv0sxc5JUTp5bDzHZXHfo1WS+84zXXI/qnDxL0EMFEtaA/Kc+UG8YKg7L BLGcDhBNWtNaf4Z3IiZEO4sIcBYlCyLG2zltolNKv5Mk3sWcCDW9CQG42cbiCqlZqIkv CQ7g== X-Gm-Message-State: ACgBeo3RqrVp/4O3QT8XvzavcLyA6YG5HOnmmF/fUMnE/ICtKbyIfCBj HzMUsS7uZ42Q9+2afF/WigHhl8pWvYm0 X-Google-Smtp-Source: AA6agR74CvzVSNoMfgJMhkgoW3tzfGVsYV/loT9yHflje8Np4KrnICz0V3tzbIuEozNJGPQW5nvajE6RSnDh X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a25:aa2e:0:b0:674:d1f6:4480 with SMTP id s43-20020a25aa2e000000b00674d1f64480mr1535820ybi.591.1659080649673; Fri, 29 Jul 2022 00:44:09 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:37 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-4-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 03/17] perf jevents: Add JEVENTS_ARCH make option From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow the architecture built into pmu-events.c to be set on the make command line with JEVENTS_ARCH. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/Build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build index 28a9d01b08af..04ef95174660 100644 --- a/tools/perf/pmu-events/Build +++ b/tools/perf/pmu-events/Build @@ -7,6 +7,10 @@ JSON_TEST =3D $(shell [ -d $(JDIR_TEST) ] && \ find $(JDIR_TEST) -name '*.json') JEVENTS_PY =3D pmu-events/jevents.py =20 +ifeq ($(JEVENTS_ARCH),) +JEVENTS_ARCH=3D$(SRCARCH) +endif + # # Locate/process JSON files in pmu-events/arch/ # directory and create tables in pmu-events.c. @@ -19,5 +23,5 @@ $(OUTPUT)pmu-events/pmu-events.c: pmu-events/empty-pmu-ev= ents.c else $(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(SRCARCH) pmu-events/arc= h $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) pmu-event= s/arch $@ endif --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CC41C00144 for ; Fri, 29 Jul 2022 07:44:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235042AbiG2Ho1 (ORCPT ); Fri, 29 Jul 2022 03:44:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234988AbiG2HoR (ORCPT ); Fri, 29 Jul 2022 03:44:17 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E258814BF for ; Fri, 29 Jul 2022 00:44:12 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id m123-20020a253f81000000b0066ff6484995so3298838yba.22 for ; Fri, 29 Jul 2022 00:44:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=EjcW2819bK3ME3rSbBlXh7xG57ULhBVjyEq6SCnJgHs=; b=Q+jaj+dVmVWsljBSPYTpmdqOXVicg9AGaWh1ve7iGaro2yUiFb9EbEpzlHcUumAh+I birhsTaWS7VUc7Ai6egLJUB6iZ9Y8q7Gw/NOCuivCXrSPl1guInU8wHgfLMyGyRcpJOU jiomfTWcm8zrpnK7X91SWa2YQa4i4XnHrXT4245hwxHM00pdOsQW+5RrBkEj02Os8EMS 9ylCnAe2AzstfykP8LDN7qEGUb0Ir3430t2OU3y4nRGWOGq2mpK3G+p6AiPzKGTwlkSX cTdC1uG/nZ8rsBIG4s+DFbJMETYZ3xw7GQME93y0np2DMlSDFmpD890446EhAweaY4Ce NNJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=EjcW2819bK3ME3rSbBlXh7xG57ULhBVjyEq6SCnJgHs=; b=H83G6oJZdNW0wA4kMB8HXnF2bQtlzJuF/1d0JroNYtHRg09sB7K7Gad1UG18MOhG8R 8Omwm4MSHlWVErPtJ7OsfqNu7uJ8bukJWMp8/qqTy3z5C8Q7YU4sqnv0nn/3cPbcBPs4 4DsaQ2KiUn8sAgibt3IPy4PXqVkdFGq7n37W/LVS2ttYmbOm4XynVHhquCWPO7Bu91Tw k9y5eCGBmleJ/jN45v3CaPFwOYdQWZtN/s4b49nfWlN212XJK6nFTpDoMvcLZ4YshRSM tNMGk/Oj0RlO1hCbiToxj3eLkc9UfIC1mI6HSmnyfQ/AZJ9E0haem1MtJVyCsevJVEy4 tU4Q== X-Gm-Message-State: ACgBeo152Ne6LGYpzMIrUCWLzjkotzBCoP2hMJkK+iw/y2zI1QFmH9v6 QGDTMOIjb4TUEb4VlxFK3RRqXk95mGdP X-Google-Smtp-Source: AA6agR7FJFm/zePAwFdaLuEQB8H/PqGRX8IU3YjwZixunkmchzQY1GHOYMRcP36hjVCwrEMBWBNzE4eKg1XC X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a25:19d5:0:b0:670:7c04:8593 with SMTP id 204-20020a2519d5000000b006707c048593mr1551592ybz.95.1659080652160; Fri, 29 Jul 2022 00:44:12 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:38 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-5-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 04/17] perf jevent: Add an 'all' architecture argument From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When 'all' is passed as the architecture generate a mapping table for all architectures. This simplifies testing. To identify the table for an architecture add an arch variable to the pmu_events_map. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 70 ++++++++++++++++++------------ tools/perf/pmu-events/pmu-events.h | 1 + tools/perf/tests/pmu-events.c | 3 +- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index cdfa4e0e7557..e6e6c42c3f8a 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -304,38 +304,45 @@ def process_one_file(parents: Sequence[str], item: os= .DirEntry) -> None: print_events_table_entries(item, get_topic(item.name)) =20 =20 -def print_mapping_table() -> None: +def print_mapping_table(archs: Sequence[str]) -> None: """Read the mapfile and generate the struct from cpuid string to event t= able.""" - with open(f'{_args.starting_dir}/{_args.arch}/mapfile.csv') as csvfile: - table =3D csv.reader(csvfile) - _args.output_file.write( - 'const struct pmu_events_map pmu_events_map[] =3D {\n') - first =3D True - for row in table: - # Skip the first row or any row beginning with #. - if not first and len(row) > 0 and not row[0].startswith('#'): - tblname =3D file_name_to_table_name([], row[2].replace('/', '_')) - _args.output_file.write("""{ -\t.cpuid =3D \"%s\", -\t.version =3D \"%s\", -\t.type =3D \"%s\", -\t.table =3D %s -}, -""" % (row[0].replace('\\', '\\\\'), row[1], row[3], tblname)) - first =3D False - - _args.output_file.write("""{ + _args.output_file.write('const struct pmu_events_map pmu_events_map[] = =3D {\n') + for arch in archs: + if arch =3D=3D 'test': + _args.output_file.write("""{ +\t.arch =3D "testarch", \t.cpuid =3D "testcpu", \t.version =3D "v1", \t.type =3D "core", \t.table =3D pme_test_soc_cpu, }, -{ +""") + else: + with open(f'{_args.starting_dir}/{arch}/mapfile.csv') as csvfile: + table =3D csv.reader(csvfile) + first =3D True + for row in table: + # Skip the first row or any row beginning with #. + if not first and len(row) > 0 and not row[0].startswith('#'): + tblname =3D file_name_to_table_name([], row[2].replace('/', '_= ')) + cpuid =3D row[0].replace('\\', '\\\\') + _args.output_file.write(f"""{{ +\t.arch =3D "{arch}", +\t.cpuid =3D "{cpuid}", +\t.version =3D "{row[1]}", +\t.type =3D "{row[3]}", +\t.table =3D {tblname} +}}, +""") + first =3D False + + _args.output_file.write("""{ +\t.arch =3D 0, \t.cpuid =3D 0, \t.version =3D 0, \t.type =3D 0, \t.table =3D 0, -}, +} }; """) =20 @@ -386,15 +393,24 @@ def main() -> None: _args =3D ap.parse_args() =20 _args.output_file.write("#include \"pmu-events/pmu-events.h\"\n") - for path in [_args.arch, 'test']: - arch_path =3D f'{_args.starting_dir}/{path}' - if not os.path.isdir(arch_path): - raise IOError(f'Missing architecture directory in \'{arch_path}\'') + archs =3D [] + for item in os.scandir(_args.starting_dir): + if not item.is_dir(): + continue + if item.name =3D=3D _args.arch or _args.arch =3D=3D 'all' or item.name= =3D=3D 'test': + archs.append(item.name) + + if len(archs) < 2: + raise IOError(f'Missing architecture directory \'{_args.arch}\'') + + archs.sort() + for arch in archs: + arch_path =3D f'{_args.starting_dir}/{arch}' preprocess_arch_std_files(arch_path) ftw(arch_path, [], process_one_file) print_events_table_suffix() =20 - print_mapping_table() + print_mapping_table(archs) print_system_mapping_table() =20 =20 diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 6efe73976440..7a360792635f 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -38,6 +38,7 @@ struct pmu_event { * The cpuid can contain any character other than the comma. */ struct pmu_events_map { + const char *arch; const char *cpuid; const char *version; const char *type; /* core, uncore etc */ diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 263cbb67c861..82192f1a7bf7 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -864,8 +864,7 @@ static void expr_failure(const char *msg, const struct pmu_events_map *map, const struct pmu_event *pe) { - pr_debug("%s for map %s %s %s\n", - msg, map->cpuid, map->version, map->type); + pr_debug("%s for map %s %s\n", msg, map->arch, map->cpuid); pr_debug("On metric %s\n", pe->metric_name); pr_debug("On expression %s\n", pe->metric_expr); } --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06E00C19F2A for ; Fri, 29 Jul 2022 07:44:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234966AbiG2Hof (ORCPT ); Fri, 29 Jul 2022 03:44:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235026AbiG2HoS (ORCPT ); Fri, 29 Jul 2022 03:44:18 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC01E81B03 for ; Fri, 29 Jul 2022 00:44:14 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-317f6128c86so36331427b3.22 for ; Fri, 29 Jul 2022 00:44:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=0p5UtNhgly+OTzkIJIIsc2EA2UcuBV0UctPUvpqsf3w=; b=m8bPlFQpgLYJUbB+UeU3eNFKTszNzcYKPY4sMWEB4i8lPeEdHF1ko8hWyRi7g6lflv +OsMGJFc6EY6Oy2kIuGOxIFqAaorn1NeHpngcC6WNYuMY22GpCAK+IRSYroXU0SP3sLG VKp0QcUBs8jzqjp/66l8mYymCba/9iFJmqatIxgyuwIc6GMe2mhND79XxhWDZ8PT5/mq pawV8GV2vnCV7YY6jaXHOG3hjx6Q3jPSrjZRuxZCmmrwEzZ9i2l+CbXRkN5aVDeR5/PO flR+ilwXLJDqxXYCf1af4n+QE4YDuze779KGRZtKigtjGnhg3othnTFwB5P40oXX53Fn 22kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=0p5UtNhgly+OTzkIJIIsc2EA2UcuBV0UctPUvpqsf3w=; b=XxbHl9HRbr/PMe6UEKy3BS8vubriqytHr1Ch53JW7gXFDucBdYX1vw2jFqrymD1KuP t6SvJLV6MFc2ICTcDkFSqa2k9PYQOlkQIMB6NKny5aiiUcJl3tcKV4MQGHobM3VJ8PMn s+eNMbA5Vztx6SI59asDfqsTq5rX6cLX6auPJGu3Fg1JN3Zu3cLtgjc/aLELxkARpF4t sxLElW4jWsSAnOOykBph78p0mAD46u5WXUm1hfOd0Jfb9c9Y6vxVLEyGZp5TCPZ6YRMZ qGRjy9du+B5mNl2dbiCxOXarn2kx/3lJxhtN0StAclk50hGNVc3UHSgERcUxqoyCdDiq xEQA== X-Gm-Message-State: ACgBeo0/LbIIyy5i3z/ga/FPNd8586NKxZJZAuik+TTYA776LPgZ9ZRW S7jKrie8ImHwUc38Ee1WG9Wydkf6VMo/ X-Google-Smtp-Source: AA6agR5UupBuBpyx9U7oV6Zn/0T9hjA3Obc+2V2iQvV2q7Rr0iTRvbk9/ckSXIRERBkQ06cuJvrB/n2XF+Of X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a05:6902:ce:b0:670:82dd:d174 with SMTP id i14-20020a05690200ce00b0067082ddd174mr1627428ybs.76.1659080654685; Fri, 29 Jul 2022 00:44:14 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:39 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-6-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 05/17] perf jevents: Remove the type/version variables From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" pmu_events_map has a type variable that is always initialized to "core" and a version variable that is never read. Remove these from the API as it is straightforward to add them back when necessary. Signed-off-by: Ian Rogers Reviewed-by: John Garry --- tools/perf/pmu-events/empty-pmu-events.c | 6 ++---- tools/perf/pmu-events/jevents.py | 6 ------ tools/perf/pmu-events/pmu-events.h | 2 -- tools/perf/tests/expand-cgroup.c | 2 -- tools/perf/tests/parse-metric.c | 2 -- 5 files changed, 2 insertions(+), 16 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 77e655c6f116..4182a986f505 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -110,15 +110,13 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { =20 const struct pmu_events_map pmu_events_map[] =3D { { + .arch =3D "testarch", .cpuid =3D "testcpu", - .version =3D "v1", - .type =3D "core", .table =3D pme_test_soc_cpu, }, { + .arch =3D 0, .cpuid =3D 0, - .version =3D 0, - .type =3D 0, .table =3D 0, }, }; diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index e6e6c42c3f8a..98d18d5c3830 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -312,8 +312,6 @@ def print_mapping_table(archs: Sequence[str]) -> None: _args.output_file.write("""{ \t.arch =3D "testarch", \t.cpuid =3D "testcpu", -\t.version =3D "v1", -\t.type =3D "core", \t.table =3D pme_test_soc_cpu, }, """) @@ -329,8 +327,6 @@ def print_mapping_table(archs: Sequence[str]) -> None: _args.output_file.write(f"""{{ \t.arch =3D "{arch}", \t.cpuid =3D "{cpuid}", -\t.version =3D "{row[1]}", -\t.type =3D "{row[3]}", \t.table =3D {tblname} }}, """) @@ -339,8 +335,6 @@ def print_mapping_table(archs: Sequence[str]) -> None: _args.output_file.write("""{ \t.arch =3D 0, \t.cpuid =3D 0, -\t.version =3D 0, -\t.type =3D 0, \t.table =3D 0, } }; diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 7a360792635f..a491b117c8ac 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -40,8 +40,6 @@ struct pmu_event { struct pmu_events_map { const char *arch; const char *cpuid; - const char *version; - const char *type; /* core, uncore etc */ const struct pmu_event *table; }; =20 diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index dfefe5b60eb2..dc4038f997d7 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -197,8 +197,6 @@ static int expand_metric_events(void) }; const struct pmu_events_map ev_map =3D { .cpuid =3D "test", - .version =3D "1", - .type =3D "core", .table =3D pme_test, }; =20 diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 07b6f4ec024f..1b811a26f4ee 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -81,8 +81,6 @@ static struct pmu_event pme_test[] =3D { =20 static const struct pmu_events_map map =3D { .cpuid =3D "test", - .version =3D "1", - .type =3D "core", .table =3D pme_test, }; =20 --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D06AC00144 for ; Fri, 29 Jul 2022 07:44:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235128AbiG2Hoj (ORCPT ); Fri, 29 Jul 2022 03:44:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53544 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234694AbiG2HoS (ORCPT ); Fri, 29 Jul 2022 03:44:18 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51D6781B2C for ; Fri, 29 Jul 2022 00:44:17 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id m11-20020a5b040b000000b0066fcc60d1a0so3287694ybp.19 for ; Fri, 29 Jul 2022 00:44:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=mqNHYsVWGj0fcO4+XKl+I9RLjcmp/sKEanarsLP2wxg=; b=RJcVJE+hnyZrLqpNeLhiP9SbUZi5PF1h2Xz8hG5gfDrto2ZQvRbIcC6+pAXjRuhbXS hxf5W34jXcMzU2CSQeY4iX89QrtXGzGakLrL+jut524o4UiZznud+g/U7dnxxAqrqlQT pzXDXlpBwMSb0l3uxn+/I7DzOr+PXPhV5f2aefc12bYS8AsaCHGNI7SYJli4tevGjywb sjAke3+r/1BZzyPlQMjKvu4ZlUqYoJZIcGX2HFRv2ByMovs9934a832sOvC4E/EY360c Z9KwuNdsFQwBBf5wGlduUlXAcoWQRtqSha80ussn7tI3v6pjtpcTMvkdeP2C/mBzt5DT vnJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=mqNHYsVWGj0fcO4+XKl+I9RLjcmp/sKEanarsLP2wxg=; b=EVuL8Q1+cUP3X/SJ3gSPA/f+DubrJSsygUiHBR6OgpBjXUBxCpnqm2tNtE/r9eRq0U oaoNrPTsHvNVYMpjzp5gHPuTO1tYEbfuUxoJKpaagE6AdxOkv2GswfGbEDaRZSogJuat CJ2ExNQpZ2fIQAKfOcFGvGwOx0bkv1J7EmljvL/MQY8THOMtbYPuZmkmIyxkKTdybOsF fxY+0tE0cpinM9dM6w6ZWGASs8Un6IcdKmOf1XWl39zqO/PrvJNQug7Sod80BJod/9ji DIgnEaP8Agoqikk2pAJqR80BGOJRD3V305c5Io9IkSAEeDv56oXnrK/+fOMk9b9Gj9bS 3n5A== X-Gm-Message-State: ACgBeo3yi7Ocm5sTdEzbKBKDkpYw3MEZ/QQ+yITnhbOxRLbU6Ivglpd7 XufqCzYHJzcg//5MThipbzIsANJHD6Gx X-Google-Smtp-Source: AA6agR5bkDJ5EE78BgJwxPU+WAXWDt1bh9VDrLedHC8RwnOPxWMaMu2tKQ6y1risxyc6dYbK0QDT6tXW0iKG X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a0d:c602:0:b0:31c:822a:c168 with SMTP id i2-20020a0dc602000000b0031c822ac168mr2198798ywd.134.1659080657058; Fri, 29 Jul 2022 00:44:17 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:40 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-7-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 06/17] perf jevents: Provide path to json file on error From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If a JSONDecoderError or similar is raised then it is useful to know the path. Print this and then raise the exception agan. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 98d18d5c3830..12d2daf3570c 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -224,7 +224,12 @@ class JsonEvent: =20 def read_json_events(path: str) -> Sequence[JsonEvent]: """Read json events from the specified file.""" - return json.load(open(path), object_hook=3Dlambda d: JsonEvent(d)) + + try: + return json.load(open(path), object_hook=3Dlambda d: JsonEvent(d)) + except BaseException as err: + print(f"Exception processing {path}") + raise =20 =20 def preprocess_arch_std_files(archpath: str) -> None: --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0866EC3F6B0 for ; Fri, 29 Jul 2022 07:44:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235164AbiG2Hoo (ORCPT ); Fri, 29 Jul 2022 03:44:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235061AbiG2HoV (ORCPT ); Fri, 29 Jul 2022 03:44:21 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58E877CB68 for ; Fri, 29 Jul 2022 00:44:20 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id c21-20020a624e15000000b0052abf43401fso1639838pfb.14 for ; Fri, 29 Jul 2022 00:44:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=3yOwoFZ3Wf3i4mCbDyBSkX0NefzV6upIW3aFDzVLgcY=; b=XWlzqABpM6mfUKHqdgs03Q1OMATyLjTsT+obDuGtUoYQ2Suf2CieHkfRGSuBk1qCQK Z46IBmlwp0snGR8PF6G3rEx+eyM/ooZGwfJW5c9kwfQJu5Nt70RO1H+DIQB6skalORNq bGzIvYaFCAXGHbNgsrUYxVgjSz8OLHmNtmkOoe+6A5YrHwEqFHyi8we11fObjVt6S/C8 6Zg/qKT7coGx4Fp2xCxAN/Odl7C6L6nOkddiN3Xaju1DvmFhrwnqaPxprBUpOdECobUe M3+xJVc0ROzH332G6SyXz+AQhsv9Ulan8vnh/pb3n7tS8CIQ/JGH1gZra1+1IRThykpB cauA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=3yOwoFZ3Wf3i4mCbDyBSkX0NefzV6upIW3aFDzVLgcY=; b=NugwnXSxYeXqWd1u2Rxev0cTvXPlLWYPzRF9+OcbZHLF+EBlbmrbnic0dmu/i7Yi6z l16+3U7D3EjSiZI434ZHk4QAH+1IrJpDI0h5b5F88HqAlVVzB3qY2pxr79cL75iN6yik h1NkqYymGDfOA2hKkd7HJIPMLE0iqTweyre8Cy8o1xDrBIJbWQUhPZfBMosmEWZbGb0d pbf0aPcQK4rn/Rm1nhoVW4vghZouIDQu+X53Xw11OEyZ4PAbiXHfgwKrIqnRPIj5fVfn /E+b9YA45Y7GZ8+2JhTLi1wJ0c1W2dJQDD4wL87JOYLO7g4Lf2bDu42203Ttp91pFr6n omCA== X-Gm-Message-State: ACgBeo05kw1E4hi2b0DYKY58yivJ7CiM14A4oAwnLhV80BHPUOxJ9t3d sVI6xT2Ek5IsS9MUpt8mR57DAYR6ooKl X-Google-Smtp-Source: AA6agR4X2OdUFG3Qzn8PCM8EFybFzGARwPe8r1WhL3LwDYzR0P8x9tl8f4DrUGUCiSqSNOhjh2ZjnCQFRyF6 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a17:90a:94c2:b0:1f3:2590:8693 with SMTP id j2-20020a17090a94c200b001f325908693mr3400234pjw.153.1659080659864; Fri, 29 Jul 2022 00:44:19 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:41 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-8-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 07/17] perf jevents: Sort json files entries From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Sort the json files entries on conversion to C. The sort order tries to replicated cmp_sevent from pmu.c so that the input there is already sorted except for sysfs events. Add the topic to JsonEvent on reading to simplify. Remove an unnecessary lambda in the json reading. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 48 +++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 12d2daf3570c..30e0e792221a 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -18,6 +18,8 @@ _sys_event_tables =3D [] _arch_std_events =3D {} # Track whether an events table is currently being defined and needs closi= ng. _close_table =3D False +# Events to write out when the table is closed +_pending_events =3D [] =20 =20 def removesuffix(s: str, suffix: str) -> str: @@ -127,6 +129,7 @@ class JsonEvent: eventcode |=3D int(jd['ExtSel']) << 8 configcode =3D int(jd['ConfigCode'], 0) if 'ConfigCode' in jd else None self.name =3D jd['EventName'].lower() if 'EventName' in jd else None + self.topic =3D '' self.compat =3D jd.get('Compat') self.desc =3D fixdesc(jd.get('BriefDescription')) self.long_desc =3D fixdesc(jd.get('PublicDescription')) @@ -199,7 +202,7 @@ class JsonEvent: s +=3D f'\t{attr} =3D {value},\n' return s + '}' =20 - def to_c_string(self, topic_local: str) -> str: + def to_c_string(self) -> str: """Representation of the event as a C struct initializer.""" =20 def attr_string(attr: str, value: str) -> str: @@ -211,25 +214,27 @@ class JsonEvent: return attr_string(attr, getattr(self, attr)) =20 s =3D '{\n' - s +=3D f'\t.topic =3D "{topic_local}",\n' for attr in [ 'aggr_mode', 'compat', 'deprecated', 'desc', 'event', 'long_desc', 'metric_constraint', 'metric_expr', 'metric_group', 'metric_name', - 'name', 'perpkg', 'pmu', 'unit' + 'name', 'perpkg', 'pmu', 'topic', 'unit' ]: s +=3D str_if_present(self, attr) s +=3D '},\n' return s =20 =20 -def read_json_events(path: str) -> Sequence[JsonEvent]: +def read_json_events(path: str, topic: str) -> Sequence[JsonEvent]: """Read json events from the specified file.""" =20 try: - return json.load(open(path), object_hook=3Dlambda d: JsonEvent(d)) + result =3D json.load(open(path), object_hook=3DJsonEvent) except BaseException as err: print(f"Exception processing {path}") raise + for event in result: + event.topic =3D topic + return result =20 =20 def preprocess_arch_std_files(archpath: str) -> None: @@ -237,7 +242,7 @@ def preprocess_arch_std_files(archpath: str) -> None: global _arch_std_events for item in os.scandir(archpath): if item.is_file() and item.name.endswith('.json'): - for event in read_json_events(item.path): + for event in read_json_events(item.path, topic=3D''): if event.name: _arch_std_events[event.name.lower()] =3D event =20 @@ -251,19 +256,36 @@ def print_events_table_prefix(tblname: str) -> None: _close_table =3D True =20 =20 -def print_events_table_entries(item: os.DirEntry, topic: str) -> None: - """Create contents of an events table.""" +def add_events_table_entries(item: os.DirEntry, topic: str) -> None: + """Add contents of file to _pending_events table.""" if not _close_table: raise IOError('Table entries missing prefix') - for event in read_json_events(item.path): - _args.output_file.write(event.to_c_string(topic)) + for e in read_json_events(item.path, topic): + _pending_events.append(e) =20 =20 def print_events_table_suffix() -> None: """Optionally close events table.""" + + def event_cmp_key(j: JsonEvent): + def fix_none(s: str): + if s is None: + return '' + return s + + return (not j.desc is None, fix_none(j.topic), fix_none(j.name), fix_n= one(j.pmu), + fix_none(j.metric_name)) + global _close_table - if _close_table: - _args.output_file.write("""{ + if not _close_table: + return + + global _pending_events + for event in sorted(_pending_events, key=3Devent_cmp_key): + _args.output_file.write(event.to_c_string()) + _pending_events =3D [] + + _args.output_file.write("""{ \t.name =3D 0, \t.event =3D 0, \t.desc =3D 0, @@ -306,7 +328,7 @@ def process_one_file(parents: Sequence[str], item: os.D= irEntry) -> None: if not item.is_file() or not item.name.endswith('.json'): return =20 - print_events_table_entries(item, get_topic(item.name)) + add_events_table_entries(item, get_topic(item.name)) =20 =20 def print_mapping_table(archs: Sequence[str]) -> None: --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83ED0C00144 for ; Fri, 29 Jul 2022 07:44:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235175AbiG2Hor (ORCPT ); Fri, 29 Jul 2022 03:44:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53534 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235023AbiG2HoY (ORCPT ); Fri, 29 Jul 2022 03:44:24 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CC04814BF for ; Fri, 29 Jul 2022 00:44:23 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-3238ce833beso20326217b3.11 for ; Fri, 29 Jul 2022 00:44:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=5r7KpXClmZzIJUu6VoWF+PxBHcALGulwqyZkCHJz+dc=; b=L9UT7pFKEMv8kmhKTFboeMQHgbNjypzxWtClefHRJXeuk7El88DNhUGL4PqSb2pxBt UUcOzUDVOnbLXDk7ADQF8gwzoy0tFbnIJQoWp00c6r1J4xo8jWshWT4mpOhestPPnV2m 31p0htLfJiSCQ2GcnIhA8XjMPzhJ6UF1OOS72tmsudDUX5X5uOjGU4aDnEPbBzQtFfPR h9/FepigXVjZTiyqlOKgRSaq9TO9PIy2rPBTb5Jiuxn3ceLTiENmnJj2kVS37+Xg+5sN C+JZfVZ4SXaxQMf/IsC0qlPUQKGYUPG8J+i1wpIpv4uwKIjNgz+tD/cTlkJWh3krAyHJ duMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=5r7KpXClmZzIJUu6VoWF+PxBHcALGulwqyZkCHJz+dc=; b=cIo6NY6WIGoUfZdE1CsXixOg7nMZ8Xm8ISYV7v16+4ndF18YqLKkRWJb5xhszpmWms euaI+6qTBdCjePKikC3yzOSFtmGesxlfxITIDRazZXU4HDWOyuJ6WisC8xj7YDs1o/Q7 jhmDU0ZbGEPUNjN2WiR6LcD+AMJu9oEiTgtAOPR42U+ZkNcfFpSL+uzp3LM4IIUacRly YhU41idizI/HcDY7tljk4enfMwgw+1VUj3/dSprqwpEp6jgVx4cawYe9UkwDIthjM+aU RhAXQzyRzMGF7YRluouTcDX4DtqwRDUsx5cYPCPsZ+3rdgfpJHvKkera51ilI9Xqzm7T QUFw== X-Gm-Message-State: ACgBeo1cGq+HHGOqW3ad9f2I1IxR5iX/pClN+6MC+NGhsFVmMpFiP+dY rA4yvlELIPYdqmGwyqU+wbnxAlS1M/VI X-Google-Smtp-Source: AA6agR4lvVMHfSoejMkozQjmS9qJTDKTwsU5cAD6r+dvPCEB7yVOfvYBAS7Y09yz2U8G7/kdQP/Wm9mQYGrh X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a25:41d6:0:b0:673:817c:e163 with SMTP id o205-20020a2541d6000000b00673817ce163mr1461338yba.561.1659080662475; Fri, 29 Jul 2022 00:44:22 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:42 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-9-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 08/17] perf pmu-events: Hide pmu_sys_event_tables From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move usage of the table to pmu-events.c so it may be hidden. By abstracting the table the implementation can later be changed. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 37 ++++++++++++++++++- tools/perf/pmu-events/jevents.py | 45 ++++++++++++++++++++++-- tools/perf/pmu-events/pmu-events.h | 11 +++--- tools/perf/tests/pmu-events.c | 14 +------- tools/perf/util/pmu.c | 27 -------------- tools/perf/util/pmu.h | 2 -- 6 files changed, 84 insertions(+), 52 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 4182a986f505..216ea0482c37 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -6,6 +6,8 @@ * The test cpu/soc is provided for testing. */ #include "pmu-events/pmu-events.h" +#include +#include =20 static const struct pmu_event pme_test_soc_cpu[] =3D { { @@ -145,7 +147,12 @@ static const struct pmu_event pme_test_soc_sys[] =3D { }, }; =20 -const struct pmu_sys_events pmu_sys_event_tables[] =3D { +struct pmu_sys_events { + const char *name; + const struct pmu_event *table; +}; + +static const struct pmu_sys_events pmu_sys_event_tables[] =3D { { .table =3D pme_test_soc_sys, .name =3D "pme_test_soc_sys", @@ -154,3 +161,31 @@ const struct pmu_sys_events pmu_sys_event_tables[] =3D= { .table =3D 0 }, }; + +const struct pmu_event *find_sys_events_table(const char *name) +{ + for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; + tables->name; + tables++) { + if (!strcmp(tables->name, name)) + return tables->table; + } + return NULL; +} + +int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) +{ + for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; + tables->name; + tables++) { + for (const struct pmu_event *pe =3D &tables->table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, data); + + if (ret) + return ret; + } + } + return 0; +} diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 30e0e792221a..dd21bc9eeeed 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -370,8 +370,14 @@ def print_mapping_table(archs: Sequence[str]) -> None: =20 def print_system_mapping_table() -> None: """C struct mapping table array for tables from /sys directories.""" - _args.output_file.write( - '\nconst struct pmu_sys_events pmu_sys_event_tables[] =3D {\n') + _args.output_file.write(""" +struct pmu_sys_events { +\tconst char *name; +\tconst struct pmu_event *table; +}; + +static const struct pmu_sys_events pmu_sys_event_tables[] =3D { +""") for tblname in _sys_event_tables: _args.output_file.write(f"""\t{{ \t\t.table =3D {tblname}, @@ -382,6 +388,34 @@ def print_system_mapping_table() -> None: \t\t.table =3D 0 \t}, }; + +const struct pmu_event *find_sys_events_table(const char *name) +{ + for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; + tables->name; + tables++) { + if (!strcmp(tables->name, name)) + return tables->table; + } + return NULL; +} + +int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) +{ + for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; + tables->name; + tables++) { + for (const struct pmu_event *pe =3D &tables->table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, data); + + if (ret) + return ret; + } + } + return 0; +} """) =20 =20 @@ -413,7 +447,12 @@ def main() -> None: 'output_file', type=3Dargparse.FileType('w'), nargs=3D'?', default= =3Dsys.stdout) _args =3D ap.parse_args() =20 - _args.output_file.write("#include \"pmu-events/pmu-events.h\"\n") + _args.output_file.write(""" +#include "pmu-events/pmu-events.h" +#include +#include + +""") archs =3D [] for item in os.scandir(_args.starting_dir): if not item.is_dir(): diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index a491b117c8ac..2386212b1df0 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -43,16 +43,15 @@ struct pmu_events_map { const struct pmu_event *table; }; =20 -struct pmu_sys_events { - const char *name; - const struct pmu_event *table; -}; - /* * Global table mapping each known CPU for the architecture to its * table of PMU events. */ extern const struct pmu_events_map pmu_events_map[]; -extern const struct pmu_sys_events pmu_sys_event_tables[]; + +const struct pmu_event *find_sys_events_table(const char *name); + +typedef int (*pmu_event_iter_fn)(const struct pmu_event *pe, void *data); +int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data); =20 #endif diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 82192f1a7bf7..a39a2c99ede6 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -286,18 +286,6 @@ static const struct pmu_events_map *__test_pmu_get_eve= nts_map(void) return NULL; } =20 -static const struct pmu_event *__test_pmu_get_sys_events_table(void) -{ - const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; - - for ( ; tables->name; tables++) { - if (!strcmp("pme_test_soc_sys", tables->name)) - return tables->table; - } - - return NULL; -} - static int compare_pmu_events(const struct pmu_event *e1, const struct pmu= _event *e2) { if (!is_same(e1->name, e2->name)) { @@ -451,7 +439,7 @@ static int compare_alias_to_test_event(struct perf_pmu_= alias *alias, static int test__pmu_event_table(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_event *sys_event_tables =3D __test_pmu_get_sys_events_ta= ble(); + const struct pmu_event *sys_event_tables =3D find_sys_events_table("pme_t= est_soc_sys"); const struct pmu_events_map *map =3D __test_pmu_get_events_map(); const struct pmu_event *table; int map_events =3D 0, expected_events; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 0112e1c36418..d8717c4548a4 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -868,33 +868,6 @@ static void pmu_add_cpu_aliases(struct list_head *head= , struct perf_pmu *pmu) pmu_add_cpu_aliases_map(head, pmu, map); } =20 -void pmu_for_each_sys_event(pmu_sys_event_iter_fn fn, void *data) -{ - int i =3D 0; - - while (1) { - const struct pmu_sys_events *event_table; - int j =3D 0; - - event_table =3D &pmu_sys_event_tables[i++]; - - if (!event_table->table) - break; - - while (1) { - const struct pmu_event *pe =3D &event_table->table[j++]; - int ret; - - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - - ret =3D fn(pe, data); - if (ret) - break; - } - } -} - struct pmu_sys_event_iter_data { struct list_head *head; struct perf_pmu *pmu; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 4b45fd8da5a3..7e667eec2a01 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -133,8 +133,6 @@ const struct pmu_events_map *pmu_events_map__find(void); bool pmu_uncore_alias_match(const char *pmu_name, const char *name); void perf_pmu_free_alias(struct perf_pmu_alias *alias); =20 -typedef int (*pmu_sys_event_iter_fn)(const struct pmu_event *pe, void *dat= a); -void pmu_for_each_sys_event(pmu_sys_event_iter_fn fn, void *data); int perf_pmu__convert_scale(const char *scale, char **end, double *sval); =20 int perf_pmu__caps_parse(struct perf_pmu *pmu); --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2890BC00144 for ; Fri, 29 Jul 2022 07:45:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235353AbiG2HpU (ORCPT ); Fri, 29 Jul 2022 03:45:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54600 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235079AbiG2Hoz (ORCPT ); Fri, 29 Jul 2022 03:44:55 -0400 Received: from mail-ot1-x349.google.com (mail-ot1-x349.google.com [IPv6:2607:f8b0:4864:20::349]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A36A4820E1 for ; Fri, 29 Jul 2022 00:44:36 -0700 (PDT) Received: by mail-ot1-x349.google.com with SMTP id d21-20020a056830045500b0061c9e620f7aso1649636otc.22 for ; Fri, 29 Jul 2022 00:44:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=VXhSTEVkI/CrVpUsFXZjiJMJG+T/lVKu57GVikOUMIo=; b=iDZ3RzuaMriM5TbNinn1vfx+4YjiSrq8msuoETb7vN7iMAtNVYGzBJttomfm6TQxHm vnTIn53H6xSQS5vtv93vVsmvr2DBX5QGrkT/JKrgNkD2CsdBjr61yaKbmE2BIS9WQ797 mkfIzCSojoWWaTPtY4ZqiJUrGQiVzmxLBBAp3veXxKglJGk3x97+ITRVSGRguyjcKoEf loMn/iMPQAj8pd3Yd8HEieMRpcNL08ED/B5N9UFzQx4Uc0zgSEdB5wL3882XpQT6xykw iSvqCSSpAuycAAp736uCerBI8I1isiihh/LFUZEVNErMv1vu/JBmZ1GkkKGrMZLB4uMd h8dA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=VXhSTEVkI/CrVpUsFXZjiJMJG+T/lVKu57GVikOUMIo=; b=IykdZsM5HqL0TcDSwQFHJykQMf/GmywySrtxLd4iRIJMO59LYBuOsBkubv8MGZDjtA LRAMuAco/zmrLMgNrYYY1FRLd6Cxl9tubCI7OtXukMf2b1q4tey6qgSQw7Wgvi94aPV6 68xHOkMmEjb/bG7uy7FAXbZBlEtrPgazYVoldBFUmXsz00AJj/BudpOq//P1zAp2xWrN VuZnRM+8SecyAnHHBlZBVkpdBe50s7f9MwJs5aI/Mqjgn58eFDIJakpv4WRAEOhS/Z2h 9bzQYAZnv8VfBaoDNZk0nfovp774oaCyQ5DkxoI092b4TutzxgL+yishs+dYNzfKB/3c X7rw== X-Gm-Message-State: AJIora/KT7Thy48wLYXvL7utT19f0UnUdV08OPFkAB75NeFuLTcLBAfN UZ1p9zidghyI2HsFz364tXp7xSM3Inyg X-Google-Smtp-Source: AA6agR79M5lTtcVXR8ESBr+LElXJ1o823HAgMQZYQYcmdLpTy26roPZ3fJB+0HnULpZ7kBasw2XCKEIQmjl7 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a25:a41:0:b0:673:746:76ef with SMTP id 62-20020a250a41000000b00673074676efmr1702620ybk.132.1659080665126; Fri, 29 Jul 2022 00:44:25 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:43 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-10-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 09/17] perf pmu-events: Avoid passing pmu_events_map From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Preparation for hiding pmu_events_map as an implementation detail. While the map is passed, the table of events is all that is normally wanted. Signed-off-by: Ian Rogers --- tools/perf/arch/arm64/util/pmu.c | 4 +- tools/perf/tests/expand-cgroup.c | 6 +-- tools/perf/tests/parse-metric.c | 7 +-- tools/perf/tests/pmu-events.c | 63 +++++++++++------------- tools/perf/util/metricgroup.c | 82 +++++++++++++++---------------- tools/perf/util/metricgroup.h | 4 +- tools/perf/util/pmu.c | 33 +++++++------ tools/perf/util/pmu.h | 6 +-- tools/perf/util/s390-sample-raw.c | 12 ++--- 9 files changed, 99 insertions(+), 118 deletions(-) diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/= pmu.c index 79124bba713e..646af8603227 100644 --- a/tools/perf/arch/arm64/util/pmu.c +++ b/tools/perf/arch/arm64/util/pmu.c @@ -3,7 +3,7 @@ #include "../../../util/cpumap.h" #include "../../../util/pmu.h" =20 -const struct pmu_events_map *pmu_events_map__find(void) +const struct pmu_event *pmu_events_map__find(void) { struct perf_pmu *pmu =3D NULL; =20 @@ -18,7 +18,7 @@ const struct pmu_events_map *pmu_events_map__find(void) if (pmu->cpus->nr !=3D cpu__max_cpu().cpu) return NULL; =20 - return perf_pmu__find_map(pmu); + return perf_pmu__find_table(pmu); } =20 return NULL; diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index dc4038f997d7..411fc578e5a4 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -195,16 +195,12 @@ static int expand_metric_events(void) .metric_name =3D NULL, }, }; - const struct pmu_events_map ev_map =3D { - .cpuid =3D "test", - .table =3D pme_test, - }; =20 evlist =3D evlist__new(); TEST_ASSERT_VAL("failed to get evlist", evlist); =20 rblist__init(&metric_events); - ret =3D metricgroup__parse_groups_test(evlist, &ev_map, metric_str, + ret =3D metricgroup__parse_groups_test(evlist, pme_test, metric_str, false, false, &metric_events); if (ret < 0) { pr_debug("failed to parse '%s' metric\n", metric_str); diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 1b811a26f4ee..7aebde7c37ec 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -79,11 +79,6 @@ static struct pmu_event pme_test[] =3D { } }; =20 -static const struct pmu_events_map map =3D { - .cpuid =3D "test", - .table =3D pme_test, -}; - struct value { const char *event; u64 val; @@ -166,7 +161,7 @@ static int __compute_metric(const char *name, struct va= lue *vals, runtime_stat__init(&st); =20 /* Parse the metric into metric_events list. */ - err =3D metricgroup__parse_groups_test(evlist, &map, name, + err =3D metricgroup__parse_groups_test(evlist, pme_test, name, false, false, &metric_events); if (err) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index a39a2c99ede6..b3cde5f98982 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -272,13 +272,11 @@ static bool is_same(const char *reference, const char= *test) return !strcmp(reference, test); } =20 -static const struct pmu_events_map *__test_pmu_get_events_map(void) +static const struct pmu_event *__test_pmu_get_events_table(void) { - const struct pmu_events_map *map; - - for (map =3D &pmu_events_map[0]; map->cpuid; map++) { + for (const struct pmu_events_map *map =3D &pmu_events_map[0]; map->cpuid;= map++) { if (!strcmp(map->cpuid, "testcpu")) - return map; + return map->table; } =20 pr_err("could not find test events map\n"); @@ -440,8 +438,7 @@ static int test__pmu_event_table(struct test_suite *tes= t __maybe_unused, int subtest __maybe_unused) { const struct pmu_event *sys_event_tables =3D find_sys_events_table("pme_t= est_soc_sys"); - const struct pmu_events_map *map =3D __test_pmu_get_events_map(); - const struct pmu_event *table; + const struct pmu_event *table =3D __test_pmu_get_events_table(); int map_events =3D 0, expected_events; =20 /* ignore 3x sentinels */ @@ -449,10 +446,10 @@ static int test__pmu_event_table(struct test_suite *t= est __maybe_unused, ARRAY_SIZE(uncore_events) + ARRAY_SIZE(sys_events) - 3; =20 - if (!map || !sys_event_tables) + if (!table || !sys_event_tables) return -1; =20 - for (table =3D map->table; table->name; table++) { + for (; table->name; table++) { struct perf_pmu_test_event const **test_event_table; bool found =3D false; =20 @@ -537,10 +534,10 @@ static int __test_core_pmu_event_aliases(char *pmu_na= me, int *count) struct perf_pmu *pmu; LIST_HEAD(aliases); int res =3D 0; - const struct pmu_events_map *map =3D __test_pmu_get_events_map(); + const struct pmu_event *table =3D __test_pmu_get_events_table(); struct perf_pmu_alias *a, *tmp; =20 - if (!map) + if (!table) return -1; =20 test_event_table =3D &core_events[0]; @@ -551,7 +548,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name= , int *count) =20 pmu->name =3D pmu_name; =20 - pmu_add_cpu_aliases_map(&aliases, pmu, map); + pmu_add_cpu_aliases_map(&aliases, pmu, table); =20 for (; *test_event_table; test_event_table++) { struct perf_pmu_test_event const *test_event =3D *test_event_table; @@ -590,14 +587,14 @@ static int __test_uncore_pmu_event_aliases(struct per= f_pmu_test_pmu *test_pmu) struct perf_pmu *pmu =3D &test_pmu->pmu; const char *pmu_name =3D pmu->name; struct perf_pmu_alias *a, *tmp, *alias; - const struct pmu_events_map *map; + const struct pmu_event *events_table; LIST_HEAD(aliases); int res =3D 0; =20 - map =3D __test_pmu_get_events_map(); - if (!map) + events_table =3D __test_pmu_get_events_table(); + if (!events_table) return -1; - pmu_add_cpu_aliases_map(&aliases, pmu, map); + pmu_add_cpu_aliases_map(&aliases, pmu, events_table); pmu_add_sys_aliases(&aliases, pmu); =20 /* Count how many aliases we generated */ @@ -848,13 +845,9 @@ static int check_parse_fake(const char *id) return ret; } =20 -static void expr_failure(const char *msg, - const struct pmu_events_map *map, - const struct pmu_event *pe) +static void expr_failure(const char *msg, const struct pmu_event *pe) { - pr_debug("%s for map %s %s\n", msg, map->arch, map->cpuid); - pr_debug("On metric %s\n", pe->metric_name); - pr_debug("On expression %s\n", pe->metric_expr); + pr_debug("%s\nOn metric %s\nOn expression %s\n", msg, pe->metric_name, pe= ->metric_expr); } =20 struct metric { @@ -864,7 +857,7 @@ struct metric { =20 static int resolve_metric_simple(struct expr_parse_ctx *pctx, struct list_head *compound_list, - const struct pmu_events_map *map, + const struct pmu_event *map, const char *metric_name) { struct hashmap_entry *cur, *cur_tmp; @@ -925,8 +918,7 @@ static int resolve_metric_simple(struct expr_parse_ctx = *pctx, static int test__parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_events_map *cpus_map =3D pmu_events_map__find(); - const struct pmu_events_map *map; + const struct pmu_event *cpus_table =3D pmu_events_map__find(); const struct pmu_event *pe; int i, j, k; int ret =3D 0; @@ -940,7 +932,8 @@ static int test__parsing(struct test_suite *test __mayb= e_unused, } i =3D 0; for (;;) { - map =3D &pmu_events_map[i++]; + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + if (!map->table) break; j =3D 0; @@ -957,14 +950,14 @@ static int test__parsing(struct test_suite *test __ma= ybe_unused, continue; expr__ctx_clear(ctx); if (expr__find_ids(pe->metric_expr, NULL, ctx) < 0) { - expr_failure("Parse find ids failed", map, pe); + expr_failure("Parse find ids failed", pe); ret++; continue; } =20 - if (resolve_metric_simple(ctx, &compound_list, map, + if (resolve_metric_simple(ctx, &compound_list, map->table, pe->metric_name)) { - expr_failure("Could not resolve metrics", map, pe); + expr_failure("Could not resolve metrics", pe); ret++; goto exit; /* Don't tolerate errors due to severity */ } @@ -979,7 +972,7 @@ static int test__parsing(struct test_suite *test __mayb= e_unused, expr__add_id_val(ctx, strdup(cur->key), k++); =20 hashmap__for_each_entry(ctx->ids, cur, bkt) { - if (check_parse_cpu(cur->key, map =3D=3D cpus_map, + if (check_parse_cpu(cur->key, map->table =3D=3D cpus_table, pe)) ret++; } @@ -999,7 +992,7 @@ static int test__parsing(struct test_suite *test __mayb= e_unused, hashmap__for_each_entry(ctx->ids, cur, bkt) expr__add_id_val(ctx, strdup(cur->key), k--); if (expr__parse(&result, ctx, pe->metric_expr)) { - expr_failure("Parse failed", map, pe); + expr_failure("Parse failed", pe); ret++; } } @@ -1088,8 +1081,6 @@ static int metric_parse_fake(const char *str) static int test__parsing_fake(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_events_map *map; - const struct pmu_event *pe; unsigned int i, j; int err =3D 0; =20 @@ -1101,12 +1092,14 @@ static int test__parsing_fake(struct test_suite *te= st __maybe_unused, =20 i =3D 0; for (;;) { - map =3D &pmu_events_map[i++]; + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + if (!map->table) break; j =3D 0; for (;;) { - pe =3D &map->table[j++]; + const struct pmu_event *pe =3D &map->table[j++]; + if (!pe->name && !pe->metric_group && !pe->metric_name) break; if (!pe->metric_expr) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8f7baeabc5cf..4d32b4fbf67d 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -539,9 +539,6 @@ static int metricgroup__print_sys_event_iter(const stru= ct pmu_event *pe, void *d void metricgroup__print(bool metrics, bool metricgroups, char *filter, bool raw, bool details, const char *pmu_name) { - const struct pmu_events_map *map =3D pmu_events_map__find(); - const struct pmu_event *pe; - int i; struct rblist groups; struct rb_node *node, *next; struct strlist *metriclist =3D NULL; @@ -556,8 +553,7 @@ void metricgroup__print(bool metrics, bool metricgroups= , char *filter, groups.node_new =3D mep_new; groups.node_cmp =3D mep_cmp; groups.node_delete =3D mep_delete; - for (i =3D 0; map; i++) { - pe =3D &map->table[i]; + for (const struct pmu_event *pe =3D pmu_events_map__find(); pe; pe++) { =20 if (!pe->name && !pe->metric_group && !pe->metric_name) break; @@ -850,7 +846,7 @@ struct metricgroup_add_iter_data { bool metric_no_group; struct metric *root_metric; const struct visited_metric *visited; - const struct pmu_events_map *map; + const struct pmu_event *table; }; =20 static int add_metric(struct list_head *metric_list, @@ -859,7 +855,7 @@ static int add_metric(struct list_head *metric_list, bool metric_no_group, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_events_map *map); + const struct pmu_event *table); =20 /** * resolve_metric - Locate metrics within the root metric and recursively = add @@ -874,7 +870,7 @@ static int add_metric(struct list_head *metric_list, * metrics. When adding a root this argument is NULL. * @visited: A singly linked list of metric names being added that is used= to * detect recursion. - * @map: The map that is searched for metrics, most commonly the table for= the + * @table: The table that is searched for metrics, most commonly the table= for the * architecture perf is running upon. */ static int resolve_metric(struct list_head *metric_list, @@ -882,7 +878,7 @@ static int resolve_metric(struct list_head *metric_list, bool metric_no_group, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_events_map *map) + const struct pmu_event *table) { struct hashmap_entry *cur; size_t bkt; @@ -904,7 +900,7 @@ static int resolve_metric(struct list_head *metric_list, hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) { const struct pmu_event *pe; =20 - pe =3D metricgroup__find_metric(cur->key, map); + pe =3D metricgroup__find_metric(cur->key, table); if (pe) { pending =3D realloc(pending, (pending_cnt + 1) * sizeof(struct to_resolve)); @@ -927,7 +923,7 @@ static int resolve_metric(struct list_head *metric_list, */ for (i =3D 0; i < pending_cnt; i++) { ret =3D add_metric(metric_list, pending[i].pe, modifier, metric_no_group, - root_metric, visited, map); + root_metric, visited, table); if (ret) break; } @@ -950,7 +946,7 @@ static int resolve_metric(struct list_head *metric_list, * metrics. When adding a root this argument is NULL. * @visited: A singly linked list of metric names being added that is used= to * detect recursion. - * @map: The map that is searched for metrics, most commonly the table for= the + * @table: The table that is searched for metrics, most commonly the table= for the * architecture perf is running upon. */ static int __add_metric(struct list_head *metric_list, @@ -960,7 +956,7 @@ static int __add_metric(struct list_head *metric_list, int runtime, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_events_map *map) + const struct pmu_event *table) { const struct visited_metric *vm; int ret; @@ -1032,7 +1028,7 @@ static int __add_metric(struct list_head *metric_list, } else { /* Resolve referenced metrics. */ ret =3D resolve_metric(metric_list, modifier, metric_no_group, root_metr= ic, - &visited_node, map); + &visited_node, table); } =20 if (ret) { @@ -1045,25 +1041,25 @@ static int __add_metric(struct list_head *metric_li= st, return ret; } =20 -#define map_for_each_event(__pe, __idx, __map) \ - if (__map) \ - for (__idx =3D 0, __pe =3D &__map->table[__idx]; \ +#define table_for_each_event(__pe, __idx, __table) \ + if (__table) \ + for (__idx =3D 0, __pe =3D &__table[__idx]; \ __pe->name || __pe->metric_group || __pe->metric_name; \ - __pe =3D &__map->table[++__idx]) + __pe =3D &__table[++__idx]) =20 -#define map_for_each_metric(__pe, __idx, __map, __metric) \ - map_for_each_event(__pe, __idx, __map) \ +#define table_for_each_metric(__pe, __idx, __table, __metric) \ + table_for_each_event(__pe, __idx, __table) \ if (__pe->metric_expr && \ (match_metric(__pe->metric_group, __metric) || \ match_metric(__pe->metric_name, __metric))) =20 const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_events_map *map) + const struct pmu_event *table) { const struct pmu_event *pe; int i; =20 - map_for_each_event(pe, i, map) { + table_for_each_event(pe, i, table) { if (match_metric(pe->metric_name, metric)) return pe; } @@ -1077,7 +1073,7 @@ static int add_metric(struct list_head *metric_list, bool metric_no_group, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_events_map *map) + const struct pmu_event *table) { int ret =3D 0; =20 @@ -1085,7 +1081,7 @@ static int add_metric(struct list_head *metric_list, =20 if (!strstr(pe->metric_expr, "?")) { ret =3D __add_metric(metric_list, pe, modifier, metric_no_group, 0, - root_metric, visited, map); + root_metric, visited, table); } else { int j, count; =20 @@ -1098,7 +1094,7 @@ static int add_metric(struct list_head *metric_list, =20 for (j =3D 0; j < count && !ret; j++) ret =3D __add_metric(metric_list, pe, modifier, metric_no_group, j, - root_metric, visited, map); + root_metric, visited, table); } =20 return ret; @@ -1114,7 +1110,7 @@ static int metricgroup__add_metric_sys_event_iter(con= st struct pmu_event *pe, return 0; =20 ret =3D add_metric(d->metric_list, pe, d->modifier, d->metric_no_group, - d->root_metric, d->visited, d->map); + d->root_metric, d->visited, d->table); if (ret) goto out; =20 @@ -1162,13 +1158,13 @@ static int metric_list_cmp(void *priv __maybe_unuse= d, const struct list_head *l, * global. Grouping is the default but due to multiplexi= ng the * user may override. * @metric_list: The list that the metric or metric group are added to. - * @map: The map that is searched for metrics, most commonly the table for= the + * @table: The table that is searched for metrics, most commonly the table= for the * architecture perf is running upon. */ static int metricgroup__add_metric(const char *metric_name, const char *mo= difier, bool metric_no_group, struct list_head *metric_list, - const struct pmu_events_map *map) + const struct pmu_event *table) { const struct pmu_event *pe; LIST_HEAD(list); @@ -1179,11 +1175,11 @@ static int metricgroup__add_metric(const char *metr= ic_name, const char *modifier * Iterate over all metrics seeing if metric matches either the name or * group. When it does add the metric to the list. */ - map_for_each_metric(pe, i, map, metric_name) { + table_for_each_metric(pe, i, table, metric_name) { has_match =3D true; ret =3D add_metric(&list, pe, modifier, metric_no_group, /*root_metric=3D*/NULL, - /*visited_metrics=3D*/NULL, map); + /*visited_metrics=3D*/NULL, table); if (ret) goto out; } @@ -1198,7 +1194,7 @@ static int metricgroup__add_metric(const char *metric= _name, const char *modifier .metric_no_group =3D metric_no_group, .has_match =3D &has_match, .ret =3D &ret, - .map =3D map, + .table =3D table, }, }; =20 @@ -1227,12 +1223,12 @@ static int metricgroup__add_metric(const char *metr= ic_name, const char *modifier * global. Grouping is the default but due to multiplexi= ng the * user may override. * @metric_list: The list that metrics are added to. - * @map: The map that is searched for metrics, most commonly the table for= the + * @table: The table that is searched for metrics, most commonly the table= for the * architecture perf is running upon. */ static int metricgroup__add_metric_list(const char *list, bool metric_no_g= roup, struct list_head *metric_list, - const struct pmu_events_map *map) + const struct pmu_event *table) { char *list_itr, *list_copy, *metric_name, *modifier; int ret, count =3D 0; @@ -1249,7 +1245,7 @@ static int metricgroup__add_metric_list(const char *l= ist, bool metric_no_group, =20 ret =3D metricgroup__add_metric(metric_name, modifier, metric_no_group, metric_list, - map); + table); if (ret =3D=3D -EINVAL) pr_err("Cannot find metric or group `%s'\n", metric_name); =20 @@ -1440,7 +1436,7 @@ static int parse_groups(struct evlist *perf_evlist, c= onst char *str, bool metric_no_merge, struct perf_pmu *fake_pmu, struct rblist *metric_events_list, - const struct pmu_events_map *map) + const struct pmu_event *table) { struct evlist *combined_evlist =3D NULL; LIST_HEAD(metric_list); @@ -1451,7 +1447,7 @@ static int parse_groups(struct evlist *perf_evlist, c= onst char *str, if (metric_events_list->nr_entries =3D=3D 0) metricgroup__rblist_init(metric_events_list); ret =3D metricgroup__add_metric_list(str, metric_no_group, - &metric_list, map); + &metric_list, table); if (ret) goto out; =20 @@ -1586,34 +1582,34 @@ int metricgroup__parse_groups(const struct option *= opt, struct rblist *metric_events) { struct evlist *perf_evlist =3D *(struct evlist **)opt->value; - const struct pmu_events_map *map =3D pmu_events_map__find(); + const struct pmu_event *table =3D pmu_events_map__find(); =20 return parse_groups(perf_evlist, str, metric_no_group, - metric_no_merge, NULL, metric_events, map); + metric_no_merge, NULL, metric_events, table); } =20 int metricgroup__parse_groups_test(struct evlist *evlist, - const struct pmu_events_map *map, + const struct pmu_event *table, const char *str, bool metric_no_group, bool metric_no_merge, struct rblist *metric_events) { return parse_groups(evlist, str, metric_no_group, - metric_no_merge, &perf_pmu__fake, metric_events, map); + metric_no_merge, &perf_pmu__fake, metric_events, table); } =20 bool metricgroup__has_metric(const char *metric) { - const struct pmu_events_map *map =3D pmu_events_map__find(); + const struct pmu_event *table =3D pmu_events_map__find(); const struct pmu_event *pe; int i; =20 - if (!map) + if (!table) return false; =20 for (i =3D 0; ; i++) { - pe =3D &map->table[i]; + pe =3D &table[i]; =20 if (!pe->name && !pe->metric_group && !pe->metric_name) break; diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 2b42b778d1bf..5a1390e73d25 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -71,9 +71,9 @@ int metricgroup__parse_groups(const struct option *opt, bool metric_no_merge, struct rblist *metric_events); const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_events_map *map); + const struct pmu_event *table); int metricgroup__parse_groups_test(struct evlist *evlist, - const struct pmu_events_map *map, + const struct pmu_event *table, const char *str, bool metric_no_group, bool metric_no_merge, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d8717c4548a4..f3e3c4a147e9 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -710,9 +710,9 @@ static char *perf_pmu__getcpuid(struct perf_pmu *pmu) return cpuid; } =20 -const struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu) +const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) { - const struct pmu_events_map *map; + const struct pmu_event *table =3D NULL; char *cpuid =3D perf_pmu__getcpuid(pmu); int i; =20 @@ -724,22 +724,23 @@ const struct pmu_events_map *perf_pmu__find_map(struc= t perf_pmu *pmu) =20 i =3D 0; for (;;) { - map =3D &pmu_events_map[i++]; - if (!map->table) { - map =3D NULL; + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + + if (!map->table) break; - } =20 - if (!strcmp_cpuid_str(map->cpuid, cpuid)) + if (!strcmp_cpuid_str(map->cpuid, cpuid)) { + table =3D map->table; break; + } } free(cpuid); - return map; + return table; } =20 -const struct pmu_events_map *__weak pmu_events_map__find(void) +__weak const struct pmu_event *pmu_events_map__find(void) { - return perf_pmu__find_map(NULL); + return perf_pmu__find_table(NULL); } =20 /* @@ -824,7 +825,7 @@ bool pmu_uncore_alias_match(const char *pmu_name, const= char *name) * as aliases. */ void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, - const struct pmu_events_map *map) + const struct pmu_event *table) { int i; const char *name =3D pmu->name; @@ -834,7 +835,7 @@ void pmu_add_cpu_aliases_map(struct list_head *head, st= ruct perf_pmu *pmu, i =3D 0; while (1) { const char *cpu_name =3D is_arm_pmu_core(name) ? name : "cpu"; - const struct pmu_event *pe =3D &map->table[i++]; + const struct pmu_event *pe =3D &table[i++]; const char *pname =3D pe->pmu ? pe->pmu : cpu_name; =20 if (!pe->name) { @@ -859,13 +860,13 @@ void pmu_add_cpu_aliases_map(struct list_head *head, = struct perf_pmu *pmu, =20 static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *p= mu) { - const struct pmu_events_map *map; + const struct pmu_event *table; =20 - map =3D perf_pmu__find_map(pmu); - if (!map) + table =3D perf_pmu__find_table(pmu); + if (!table) return; =20 - pmu_add_cpu_aliases_map(head, pmu, map); + pmu_add_cpu_aliases_map(head, pmu, table); } =20 struct pmu_sys_event_iter_data { diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 7e667eec2a01..015242c83698 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -126,10 +126,10 @@ int perf_pmu__test(void); =20 struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu); void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, - const struct pmu_events_map *map); + const struct pmu_event *map); =20 -const struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu); -const struct pmu_events_map *pmu_events_map__find(void); +const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu); +const struct pmu_event *pmu_events_map__find(void); bool pmu_uncore_alias_match(const char *pmu_name, const char *name); void perf_pmu_free_alias(struct perf_pmu_alias *alias); =20 diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index cd3a34840389..1ecb718fc0eb 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -135,12 +135,12 @@ static int get_counterset_start(int setnr) * the name of this counter. * If no match is found a NULL pointer is returned. */ -static const char *get_counter_name(int set, int nr, const struct pmu_even= ts_map *map) +static const char *get_counter_name(int set, int nr, const struct pmu_even= t *table) { int rc, event_nr, wanted =3D get_counterset_start(set) + nr; =20 - if (map) { - const struct pmu_event *evp =3D map->table; + if (table) { + const struct pmu_event *evp =3D table; =20 for (; evp->name || evp->event || evp->desc; ++evp) { if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) @@ -159,10 +159,10 @@ static void s390_cpumcfdg_dump(struct perf_sample *sa= mple) unsigned char *buf =3D sample->raw_data; const char *color =3D PERF_COLOR_BLUE; struct cf_ctrset_entry *cep, ce; - const struct pmu_events_map *map; + const struct pmu_event *table; u64 *p; =20 - map =3D pmu_events_map__find(); + table =3D pmu_events_map__find(); while (offset < len) { cep =3D (struct cf_ctrset_entry *)(buf + offset); =20 @@ -180,7 +180,7 @@ static void s390_cpumcfdg_dump(struct perf_sample *samp= le) color_fprintf(stdout, color, " [%#08zx] Counterset:%d" " Counters:%d\n", offset, ce.set, ce.ctr); for (i =3D 0, p =3D (u64 *)(cep + 1); i < ce.ctr; ++i, ++p) { - const char *ev_name =3D get_counter_name(ce.set, i, map); + const char *ev_name =3D get_counter_name(ce.set, i, table); =20 color_fprintf(stdout, color, "\tCounter:%03d %s Value:%#018lx\n", i, --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBF52C19F2C for ; Fri, 29 Jul 2022 07:45:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235136AbiG2HpB (ORCPT ); Fri, 29 Jul 2022 03:45:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53804 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235085AbiG2Hoa (ORCPT ); Fri, 29 Jul 2022 03:44:30 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDB0481B21 for ; Fri, 29 Jul 2022 00:44:27 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id m11-20020a5b040b000000b0066fcc60d1a0so3287936ybp.19 for ; Fri, 29 Jul 2022 00:44:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Tagrozpgrc9vyY8Ly8l/FK550pEPqWVw3iz3s7f6M28=; b=Hjp50gdbNZXTbvCtvr/MVpzEEICvoH3sczAWbt6RCKyGo+ofw9L/lxPzFwn1gUssGL QH7pDfCB8KgoGEAwcC2wuyZVgzJu0PP2XzGQD8+MwFdcOW+4AjSGDe58xhWaYldJCeuY YxAciG/V6edrXykV3FNIGIW+8VVuJKiT7tTyVP3O/+6L8Wfy6gdaCX1HV+Y4xu0WXuzf lOwP17bGO5pbcUDuSrY4C0gAFyWumgFejogp3zW0GhpyAZhcormuoRKynGqUWofPzUre 7ZYg2KAVFoY/U9bTTZ8BldeTU6Av0QL6xNK172k7dmRvaQ2XMk4IyArleleLtV0DZVnL VprQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Tagrozpgrc9vyY8Ly8l/FK550pEPqWVw3iz3s7f6M28=; b=ltJpzdcnRjIoR73J2mtSyTl2HCMtf3a/xhI4w8qXqQxKLGXOg0oSwhllasSuihQTIQ mqFI32lUX70Gufg49pXviroubauZPYgTz2zqTHKS/EIwCcC0dPdjiEqtADm+4oAKagKR jo07QVckKDRjlPU+FanXA5n31yj6YdXuVAQHLqAkT2l3WCHWC1UYzIgSiQnE2Bp+yeKO uypCe/8JAT8cwU+R/jQXuZsQeQ+l5gvdKXXGXAYpFyoU/6g6vg1cBy/T3qSBT40gB8bd oBVT5tqsiMTa3EepGAMAtKw9otg7E9CeybYA9AbF8Q5rncTjhNoMlm56mQQDnEmeNI8Y sDeg== X-Gm-Message-State: ACgBeo0GOejxOvDPfk1XC5or4SjvwFY0nlTbwOfcmYySRXaBA2pfZV6X s1XKszqqnnR9EtChRlB0IHP/H1mbifsl X-Google-Smtp-Source: AA6agR7KjRxVZzm7xm8PTDacYS2lbXtE3KdJIIOHRJOLsQhqSS2XwZf4DSY97cJT2+iloHCb0wuo7oW2R5Ne X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a05:6902:10c:b0:671:68b7:ab41 with SMTP id o12-20020a056902010c00b0067168b7ab41mr1459964ybh.608.1659080667646; Fri, 29 Jul 2022 00:44:27 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:44 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-11-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 10/17] perf pmu-events: Hide pmu_events_map From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move usage of the table to pmu-events.c so it may be hidden. By abstracting the table the implementation can later be changed. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 81 ++++++++- tools/perf/pmu-events/jevents.py | 81 ++++++++- tools/perf/pmu-events/pmu-events.h | 29 +-- tools/perf/tests/pmu-events.c | 218 +++++++++++------------ tools/perf/util/metricgroup.c | 15 +- tools/perf/util/pmu.c | 34 +--- tools/perf/util/pmu.h | 2 +- 7 files changed, 280 insertions(+), 180 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 216ea0482c37..8ef75aff996c 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -6,6 +6,8 @@ * The test cpu/soc is provided for testing. */ #include "pmu-events/pmu-events.h" +#include "util/header.h" +#include "util/pmu.h" #include #include =20 @@ -110,7 +112,26 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { }, }; =20 -const struct pmu_events_map pmu_events_map[] =3D { + +/* + * Map a CPU to its table of PMU events. The CPU is identified by the + * cpuid field, which is an arch-specific identifier for the CPU. + * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile + * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c) + * + * The cpuid can contain any character other than the comma. + */ +struct pmu_events_map { + const char *arch; + const char *cpuid; + const struct pmu_event *table; +}; + +/* + * Global table mapping each known CPU for the architecture to its + * table of PMU events. + */ +static const struct pmu_events_map pmu_events_map[] =3D { { .arch =3D "testarch", .cpuid =3D "testcpu", @@ -162,6 +183,62 @@ static const struct pmu_sys_events pmu_sys_event_table= s[] =3D { }, }; =20 +const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) +{ + const struct pmu_event *table =3D NULL; + char *cpuid =3D perf_pmu__getcpuid(pmu); + int i; + + /* on some platforms which uses cpus map, cpuid can be NULL for + * PMUs other than CORE PMUs. + */ + if (!cpuid) + return NULL; + + i =3D 0; + for (;;) { + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + + if (!map->table) + break; + + if (!strcmp_cpuid_str(map->cpuid, cpuid)) { + table =3D map->table; + break; + } + } + free(cpuid); + return table; +} + +const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid) +{ + for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; + tables->table; + tables++) { + if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpui= d)) + return tables->table; + } + return NULL; +} + +int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) +{ + for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; + tables->table; + tables++) { + for (const struct pmu_event *pe =3D &tables->table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, &tables->table[0], data); + + if (ret) + return ret; + } + } + return 0; +} + const struct pmu_event *find_sys_events_table(const char *name) { for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; @@ -181,7 +258,7 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *= data) for (const struct pmu_event *pe =3D &tables->table[0]; pe->name || pe->metric_group || pe->metric_name; pe++) { - int ret =3D fn(pe, data); + int ret =3D fn(pe, &tables->table[0], data); =20 if (ret) return ret; diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index dd21bc9eeeed..e976c5e8e80b 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -333,7 +333,27 @@ def process_one_file(parents: Sequence[str], item: os.= DirEntry) -> None: =20 def print_mapping_table(archs: Sequence[str]) -> None: """Read the mapfile and generate the struct from cpuid string to event t= able.""" - _args.output_file.write('const struct pmu_events_map pmu_events_map[] = =3D {\n') + _args.output_file.write(""" +/* + * Map a CPU to its table of PMU events. The CPU is identified by the + * cpuid field, which is an arch-specific identifier for the CPU. + * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile + * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c) + * + * The cpuid can contain any character other than the comma. + */ +struct pmu_events_map { + const char *arch; + const char *cpuid; + const struct pmu_event *table; +}; + +/* + * Global table mapping each known CPU for the architecture to its + * table of PMU events. + */ +const struct pmu_events_map pmu_events_map[] =3D { +""") for arch in archs: if arch =3D=3D 'test': _args.output_file.write("""{ @@ -389,6 +409,61 @@ static const struct pmu_sys_events pmu_sys_event_table= s[] =3D { \t}, }; =20 +const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) +{ + const struct pmu_event *table =3D NULL; + char *cpuid =3D perf_pmu__getcpuid(pmu); + int i; + + /* on some platforms which uses cpus map, cpuid can be NULL for + * PMUs other than CORE PMUs. + */ + if (!cpuid) + return NULL; + + i =3D 0; + for (;;) { + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + if (!map->table) + break; + + if (!strcmp_cpuid_str(map->cpuid, cpuid)) { + table =3D map->table; + break; + } + } + free(cpuid); + return table; +} + +const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid) +{ + for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; + tables->table; + tables++) { + if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(table= s->cpuid, cpuid)) + return tables->table; + } + return NULL; +} + +int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) +{ + for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; + tables->table; + tables++) { + for (const struct pmu_event *pe =3D &tables->table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, &tables->table[0], data); + + if (ret) + return ret; + } + } + return 0; +} + const struct pmu_event *find_sys_events_table(const char *name) { for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; @@ -408,7 +483,7 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *= data) for (const struct pmu_event *pe =3D &tables->table[0]; pe->name || pe->metric_group || pe->metric_name; pe++) { - int ret =3D fn(pe, data); + int ret =3D fn(pe, &tables->table[0], data); =20 if (ret) return ret; @@ -449,6 +524,8 @@ def main() -> None: =20 _args.output_file.write(""" #include "pmu-events/pmu-events.h" +#include "util/header.h" +#include "util/pmu.h" #include #include =20 diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 2386212b1df0..485e730f9922 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -2,6 +2,8 @@ #ifndef PMU_EVENTS_H #define PMU_EVENTS_H =20 +struct perf_pmu; + enum aggr_mode_class { PerChip =3D 1, PerCore @@ -28,30 +30,15 @@ struct pmu_event { const char *metric_constraint; }; =20 -/* - * - * Map a CPU to its table of PMU events. The CPU is identified by the - * cpuid field, which is an arch-specific identifier for the CPU. - * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile - * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c) - * - * The cpuid can contain any character other than the comma. - */ -struct pmu_events_map { - const char *arch; - const char *cpuid; - const struct pmu_event *table; -}; +typedef int (*pmu_event_iter_fn)(const struct pmu_event *pe, + const struct pmu_event *table, + void *data); =20 -/* - * Global table mapping each known CPU for the architecture to its - * table of PMU events. - */ -extern const struct pmu_events_map pmu_events_map[]; +const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu); +const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid); +int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data); =20 const struct pmu_event *find_sys_events_table(const char *name); - -typedef int (*pmu_event_iter_fn)(const struct pmu_event *pe, void *data); int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data); =20 #endif diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index b3cde5f98982..ea8b41b5c4e3 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -272,18 +272,6 @@ static bool is_same(const char *reference, const char = *test) return !strcmp(reference, test); } =20 -static const struct pmu_event *__test_pmu_get_events_table(void) -{ - for (const struct pmu_events_map *map =3D &pmu_events_map[0]; map->cpuid;= map++) { - if (!strcmp(map->cpuid, "testcpu")) - return map->table; - } - - pr_err("could not find test events map\n"); - - return NULL; -} - static int compare_pmu_events(const struct pmu_event *e1, const struct pmu= _event *e2) { if (!is_same(e1->name, e2->name)) { @@ -438,7 +426,7 @@ static int test__pmu_event_table(struct test_suite *tes= t __maybe_unused, int subtest __maybe_unused) { const struct pmu_event *sys_event_tables =3D find_sys_events_table("pme_t= est_soc_sys"); - const struct pmu_event *table =3D __test_pmu_get_events_table(); + const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); int map_events =3D 0, expected_events; =20 /* ignore 3x sentinels */ @@ -534,7 +522,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name= , int *count) struct perf_pmu *pmu; LIST_HEAD(aliases); int res =3D 0; - const struct pmu_event *table =3D __test_pmu_get_events_table(); + const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); struct perf_pmu_alias *a, *tmp; =20 if (!table) @@ -591,7 +579,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) LIST_HEAD(aliases); int res =3D 0; =20 - events_table =3D __test_pmu_get_events_table(); + events_table =3D find_core_events_table("testarch", "testcpu"); if (!events_table) return -1; pmu_add_cpu_aliases_map(&aliases, pmu, events_table); @@ -845,11 +833,6 @@ static int check_parse_fake(const char *id) return ret; } =20 -static void expr_failure(const char *msg, const struct pmu_event *pe) -{ - pr_debug("%s\nOn metric %s\nOn expression %s\n", msg, pe->metric_name, pe= ->metric_expr); -} - struct metric { struct list_head list; struct metric_ref metric_ref; @@ -915,93 +898,100 @@ static int resolve_metric_simple(struct expr_parse_c= tx *pctx, =20 } =20 -static int test__parsing(struct test_suite *test __maybe_unused, - int subtest __maybe_unused) +static void expr_failure(const char *msg, const struct pmu_event *pe) { - const struct pmu_event *cpus_table =3D pmu_events_map__find(); - const struct pmu_event *pe; - int i, j, k; - int ret =3D 0; + pr_debug("%s\nOn metric %s\nOn expression %s\n", msg, pe->metric_name, pe= ->metric_expr); +} + + +struct test__parsing_data { + const struct pmu_event *cpus_table; struct expr_parse_ctx *ctx; + int failures; +}; + +static int test__parsing_callback(const struct pmu_event *pe, const struct= pmu_event *table, + void *vdata) +{ + struct test__parsing_data *data =3D vdata; + struct metric *metric, *tmp; + struct hashmap_entry *cur; + LIST_HEAD(compound_list); + size_t bkt; + int k; double result; =20 - ctx =3D expr__ctx_new(); - if (!ctx) { - pr_debug("expr__ctx_new failed"); - return TEST_FAIL; + if (!pe->metric_expr) + return 0; + + pr_debug("Found metric '%s'\n", pe->metric_name); + + expr__ctx_clear(data->ctx); + if (expr__find_ids(pe->metric_expr, NULL, data->ctx) < 0) { + expr_failure("Parse find ids failed", pe); + data->failures++; + return 0; } - i =3D 0; - for (;;) { - const struct pmu_events_map *map =3D &pmu_events_map[i++]; =20 - if (!map->table) - break; - j =3D 0; - for (;;) { - struct metric *metric, *tmp; - struct hashmap_entry *cur; - LIST_HEAD(compound_list); - size_t bkt; - - pe =3D &map->table[j++]; - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - if (!pe->metric_expr) - continue; - expr__ctx_clear(ctx); - if (expr__find_ids(pe->metric_expr, NULL, ctx) < 0) { - expr_failure("Parse find ids failed", pe); - ret++; - continue; - } + if (resolve_metric_simple(data->ctx, &compound_list, table, + pe->metric_name)) { + expr_failure("Could not resolve metrics", pe); + data->failures++; + return TEST_FAIL; /* Don't tolerate errors due to severity */ + } =20 - if (resolve_metric_simple(ctx, &compound_list, map->table, - pe->metric_name)) { - expr_failure("Could not resolve metrics", pe); - ret++; - goto exit; /* Don't tolerate errors due to severity */ - } + /* + * Add all ids with a made up value. The value may trigger divide by + * zero when subtracted and so try to make them unique. + */ + k =3D 1; + hashmap__for_each_entry(data->ctx->ids, cur, bkt) + expr__add_id_val(data->ctx, strdup(cur->key), k++); =20 - /* - * Add all ids with a made up value. The value may - * trigger divide by zero when subtracted and so try to - * make them unique. - */ - k =3D 1; - hashmap__for_each_entry(ctx->ids, cur, bkt) - expr__add_id_val(ctx, strdup(cur->key), k++); - - hashmap__for_each_entry(ctx->ids, cur, bkt) { - if (check_parse_cpu(cur->key, map->table =3D=3D cpus_table, - pe)) - ret++; - } + hashmap__for_each_entry(data->ctx->ids, cur, bkt) { + if (check_parse_cpu(cur->key, table =3D=3D data->cpus_table, pe)) + data->failures++; + } =20 - list_for_each_entry_safe(metric, tmp, &compound_list, list) { - expr__add_ref(ctx, &metric->metric_ref); - free(metric); - } + list_for_each_entry_safe(metric, tmp, &compound_list, list) { + expr__add_ref(data->ctx, &metric->metric_ref); + free(metric); + } =20 - if (expr__parse(&result, ctx, pe->metric_expr)) { - /* - * Parsing failed, make numbers go from large to - * small which can resolve divide by zero - * issues. - */ - k =3D 1024; - hashmap__for_each_entry(ctx->ids, cur, bkt) - expr__add_id_val(ctx, strdup(cur->key), k--); - if (expr__parse(&result, ctx, pe->metric_expr)) { - expr_failure("Parse failed", pe); - ret++; - } - } + if (expr__parse(&result, data->ctx, pe->metric_expr)) { + /* + * Parsing failed, make numbers go from large to small which can + * resolve divide by zero issues. + */ + k =3D 1024; + hashmap__for_each_entry(data->ctx->ids, cur, bkt) + expr__add_id_val(data->ctx, strdup(cur->key), k--); + if (expr__parse(&result, data->ctx, pe->metric_expr)) { + expr_failure("Parse failed", pe); + data->failures++; } } - expr__ctx_free(ctx); - /* TODO: fail when not ok */ -exit: - return ret =3D=3D 0 ? TEST_OK : TEST_SKIP; + return 0; +} + +static int test__parsing(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) +{ + struct test__parsing_data data =3D { + .cpus_table =3D pmu_events_map__find(), + .ctx =3D expr__ctx_new(), + .failures =3D 0, + }; + + if (!data.ctx) { + pr_debug("expr__ctx_new failed"); + return TEST_FAIL; + } + pmu_for_each_core_event(test__parsing_callback, &data); + pmu_for_each_sys_event(test__parsing_callback, &data); + + expr__ctx_free(data.ctx); + return data.failures =3D=3D 0 ? TEST_OK : TEST_FAIL; } =20 struct test_metric { @@ -1073,6 +1063,16 @@ static int metric_parse_fake(const char *str) return ret; } =20 +static int test__parsing_fake_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data __maybe_unused) +{ + if (!pe->metric_expr) + return 0; + + return metric_parse_fake(pe->metric_expr); +} + /* * Parse all the metrics for current architecture, * or all defined cpus via the 'fake_pmu' @@ -1081,37 +1081,19 @@ static int metric_parse_fake(const char *str) static int test__parsing_fake(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - unsigned int i, j; int err =3D 0; =20 - for (i =3D 0; i < ARRAY_SIZE(metrics); i++) { + for (size_t i =3D 0; i < ARRAY_SIZE(metrics); i++) { err =3D metric_parse_fake(metrics[i].str); if (err) return err; } =20 - i =3D 0; - for (;;) { - const struct pmu_events_map *map =3D &pmu_events_map[i++]; + err =3D pmu_for_each_core_event(test__parsing_fake_callback, NULL); + if (err) + return err; =20 - if (!map->table) - break; - j =3D 0; - for (;;) { - const struct pmu_event *pe =3D &map->table[j++]; - - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - if (!pe->metric_expr) - continue; - pr_debug("Found metric '%s' for '%s'\n", pe->metric_name, map->cpuid); - err =3D metric_parse_fake(pe->metric_expr); - if (err) - return err; - } - } - - return 0; + return pmu_for_each_sys_event(test__parsing_fake_callback, NULL); } =20 static struct test_case pmu_events_tests[] =3D { diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 4d32b4fbf67d..680f7c63838d 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -502,14 +502,14 @@ struct metricgroup_print_sys_idata { bool details; }; =20 -typedef int (*metricgroup_sys_event_iter_fn)(const struct pmu_event *pe, v= oid *); - struct metricgroup_iter_data { - metricgroup_sys_event_iter_fn fn; + pmu_event_iter_fn fn; void *data; }; =20 -static int metricgroup__sys_event_iter(const struct pmu_event *pe, void *d= ata) +static int metricgroup__sys_event_iter(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data) { struct metricgroup_iter_data *d =3D data; struct perf_pmu *pmu =3D NULL; @@ -522,13 +522,15 @@ static int metricgroup__sys_event_iter(const struct p= mu_event *pe, void *data) if (!pmu->id || strcmp(pmu->id, pe->compat)) continue; =20 - return d->fn(pe, d->data); + return d->fn(pe, table, d->data); } =20 return 0; } =20 -static int metricgroup__print_sys_event_iter(const struct pmu_event *pe, v= oid *data) +static int metricgroup__print_sys_event_iter(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data) { struct metricgroup_print_sys_idata *d =3D data; =20 @@ -1101,6 +1103,7 @@ static int add_metric(struct list_head *metric_list, } =20 static int metricgroup__add_metric_sys_event_iter(const struct pmu_event *= pe, + const struct pmu_event *table __maybe_unused, void *data) { struct metricgroup_add_iter_data *d =3D data; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f3e3c4a147e9..5bb03d4e52a3 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -690,7 +690,7 @@ static int is_arm_pmu_core(const char *name) return file_available(path); } =20 -static char *perf_pmu__getcpuid(struct perf_pmu *pmu) +char *perf_pmu__getcpuid(struct perf_pmu *pmu) { char *cpuid; static bool printed; @@ -710,34 +710,6 @@ static char *perf_pmu__getcpuid(struct perf_pmu *pmu) return cpuid; } =20 -const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) -{ - const struct pmu_event *table =3D NULL; - char *cpuid =3D perf_pmu__getcpuid(pmu); - int i; - - /* on some platforms which uses cpus map, cpuid can be NULL for - * PMUs other than CORE PMUs. - */ - if (!cpuid) - return NULL; - - i =3D 0; - for (;;) { - const struct pmu_events_map *map =3D &pmu_events_map[i++]; - - if (!map->table) - break; - - if (!strcmp_cpuid_str(map->cpuid, cpuid)) { - table =3D map->table; - break; - } - } - free(cpuid); - return table; -} - __weak const struct pmu_event *pmu_events_map__find(void) { return perf_pmu__find_table(NULL); @@ -874,7 +846,9 @@ struct pmu_sys_event_iter_data { struct perf_pmu *pmu; }; =20 -static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe, void *d= ata) +static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data) { struct pmu_sys_event_iter_data *idata =3D data; struct perf_pmu *pmu =3D idata->pmu; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 015242c83698..06df99ba2029 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -128,7 +128,7 @@ struct perf_event_attr *perf_pmu__get_default_config(st= ruct perf_pmu *pmu); void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, const struct pmu_event *map); =20 -const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu); +char *perf_pmu__getcpuid(struct perf_pmu *pmu); const struct pmu_event *pmu_events_map__find(void); bool pmu_uncore_alias_match(const char *pmu_name, const char *name); void perf_pmu_free_alias(struct perf_pmu_alias *alias); --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92487C19F2A for ; Fri, 29 Jul 2022 07:45:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235194AbiG2HpE (ORCPT ); Fri, 29 Jul 2022 03:45:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235116AbiG2Hoe (ORCPT ); Fri, 29 Jul 2022 03:44:34 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1851481B3E for ; Fri, 29 Jul 2022 00:44:31 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31ea3f0e357so36261487b3.16 for ; Fri, 29 Jul 2022 00:44:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=qKMuTgZyBMjnNbHnrNnTfnZV0TLakEyEiZz0dtiihIo=; b=W+/MAQAoPo1ColXaX7DPgbvMppqd8WzaJUGcRdJ+rV/rNpjPxI2RvziikIaLHJS1D0 Bz+7zHE1W+GXAK2jSfU4XFDsjRZrvCieMRzgakrGVtktRLJlL7twEi6clXX+y+jlmM15 JcpJ9MpKtuzH2obtBphdCnHZE7MFcLzJLVcqV8REQvWpMObO4lqEJlCpDIBhr91hCVEd JXnCvFg/8b1xdVFJk7nvVCYG6+b4IIjm1PqMOZvOt3+CKlGhcxSJ+8yUQ3QvXJpAu6YJ UUmD9qNhne3719pqpnnFKlTlPJ74Jm6O44lj8wrQF7TBEVY6EDywEzS9yMFsx2KoGXC2 a5cQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=qKMuTgZyBMjnNbHnrNnTfnZV0TLakEyEiZz0dtiihIo=; b=fJcYdW0f2iU7a0p1ngWaPCvsoCN8jpd5K/g2/U10aab4X5RG/3cuDVwr+H+yAU6Erg vTCmGdMFxyN4vuq8fDw55eriAWG/my48GJwG3O5zNMVkr78sfVfFwwjuzLaw5mSWoBBK Zgh/ULqdQmGiKf12RrnpxRkZKmW5AiA+VGkInBlp3zxtCaDUJ235NH0l1AjWHMj48g08 SCStmMD1Z1S394vGiuiDhegECXIEkyr/MhJuqN8xttPQanftAoZJEuA33/xqmUdXOXH1 xL9cVJ6YF5Y27UdsvqyXDrUi21XAzZbx0mmFj53RBy72aQQX2bfEUBqAW42qmtLxR7pH H24w== X-Gm-Message-State: ACgBeo1yDIju9Cfi9/wlJd1SmRvOxp8xmsWJERREnbougSQrnkKKiCOI TUcIqVD2pPHhkVm7rIfG/yoo6oZJ4e9X X-Google-Smtp-Source: AA6agR6s9LWrQn3K3TqbvVU8RreNq2Lz8BYST7enJeB+eoMvoH8TswmkS1N2q75d/K/F8IptDLZ7FaLrDg6j X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a81:8396:0:b0:322:ed8f:9bdf with SMTP id t144-20020a818396000000b00322ed8f9bdfmr2090644ywf.455.1659080670292; Fri, 29 Jul 2022 00:44:30 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:45 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-12-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 11/17] perf test: Use full metric resolution From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The simple metric resolution doesn't handle recursion properly, switch to use the full resolution as with the parse-metric tests which also increases coverage. Don't set the values for the metric backward as failures to generate a result are ignored. Signed-off-by: Ian Rogers --- tools/perf/tests/pmu-events.c | 222 ++++++++++++---------------------- 1 file changed, 77 insertions(+), 145 deletions(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index ea8b41b5c4e3..e8df6bc26ebd 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -9,10 +9,12 @@ #include #include "debug.h" #include "../pmu-events/pmu-events.h" +#include #include "util/evlist.h" #include "util/expr.h" #include "util/parse-events.h" #include "metricgroup.h" +#include "stat.h" =20 struct perf_pmu_test_event { /* used for matching against events from generated pmu-events.c */ @@ -801,27 +803,6 @@ static int check_parse_id(const char *id, struct parse= _events_error *error, return ret; } =20 -static int check_parse_cpu(const char *id, bool same_cpu, const struct pmu= _event *pe) -{ - struct parse_events_error error; - int ret; - - parse_events_error__init(&error); - ret =3D check_parse_id(id, &error, NULL); - if (ret && same_cpu) { - pr_warning("Parse event failed metric '%s' id '%s' expr '%s'\n", - pe->metric_name, id, pe->metric_expr); - pr_warning("Error string '%s' help '%s'\n", error.str, - error.help); - } else if (ret) { - pr_debug3("Parse event failed, but for an event that may not be supporte= d by this CPU.\nid '%s' metric '%s' expr '%s'\n", - id, pe->metric_name, pe->metric_expr); - ret =3D 0; - } - parse_events_error__exit(&error); - return ret; -} - static int check_parse_fake(const char *id) { struct parse_events_error error; @@ -838,160 +819,111 @@ struct metric { struct metric_ref metric_ref; }; =20 -static int resolve_metric_simple(struct expr_parse_ctx *pctx, - struct list_head *compound_list, - const struct pmu_event *map, - const char *metric_name) -{ - struct hashmap_entry *cur, *cur_tmp; - struct metric *metric, *tmp; - size_t bkt; - bool all; - int rc; - - do { - all =3D true; - hashmap__for_each_entry_safe(pctx->ids, cur, cur_tmp, bkt) { - struct metric_ref *ref; - const struct pmu_event *pe; - - pe =3D metricgroup__find_metric(cur->key, map); - if (!pe) - continue; - - if (!strcmp(metric_name, (char *)cur->key)) { - pr_warning("Recursion detected for metric %s\n", metric_name); - rc =3D -1; - goto out_err; - } - - all =3D false; - - /* The metric key itself needs to go out.. */ - expr__del_id(pctx, cur->key); - - metric =3D malloc(sizeof(*metric)); - if (!metric) { - rc =3D -ENOMEM; - goto out_err; - } - - ref =3D &metric->metric_ref; - ref->metric_name =3D pe->metric_name; - ref->metric_expr =3D pe->metric_expr; - list_add_tail(&metric->list, compound_list); - - rc =3D expr__find_ids(pe->metric_expr, NULL, pctx); - if (rc) - goto out_err; - break; /* The hashmap has been modified, so restart */ - } - } while (!all); - - return 0; - -out_err: - list_for_each_entry_safe(metric, tmp, compound_list, list) - free(metric); - - return rc; - -} - -static void expr_failure(const char *msg, const struct pmu_event *pe) -{ - pr_debug("%s\nOn metric %s\nOn expression %s\n", msg, pe->metric_name, pe= ->metric_expr); -} - - -struct test__parsing_data { - const struct pmu_event *cpus_table; - struct expr_parse_ctx *ctx; - int failures; -}; - static int test__parsing_callback(const struct pmu_event *pe, const struct= pmu_event *table, - void *vdata) + void *data) { - struct test__parsing_data *data =3D vdata; - struct metric *metric, *tmp; - struct hashmap_entry *cur; - LIST_HEAD(compound_list); - size_t bkt; + int *failures =3D data; int k; - double result; + struct evlist *evlist; + struct perf_cpu_map *cpus; + struct runtime_stat st; + struct evsel *evsel; + struct rblist metric_events =3D { + .nr_entries =3D 0, + }; + int err =3D 0; =20 if (!pe->metric_expr) return 0; =20 pr_debug("Found metric '%s'\n", pe->metric_name); + (*failures)++; =20 - expr__ctx_clear(data->ctx); - if (expr__find_ids(pe->metric_expr, NULL, data->ctx) < 0) { - expr_failure("Parse find ids failed", pe); - data->failures++; - return 0; + /* + * We need to prepare evlist for stat mode running on CPU 0 + * because that's where all the stats are going to be created. + */ + evlist =3D evlist__new(); + if (!evlist) + return -ENOMEM; + + cpus =3D perf_cpu_map__new("0"); + if (!cpus) { + evlist__delete(evlist); + return -ENOMEM; } =20 - if (resolve_metric_simple(data->ctx, &compound_list, table, - pe->metric_name)) { - expr_failure("Could not resolve metrics", pe); - data->failures++; - return TEST_FAIL; /* Don't tolerate errors due to severity */ + perf_evlist__set_maps(&evlist->core, cpus, NULL); + runtime_stat__init(&st); + + err =3D metricgroup__parse_groups_test(evlist, table, pe->metric_name, + false, false, + &metric_events); + if (err) { + if (!strcmp(pe->metric_name, "M1") || !strcmp(pe->metric_name, "M2") || + !strcmp(pe->metric_name, "M3")) { + (*failures)--; + pr_debug("Expected broken metric %s skipping\n", pe->metric_name); + err =3D 0; + } + goto out_err; } =20 + err =3D evlist__alloc_stats(evlist, false); + if (err) + goto out_err; /* * Add all ids with a made up value. The value may trigger divide by * zero when subtracted and so try to make them unique. */ k =3D 1; - hashmap__for_each_entry(data->ctx->ids, cur, bkt) - expr__add_id_val(data->ctx, strdup(cur->key), k++); - - hashmap__for_each_entry(data->ctx->ids, cur, bkt) { - if (check_parse_cpu(cur->key, table =3D=3D data->cpus_table, pe)) - data->failures++; + perf_stat__reset_shadow_stats(); + evlist__for_each_entry(evlist, evsel) { + perf_stat__update_shadow_stats(evsel, k, 0, &st); + if (!strcmp(evsel->name, "duration_time")) + update_stats(&walltime_nsecs_stats, k); + k++; } + evlist__for_each_entry(evlist, evsel) { + struct metric_event *me =3D metricgroup__lookup(&metric_events, evsel, f= alse); =20 - list_for_each_entry_safe(metric, tmp, &compound_list, list) { - expr__add_ref(data->ctx, &metric->metric_ref); - free(metric); - } + if (me !=3D NULL) { + struct metric_expr *mexp; =20 - if (expr__parse(&result, data->ctx, pe->metric_expr)) { - /* - * Parsing failed, make numbers go from large to small which can - * resolve divide by zero issues. - */ - k =3D 1024; - hashmap__for_each_entry(data->ctx->ids, cur, bkt) - expr__add_id_val(data->ctx, strdup(cur->key), k--); - if (expr__parse(&result, data->ctx, pe->metric_expr)) { - expr_failure("Parse failed", pe); - data->failures++; + list_for_each_entry (mexp, &me->head, nd) { + if (strcmp(mexp->metric_name, pe->metric_name)) + continue; + pr_debug("Result %f\n", test_generic_metric(mexp, 0, &st)); + err =3D 0; + (*failures)--; + goto out_err; + } } } - return 0; + pr_debug("Didn't find parsed metric %s", pe->metric_name); + err =3D 1; +out_err: + if (err) + pr_debug("Broken metric %s\n", pe->metric_name); + + /* ... cleanup. */ + metricgroup__rblist_exit(&metric_events); + runtime_stat__exit(&st); + evlist__free_stats(evlist); + perf_cpu_map__put(cpus); + evlist__delete(evlist); + return err; } =20 static int test__parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - struct test__parsing_data data =3D { - .cpus_table =3D pmu_events_map__find(), - .ctx =3D expr__ctx_new(), - .failures =3D 0, - }; + int failures =3D 0; =20 - if (!data.ctx) { - pr_debug("expr__ctx_new failed"); - return TEST_FAIL; - } - pmu_for_each_core_event(test__parsing_callback, &data); - pmu_for_each_sys_event(test__parsing_callback, &data); + pmu_for_each_core_event(test__parsing_callback, &failures); + pmu_for_each_sys_event(test__parsing_callback, &failures); =20 - expr__ctx_free(data.ctx); - return data.failures =3D=3D 0 ? TEST_OK : TEST_FAIL; + return failures =3D=3D 0 ? TEST_OK : TEST_FAIL; } =20 struct test_metric { --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A160C00144 for ; Fri, 29 Jul 2022 07:45:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235331AbiG2HpI (ORCPT ); Fri, 29 Jul 2022 03:45:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235062AbiG2Hom (ORCPT ); Fri, 29 Jul 2022 03:44:42 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0F42820D5 for ; Fri, 29 Jul 2022 00:44:33 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f5668674cso36295857b3.8 for ; Fri, 29 Jul 2022 00:44:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=1Fnwkxe00fzii+/AdoCdigiKOH/6tox9V/XrXmPYCso=; b=KYiw9jpWBj6G9TItyX5toEX3s7SmRCn3h0SsaT9E5DY3Eeb7n+mbNqbpvCOqpDk5Mt DlxxHR8Oftf3ajn7jgtyfT1OYbIjtdkln/z2Ll8LF7AVkCsqsabrRzOV9yzh9frJo2Rt /OM5FyBERW9J9pz8+Hv0dAqRIvTatVBtfOOvGqIJnNeFzOyK54JZQOxLlhPgR1KxQSsx fnlf6A+lKKopZgQ9LTC9dBMrcXnV1ZGS/8DbX6IcQbdprU0hU85XOgJuxVYY3DXAL/qz Vr23ZMuq2pwROKS+bRSb4P+Q5BHCrCBtJOaAeaC2+mex2FPAtW+tfQQecSNzkvD78uiF +EKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=1Fnwkxe00fzii+/AdoCdigiKOH/6tox9V/XrXmPYCso=; b=hW7KTkTIuvmTThrC1nVC2TtxgmZCUHkQkkLdxD3BUUryQL6FcG18J1P+ABB0kIev9q Y1PtI+pC9OpSfjORcrYBAfCHk4zMq59B/9E+WFDo2Yvmm3LxYdwhHwz/ajjU2A3mI4Ht PdHsjyhUFdo+1ihCEmdTm/bvYkmsIXYjvGkjUAmbIuI9XFJZRruJHaO+7F7AIe8kDJm0 ptqoZfaG6oljHLBUYcT0wMz7wlVlyxX7yVpdmIdqWd9WmegcBzSfEjw0zw9UwTx7dzqz jlQ1C4lxIlxl5eqMsUwoYg+bU8bJYim+ZVZaHfrfkrlMB59T9plpu2hWS0mc9LpC0TmZ NH1g== X-Gm-Message-State: ACgBeo2Ge7CTI6Q/BVmDa1Jj2FGgsQnE/A4NqJooYWYPe1cy4V49M8Hv Rhzov6T2bHYwzkzk+Xj2zbwBz+Vsd9wZ X-Google-Smtp-Source: AA6agR4LYFC6eDgwM7HD1rQOkSGD5tFgKlNRIBx/0KWnLUZpogsWNMU6BPKOQadFEP95olksrb3ofYrq4Bey X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a05:6902:150c:b0:670:af5c:c431 with SMTP id q12-20020a056902150c00b00670af5cc431mr1659343ybu.37.1659080672858; Fri, 29 Jul 2022 00:44:32 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:46 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-13-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 12/17] perf pmu-events: Move test events/metrics to json From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move arrays of pmu_events into the json code so that it may be regenerated and modified by the jevents.py script. Signed-off-by: Ian Rogers --- .../arch/test/test_soc/cpu/metrics.json | 64 +++++++++++++++++ tools/perf/pmu-events/empty-pmu-events.c | 64 +++++++++++++++++ tools/perf/tests/expand-cgroup.c | 17 +---- tools/perf/tests/parse-metric.c | 68 +------------------ 4 files changed, 132 insertions(+), 81 deletions(-) create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.js= on diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.json b/to= ols/perf/pmu-events/arch/test/test_soc/cpu/metrics.json new file mode 100644 index 000000000000..42d9b5242fd7 --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.json @@ -0,0 +1,64 @@ +[ + { + "MetricExpr": "1 / IPC", + "MetricName": "CPI" + }, + { + "MetricExpr": "inst_retired.any / cpu_clk_unhalted.thread", + "MetricName": "IPC", + "MetricGroup": "group1" + }, + { + "MetricExpr": "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalte= d.thread / 2 ) * ( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalte= d.ref_xclk ) )))", + "MetricName": "Frontend_Bound_SMT" + }, + { + "MetricExpr": "l1d\\-loads\\-misses / inst_retired.any", + "MetricName": "dcache_miss_cpi" + }, + { + "MetricExpr": "l1i\\-loads\\-misses / inst_retired.any", + "MetricName": "icache_miss_cycles" + }, + { + "MetricExpr": "(dcache_miss_cpi + icache_miss_cycles)", + "MetricName": "cache_miss_cycles", + "MetricGroup": "group1" + }, + { + "MetricExpr": "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqst= s.rfo_hit", + "MetricName": "DCache_L2_All_Hits" + }, + { + "MetricExpr": "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_= rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss", + "MetricName": "DCache_L2_All_Miss" + }, + { + "MetricExpr": "dcache_l2_all_hits + dcache_l2_all_miss", + "MetricName": "DCache_L2_All" + }, + { + "MetricExpr": "d_ratio(dcache_l2_all_hits, dcache_l2_all)", + "MetricName": "DCache_L2_Hits" + }, + { + "MetricExpr": "d_ratio(dcache_l2_all_miss, dcache_l2_all)", + "MetricName": "DCache_L2_Misses" + }, + { + "MetricExpr": "ipc + M2", + "MetricName": "M1" + }, + { + "MetricExpr": "ipc + M1", + "MetricName": "M2" + }, + { + "MetricExpr": "1/M3", + "MetricName": "M3" + }, + { + "MetricExpr": "64 * l1d.replacement / 1000000000 / duration_time", + "MetricName": "L1D_Cache_Fill_BW" + } +] diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 8ef75aff996c..028f44efe48d 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -105,6 +105,70 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { .desc =3D "L2 BTB Correction", .topic =3D "branch", }, + { + .metric_expr =3D "1 / IPC", + .metric_name =3D "CPI", + }, + { + .metric_expr =3D "inst_retired.any / cpu_clk_unhalted.thread", + .metric_name =3D "IPC", + .metric_group =3D "group1", + }, + { + .metric_expr =3D "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalt= ed.thread / 2 ) * " + "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) = )))", + .metric_name =3D "Frontend_Bound_SMT", + }, + { + .metric_expr =3D "l1d\\-loads\\-misses / inst_retired.any", + .metric_name =3D "dcache_miss_cpi", + }, + { + .metric_expr =3D "l1i\\-loads\\-misses / inst_retired.any", + .metric_name =3D "icache_miss_cycles", + }, + { + .metric_expr =3D "(dcache_miss_cpi + icache_miss_cycles)", + .metric_name =3D "cache_miss_cycles", + .metric_group =3D "group1", + }, + { + .metric_expr =3D "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqs= ts.rfo_hit", + .metric_name =3D "DCache_L2_All_Hits", + }, + { + .metric_expr =3D "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data= _rd_hit, 0) + " + "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", + .metric_name =3D "DCache_L2_All_Miss", + }, + { + .metric_expr =3D "dcache_l2_all_hits + dcache_l2_all_miss", + .metric_name =3D "DCache_L2_All", + }, + { + .metric_expr =3D "d_ratio(dcache_l2_all_hits, dcache_l2_all)", + .metric_name =3D "DCache_L2_Hits", + }, + { + .metric_expr =3D "d_ratio(dcache_l2_all_miss, dcache_l2_all)", + .metric_name =3D "DCache_L2_Misses", + }, + { + .metric_expr =3D "ipc + M2", + .metric_name =3D "M1", + }, + { + .metric_expr =3D "ipc + M1", + .metric_name =3D "M2", + }, + { + .metric_expr =3D "1/M3", + .metric_name =3D "M3", + }, + { + .metric_expr =3D "64 * l1d.replacement / 1000000000 / duration_time", + .metric_name =3D "L1D_Cache_Fill_BW", + }, { .name =3D 0, .event =3D 0, diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index 411fc578e5a4..e79ee8621a90 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -180,26 +180,13 @@ static int expand_metric_events(void) struct evlist *evlist; struct rblist metric_events; const char metric_str[] =3D "CPI"; - - struct pmu_event pme_test[] =3D { - { - .metric_expr =3D "instructions / cycles", - .metric_name =3D "IPC", - }, - { - .metric_expr =3D "1 / IPC", - .metric_name =3D "CPI", - }, - { - .metric_expr =3D NULL, - .metric_name =3D NULL, - }, - }; + const struct pmu_event *pme_test; =20 evlist =3D evlist__new(); TEST_ASSERT_VAL("failed to get evlist", evlist); =20 rblist__init(&metric_events); + pme_test =3D find_core_events_table("testarch", "testcpu"); ret =3D metricgroup__parse_groups_test(evlist, pme_test, metric_str, false, false, &metric_events); if (ret < 0) { diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 7aebde7c37ec..30c7091857b8 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -13,72 +13,6 @@ #include "stat.h" #include "pmu.h" =20 -static struct pmu_event pme_test[] =3D { -{ - .metric_expr =3D "inst_retired.any / cpu_clk_unhalted.thread", - .metric_name =3D "IPC", - .metric_group =3D "group1", -}, -{ - .metric_expr =3D "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalte= d.thread / 2 ) * " - "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk= ) )))", - .metric_name =3D "Frontend_Bound_SMT", -}, -{ - .metric_expr =3D "l1d\\-loads\\-misses / inst_retired.any", - .metric_name =3D "dcache_miss_cpi", -}, -{ - .metric_expr =3D "l1i\\-loads\\-misses / inst_retired.any", - .metric_name =3D "icache_miss_cycles", -}, -{ - .metric_expr =3D "(dcache_miss_cpi + icache_miss_cycles)", - .metric_name =3D "cache_miss_cycles", - .metric_group =3D "group1", -}, -{ - .metric_expr =3D "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqst= s.rfo_hit", - .metric_name =3D "DCache_L2_All_Hits", -}, -{ - .metric_expr =3D "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_= rd_hit, 0) + " - "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", - .metric_name =3D "DCache_L2_All_Miss", -}, -{ - .metric_expr =3D "dcache_l2_all_hits + dcache_l2_all_miss", - .metric_name =3D "DCache_L2_All", -}, -{ - .metric_expr =3D "d_ratio(dcache_l2_all_hits, dcache_l2_all)", - .metric_name =3D "DCache_L2_Hits", -}, -{ - .metric_expr =3D "d_ratio(dcache_l2_all_miss, dcache_l2_all)", - .metric_name =3D "DCache_L2_Misses", -}, -{ - .metric_expr =3D "ipc + m2", - .metric_name =3D "M1", -}, -{ - .metric_expr =3D "ipc + m1", - .metric_name =3D "M2", -}, -{ - .metric_expr =3D "1/m3", - .metric_name =3D "M3", -}, -{ - .metric_expr =3D "64 * l1d.replacement / 1000000000 / duration_time", - .metric_name =3D "L1D_Cache_Fill_BW", -}, -{ - .name =3D NULL, -} -}; - struct value { const char *event; u64 val; @@ -138,6 +72,7 @@ static int __compute_metric(const char *name, struct val= ue *vals, struct rblist metric_events =3D { .nr_entries =3D 0, }; + const struct pmu_event *pme_test; struct perf_cpu_map *cpus; struct runtime_stat st; struct evlist *evlist; @@ -161,6 +96,7 @@ static int __compute_metric(const char *name, struct val= ue *vals, runtime_stat__init(&st); =20 /* Parse the metric into metric_events list. */ + pme_test =3D find_core_events_table("testarch", "testcpu"); err =3D metricgroup__parse_groups_test(evlist, pme_test, name, false, false, &metric_events); --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1AA45C00144 for ; Fri, 29 Jul 2022 07:45:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235345AbiG2HpM (ORCPT ); Fri, 29 Jul 2022 03:45:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235023AbiG2Hoy (ORCPT ); Fri, 29 Jul 2022 03:44:54 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD03E820D2 for ; Fri, 29 Jul 2022 00:44:35 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-3225b644be1so36448557b3.1 for ; Fri, 29 Jul 2022 00:44:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Nie16ezqAkT8oDeGxazLBU2pNUTiS13bS4q6/UMs4OA=; b=I4IQ0hmU15xVKngOlZUJG/64xEoagipU4FfK9PDANYimvs6WrXP4n4rPQKo6nhe1BL rrpFhf+g8Uychwj34RpHHDoeHoei5BLsRZL7eh6p9kA7oKNw0y/YQsqOGBYP3Tbg3kiv WqNpPtHJyR0dzSlwgHwDbJoXcQ22KHAtaarl1LxvQi+gZB0oiswp+E3qDf0dlXqmLM98 TXXAJxITDVTZICDxoD1qqmCctstu07QkByAMkbwtLr7JZKVqYIcL9VXfVK1r3J6fpewz 4efacmwBFk1CO17O4w14ZvA8vlNh0Cmc7vl7W565LdWlDtYlKDnECIPJ26qZdCnELgWc 6oGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Nie16ezqAkT8oDeGxazLBU2pNUTiS13bS4q6/UMs4OA=; b=NuOgfd5VY1D4moBWjqvnzgn2vyAAPPJMfyE6tPnD4f6SSlJqc280gywriYsEFPyczU OF8PBCRpNDZw/VnEZeCEv9ddJLMx3S2Ie7ZuKkhI+so9Kw+XmSBK7q/E5LWWqcbVLne/ /ubIy7AaiU59Z2JClAjQYuzCslhtacHg6e/0UhHpgxHSuxOVfDCKv//QE6w6XFeL4zWd tHTQAdcG+Y2wd3SmiQEQ4g0k4VaGFLKXsi1NwFs4Sy8rRKlQHRagMmlSo78nRz1KtorL 0I/JpM3ZLzMXfBRFGhQqRtCJfpDezMwmnbyaMM+U8UsrEehpebjjgENuzA91OcX53a4J 43sQ== X-Gm-Message-State: ACgBeo1/WuRBAbv9Bb+bjAjr1943LNfPnP7U+qb4M/kZvku9D1pqOMUZ V6fZx52DUMDWaYsdqdZyvfOxopMF8FGh X-Google-Smtp-Source: AA6agR58xrTHINBcIHmygNCoNROVgasw5mDApSTlMhqeU5Yj+vZW9bTi8O7i/Nbl1MEyCviYrFR9sAbwVrCR X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a81:2f8a:0:b0:31e:7c60:5d61 with SMTP id v132-20020a812f8a000000b0031e7c605d61mr2073897ywv.6.1659080675636; Fri, 29 Jul 2022 00:44:35 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:47 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-14-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 13/17] perf pmu-events: Don't assume pmu_event is an array From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Current code assumes that a struct pmu_event can be iterated over forward until a NULL pmu_event is encountered. This makes it difficult to refactor pmu_event. Add a loop function taking a callback function that's passed the struct pmu_event. This way the pmu_event is only needed for one element and not an entire array. Switch existing code iterating over the pmu_event arrays to use the new loop function pmu_events_table_for_each_event. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 34 +++-- tools/perf/pmu-events/jevents.py | 34 +++-- tools/perf/pmu-events/pmu-events.h | 3 + tools/perf/tests/pmu-events.c | 136 +++++++++-------- tools/perf/util/metricgroup.c | 181 ++++++++++++++++------- tools/perf/util/pmu.c | 65 ++++---- tools/perf/util/s390-sample-raw.c | 42 ++++-- 7 files changed, 313 insertions(+), 182 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 028f44efe48d..bee1967baa2b 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -247,6 +247,20 @@ static const struct pmu_sys_events pmu_sys_event_table= s[] =3D { }, }; =20 +int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, + void *data) +{ + for (const struct pmu_event *pe =3D &table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, table, data); + + if (ret) + return ret; + } + return 0; +} + const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) { const struct pmu_event *table =3D NULL; @@ -291,14 +305,10 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, voi= d *data) for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; tables->table; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } @@ -319,14 +329,10 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void= *data) for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; tables->name; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index e976c5e8e80b..365c960202b0 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -409,6 +409,20 @@ static const struct pmu_sys_events pmu_sys_event_table= s[] =3D { \t}, }; =20 +int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, + void *data) +{ + for (const struct pmu_event *pe =3D &table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, table, data); + + if (ret) + return ret; + } + return 0; +} + const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) { const struct pmu_event *table =3D NULL; @@ -452,14 +466,10 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, voi= d *data) for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; tables->table; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table,= fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } @@ -480,14 +490,10 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void= *data) for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; tables->name; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table,= fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 485e730f9922..70672842f77f 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -34,6 +34,9 @@ typedef int (*pmu_event_iter_fn)(const struct pmu_event *= pe, const struct pmu_event *table, void *data); =20 +int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, + void *data); + const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu); const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid); int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data); diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index e8df6bc26ebd..1c3479e5890e 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -423,84 +423,104 @@ static int compare_alias_to_test_event(struct perf_p= mu_alias *alias, return 0; } =20 -/* Verify generated events from pmu-events.c are as expected */ -static int test__pmu_event_table(struct test_suite *test __maybe_unused, - int subtest __maybe_unused) +static int test__pmu_event_table_core_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data) { - const struct pmu_event *sys_event_tables =3D find_sys_events_table("pme_t= est_soc_sys"); - const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); - int map_events =3D 0, expected_events; + int *map_events =3D data; + struct perf_pmu_test_event const **test_event_table; + bool found =3D false; =20 - /* ignore 3x sentinels */ - expected_events =3D ARRAY_SIZE(core_events) + - ARRAY_SIZE(uncore_events) + - ARRAY_SIZE(sys_events) - 3; + if (!pe->name) + return 0; =20 - if (!table || !sys_event_tables) - return -1; + if (pe->pmu) + test_event_table =3D &uncore_events[0]; + else + test_event_table =3D &core_events[0]; =20 - for (; table->name; table++) { - struct perf_pmu_test_event const **test_event_table; - bool found =3D false; + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event =3D *test_event_table; + struct pmu_event const *event =3D &test_event->event; =20 - if (table->pmu) - test_event_table =3D &uncore_events[0]; - else - test_event_table =3D &core_events[0]; + if (strcmp(pe->name, event->name)) + continue; + found =3D true; + (*map_events)++; =20 - for (; *test_event_table; test_event_table++) { - struct perf_pmu_test_event const *test_event =3D *test_event_table; - struct pmu_event const *event =3D &test_event->event; + if (compare_pmu_events(pe, event)) + return -1; =20 - if (strcmp(table->name, event->name)) - continue; - found =3D true; - map_events++; + pr_debug("testing event table %s: pass\n", pe->name); + } + if (!found) { + pr_err("testing event table: could not find event %s\n", pe->name); + return -1; + } + return 0; +} =20 - if (compare_pmu_events(table, event)) - return -1; +static int test__pmu_event_table_sys_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data) +{ + int *map_events =3D data; + struct perf_pmu_test_event const **test_event_table; + bool found =3D false; =20 - pr_debug("testing event table %s: pass\n", table->name); - } + test_event_table =3D &sys_events[0]; =20 - if (!found) { - pr_err("testing event table: could not find event %s\n", - table->name); - return -1; - } - } + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event =3D *test_event_table; + struct pmu_event const *event =3D &test_event->event; =20 - for (table =3D sys_event_tables; table->name; table++) { - struct perf_pmu_test_event const **test_event_table; - bool found =3D false; + if (strcmp(pe->name, event->name)) + continue; + found =3D true; + (*map_events)++; =20 - test_event_table =3D &sys_events[0]; + if (compare_pmu_events(pe, event)) + return TEST_FAIL; =20 - for (; *test_event_table; test_event_table++) { - struct perf_pmu_test_event const *test_event =3D *test_event_table; - struct pmu_event const *event =3D &test_event->event; + pr_debug("testing sys event table %s: pass\n", pe->name); + } + if (!found) { + pr_debug("testing sys event table: could not find event %s\n", pe->name); + return TEST_FAIL; + } + return TEST_OK; +} =20 - if (strcmp(table->name, event->name)) - continue; - found =3D true; - map_events++; +/* Verify generated events from pmu-events.c are as expected */ +static int test__pmu_event_table(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) +{ + const struct pmu_event *sys_event_table =3D find_sys_events_table("pme_te= st_soc_sys"); + const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); + int map_events =3D 0, expected_events, err; =20 - if (compare_pmu_events(table, event)) - return -1; + /* ignore 3x sentinels */ + expected_events =3D ARRAY_SIZE(core_events) + + ARRAY_SIZE(uncore_events) + + ARRAY_SIZE(sys_events) - 3; =20 - pr_debug("testing sys event table %s: pass\n", table->name); - } - if (!found) { - pr_debug("testing event table: could not find event %s\n", - table->name); - return -1; - } - } + if (!table || !sys_event_table) + return -1; + + err =3D pmu_events_table_for_each_event(table, test__pmu_event_table_core= _callback, + &map_events); + if (err) + return err; + + err =3D pmu_events_table_for_each_event(sys_event_table, test__pmu_event_= table_sys_callback, + &map_events); + if (err) + return err; =20 if (map_events !=3D expected_events) { pr_err("testing event table: found %d, but expected %d\n", map_events, expected_events); - return -1; + return TEST_FAIL; } =20 return 0; diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 680f7c63838d..f702b73a7609 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -538,12 +538,40 @@ static int metricgroup__print_sys_event_iter(const st= ruct pmu_event *pe, d->details, d->groups, d->metriclist); } =20 +struct metricgroup_print_data { + const char *pmu_name; + struct strlist *metriclist; + char *filter; + struct rblist *groups; + bool metricgroups; + bool raw; + bool details; +}; + +static int metricgroup__print_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct metricgroup_print_data *data =3D vdata; + + if (!pe->metric_expr) + return 0; + + if (data->pmu_name && perf_pmu__is_hybrid(pe->pmu) && strcmp(data->pmu_na= me, pe->pmu)) + return 0; + + return metricgroup__print_pmu_event(pe, data->metricgroups, data->filter, + data->raw, data->details, data->groups, + data->metriclist); +} + void metricgroup__print(bool metrics, bool metricgroups, char *filter, bool raw, bool details, const char *pmu_name) { struct rblist groups; struct rb_node *node, *next; struct strlist *metriclist =3D NULL; + const struct pmu_event *table; =20 if (!metricgroups) { metriclist =3D strlist__new(NULL, NULL); @@ -555,22 +583,22 @@ void metricgroup__print(bool metrics, bool metricgrou= ps, char *filter, groups.node_new =3D mep_new; groups.node_cmp =3D mep_cmp; groups.node_delete =3D mep_delete; - for (const struct pmu_event *pe =3D pmu_events_map__find(); pe; pe++) { + table =3D pmu_events_map__find(); + if (table) { + struct metricgroup_print_data data =3D { + .pmu_name =3D pmu_name, + .metriclist =3D metriclist, + .metricgroups =3D metricgroups, + .filter =3D filter, + .raw =3D raw, + .details =3D details, + .groups =3D &groups, + }; =20 - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - if (!pe->metric_expr) - continue; - if (pmu_name && perf_pmu__is_hybrid(pe->pmu) && - strcmp(pmu_name, pe->pmu)) { - continue; - } - if (metricgroup__print_pmu_event(pe, metricgroups, filter, - raw, details, &groups, - metriclist) < 0) - return; + pmu_events_table_for_each_event(table, + metricgroup__print_callback, + &data); } - { struct metricgroup_iter_data data =3D { .fn =3D metricgroup__print_sys_event_iter, @@ -1043,30 +1071,35 @@ static int __add_metric(struct list_head *metric_li= st, return ret; } =20 -#define table_for_each_event(__pe, __idx, __table) \ - if (__table) \ - for (__idx =3D 0, __pe =3D &__table[__idx]; \ - __pe->name || __pe->metric_group || __pe->metric_name; \ - __pe =3D &__table[++__idx]) +struct metricgroup__find_metric_data { + const char *metric; + const struct pmu_event *pe; +}; + +static int metricgroup__find_metric_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct metricgroup__find_metric_data *data =3D vdata; + + if (!match_metric(pe->metric_name, data->metric)) + return 0; =20 -#define table_for_each_metric(__pe, __idx, __table, __metric) \ - table_for_each_event(__pe, __idx, __table) \ - if (__pe->metric_expr && \ - (match_metric(__pe->metric_group, __metric) || \ - match_metric(__pe->metric_name, __metric))) + data->pe =3D pe; + return -1; +} =20 const struct pmu_event *metricgroup__find_metric(const char *metric, const struct pmu_event *table) { - const struct pmu_event *pe; - int i; + struct metricgroup__find_metric_data data =3D { + .metric =3D metric, + .pe =3D NULL, + }; =20 - table_for_each_event(pe, i, table) { - if (match_metric(pe->metric_name, metric)) - return pe; - } + pmu_events_table_for_each_event(table, metricgroup__find_metric_callback,= &data); =20 - return NULL; + return data.pe; } =20 static int add_metric(struct list_head *metric_list, @@ -1151,6 +1184,33 @@ static int metric_list_cmp(void *priv __maybe_unused= , const struct list_head *l, return right_count - left_count; } =20 +struct metricgroup__add_metric_data { + struct list_head *list; + const char *metric_name; + const char *modifier; + bool metric_no_group; + bool has_match; +}; + +static int metricgroup__add_metric_callback(const struct pmu_event *pe, + const struct pmu_event *table, + void *vdata) +{ + struct metricgroup__add_metric_data *data =3D vdata; + int ret =3D 0; + + if (pe->metric_expr && + (match_metric(pe->metric_group, data->metric_name) || + match_metric(pe->metric_name, data->metric_name))) { + + data->has_match =3D true; + ret =3D add_metric(data->list, pe, data->modifier, data->metric_no_group, + /*root_metric=3D*/NULL, + /*visited_metrics=3D*/NULL, table); + } + return ret; +} + /** * metricgroup__add_metric - Find and add a metric, or a metric group. * @metric_name: The name of the metric or metric group. For example, "IPC" @@ -1169,24 +1229,29 @@ static int metricgroup__add_metric(const char *metr= ic_name, const char *modifier struct list_head *metric_list, const struct pmu_event *table) { - const struct pmu_event *pe; LIST_HEAD(list); - int i, ret; + int ret; bool has_match =3D false; =20 - /* - * Iterate over all metrics seeing if metric matches either the name or - * group. When it does add the metric to the list. - */ - table_for_each_metric(pe, i, table, metric_name) { - has_match =3D true; - ret =3D add_metric(&list, pe, modifier, metric_no_group, - /*root_metric=3D*/NULL, - /*visited_metrics=3D*/NULL, table); + { + struct metricgroup__add_metric_data data =3D { + .list =3D &list, + .metric_name =3D metric_name, + .modifier =3D modifier, + .metric_no_group =3D metric_no_group, + .has_match =3D false, + }; + /* + * Iterate over all metrics seeing if metric matches either the + * name or group. When it does add the metric to the list. + */ + ret =3D pmu_events_table_for_each_event(table, metricgroup__add_metric_c= allback, + &data); if (ret) goto out; - } =20 + has_match =3D data.has_match; + } { struct metricgroup_iter_data data =3D { .fn =3D metricgroup__add_metric_sys_event_iter, @@ -1602,26 +1667,30 @@ int metricgroup__parse_groups_test(struct evlist *e= vlist, metric_no_merge, &perf_pmu__fake, metric_events, table); } =20 +static int metricgroup__has_metric_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + const char *metric =3D vdata; + + if (!pe->metric_expr) + return 0; + + if (match_metric(pe->metric_name, metric)) + return 1; + + return 0; +} + bool metricgroup__has_metric(const char *metric) { const struct pmu_event *table =3D pmu_events_map__find(); - const struct pmu_event *pe; - int i; =20 if (!table) return false; =20 - for (i =3D 0; ; i++) { - pe =3D &table[i]; - - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - if (!pe->metric_expr) - continue; - if (match_metric(pe->metric_name, metric)) - return true; - } - return false; + return pmu_events_table_for_each_event(table, metricgroup__has_metric_cal= lback, + (void *)metric) ? true : false; } =20 int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *= cgrp, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 5bb03d4e52a3..ab94d672d7bf 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -791,6 +791,36 @@ bool pmu_uncore_alias_match(const char *pmu_name, cons= t char *name) return res; } =20 +struct pmu_add_cpu_aliases_map_data { + struct list_head *head; + const char *name; + const char *cpu_name; + struct perf_pmu *pmu; +}; + +static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct pmu_add_cpu_aliases_map_data *data =3D vdata; + const char *pname =3D pe->pmu ? pe->pmu : data->cpu_name; + + if (!pe->name) + return 0; + + if (data->pmu->is_uncore && pmu_uncore_alias_match(pname, data->name)) + goto new_alias; + + if (strcmp(pname, data->name)) + return 0; + +new_alias: + /* need type casts to override 'const' */ + __perf_pmu__new_alias(data->head, NULL, (char *)pe->name, (char *)pe->des= c, + (char *)pe->event, pe); + return 0; +} + /* * From the pmu_events_map, find the table of PMU events that corresponds * to the current running CPU. Then, add all PMU events from that table @@ -799,35 +829,14 @@ bool pmu_uncore_alias_match(const char *pmu_name, con= st char *name) void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, const struct pmu_event *table) { - int i; - const char *name =3D pmu->name; - /* - * Found a matching PMU events table. Create aliases - */ - i =3D 0; - while (1) { - const char *cpu_name =3D is_arm_pmu_core(name) ? name : "cpu"; - const struct pmu_event *pe =3D &table[i++]; - const char *pname =3D pe->pmu ? pe->pmu : cpu_name; - - if (!pe->name) { - if (pe->metric_group || pe->metric_name) - continue; - break; - } - - if (pmu->is_uncore && pmu_uncore_alias_match(pname, name)) - goto new_alias; - - if (strcmp(pname, name)) - continue; + struct pmu_add_cpu_aliases_map_data data =3D { + .head =3D head, + .name =3D pmu->name, + .cpu_name =3D is_arm_pmu_core(pmu->name) ? pmu->name : "cpu", + .pmu =3D pmu, + }; =20 -new_alias: - /* need type casts to override 'const' */ - __perf_pmu__new_alias(head, NULL, (char *)pe->name, - (char *)pe->desc, (char *)pe->event, - pe); - } + pmu_events_table_for_each_event(table, pmu_add_cpu_aliases_map_callback, = &data); } =20 static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *p= mu) diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index 1ecb718fc0eb..b1c052c176bb 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -129,6 +129,28 @@ static int get_counterset_start(int setnr) } } =20 +struct get_counter_name_data { + int wanted; + const char *result; +}; + +static int get_counter_name_callback(const struct pmu_event *evp, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct get_counter_name_data *data =3D vdata; + int rc, event_nr; + + if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) + return 0; + rc =3D sscanf(evp->event, "event=3D%x", &event_nr); + if (rc =3D=3D 1 && event_nr =3D=3D data->wanted) { + data->result =3D evp->name; + return 1; /* Terminate the search. */ + } + return 0; +} + /* Scan the PMU table and extract the logical name of a counter from the * PMU events table. Input is the counter set and counter number with in t= he * set. Construct the event number and use this as key. If they match retu= rn @@ -137,20 +159,16 @@ static int get_counterset_start(int setnr) */ static const char *get_counter_name(int set, int nr, const struct pmu_even= t *table) { - int rc, event_nr, wanted =3D get_counterset_start(set) + nr; + struct get_counter_name_data data =3D { + .wanted =3D get_counterset_start(set) + nr, + .result =3D NULL, + }; =20 - if (table) { - const struct pmu_event *evp =3D table; + if (!table) + return NULL; =20 - for (; evp->name || evp->event || evp->desc; ++evp) { - if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) - continue; - rc =3D sscanf(evp->event, "event=3D%x", &event_nr); - if (rc =3D=3D 1 && event_nr =3D=3D wanted) - return evp->name; - } - } - return NULL; + pmu_events_table_for_each_event(table, get_counter_name_callback, &data); + return data.result; } =20 static void s390_cpumcfdg_dump(struct perf_sample *sample) --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85E51C19F2A for ; Fri, 29 Jul 2022 07:45:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235377AbiG2Hp0 (ORCPT ); Fri, 29 Jul 2022 03:45:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54622 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235199AbiG2Ho4 (ORCPT ); Fri, 29 Jul 2022 03:44:56 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2272820EF for ; Fri, 29 Jul 2022 00:44:39 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id k16-20020a252410000000b006718984ef63so3311532ybk.3 for ; Fri, 29 Jul 2022 00:44:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=lbJIQr4Vvv60PESxVdDbhAlSw9LRcNbW3R+YO0jcP94=; b=D9qMEmzbxlQLQLAwGUvFbKrXZrI13hZCML9SPqWfSii21m8DoUs6RC3npHkeSMtsq/ d6cuBtd3cZz7GQ/Xl52F8AeU9PMpKhsBJsvFue6yZq5wUlNxhTO2ILN75xIqx1nrQuDl BOsslgMudJqthhMzpYMFwxqWj72Ap4svHXD508+zMwlBSbVpGb4U2qkdaCyFJ26Xmo7a MsXt7W3vm7a9mbsHaX9TDpI1QhP8Kzz9va6qFytW7YLxhpVkAP4m04ivEK0cKY6bPRl1 n1W8fnROKwpLwHiEytAYvUpUE53wc9pTAyjcEHzEjkHKG0wudUVhr/V0ufvH/2TW3yOG tvfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=lbJIQr4Vvv60PESxVdDbhAlSw9LRcNbW3R+YO0jcP94=; b=5uMdpW2Ru8kUWd3icFeSkgmTsTOlTgr+kib4fkfKROVn3vTu/Wgi5xm0E4vNFY3Hjk 0UL4InpgPYvpLOVNrSqe/X4FF3R90LDWk02pCi1SCacCPHU+ejy/NUjOp3tQvU1XbekZ 3DXFYtd13EFWElZAMZzM04yPfJ1Um4k++F+7zv0M1D+Pd0PU9LhFXT0FUBnOV6bPWTit 7ruWdJ2qcHNbB6s6kYuyGwu22NSkfq55tQrdY1Jxtn3FmgpoStAT1J4szYOYXbWqoN30 rrHXNDWmBbLB+TOfaQh2+fnHFVz1+E4D2+FCJDX4z91WFbdeH3BlEixxd+EKfLcqxJUq ErXg== X-Gm-Message-State: ACgBeo0DBmoMtcOw1SRIo1ZRtYK9gjVPBQ3vuzB+JTFIVJJEqcQeEYdw PHcEUZil0tqYsPgzwpNhqeQS4Zr8mJMj X-Google-Smtp-Source: AA6agR4A5YraZp8PRsTdxNL289SyXJN9NWrSQQ/0jdTKgviJhWCXvZfR9JtOf+Xdet3koKI6PBTBhyRCuhPH X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a05:6902:1082:b0:675:3bca:71fd with SMTP id v2-20020a056902108200b006753bca71fdmr1575028ybu.639.1659080678240; Fri, 29 Jul 2022 00:44:38 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:48 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-15-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 14/17] perf pmu-events: Hide the pmu_events From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hide that the pmu_event structs are an array with a new wrapper struct. Signed-off-by: Ian Rogers --- tools/perf/arch/arm64/util/pmu.c | 2 +- tools/perf/pmu-events/empty-pmu-events.c | 44 ++++++++++++---------- tools/perf/pmu-events/jevents.py | 47 +++++++++++++----------- tools/perf/pmu-events/pmu-events.h | 12 +++--- tools/perf/tests/expand-cgroup.c | 2 +- tools/perf/tests/parse-metric.c | 2 +- tools/perf/tests/pmu-events.c | 16 ++++---- tools/perf/util/metricgroup.c | 42 ++++++++++----------- tools/perf/util/metricgroup.h | 5 +-- tools/perf/util/pmu.c | 10 ++--- tools/perf/util/pmu.h | 4 +- tools/perf/util/s390-sample-raw.c | 6 +-- 12 files changed, 101 insertions(+), 91 deletions(-) diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/= pmu.c index 646af8603227..149fb334b40b 100644 --- a/tools/perf/arch/arm64/util/pmu.c +++ b/tools/perf/arch/arm64/util/pmu.c @@ -3,7 +3,7 @@ #include "../../../util/cpumap.h" #include "../../../util/pmu.h" =20 -const struct pmu_event *pmu_events_map__find(void) +const struct pmu_events_table *pmu_events_map__find(void) { struct perf_pmu *pmu =3D NULL; =20 diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index bee1967baa2b..5ed8c0aa4817 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -176,6 +176,10 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { }, }; =20 +/* Struct used to make the PMU event table implementation opaque to caller= s. */ +struct pmu_events_table { + const struct pmu_event *entries; +}; =20 /* * Map a CPU to its table of PMU events. The CPU is identified by the @@ -188,7 +192,7 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { struct pmu_events_map { const char *arch; const char *cpuid; - const struct pmu_event *table; + const struct pmu_events_table table; }; =20 /* @@ -199,12 +203,12 @@ static const struct pmu_events_map pmu_events_map[] = =3D { { .arch =3D "testarch", .cpuid =3D "testcpu", - .table =3D pme_test_soc_cpu, + .table =3D { pme_test_soc_cpu }, }, { .arch =3D 0, .cpuid =3D 0, - .table =3D 0, + .table =3D { 0 }, }, }; =20 @@ -234,23 +238,23 @@ static const struct pmu_event pme_test_soc_sys[] =3D { =20 struct pmu_sys_events { const char *name; - const struct pmu_event *table; + const struct pmu_events_table table; }; =20 static const struct pmu_sys_events pmu_sys_event_tables[] =3D { { - .table =3D pme_test_soc_sys, + .table =3D { pme_test_soc_sys }, .name =3D "pme_test_soc_sys", }, { - .table =3D 0 + .table =3D { 0 } }, }; =20 -int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, +int pmu_events_table_for_each_event(const struct pmu_events_table *table, = pmu_event_iter_fn fn, void *data) { - for (const struct pmu_event *pe =3D &table[0]; + for (const struct pmu_event *pe =3D &table->entries[0]; pe->name || pe->metric_group || pe->metric_name; pe++) { int ret =3D fn(pe, table, data); @@ -261,9 +265,9 @@ int pmu_events_table_for_each_event(const struct pmu_ev= ent *table, pmu_event_ite return 0; } =20 -const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) +const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu) { - const struct pmu_event *table =3D NULL; + const struct pmu_events_table *table =3D NULL; char *cpuid =3D perf_pmu__getcpuid(pmu); int i; =20 @@ -277,11 +281,11 @@ const struct pmu_event *perf_pmu__find_table(struct p= erf_pmu *pmu) for (;;) { const struct pmu_events_map *map =3D &pmu_events_map[i++]; =20 - if (!map->table) + if (!map->cpuid) break; =20 if (!strcmp_cpuid_str(map->cpuid, cpuid)) { - table =3D map->table; + table =3D &map->table; break; } } @@ -289,13 +293,13 @@ const struct pmu_event *perf_pmu__find_table(struct p= erf_pmu *pmu) return table; } =20 -const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid) +const struct pmu_events_table *find_core_events_table(const char *arch, co= nst char *cpuid) { for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; - tables->table; + tables->arch; tables++) { if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpui= d)) - return tables->table; + return &tables->table; } return NULL; } @@ -303,9 +307,9 @@ const struct pmu_event *find_core_events_table(const ch= ar *arch, const char *cpu int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) { for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; - tables->table; + tables->arch; tables++) { - int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); + int ret =3D pmu_events_table_for_each_event(&tables->table, fn, data); =20 if (ret) return ret; @@ -313,13 +317,13 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, voi= d *data) return 0; } =20 -const struct pmu_event *find_sys_events_table(const char *name) +const struct pmu_events_table *find_sys_events_table(const char *name) { for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; tables->name; tables++) { if (!strcmp(tables->name, name)) - return tables->table; + return &tables->table; } return NULL; } @@ -329,7 +333,7 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *= data) for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; tables->name; tables++) { - int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); + int ret =3D pmu_events_table_for_each_event(&tables->table, fn, data); =20 if (ret) return ret; diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 365c960202b0..aa8df649025a 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -334,6 +334,11 @@ def process_one_file(parents: Sequence[str], item: os.= DirEntry) -> None: def print_mapping_table(archs: Sequence[str]) -> None: """Read the mapfile and generate the struct from cpuid string to event t= able.""" _args.output_file.write(""" +/* Struct used to make the PMU event table implementation opaque to caller= s. */ +struct pmu_events_table { + const struct pmu_event *entries; +}; + /* * Map a CPU to its table of PMU events. The CPU is identified by the * cpuid field, which is an arch-specific identifier for the CPU. @@ -345,7 +350,7 @@ def print_mapping_table(archs: Sequence[str]) -> None: struct pmu_events_map { const char *arch; const char *cpuid; - const struct pmu_event *table; + struct pmu_events_table table; }; =20 /* @@ -359,7 +364,7 @@ const struct pmu_events_map pmu_events_map[] =3D { _args.output_file.write("""{ \t.arch =3D "testarch", \t.cpuid =3D "testcpu", -\t.table =3D pme_test_soc_cpu, +\t.table =3D { pme_test_soc_cpu }, }, """) else: @@ -374,7 +379,7 @@ const struct pmu_events_map pmu_events_map[] =3D { _args.output_file.write(f"""{{ \t.arch =3D "{arch}", \t.cpuid =3D "{cpuid}", -\t.table =3D {tblname} +\t.table =3D {{ {tblname} }} }}, """) first =3D False @@ -382,7 +387,7 @@ const struct pmu_events_map pmu_events_map[] =3D { _args.output_file.write("""{ \t.arch =3D 0, \t.cpuid =3D 0, -\t.table =3D 0, +\t.table =3D { 0 }, } }; """) @@ -393,26 +398,26 @@ def print_system_mapping_table() -> None: _args.output_file.write(""" struct pmu_sys_events { \tconst char *name; -\tconst struct pmu_event *table; +\tstruct pmu_events_table table; }; =20 static const struct pmu_sys_events pmu_sys_event_tables[] =3D { """) for tblname in _sys_event_tables: _args.output_file.write(f"""\t{{ -\t\t.table =3D {tblname}, +\t\t.table =3D {{ {tblname} }}, \t\t.name =3D \"{tblname}\", \t}}, """) _args.output_file.write("""\t{ -\t\t.table =3D 0 +\t\t.table =3D { 0 } \t}, }; =20 -int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, +int pmu_events_table_for_each_event(const struct pmu_events_table *table, = pmu_event_iter_fn fn, void *data) { - for (const struct pmu_event *pe =3D &table[0]; + for (const struct pmu_event *pe =3D &table->entries[0]; pe->name || pe->metric_group || pe->metric_name; pe++) { int ret =3D fn(pe, table, data); @@ -423,9 +428,9 @@ int pmu_events_table_for_each_event(const struct pmu_ev= ent *table, pmu_event_ite return 0; } =20 -const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) +const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu) { - const struct pmu_event *table =3D NULL; + const struct pmu_events_table *table =3D NULL; char *cpuid =3D perf_pmu__getcpuid(pmu); int i; =20 @@ -438,11 +443,11 @@ const struct pmu_event *perf_pmu__find_table(struct p= erf_pmu *pmu) i =3D 0; for (;;) { const struct pmu_events_map *map =3D &pmu_events_map[i++]; - if (!map->table) + if (!map->arch) break; =20 if (!strcmp_cpuid_str(map->cpuid, cpuid)) { - table =3D map->table; + table =3D &map->table; break; } } @@ -450,13 +455,13 @@ const struct pmu_event *perf_pmu__find_table(struct p= erf_pmu *pmu) return table; } =20 -const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid) +const struct pmu_events_table *find_core_events_table(const char *arch, co= nst char *cpuid) { for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; - tables->table; + tables->arch; tables++) { if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(table= s->cpuid, cpuid)) - return tables->table; + return &tables->table; } return NULL; } @@ -464,9 +469,9 @@ const struct pmu_event *find_core_events_table(const ch= ar *arch, const char *cpu int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) { for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; - tables->table; + tables->arch; tables++) { - int ret =3D pmu_events_table_for_each_event(tables->table,= fn, data); + int ret =3D pmu_events_table_for_each_event(&tables->table= , fn, data); =20 if (ret) return ret; @@ -474,13 +479,13 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, voi= d *data) return 0; } =20 -const struct pmu_event *find_sys_events_table(const char *name) +const struct pmu_events_table *find_sys_events_table(const char *name) { for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; tables->name; tables++) { if (!strcmp(tables->name, name)) - return tables->table; + return &tables->table; } return NULL; } @@ -490,7 +495,7 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *= data) for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; tables->name; tables++) { - int ret =3D pmu_events_table_for_each_event(tables->table,= fn, data); + int ret =3D pmu_events_table_for_each_event(&tables->table= , fn, data); =20 if (ret) return ret; diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 70672842f77f..fe343c4d8016 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -30,18 +30,20 @@ struct pmu_event { const char *metric_constraint; }; =20 +struct pmu_events_table; + typedef int (*pmu_event_iter_fn)(const struct pmu_event *pe, - const struct pmu_event *table, + const struct pmu_events_table *table, void *data); =20 -int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, +int pmu_events_table_for_each_event(const struct pmu_events_table *table, = pmu_event_iter_fn fn, void *data); =20 -const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu); -const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid); +const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu); +const struct pmu_events_table *find_core_events_table(const char *arch, co= nst char *cpuid); int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data); =20 -const struct pmu_event *find_sys_events_table(const char *name); +const struct pmu_events_table *find_sys_events_table(const char *name); int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data); =20 #endif diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index e79ee8621a90..51fb5f34c1dd 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -180,7 +180,7 @@ static int expand_metric_events(void) struct evlist *evlist; struct rblist metric_events; const char metric_str[] =3D "CPI"; - const struct pmu_event *pme_test; + const struct pmu_events_table *pme_test; =20 evlist =3D evlist__new(); TEST_ASSERT_VAL("failed to get evlist", evlist); diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 30c7091857b8..68f5a2a03242 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -72,7 +72,7 @@ static int __compute_metric(const char *name, struct valu= e *vals, struct rblist metric_events =3D { .nr_entries =3D 0, }; - const struct pmu_event *pme_test; + const struct pmu_events_table *pme_test; struct perf_cpu_map *cpus; struct runtime_stat st; struct evlist *evlist; diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 1c3479e5890e..9111725041d0 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -424,7 +424,7 @@ static int compare_alias_to_test_event(struct perf_pmu_= alias *alias, } =20 static int test__pmu_event_table_core_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data) { int *map_events =3D data; @@ -461,7 +461,7 @@ static int test__pmu_event_table_core_callback(const st= ruct pmu_event *pe, } =20 static int test__pmu_event_table_sys_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data) { int *map_events =3D data; @@ -495,8 +495,8 @@ static int test__pmu_event_table_sys_callback(const str= uct pmu_event *pe, static int test__pmu_event_table(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_event *sys_event_table =3D find_sys_events_table("pme_te= st_soc_sys"); - const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); + const struct pmu_events_table *sys_event_table =3D find_sys_events_table(= "pme_test_soc_sys"); + const struct pmu_events_table *table =3D find_core_events_table("testarch= ", "testcpu"); int map_events =3D 0, expected_events, err; =20 /* ignore 3x sentinels */ @@ -544,7 +544,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name= , int *count) struct perf_pmu *pmu; LIST_HEAD(aliases); int res =3D 0; - const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); + const struct pmu_events_table *table =3D find_core_events_table("testarch= ", "testcpu"); struct perf_pmu_alias *a, *tmp; =20 if (!table) @@ -597,7 +597,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) struct perf_pmu *pmu =3D &test_pmu->pmu; const char *pmu_name =3D pmu->name; struct perf_pmu_alias *a, *tmp, *alias; - const struct pmu_event *events_table; + const struct pmu_events_table *events_table; LIST_HEAD(aliases); int res =3D 0; =20 @@ -839,7 +839,7 @@ struct metric { struct metric_ref metric_ref; }; =20 -static int test__parsing_callback(const struct pmu_event *pe, const struct= pmu_event *table, +static int test__parsing_callback(const struct pmu_event *pe, const struct= pmu_events_table *table, void *data) { int *failures =3D data; @@ -1016,7 +1016,7 @@ static int metric_parse_fake(const char *str) } =20 static int test__parsing_fake_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data __maybe_unused) { if (!pe->metric_expr) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index f702b73a7609..8ef44f4b5e9a 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -508,7 +508,7 @@ struct metricgroup_iter_data { }; =20 static int metricgroup__sys_event_iter(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table, void *data) { struct metricgroup_iter_data *d =3D data; @@ -529,7 +529,7 @@ static int metricgroup__sys_event_iter(const struct pmu= _event *pe, } =20 static int metricgroup__print_sys_event_iter(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data) { struct metricgroup_print_sys_idata *d =3D data; @@ -549,7 +549,7 @@ struct metricgroup_print_data { }; =20 static int metricgroup__print_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *vdata) { struct metricgroup_print_data *data =3D vdata; @@ -571,7 +571,7 @@ void metricgroup__print(bool metrics, bool metricgroups= , char *filter, struct rblist groups; struct rb_node *node, *next; struct strlist *metriclist =3D NULL; - const struct pmu_event *table; + const struct pmu_events_table *table; =20 if (!metricgroups) { metriclist =3D strlist__new(NULL, NULL); @@ -876,7 +876,7 @@ struct metricgroup_add_iter_data { bool metric_no_group; struct metric *root_metric; const struct visited_metric *visited; - const struct pmu_event *table; + const struct pmu_events_table *table; }; =20 static int add_metric(struct list_head *metric_list, @@ -885,7 +885,7 @@ static int add_metric(struct list_head *metric_list, bool metric_no_group, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_event *table); + const struct pmu_events_table *table); =20 /** * resolve_metric - Locate metrics within the root metric and recursively = add @@ -908,7 +908,7 @@ static int resolve_metric(struct list_head *metric_list, bool metric_no_group, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_event *table) + const struct pmu_events_table *table) { struct hashmap_entry *cur; size_t bkt; @@ -986,7 +986,7 @@ static int __add_metric(struct list_head *metric_list, int runtime, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_event *table) + const struct pmu_events_table *table) { const struct visited_metric *vm; int ret; @@ -1077,7 +1077,7 @@ struct metricgroup__find_metric_data { }; =20 static int metricgroup__find_metric_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *vdata) { struct metricgroup__find_metric_data *data =3D vdata; @@ -1090,7 +1090,7 @@ static int metricgroup__find_metric_callback(const st= ruct pmu_event *pe, } =20 const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_event *table) + const struct pmu_events_table *table) { struct metricgroup__find_metric_data data =3D { .metric =3D metric, @@ -1108,7 +1108,7 @@ static int add_metric(struct list_head *metric_list, bool metric_no_group, struct metric *root_metric, const struct visited_metric *visited, - const struct pmu_event *table) + const struct pmu_events_table *table) { int ret =3D 0; =20 @@ -1136,8 +1136,8 @@ static int add_metric(struct list_head *metric_list, } =20 static int metricgroup__add_metric_sys_event_iter(const struct pmu_event *= pe, - const struct pmu_event *table __maybe_unused, - void *data) + const struct pmu_events_table *table __maybe_unused, + void *data) { struct metricgroup_add_iter_data *d =3D data; int ret; @@ -1193,7 +1193,7 @@ struct metricgroup__add_metric_data { }; =20 static int metricgroup__add_metric_callback(const struct pmu_event *pe, - const struct pmu_event *table, + const struct pmu_events_table *table, void *vdata) { struct metricgroup__add_metric_data *data =3D vdata; @@ -1227,7 +1227,7 @@ static int metricgroup__add_metric_callback(const str= uct pmu_event *pe, static int metricgroup__add_metric(const char *metric_name, const char *mo= difier, bool metric_no_group, struct list_head *metric_list, - const struct pmu_event *table) + const struct pmu_events_table *table) { LIST_HEAD(list); int ret; @@ -1296,7 +1296,7 @@ static int metricgroup__add_metric(const char *metric= _name, const char *modifier */ static int metricgroup__add_metric_list(const char *list, bool metric_no_g= roup, struct list_head *metric_list, - const struct pmu_event *table) + const struct pmu_events_table *table) { char *list_itr, *list_copy, *metric_name, *modifier; int ret, count =3D 0; @@ -1504,7 +1504,7 @@ static int parse_groups(struct evlist *perf_evlist, c= onst char *str, bool metric_no_merge, struct perf_pmu *fake_pmu, struct rblist *metric_events_list, - const struct pmu_event *table) + const struct pmu_events_table *table) { struct evlist *combined_evlist =3D NULL; LIST_HEAD(metric_list); @@ -1650,14 +1650,14 @@ int metricgroup__parse_groups(const struct option *= opt, struct rblist *metric_events) { struct evlist *perf_evlist =3D *(struct evlist **)opt->value; - const struct pmu_event *table =3D pmu_events_map__find(); + const struct pmu_events_table *table =3D pmu_events_map__find(); =20 return parse_groups(perf_evlist, str, metric_no_group, metric_no_merge, NULL, metric_events, table); } =20 int metricgroup__parse_groups_test(struct evlist *evlist, - const struct pmu_event *table, + const struct pmu_events_table *table, const char *str, bool metric_no_group, bool metric_no_merge, @@ -1668,7 +1668,7 @@ int metricgroup__parse_groups_test(struct evlist *evl= ist, } =20 static int metricgroup__has_metric_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *vdata) { const char *metric =3D vdata; @@ -1684,7 +1684,7 @@ static int metricgroup__has_metric_callback(const str= uct pmu_event *pe, =20 bool metricgroup__has_metric(const char *metric) { - const struct pmu_event *table =3D pmu_events_map__find(); + const struct pmu_events_table *table =3D pmu_events_map__find(); =20 if (!table) return false; diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 5a1390e73d25..f54d170043e9 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -11,7 +11,6 @@ struct evlist; struct evsel; struct option; struct rblist; -struct pmu_events_map; struct cgroup; =20 /** @@ -71,9 +70,9 @@ int metricgroup__parse_groups(const struct option *opt, bool metric_no_merge, struct rblist *metric_events); const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_event *table); + const struct pmu_events_table *table); int metricgroup__parse_groups_test(struct evlist *evlist, - const struct pmu_event *table, + const struct pmu_events_table *table, const char *str, bool metric_no_group, bool metric_no_merge, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index ab94d672d7bf..a84fa532817f 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -710,7 +710,7 @@ char *perf_pmu__getcpuid(struct perf_pmu *pmu) return cpuid; } =20 -__weak const struct pmu_event *pmu_events_map__find(void) +__weak const struct pmu_events_table *pmu_events_map__find(void) { return perf_pmu__find_table(NULL); } @@ -799,7 +799,7 @@ struct pmu_add_cpu_aliases_map_data { }; =20 static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *vdata) { struct pmu_add_cpu_aliases_map_data *data =3D vdata; @@ -827,7 +827,7 @@ static int pmu_add_cpu_aliases_map_callback(const struc= t pmu_event *pe, * as aliases. */ void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, - const struct pmu_event *table) + const struct pmu_events_table *table) { struct pmu_add_cpu_aliases_map_data data =3D { .head =3D head, @@ -841,7 +841,7 @@ void pmu_add_cpu_aliases_map(struct list_head *head, st= ruct perf_pmu *pmu, =20 static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *p= mu) { - const struct pmu_event *table; + const struct pmu_events_table *table; =20 table =3D perf_pmu__find_table(pmu); if (!table) @@ -856,7 +856,7 @@ struct pmu_sys_event_iter_data { }; =20 static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data) { struct pmu_sys_event_iter_data *idata =3D data; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 06df99ba2029..78f87b46ddf3 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -126,10 +126,10 @@ int perf_pmu__test(void); =20 struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu); void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, - const struct pmu_event *map); + const struct pmu_events_table *map); =20 char *perf_pmu__getcpuid(struct perf_pmu *pmu); -const struct pmu_event *pmu_events_map__find(void); +const struct pmu_events_table *pmu_events_map__find(void); bool pmu_uncore_alias_match(const char *pmu_name, const char *name); void perf_pmu_free_alias(struct perf_pmu_alias *alias); =20 diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index b1c052c176bb..fad1e96c74ba 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -135,7 +135,7 @@ struct get_counter_name_data { }; =20 static int get_counter_name_callback(const struct pmu_event *evp, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *vdata) { struct get_counter_name_data *data =3D vdata; @@ -157,7 +157,7 @@ static int get_counter_name_callback(const struct pmu_e= vent *evp, * the name of this counter. * If no match is found a NULL pointer is returned. */ -static const char *get_counter_name(int set, int nr, const struct pmu_even= t *table) +static const char *get_counter_name(int set, int nr, const struct pmu_even= ts_table *table) { struct get_counter_name_data data =3D { .wanted =3D get_counterset_start(set) + nr, @@ -177,7 +177,7 @@ static void s390_cpumcfdg_dump(struct perf_sample *samp= le) unsigned char *buf =3D sample->raw_data; const char *color =3D PERF_COLOR_BLUE; struct cf_ctrset_entry *cep, ce; - const struct pmu_event *table; + const struct pmu_events_table *table; u64 *p; =20 table =3D pmu_events_map__find(); --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4288C00144 for ; Fri, 29 Jul 2022 07:45:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235386AbiG2Hpc (ORCPT ); Fri, 29 Jul 2022 03:45:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53804 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234988AbiG2Ho5 (ORCPT ); Fri, 29 Jul 2022 03:44:57 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D306820E3 for ; Fri, 29 Jul 2022 00:44:41 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id a6-20020a25bac6000000b00672f6e71f15so3328001ybk.13 for ; Fri, 29 Jul 2022 00:44:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Erk4wRaNj75eOg4s5q1IE3PwAROzueG5Y9xXx5fRq5Q=; b=ceYcCHEt7cwQaf9fLFr6VwUHtuxA9NHhZDIFt4KvpdG/SeMYeJPImEw0TanZvYTkSO jxaYirq2ZfEhQN4eL6O7B494n5LDZqNi3ksV3esyIHxLlRwdNuHXt0C7VsHp4kogIIFw d/Id+nA+3IB1S9Yua+EMBvoGJ+VYKvhLZ/LNfHKbURQIO2jtj3BLHo98MOs4o42FrlyD cVgmPQ0brptiV3OAElYPAPf0rQzWbLQDDEivGL/N8NiTvYuD+Z3myQ/FBSGQvZB3twvl Xei2Q34PCWYF7BbzHnwodGeINBAiTH6WeEhnnWqYbi9AMWD3W0+IjeN2SVm5+Ev+JMTM eXFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Erk4wRaNj75eOg4s5q1IE3PwAROzueG5Y9xXx5fRq5Q=; b=P82/KxMwem55SDdX69nMkH32cKfDxHhS5VkXVWahv1Bc6fJ+sT6tR8AD9cGNBPOHjk 5LFjESgS7p/BTrNiuLDG8ku/dH/pE431uantxIBWSbWSZHuge1VTaXMpmOj5pl2hh/58 Vl6ddPI9rrCdyB0lDxsSfuSBMv5TCG/cfNC1jlnNQi9W8FQkH4MsZphmjRR4Yu+FsfAY A6Tl2gTOtR4EUfcjlwOMhLOFWzOSveWZXRXmNLIvr0DYLar44CXWlEHMYTCpUSaFNv4+ 0f26UEKN9gRqiC2UKmIi/bRfxeVi+HlqxqCfaaF3Q4//85zSr1qvNIJGanqUaY+QNE2Y sMaQ== X-Gm-Message-State: ACgBeo0W4zA7GNWSp7qdAAygh6ThNR3CelRMQZ/+L3pAaZQZsGK4JNJt GEaavAprTR8kiWisVWb9WFpXFDm1+/96 X-Google-Smtp-Source: AA6agR6TGWhOWiiJl2Sd9EKoOSeuAgEOCnNPhdEE5jN6zK7mLkK9MFuLjnjdzhv40GzTcEJLgEjZoKdkXIei X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a0d:e004:0:b0:31f:311d:2351 with SMTP id j4-20020a0de004000000b0031f311d2351mr1986253ywe.10.1659080680507; Fri, 29 Jul 2022 00:44:40 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:49 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-16-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 15/17] perf metrics: Copy entire pmu_event in find metric From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The pmu_event passed to the pmu_events_table_for_each_event is invalid after the loop. Copy the entire struct in metricgroup__find_metric. Reduce the scope of this function to static. Signed-off-by: Ian Rogers --- tools/perf/util/metricgroup.c | 33 ++++++++++++++++++--------------- tools/perf/util/metricgroup.h | 2 -- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8ef44f4b5e9a..95f4b46dba09 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -879,6 +879,10 @@ struct metricgroup_add_iter_data { const struct pmu_events_table *table; }; =20 +static bool metricgroup__find_metric(const char *metric, + const struct pmu_events_table *table, + struct pmu_event *pe); + static int add_metric(struct list_head *metric_list, const struct pmu_event *pe, const char *modifier, @@ -914,7 +918,7 @@ static int resolve_metric(struct list_head *metric_list, size_t bkt; struct to_resolve { /* The metric to resolve. */ - const struct pmu_event *pe; + struct pmu_event pe; /* * The key in the IDs map, this may differ from in case, * etc. from pe->metric_name. @@ -928,16 +932,15 @@ static int resolve_metric(struct list_head *metric_li= st, * the pending array. */ hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) { - const struct pmu_event *pe; + struct pmu_event pe; =20 - pe =3D metricgroup__find_metric(cur->key, table); - if (pe) { + if (metricgroup__find_metric(cur->key, table, &pe)) { pending =3D realloc(pending, (pending_cnt + 1) * sizeof(struct to_resolve)); if (!pending) return -ENOMEM; =20 - pending[pending_cnt].pe =3D pe; + memcpy(&pending[pending_cnt].pe, &pe, sizeof(pe)); pending[pending_cnt].key =3D cur->key; pending_cnt++; } @@ -952,7 +955,7 @@ static int resolve_metric(struct list_head *metric_list, * context. */ for (i =3D 0; i < pending_cnt; i++) { - ret =3D add_metric(metric_list, pending[i].pe, modifier, metric_no_group, + ret =3D add_metric(metric_list, &pending[i].pe, modifier, metric_no_grou= p, root_metric, visited, table); if (ret) break; @@ -1073,7 +1076,7 @@ static int __add_metric(struct list_head *metric_list, =20 struct metricgroup__find_metric_data { const char *metric; - const struct pmu_event *pe; + struct pmu_event *pe; }; =20 static int metricgroup__find_metric_callback(const struct pmu_event *pe, @@ -1085,21 +1088,21 @@ static int metricgroup__find_metric_callback(const = struct pmu_event *pe, if (!match_metric(pe->metric_name, data->metric)) return 0; =20 - data->pe =3D pe; - return -1; + memcpy(data->pe, pe, sizeof(*pe)); + return 1; } =20 -const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_events_table *table) +static bool metricgroup__find_metric(const char *metric, + const struct pmu_events_table *table, + struct pmu_event *pe) { struct metricgroup__find_metric_data data =3D { .metric =3D metric, - .pe =3D NULL, + .pe =3D pe, }; =20 - pmu_events_table_for_each_event(table, metricgroup__find_metric_callback,= &data); - - return data.pe; + return pmu_events_table_for_each_event(table, metricgroup__find_metric_ca= llback, &data) + ? true : false; } =20 static int add_metric(struct list_head *metric_list, diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index f54d170043e9..016b3b1a289a 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -69,8 +69,6 @@ int metricgroup__parse_groups(const struct option *opt, bool metric_no_group, bool metric_no_merge, struct rblist *metric_events); -const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_events_table *table); int metricgroup__parse_groups_test(struct evlist *evlist, const struct pmu_events_table *table, const char *str, --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 945AEC19F2C for ; Fri, 29 Jul 2022 07:45:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235233AbiG2Hpg (ORCPT ); Fri, 29 Jul 2022 03:45:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235208AbiG2Ho5 (ORCPT ); Fri, 29 Jul 2022 03:44:57 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D29E81B03 for ; Fri, 29 Jul 2022 00:44:43 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f46b4759bso36515287b3.0 for ; Fri, 29 Jul 2022 00:44:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=LRUf8d+uURXL8SFXLgyV3gEjVEvyagZOOmx5cGvuJJs=; b=Gm1u/Sc9Ujk0HD2StHcNwyJbN78keb1bm/Jz1Gi4C2ycVyK3Dlp5nQPpdoOKeAOZ4m Qh4yvrxF53P0gKQmrw8uSfCML/RDQOtisVTMTjH/SBD/10CxQyr4PhAQ1vDAo4aTWvby M5oA0BqwelZuR1cLrEnrTvNsTAJrQ2Z966j2ImqKWFbGey0aDOZfJj8guBTX0wHiJ+dJ /oWZWGGhDyY+L4A1axvbC/hRbA834iaQCRBHVVpTObXKWywlFiEmM5g+xr6PYz46XJcg Bhmb3Kp7tuB8GqRXjmOZDHcvCYivO6JdNJ5qX09+BV+uMg5/3rkDupGTxK0ZV25xvzIU AnFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=LRUf8d+uURXL8SFXLgyV3gEjVEvyagZOOmx5cGvuJJs=; b=oP92zOAQUam6FGpLDheYH8QKvHe0qGWC9hZwGadcDWdPHhIAETaz4OqBZ0H4l9Ppcg K0omRgl3uTW+DDjxtgGawtTMomW//7YFpkS/Ls7GjcdDk7MMXPG5dJfnoQRTPFi+IWuc R8JUa4rnHjt4RYoXDiGo3WRNGaYRWd7I1ZTz1VSFL++pGGWNOARH9TtwA2mS8BDzes9K EqcokX0AnEuXhJcM85OHQYm0B4/mgVpcW04woFEvBXa0nJ4hlF+sr6lts4fULK36hxXX NU/axNlTRMckQh6C4EIbHXiKpSz1rM0r6C7BkzSSE74Fsmdi+rGN7psQExMKGEOkfHim Jyuw== X-Gm-Message-State: ACgBeo0svWHEscb2im5JuuTQexfXeejCYqkB6Dv9C6JyZSWJXDc+FoP/ ZveJaOQZXzJqjHBTNKgqWRlwAlob3jTl X-Google-Smtp-Source: AA6agR7iT1NwWyMqAJ1jxVyIPRgvozaMjfN1CoV84qYye7v1G98MN/uWPv1gSNoTb1YPCyqKZj3+NfniwJoH X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a81:5a09:0:b0:31e:77a0:6f45 with SMTP id o9-20020a815a09000000b0031e77a06f45mr2069610ywb.59.1659080682920; Fri, 29 Jul 2022 00:44:42 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:50 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-17-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 16/17] perf jevents: Compress the pmu_events_table From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The pmu_events array requires 15 pointers per entry which in position independent code need relocating. Change the array to be an array of offsets within a big C string. Only the offset of the first variable is required, subsequent variables are stored in order after the \0 terminator (requiring a byte per variable rather than 4 bytes per offset). The file size savings are: no jevents - the same 19,788,464bytes x86 jevents - ~16.7% file size saving 23,744,288bytes vs 28,502,632bytes all jevents - ~19.5% file size saving 24,469,056bytes vs 30,379,920bytes default build options plus NO_LIBBFD=3D1. For example, the x86 build savings come from .rela.dyn and .data.rel.ro becoming smaller by 3,157,032bytes and 3,042,016bytes respectively. .rodata increases by 1,432,448bytes, giving an overall 4,766,600bytes saving. To make metric strings more shareable, the topic is changed from say 'skx metrics' to just 'metrics'. To try to help with the memory layout the pmu_events are ordered as used by perf qsort comparator functions. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 207 ++++++++++++++++++++++++------- 1 file changed, 162 insertions(+), 45 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index aa8df649025a..a5e162558994 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -6,7 +6,8 @@ import csv import json import os import sys -from typing import (Callable, Optional, Sequence) +from typing import (Callable, Dict, Optional, Sequence, Set, Tuple) +import collections =20 # Global command line arguments. _args =3D None @@ -20,6 +21,19 @@ _arch_std_events =3D {} _close_table =3D False # Events to write out when the table is closed _pending_events =3D [] +# Global BigCString shared by all structures. +_bcs =3D None +# Order specific JsonEvent attributes will be visited. +_json_event_attributes =3D [ + # cmp_sevent related attributes. + 'name', 'pmu', 'topic', 'desc', 'metric_name', 'metric_group', + # Seems useful, put it early. + 'event', + # Short things in alphabetical order. + 'aggr_mode', 'compat', 'deprecated', 'perpkg', 'unit', + # Longer things (the last won't be iterated over during decompress). + 'metric_constraint', 'metric_expr', 'long_desc' +] =20 =20 def removesuffix(s: str, suffix: str) -> str: @@ -39,6 +53,66 @@ def file_name_to_table_name(parents: Sequence[str], dirn= ame: str) -> str: tblname +=3D '_' + dirname return tblname.replace('-', '_') =20 +def c_len(s: str) -> int: + """Return the length of s a C string + + This doesn't handle all escape characters properly. It first assumes + all \ are for escaping, it then adjusts as it will have over counted + \\. The code uses \000 rather than \0 as a terminator as an adjacent + number would be folded into a string of \0 (ie. "\0" + "5" doesn't + equal a terminator followed by the number 5 but the escape of + \05). The code adjusts for \000 but not properly for all octal, hex + or unicode values. + """ + try: + utf =3D s.encode(encoding=3D'utf-8',errors=3D'strict') + except: + print(f'broken string {s}') + raise + return len(utf) - utf.count(b'\\') + utf.count(b'\\\\') - (utf.count(b'\= \000') * 2) + +class BigCString: + """A class to hold many strings concatenated together. + + Generating a large number of stand-alone C strings creates a large + number of relocations in position independent code. The BigCString + is a helper for this case. It builds a single string which within it + are all the other C strings (to avoid memory issues the string + itself is held as a list of strings). The offsets within the big + string are recorded and when stored to disk these don't need + relocation. + """ + strings: Set[str] + big_string: Sequence[str] + offsets: Dict[str, int] + + def __init__(self): + self.strings =3D set() + + def add(self, s: str) -> None: + """Called to add to the big string.""" + self.strings.add(s) + + def compute(self) -> None: + """Called once all strings are added to compute the string and offsets= .""" + + # big_string_offset is the current location within the C string + # being appended to - comments, etc. don't count. big_string is + # the string contents represented as a list. Strings are immutable + # in Python and so appending to one causes memory issues, while + # lists are mutable. + big_string_offset =3D 0 + self.big_string =3D [] + self.offsets =3D {} + # Emit all strings in a sorted manner. + for s in sorted(self.strings): + self.offsets[s] =3D big_string_offset + self.big_string.append(f'/* offset=3D{big_string_offset} */ "') + self.big_string.append(s) + self.big_string.append('"\n') + big_string_offset +=3D c_len(s) + +_bcs =3D BigCString() =20 class JsonEvent: """Representation of an event loaded from a json file dictionary.""" @@ -202,26 +276,18 @@ class JsonEvent: s +=3D f'\t{attr} =3D {value},\n' return s + '}' =20 + def build_c_string(self) -> str: + s =3D '' + for attr in _json_event_attributes: + x =3D getattr(self, attr) + s +=3D f'{x}\\000' if x else '\\000' + return s + def to_c_string(self) -> str: """Representation of the event as a C struct initializer.""" =20 - def attr_string(attr: str, value: str) -> str: - return f'\t.{attr} =3D \"{value}\",\n' - - def str_if_present(self, attr: str) -> str: - if not getattr(self, attr): - return '' - return attr_string(attr, getattr(self, attr)) - - s =3D '{\n' - for attr in [ - 'aggr_mode', 'compat', 'deprecated', 'desc', 'event', 'long_desc', - 'metric_constraint', 'metric_expr', 'metric_group', 'metric_name', - 'name', 'perpkg', 'pmu', 'topic', 'unit' - ]: - s +=3D str_if_present(self, attr) - s +=3D '},\n' - return s + s =3D self.build_c_string() + return f'{{ { _bcs.offsets[s] } }}, /* {s} */\n' =20 =20 def read_json_events(path: str, topic: str) -> Sequence[JsonEvent]: @@ -236,7 +302,6 @@ def read_json_events(path: str, topic: str) -> Sequence= [JsonEvent]: event.topic =3D topic return result =20 - def preprocess_arch_std_files(archpath: str) -> None: """Read in all architecture standard events.""" global _arch_std_events @@ -252,7 +317,7 @@ def print_events_table_prefix(tblname: str) -> None: global _close_table if _close_table: raise IOError('Printing table prefix but last table has no suffix') - _args.output_file.write(f'static const struct pmu_event {tblname}[] =3D = {{\n') + _args.output_file.write(f'static const struct compact_pmu_event {tblname= }[] =3D {{\n') _close_table =3D True =20 =20 @@ -267,13 +332,13 @@ def add_events_table_entries(item: os.DirEntry, topic= : str) -> None: def print_events_table_suffix() -> None: """Optionally close events table.""" =20 - def event_cmp_key(j: JsonEvent): - def fix_none(s: str): + def event_cmp_key(j: JsonEvent) -> Tuple[bool, str, str, str, str]: + def fix_none(s: Optional[str]) -> str: if s is None: return '' return s =20 - return (not j.desc is None, fix_none(j.topic), fix_none(j.name), fix_n= one(j.pmu), + return (j.desc is not None, fix_none(j.topic), fix_none(j.name), fix_n= one(j.pmu), fix_none(j.metric_name)) =20 global _close_table @@ -285,23 +350,37 @@ def print_events_table_suffix() -> None: _args.output_file.write(event.to_c_string()) _pending_events =3D [] =20 - _args.output_file.write("""{ -\t.name =3D 0, -\t.event =3D 0, -\t.desc =3D 0, -}, -}; -""") + _args.output_file.write('};\n\n') _close_table =3D False =20 +def get_topic(topic: str) -> str: + if topic.endswith('metrics.json'): + return 'metrics' + return removesuffix(topic, '.json').replace('-', ' ') + +def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None: + + if item.is_dir(): + return + + # base dir or too deep + level =3D len(parents) + if level =3D=3D 0 or level > 4: + return + + # Ignore other directories. If the file name does not have a .json + # extension, ignore it. It could be a readme.txt for instance. + if not item.is_file() or not item.name.endswith('.json'): + return + + topic =3D get_topic(item.name) + for event in read_json_events(item.path, topic): + _bcs.add(event.build_c_string()) =20 def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None: """Process a JSON file during the main walk.""" global _sys_event_tables =20 - def get_topic(topic: str) -> str: - return removesuffix(topic, '.json').replace('-', ' ') - def is_leaf_dir(path: str) -> bool: for item in os.scandir(path): if item.is_dir(): @@ -336,7 +415,8 @@ def print_mapping_table(archs: Sequence[str]) -> None: _args.output_file.write(""" /* Struct used to make the PMU event table implementation opaque to caller= s. */ struct pmu_events_table { - const struct pmu_event *entries; + const struct compact_pmu_event *entries; + size_t length; }; =20 /* @@ -364,7 +444,10 @@ const struct pmu_events_map pmu_events_map[] =3D { _args.output_file.write("""{ \t.arch =3D "testarch", \t.cpuid =3D "testcpu", -\t.table =3D { pme_test_soc_cpu }, +\t.table =3D { +\t.entries =3D pme_test_soc_cpu, +\t.length =3D ARRAY_SIZE(pme_test_soc_cpu), +\t} }, """) else: @@ -379,7 +462,10 @@ const struct pmu_events_map pmu_events_map[] =3D { _args.output_file.write(f"""{{ \t.arch =3D "{arch}", \t.cpuid =3D "{cpuid}", -\t.table =3D {{ {tblname} }} +\t.table =3D {{ +\t\t.entries =3D {tblname}, +\t\t.length =3D ARRAY_SIZE({tblname}) +\t}} }}, """) first =3D False @@ -387,7 +473,7 @@ const struct pmu_events_map pmu_events_map[] =3D { _args.output_file.write("""{ \t.arch =3D 0, \t.cpuid =3D 0, -\t.table =3D { 0 }, +\t.table =3D { 0, 0 }, } }; """) @@ -405,23 +491,41 @@ static const struct pmu_sys_events pmu_sys_event_tabl= es[] =3D { """) for tblname in _sys_event_tables: _args.output_file.write(f"""\t{{ -\t\t.table =3D {{ {tblname} }}, +\t\t.table =3D {{ +\t\t\t.entries =3D {tblname}, +\t\t\t.length =3D ARRAY_SIZE({tblname}) +\t\t}}, \t\t.name =3D \"{tblname}\", \t}}, """) _args.output_file.write("""\t{ -\t\t.table =3D { 0 } +\t\t.table =3D { 0, 0 } \t}, }; =20 -int pmu_events_table_for_each_event(const struct pmu_events_table *table, = pmu_event_iter_fn fn, +static void decompress(int offset, struct pmu_event *pe) +{ +\tconst char *p =3D &big_c_string[offset]; +""") + for attr in _json_event_attributes: + _args.output_file.write(f""" +\tpe->{attr} =3D (*p =3D=3D '\\0' ? NULL : p); +""") + if attr =3D=3D _json_event_attributes[-1]: + continue + _args.output_file.write('\twhile (*p++);') + _args.output_file.write("""} + +int pmu_events_table_for_each_event(const struct pmu_events_table *table, + pmu_event_iter_fn fn, void *data) { - for (const struct pmu_event *pe =3D &table->entries[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, table, data); + for (size_t i =3D 0; i < table->length; i++) { + struct pmu_event pe; + int ret; =20 + decompress(table->entries[i].offset, &pe); + ret =3D fn(&pe, table, data); if (ret) return ret; } @@ -530,7 +634,7 @@ def main() -> None: help=3D'Root of tree containing architecture directories containing = json files' ) ap.add_argument( - 'output_file', type=3Dargparse.FileType('w'), nargs=3D'?', default= =3Dsys.stdout) + 'output_file', type=3Dargparse.FileType('w', encoding=3D'utf-8'), na= rgs=3D'?', default=3Dsys.stdout) _args =3D ap.parse_args() =20 _args.output_file.write(""" @@ -540,6 +644,10 @@ def main() -> None: #include #include =20 +struct compact_pmu_event { + int offset; +}; + """) archs =3D [] for item in os.scandir(_args.starting_dir): @@ -555,6 +663,15 @@ def main() -> None: for arch in archs: arch_path =3D f'{_args.starting_dir}/{arch}' preprocess_arch_std_files(arch_path) + ftw(arch_path, [], preprocess_one_file) + + _bcs.compute() + _args.output_file.write('static const char *const big_c_string =3D\n') + for s in _bcs.big_string: + _args.output_file.write(s) + _args.output_file.write(';\n\n') + for arch in archs: + arch_path =3D f'{_args.starting_dir}/{arch}' ftw(arch_path, [], process_one_file) print_events_table_suffix() =20 --=20 2.37.1.455.g008518b4e5-goog From nobody Wed Apr 15 00:04:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4C77C00144 for ; Fri, 29 Jul 2022 07:45:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235264AbiG2Hpj (ORCPT ); Fri, 29 Jul 2022 03:45:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235104AbiG2Ho6 (ORCPT ); Fri, 29 Jul 2022 03:44:58 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55B9F820FE for ; Fri, 29 Jul 2022 00:44:45 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-31f4450c963so36270677b3.19 for ; Fri, 29 Jul 2022 00:44:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=vsVx0RXggVgT0Vzeq33Ge2ECpCDo8PPDDZprUlFUzbU=; b=d7tM7m3wSx+Nl3LsHF3Qkp1URtOSaRrhcRzOpGhMvuDIzsJ6ORKxe9qw5CIL7pLEi+ DV986YF3a/OamH6P50M+iW7ja+NNZIQ7c65kuRHpi7trc7GXOzI0a+4GqbPXR20O63Wp gM5mSRJsf0xkjfsmmhaW0JsdpFPTMIzAi5arSo5Gqmkw4E6NtXmjicsj89vV5RPOzdCs SwnikVqD2c4lL0LQLpfcwfNdvi18dCIFcH/XWMAL9HoYlW1NfWScpIXCpZMC5nROT1Qm rbwloGq+SwztiHqkJfpMc3X2e+GdNcLApSmmAU4H7gRB/zrPyPU5j/YUGapUwZWBlTuA pmTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=vsVx0RXggVgT0Vzeq33Ge2ECpCDo8PPDDZprUlFUzbU=; b=Z61PQPAoObmuBr+IAP3QvOpRFauJF0gq8FybMzQ5v2aJeBhebjIcwgU+M9WsBQZPGG 2gHNSxYw61tIJ0ewl0JhDDDtmzj2YwL5xn/E9gRmZhbZIJO3WHj/sARL3S/qudmJddqs biLq/OZqJriNlfdGbWdFQTgj01bG5xFbNC585+q7GUClEl2GK5pqcVl8IgtNfSQSpZ9Z DVMP+d1RZmRnUqf50GVlc2SVzA2LiPm+Y32ld1BEuL1sNGBCpt5T5RHD9QBA+tPLVhop ZqmNe1OefM40GgthjQd4p7dkg4d5BWojeBzvy48iOcXYpm8QIBnnki3nTO9K9gd4yS3p rgPQ== X-Gm-Message-State: ACgBeo3EIxGINLMvs0P2cz3U2zYVH/VntoIeiF0YU0/bR6S1q//0fGtM 5nesVM8INrwoaBPIm1V8+ShvAWzkw4vu X-Google-Smtp-Source: AA6agR4Gdae2DAr0F8eHUkZlTJOf6KliV4pgoBZPuV2HWpQnhPdzjdAaC/qIhk5RnUThfkaBsRPBs6u1CKjy X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:524b:47b4:2aeb:1b49]) (user=irogers job=sendgmr) by 2002:a5b:585:0:b0:671:2b80:9d42 with SMTP id l5-20020a5b0585000000b006712b809d42mr1689021ybp.154.1659080685054; Fri, 29 Jul 2022 00:44:45 -0700 (PDT) Date: Fri, 29 Jul 2022 00:43:51 -0700 In-Reply-To: <20220729074351.138260-1-irogers@google.com> Message-Id: <20220729074351.138260-18-irogers@google.com> Mime-Version: 1.0 References: <20220729074351.138260-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.455.g008518b4e5-goog Subject: [PATCH v3 17/17] perf jevents: Fold strings optimization From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" If a shorter string ends a longer string then the shorter string may reuse the longer string at an offset. For example, on x86 the event arith.cycles_div_busy and cycles_div_busy can be folded, even though they have difference names the strings are identical after 6 characters. cycles_div_busy can reuse the arith.cycles_div_busy string at an offset of 6. In pmu-events.c this looks like the following where the 'also:' lists folded strings: /* offset=3D177541 */ "arith.cycles_div_busy\000\000pipeline\000Cycles the = divider is busy\000\000\000event=3D0x14,period=3D2000000,umask=3D0x1\000\00= 0\000\000\000\000\000\000\000" /* also: cycles_div_busy\000\000pipeline\000= Cycles the divider is busy\000\000\000event=3D0x14,period=3D2000000,umask= =3D0x1\000\000\000\000\000\000\000\000\000 */ As jevents.py combines multiple strings for an event into a larger string, the amount of folding is minimal as all parts of the event must align. Other organizations can benefit more from folding, but lose space by say recording more offsets. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 55 ++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index a5e162558994..e5545758c92d 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -80,7 +80,9 @@ class BigCString: are all the other C strings (to avoid memory issues the string itself is held as a list of strings). The offsets within the big string are recorded and when stored to disk these don't need - relocation. + relocation. To reduce the size of the string further, identical + strings are merged. If a longer string ends-with the same value as a + shorter string, these entries are also merged. """ strings: Set[str] big_string: Sequence[str] @@ -96,6 +98,33 @@ class BigCString: def compute(self) -> None: """Called once all strings are added to compute the string and offsets= .""" =20 + folded_strings =3D {} + # Determine if two strings can be folded, ie. let 1 string use the + # end of another. First reverse all strings and sort them. + sorted_reversed_strings =3D sorted([x[::-1] for x in self.strings]) + + # Strings 'xyz' and 'yz' will now be [ 'zy', 'zyx' ]. Scan forward + # for each string to see if there is a better candidate to fold it + # into, in the example rather than using 'yz' we can use'xyz' at + # an offset of 1. We record which string can be folded into which + # in folded_strings, we don't need to record the offset as it is + # trivially computed from the string lengths. + for pos,s in enumerate(sorted_reversed_strings): + best_pos =3D pos + for check_pos in range(pos + 1, len(sorted_reversed_strings)): + if sorted_reversed_strings[check_pos].startswith(s): + best_pos =3D check_pos + else: + break + if pos !=3D best_pos: + folded_strings[s[::-1]] =3D sorted_reversed_strings[best_pos][::-1] + + # Compute reverse mappings for debugging. + fold_into_strings =3D collections.defaultdict(set) + for key, val in folded_strings.items(): + if key !=3D val: + fold_into_strings[val].add(key) + # big_string_offset is the current location within the C string # being appended to - comments, etc. don't count. big_string is # the string contents represented as a list. Strings are immutable @@ -104,13 +133,25 @@ class BigCString: big_string_offset =3D 0 self.big_string =3D [] self.offsets =3D {} - # Emit all strings in a sorted manner. + + # Emit all strings that aren't folded in a sorted manner. for s in sorted(self.strings): - self.offsets[s] =3D big_string_offset - self.big_string.append(f'/* offset=3D{big_string_offset} */ "') - self.big_string.append(s) - self.big_string.append('"\n') - big_string_offset +=3D c_len(s) + if s not in folded_strings: + self.offsets[s] =3D big_string_offset + self.big_string.append(f'/* offset=3D{big_string_offset} */ "') + self.big_string.append(s) + self.big_string.append('"') + if s in fold_into_strings: + self.big_string.append(' /* also: ' + ', '.join(fold_into_string= s[s]) + ' */') + self.big_string.append('\n') + big_string_offset +=3D c_len(s) + continue + + # Compute the offsets of the folded strings. + for s in folded_strings.keys(): + assert s not in self.offsets + folded_s =3D folded_strings[s] + self.offsets[s] =3D self.offsets[folded_s] + c_len(folded_s) - c_len= (s) =20 _bcs =3D BigCString() =20 --=20 2.37.1.455.g008518b4e5-goog