From nobody Sat Apr 11 21:15:09 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 09928C25B06 for ; Thu, 4 Aug 2022 22:18:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239739AbiHDWSa (ORCPT ); Thu, 4 Aug 2022 18:18:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239275AbiHDWS0 (ORCPT ); Thu, 4 Aug 2022 18:18:26 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D67476557E for ; Thu, 4 Aug 2022 15:18:25 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id x18-20020a056a000bd200b0052e70ff090dso304817pfu.18 for ; Thu, 04 Aug 2022 15:18:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=FuugmUCF0TvRTU+HzlBpRf2vN7sysi6PxjIgBXMJd4Y=; b=l5SBZQVnabn522EriGOrgVBqUMbRT8xQi8ySOJ9glx8sVCcnbvcUcqndcZpeLQ+zbf +xJfe7I5AHvmHn7n1eweTfR+QO6XOQbAz0nqcR5vk/7TuCW8EYPsC+TDifyQn2HxgRop WyP8zDUUK5tXAO2qulPSAB2ylG7qAN0tInXyggGgsS4/ijsZIZyn+woZDGt9iqckR6Yf bQmvCbVJNMG/Fwz1P15luRDcf7Nbxi0z5Xqpkl5/TLo2jebpgVngq017qCVIJ+2mAxN/ NZ2N0Lp8DwmKCeH5mXl8nEnTpcrrVcE8bV+ks+Qre8Sh8blqqTF9ZwMzkwrBDHNcSrHt JU3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=FuugmUCF0TvRTU+HzlBpRf2vN7sysi6PxjIgBXMJd4Y=; b=F71XQBnWGoYGsxUSy069NYyMijh7srAZgboXal6t8ZeZbICj2uxbcc0NOa2TttVxWh asjb+JPsP/4TtfVL89u+HNPz/Cu0+d3hTeIw3d6lRI0tlok5v5+SvSHrHZNgALqbL3VV CfnfOJ/l56iy8luu1zGf0XxNGCIlX+caStAoJXFclZ0quUwhgEqLdzy3yGwORj6uD3lX 9vEgQYFl5R8rK9xHY2UslbKdWKy+OTxpx0DT/u2Z9Zmw6BWDHBlzV/36oBD/JMg+7nYn ayG0fKQnGbxI3h2VjQh7cIAp/PBx8qRLsSlkBZWqEhyOrmBHz0vU69RRpbzRvT1L33Ed hDwg== X-Gm-Message-State: ACgBeo0rbW28e+n5s3D+s14mDWwvedc0MWpvPvuQ1QiSK46u2uOI0tTh yK3V5dkYtWW/adeDcuSWnp60bFdAnGm0 X-Google-Smtp-Source: AA6agR4FGBjujwgqDlSb71XtFqqVCyQxC3yG7Bm2g9hTbvY0gPg8s3VEUGL9nf+YZH1gR5gaEj346sgYjzrN X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a05:6a00:1395:b0:52e:128a:23de with SMTP id t21-20020a056a00139500b0052e128a23demr3962734pfg.5.1659651505336; Thu, 04 Aug 2022 15:18:25 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:00 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-2-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 38AFAC25B07 for ; Thu, 4 Aug 2022 22:18:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239905AbiHDWSe (ORCPT ); Thu, 4 Aug 2022 18:18:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239667AbiHDWS3 (ORCPT ); Thu, 4 Aug 2022 18:18:29 -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 DF1226E2F8 for ; Thu, 4 Aug 2022 15:18:28 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id 137-20020a250b8f000000b0067a5a14d730so600026ybl.12 for ; Thu, 04 Aug 2022 15:18:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=N++Mrhq6kQeFrF8RmnJUsnk+16Uv6ufZYhZg1IA0uDA=; b=TXD73nrJU+7eARBRcGR55uk4+DwtVJBAQxSiOVKpyhrRZ5RO7RndxUr8lO+mmzD4T2 BrmRQ3He1TQzRs029LnPWblE5dDPet7+BdRpqE++iRb8WKUkWedWWxDuC9LNd6CK/9Ls XQzmnEiLmYEUmR6zXQxllkqPR7bc6ihVYbrExoW3EK5EzMwEL61px4MxFO9qSKyoPdeB vQYyXhVQEiRbh4P7lnLmVwTfQLwukDO+GiT0AcC+Usl7ncPvlPu6IuVxZQjwhoVd7KXU 439AEoMLzX8I1tlwlwoC3jRIbz6ON9tce+YmPNEV4jmtBaGSTw0iXPfg1Pr7xiY5YobC HIJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=N++Mrhq6kQeFrF8RmnJUsnk+16Uv6ufZYhZg1IA0uDA=; b=x9K7bN0TXdWNdtHcB1iC8D4qylrEnHyVGnqdy2GSuWZfZLDTzX81n8QGG0ry1Tlokj Ag4qdEr9ut8m4qrASsWBQlIM7eRhMr1XuUBGV28Jw19mS5+diXe1e8kWdrYU7y6+ioGE 0bMnYLU+oWJi6DIL/gwMmjnYTAwZa3+kN+lxR8k2nQEC8QdfYfYU19d3G9GqpbDeuqWO tWY8orl/dutKTqNOsgSC6jp5uM/AQ3dgNLLFKvyYp2VUROK+6+2egGQMFz8wgOPZrLQY yzVzJVe75DcyDt1fHND6/qW35C/766pfKa5C8pjfD5c5QTmK6LPnhJWPBEka5rGhr85z 9nbQ== X-Gm-Message-State: ACgBeo05RSVafmR+Y6zTyxX/Gfx2bHKtRj5978mMfolLUB161TiKwX7A 4Z2lCBLLORzNnaPgJIHZ5jd0A4xj8O32 X-Google-Smtp-Source: AA6agR6l2OkctpCBldtJSDt5KcZmeFaj7z6S97AUd0CAOBSyjbZU2NHKqPh/zAmXOFewOm+ciB+zYLxT+Eka X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:9b48:0:b0:67a:6ad0:f078 with SMTP id u8-20020a259b48000000b0067a6ad0f078mr3169103ybo.536.1659651508142; Thu, 04 Aug 2022 15:18:28 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:01 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-3-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 2C748C25B06 for ; Thu, 4 Aug 2022 22:18:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240035AbiHDWSv (ORCPT ); Thu, 4 Aug 2022 18:18:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239821AbiHDWSc (ORCPT ); Thu, 4 Aug 2022 18:18:32 -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 8812B6E8BB for ; Thu, 4 Aug 2022 15:18:31 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-31f4b76446aso7338997b3.7 for ; Thu, 04 Aug 2022 15:18:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=3zB40Ep346GFOYo22jSNwM76yKmEJRv1RJmbyyWyLHU=; b=E6Txk7uEstiYdwC8uzQETuPMRpo8BmaaDqinpQxoLfk0uI9AQjhfYYH3HqoMxCw+3u 5N+dq3kX1h3my3fjW59H5ATiAPRBr4n7e9YZRCYRV4aK4abjUnTtcbvp6lHt+T5Zvk9D tB1+HDnx+9UzYK0okdF15reIkcSlL2XEX1DIT31RgQVVnVToVaeJ48Even3TbWVK7n3q BSmv3J9CWXZINfCIVhtZkYsVmILVfLouies1TSdpJbP8XZhO8ZC05tvS/pBJ/OpgOxYD 7X7qKspHiCGI4NtyrJe2jT8zf9JNdJJAWOZ4+Bn1LjLrDSSOhk4sM7kgQkX2cKXm3THf Zaxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=3zB40Ep346GFOYo22jSNwM76yKmEJRv1RJmbyyWyLHU=; b=F9RI/OFe1Ynu601ISl1t4kC8Uv5Ls8jgmu5k4MyKS9vEtyJY8gpxVgJLsg8OIz5Tdy vdICWvaPH9C+dug5VBzzwCWbeii+qYRqxJNKvIb6j7fW9RojyB+Cpth1D+YxVIJvnFo3 lUS+R6tZFNX1G+ybutcHfMpeds9f56lyUpuwfoTizpK8PKcoXtQzmkkL9+O8GmweoeDm PS4tzaySWTYktFM9liGxUZ2LOFeRxTNDS1mAoB/VOd54j+Qg4ARbBytGs9NpK6U6IMPb rPKOCqjbzb6zlqSPWw/MqBEX+ok851ythr5nLzx1fpCPAu2yn6ltZUYfYxlSTim9cuj3 GE0g== X-Gm-Message-State: ACgBeo3wpOpP+poutdN44aU5youR8PFsH1Og5VhvuegQdpupTX4mRwzm h9vjBq485A4OuLdBE75Vc0Koye9jHS3Z X-Google-Smtp-Source: AA6agR4fb4lCgBnjP7KBoxfNpkhYZA7oNOwumbQtO618B3WSAI3h5KQJV9FhksGoli47MgpbdpMkWxqNVy2J X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a81:1014:0:b0:324:6c13:dc01 with SMTP id 20-20020a811014000000b003246c13dc01mr3500805ywq.115.1659651510685; Thu, 04 Aug 2022 15:18:30 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:02 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-4-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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 Reviewed-by: John Garry --- 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 56D82C25B06 for ; Thu, 4 Aug 2022 22:19:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239918AbiHDWS6 (ORCPT ); Thu, 4 Aug 2022 18:18:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239920AbiHDWSq (ORCPT ); Thu, 4 Aug 2022 18:18:46 -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 1FCF66FA02 for ; Thu, 4 Aug 2022 15:18:34 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id p55-20020a056a0026f700b0052d548fe275so323112pfw.3 for ; Thu, 04 Aug 2022 15:18:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=NbYY49BXODe+emArlnZpM88UGuQQc7rN0h5APX/4HUs=; b=fb3MsSKAsTBMU031x6kDVfBS2Rbt2rRTwRTate7kAVMIfLGFf2V9YkvtYKLVP8GoEm qjPbkd0xRxb3QeF7QkgW6cztb13YphFEcdsXRfj2RHk48f4Ud9df5S8pm2vUJH/2+nsy J2HTkogtFOAWqJujmaICoiO78k19vuAlrrlo4fayJyTWSr/E4oI7AqQlCD2qumGsRVpy upmp22xHvO7qDCX2hf/sjqCDlYPgLh3DkujuPpU3ziICkRK/rfnfeZdiUO77s0/2SeGD kD5j4zv0CrnOHOKLQhBs1Ajs04rugfoVZJbB7k0dZTUIfGOaIG8MmAGv0BTrhYDL5eyI 0K2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=NbYY49BXODe+emArlnZpM88UGuQQc7rN0h5APX/4HUs=; b=eEUir391eTX9DAF1sgKXD1dQzFRk5bkcEJPmU/1EPgNgPL36qfQzn1GAG7LY3034NV SXrkAjsjwSoJu3bpI6Vvdbv2Kc95zJBZii6oHli0rqyY5nL1TJ8baQgyY8TuNHTfrgQE +oU+tScHwelL+Rnx8wLXJzn9UO9DWNT1hCQ9TmQKh44yrbRDZQmVqZVkUA6FkQhksqe7 eyurzhw40rxlXCLH+yuSDgWZFkX2H1cQz21qrjAhmu4+TJpC8hHGQoBS92F97uQBV9Sc DwJvGLr7Ta6JmyFbJlfSGdZIIBac7wuncQFwazGppFhMVole/2cel7IHM0IYtrpi0L5p 0Fsw== X-Gm-Message-State: ACgBeo3vk8qpGXDuG7jK3VpVr9q2+Y+jthHc+n5Yefmc60nDoxxmnNHy SoLch+E39YbxnsdPKF4Ndr0afDKUc2/h X-Google-Smtp-Source: AA6agR6JOC75wsFCe06eskqE64vokh0WjWqD3sq6v7eCaP/r9kukdwwErhWD3Hb0tBbfWFBQrn9arBw/4Up8 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a05:6a00:10c3:b0:52e:a666:6920 with SMTP id d3-20020a056a0010c300b0052ea6666920mr1897100pfu.67.1659651513491; Thu, 04 Aug 2022 15:18:33 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:03 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-5-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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/empty-pmu-events.c | 2 + tools/perf/pmu-events/jevents.py | 70 +++++++++++++++--------- tools/perf/pmu-events/pmu-events.h | 1 + tools/perf/tests/pmu-events.c | 3 +- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 77e655c6f116..d8cf9283e486 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -110,12 +110,14 @@ 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, 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 EEAACC25B06 for ; Thu, 4 Aug 2022 22:19:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240090AbiHDWTB (ORCPT ); Thu, 4 Aug 2022 18:19:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240008AbiHDWSr (ORCPT ); Thu, 4 Aug 2022 18:18:47 -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 4B50F70E7A for ; Thu, 4 Aug 2022 15:18:37 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f58599ad3so6975577b3.20 for ; Thu, 04 Aug 2022 15:18:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=d4S39rJSe47z417XxG+is96I4EdHbooIiUz1AHwuMQI=; b=lSo6uideD/pCPYRfvu0tpkQMCVlc2ZxYoP9NmxZ8rF/ZVtN4va0vH86E4HEUu82bW2 rXBHtbcpvl3zOMajesJtRy8rE6dpdiCDyPX2wuxm7b0B4csQWtWeanre7pcD1EdjwPyb ei9SrOirY4ZdK/HBopHsY3UNM0PgpT1A+znEmLGCTzWV+jm3pd4zTCqCcgFb9a9x6+eq 5e9QatfFOrGuMxHd1AzOp3pqK587ueystY3xh2zYbEunYUPPI5tBA5B6043ZiWBm5oEB /0i+9pAvAwv8TjByTblaHKWm631XrHo6KsVN4F4S3MDJzGBfRv5hzboem6sbvdyo7Gvj LhwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=d4S39rJSe47z417XxG+is96I4EdHbooIiUz1AHwuMQI=; b=11yTpxO7chCjn3sBOeb4ifvyevnL3PDKHBU+3lrLTuqrm77TYrEZdocazt3lVJJMa5 SOsv6wcYHY7j0qj5W3Hxft34EgHuo5n6S077D5jLu43+wH4aqSm9sbJMdISgf/nH2+0i XLlkiwEpXLUBa0dcsdHNJXdtuvnEK7AUsBuqtg9m+IDHltl9lJrLYbhotRMJBKhjBBtm PIDrhIiD7byV2rAiGB2ec9btfov8BoUkqHRrQWKggz8ydcfsx2w300Ir3qptAS0E9KTo vyjV6VfvkyWg6kTenGyATFsC1hADiV85mhWQKeylwwP5LozhR+mVQNJigouKCWTq/X6b JrDw== X-Gm-Message-State: ACgBeo2QuDIAvhKH0qSTNx3eIR7agUjvbKgM7iMSw9+JsGyaGYJ1HI0Z DaMqlD1FYxo67YrwMNLMLsKFhsJNgCDf X-Google-Smtp-Source: AA6agR65w87f1sbFT8cO2GlzK8buMgzpA2ioJgHp4z/4uUNcj6GOgy/McAVYE5+48rDu8lIkhosVqS10395v X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:3d45:0:b0:670:b35f:e4b1 with SMTP id k66-20020a253d45000000b00670b35fe4b1mr3120277yba.38.1659651516189; Thu, 04 Aug 2022 15:18:36 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:04 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-6-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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 | 4 ---- 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, 16 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index d8cf9283e486..4182a986f505 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -112,15 +112,11 @@ 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 7EAADC25B06 for ; Thu, 4 Aug 2022 22:19:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240053AbiHDWTP (ORCPT ); Thu, 4 Aug 2022 18:19:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239956AbiHDWSv (ORCPT ); Thu, 4 Aug 2022 18:18:51 -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 5C52071BDA for ; Thu, 4 Aug 2022 15:18:40 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id y13-20020a5b09cd000000b0067114eb5b50so581491ybq.17 for ; Thu, 04 Aug 2022 15:18:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=jj3QL2VB7yeMKctZCaHc1b4ABIGklkTL3vOmKj4cY9M=; b=naXkqYvmoVUVtTztzNIGjOQUWNikWsYOV4jgsyFyUFZsEVsaKf8MXMW+zQer81F4XC MiE02JVtmba5DXcB7DEo0SVOrShXwyh+1RvYubTHhKuCLHRZiY6lUCccPNhELDCPm8Vd /CTEf/hWXLcMlwY6vw/Ptfm2HOcv2cyC5i6A976rZx1jUi5s7RqHjsAUN0YER66k0dpn bbYxMXZWYUuTpnJD4Ln1S98YScsV3aZMxMAQWEG/Ssze9SKPp/I7o6xvEjlHYC6mSkaY vCYf59JQoZkWBuNWZqVb1OSW3LguO3UGRLk1uXRHG3QhiBsTITXT21K+IBjFNE/9nAqX sdnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=jj3QL2VB7yeMKctZCaHc1b4ABIGklkTL3vOmKj4cY9M=; b=Co3dTBSc4w63NxiQSOaRuJHC2pFEzL15C0fDF3LtRtBRVPijoz9zVU4jBB0SwaG5cF di9O9xBnXdLgKKiMR1QQ+wnNcCpB+QJFZHC3rVkRU84qpj2d2IOtCws52LjW/OXXUpW/ S9cz7lKLR+Gmv50edxGBIat1La5mXtlWWsju4v8MFhPbkYFq6aHOwXp7lkjlkh5Z4RvL r0tm7gz10jFv7uNl0LHSDOZkqJLtxlOkvJnsTRkfAsaAoTDmXcU4uaQXp4BI9ow78MKY jQnsT6AVrwkG9bZBlVkixXDQVvv6Q5/LO6QzBQ9m3mrtLSO+voVPUqe9l28MCaq7q0xA gvOQ== X-Gm-Message-State: ACgBeo1+hAK2zBui/uFekDtHPKzz8eCVqUNZJUTLn+qJYptJXwBtZ4tQ n79Et2Rj4IwuS+4dP7eUVUV927ysiqfc X-Google-Smtp-Source: AA6agR6rZdiG6AKqT8iby13icVKn/mvs7v0tmX3sdWha8vwGpee+4AOmvaAMXvvm9MSdbSfLPmP8mirEpP+p X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:604:0:b0:676:c237:ddf0 with SMTP id 4-20020a250604000000b00676c237ddf0mr3204397ybg.71.1659651519224; Thu, 04 Aug 2022 15:18:39 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:05 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-7-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 B333BC25B06 for ; Thu, 4 Aug 2022 22:19:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240153AbiHDWTT (ORCPT ); Thu, 4 Aug 2022 18:19:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239914AbiHDWSy (ORCPT ); Thu, 4 Aug 2022 18:18:54 -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 E4FEF71BE4 for ; Thu, 4 Aug 2022 15:18:42 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id s186-20020a255ec3000000b0067162ed1bd3so607288ybb.8 for ; Thu, 04 Aug 2022 15:18:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=16IOlO4jrn2MK9FURXqlyF6K1fZebhGz75A8J5qtD1g=; b=DtjWNSw2MjvlwjcuEAf0hYe9W4aMN2WxiogWBKB/oocccduWc9R6ai5MWQkNAbhfWH FaevJOoJ27DaVarlwEiz/sjb3Lg/L1eQtxv7IrV3LEE4PvL5mA8eszQgbRa9WWl0rf8m I4VNXmicsQ6X30wN2i6NM0KrtOJQ20X8gUVWZ4j7tWU/u0IrN6FF2kn1v3ijY/txrony z86HPf7C+kwMir0kwBkrwZROsbrmb1/YlSkPpXz5CObcVI7LCXWEX7vKifNGkrrc1ez9 RWk0D0i+wLpt/2RUA3GfnSJK5qzp+043437I5AfTQgbuZj6MvBa83II22XkrrQ06d2kB n2+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=16IOlO4jrn2MK9FURXqlyF6K1fZebhGz75A8J5qtD1g=; b=R9gNV4U5va2/ytOBGCVLtoa6bZimrfZlIwNB/ib6hk7yXQw62WMmY6/1QZvH0o85q9 MtY5jIkzb+SGrKQxRDjUnRVPZ4UUBoWjMIl0CnCMRrJlC6K85SZo7KOOk0zM9+uRxchO d127dE+D4NcJnX2aola6G5WWIPa4WNuZven4x2MCu+IprbDmTN3YBpYVwZhpjdrFLud/ Z/zI3w/YtDFVzDmkm2PyUyWMbZ6aFUkuZMoz8FoCw764I05by1aNwvrQ7Fy5Yb3ttvoB iTbKOgn5Ol6PmyAsK7TcfrOhoiBpln2fAWxnwY8G+imAvpFNd9HD25O1h+Y02/z2bK3x 8NrQ== X-Gm-Message-State: ACgBeo2j8INGiqmX0H01hOijWWXo3HXHrWFFW9JU4XrN+4fJDWsMNTPg xvbvjECV/GDKQBBXqxCvjn+FVQrt9RMI X-Google-Smtp-Source: AA6agR6GlRMybjZShfr/ikrpTB9P0SKEPOm87GFuipgaepuutqAFf8huAl4sOIdCS2Nx7YsUiDmY2VyNaqH+ X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:2417:0:b0:675:a9b2:dad0 with SMTP id k23-20020a252417000000b00675a9b2dad0mr2996819ybk.489.1659651521521; Thu, 04 Aug 2022 15:18:41 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:06 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-8-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 CC32DC25B06 for ; Thu, 4 Aug 2022 22:19:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240095AbiHDWTe (ORCPT ); Thu, 4 Aug 2022 18:19:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239920AbiHDWTA (ORCPT ); Thu, 4 Aug 2022 18:19:00 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0946F71BF6 for ; Thu, 4 Aug 2022 15:18:45 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id r13-20020a17090a454d00b001f04dfc6195so312690pjm.2 for ; Thu, 04 Aug 2022 15:18:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=3lKujElDaMLIVNqMT3GmdNng3n2nizwvX5lzOZZlR4U=; b=hCdDCU/cdKsAqKT93AFPeqqEzIMRkLJqfX6d0Z7w0RlZBK5mYNwoNDPaZ+PXgjciVo ZpztecPA5qmMEqY7OifXzpHHz0dzjJMLi8oydXFfeLIGwafk70ziMV1lysoTDiyDO/7I GvGQj3mXC8RoG4ODPSMYBxHtqzYjGx0beEN6hTm7Fmzo1XJzb6EYdvUpgXpk69Yw8x09 BzaQQTnisFm3Pf1c5ch5b96BStxQ2487zedEoYBVtnAxbN5P+iBfxHIZuZQwAOB0aJ5j d2Sg/bEzgaRSRXfybCLAOhTckegNeewiXNDTvb4s+accdVyKB8ebIXs/Ugti3gNTHig8 VVZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=3lKujElDaMLIVNqMT3GmdNng3n2nizwvX5lzOZZlR4U=; b=Lir8ZCwNh++N2BvNKW/1JXE4nVWCsthbjFOmQ7R+N38MTk4exCP8rd9VZWLEyzgdJ/ x0YPUAQVoStYTuAXmLojSwg3ytKEjbDb8FkvIaY2tue3SbQa/vhSk7CnHSm8Qe8rGJiU K8Ps6w2Bb3S+1mPmmozp+wCpNssNv7TX+kr4kMR6yWJHiYnk9BcTan1wh1juEN2AhVfd 4MldTYYmjTujEy7JD/QuVB9wXP8NMXTgoTerszy7gQ77R1IV+yBIUmf+YJo+9ZDQ9/Vc /WgUylxWZdjTa+XtD1NCVptUbwckNg/GHrgEAZOpsI3uIGjUoSsp7OGliZ6bdlKPQ8VY zBTg== X-Gm-Message-State: ACgBeo17q566mNkB/J1LYSpRmoYso3soA92eNGKYHZxKyDgGgGcuvQl+ ulPskuJknJEPQlvjbB9t3WkUcH8UpwHf X-Google-Smtp-Source: AA6agR6RI+Yv+nHhfGVSK3NKr2XzuzuG+pCsD+sAg990SdR6QjssszjC6BvRUDSQt5PcWF3jR4CkIF/M0fuO X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a05:6a00:1946:b0:52a:e551:2241 with SMTP id s6-20020a056a00194600b0052ae5512241mr3870663pfk.29.1659651524338; Thu, 04 Aug 2022 15:18:44 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:07 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-9-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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 Reviewed-by: John Garry --- 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 58CAEC25B06 for ; Thu, 4 Aug 2022 22:19:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240170AbiHDWTl (ORCPT ); Thu, 4 Aug 2022 18:19:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240098AbiHDWTK (ORCPT ); Thu, 4 Aug 2022 18:19:10 -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 C6FA26E8B7 for ; Thu, 4 Aug 2022 15:18:47 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-324f98aed9eso7034567b3.16 for ; Thu, 04 Aug 2022 15:18:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=UdRG1v93hQKR76P2lWaFgLK5gyNCdyEtLLBjlh+qkSI=; b=HvviOSmjAegx2PrfAus3XPwrtWqCFxYOB8Op4tabzLxJg1kfi96zXjcHUAaZCbFotX pVVp7wNMEqjR6AxgNrSRQi0TQiu2CVCrqQvL+P+qQwMsnoNWgshxRhjhJBSKmkrq7sIi 74Hf/asuQM5bdTVzTZbZ+ETbif9R+BxeQ592QeB71GeqNT+3A6olXVNmHSPHqCbsseNc UDYcuE8Etktvz6ix+s+V39dWGxVGcHotuiyaVKntrixMTLF6xI3uTvcIyMPfsso2663j H1bVFnQ5IOGNsXEjzkcDOBjEsVCoq4/70yilOwMEVBQvH9fd1H+uQ+MLoNKaH/2G4tJY BfRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=UdRG1v93hQKR76P2lWaFgLK5gyNCdyEtLLBjlh+qkSI=; b=pgctyQuLA30qE9qQ6DggunOoXs+vFqEM0svp3gY6fMfvGtPKDuvjYznh7WrOrEHw6G 2hObKM6fEg4sKiyqSu/VB/mJ87ReY3kMFiCcxzBeHaBtY91pCAzZVOV2+p7Vb+JdrO8e xs6tSXDddqsyhu3U7ZJqrLzTQlHZ7j0myWO71uCfviy3OKNQvGgu/YhBdC8+zFUbMrsg mJn78eWT0JOVM3uVEQvEczBrF0UsOf+jD6K5Bf3yA3an0GMch88wJ6gP8rjLKuVBI6pF wGikDM0cE7XWpA5DoG9VvddXQWfDLdajv9QQJrRFc9Dpjh6pOJt0HYMgK798XMfn/biw JimA== X-Gm-Message-State: ACgBeo3IUVxBJmvS6JGWxt9ljYzThS6J7oZNtAW+zhus+S5QV4AFBRxv JF+P4iP46nl7Sn2XkSq2Ym+jIpMg5084 X-Google-Smtp-Source: AA6agR4OePkywoQKPXqzP4H/cSNFWQ/f1I6y4QnYm58iRRqspVXUUFeWQiYsmlu28tiqJu0Ta6leC9XatwrB X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:8206:0:b0:67a:88c8:9a5d with SMTP id q6-20020a258206000000b0067a88c89a5dmr3077996ybk.277.1659651527094; Thu, 04 Aug 2022 15:18:47 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:08 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-10-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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 Reviewed-by: John Garry --- 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 C8DEFC25B0C for ; Thu, 4 Aug 2022 22:19:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240124AbiHDWT4 (ORCPT ); Thu, 4 Aug 2022 18:19:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240106AbiHDWTL (ORCPT ); Thu, 4 Aug 2022 18:19:11 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79D7C6FA18 for ; Thu, 4 Aug 2022 15:18:50 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id o69-20020a17090a0a4b00b001f527012a46so304571pjo.5 for ; Thu, 04 Aug 2022 15:18:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=RgfsHbkXim15QtFISs4UcCGIL+PR2lDFtMMHCw4t9VY=; b=bHoVaRZvvXaleicOvESSqFxMfVuzCvOkcExenWR6ChPA9G4br8Em9GIb1rbifyHoaI quBJJhvZFxcbEW1VLVy3iN1v6ifm/Pt2ZCEfK6OaNZYwss+OHcR/TNYW86LkNG0aJYnV awKah3LEQH8B1n53g6lPmSPs5R0on6tZxkT+SQoWRigl0kPex+1rvD7oDoqwCM6vpuKE Z2Z+kRCyZz17RL8v5Eq6LP8YYVIT5bO38HAZX3TRO9jHDCjG29jbSA0qPmG3F0097SXe 2gRZgStHXDUU+ITr+0icYKAReVvqLSk81m7IwCLZaVn9XkcMGbN+K2nQE10g0vzCkRFz wt5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=RgfsHbkXim15QtFISs4UcCGIL+PR2lDFtMMHCw4t9VY=; b=zqraoSxaAotmioF7ODGDgEFODL2Pt6DM1O7rP1xP1lx0+EydBjWfXSHG+dcOatf3yS k8K9fbmzOCbNhCAYI+XNmIJevcbmIuei9qBADzh2ZzC9F5KxBeR81l8RYobiY0+6eihX EBwJDECCX2FU/lJlnnykQ0H1ktAux/K1ZH4qRCzyBqO1e23IRORyNZmySHcVfg4l8xCU czZykzogeXDyiTv3ah1pmkAygWp3SGCkg0DzPe1J4HljgFJrCsFfdXpckXm+VJBP6Aae OLoKYPkng8ykyfsQ00b9JWji4JR8fr//TKJx3AuuO48/88FpklhosvPZ/sRKqET+Bbzx 6ZwA== X-Gm-Message-State: ACgBeo12W2nphd/N2aZ0nRY/oN9OCcwEB02vWf33xGHO0hy/TYFff7at IBXdNB083/umWo8d6JrMlkt3maKe2c2C X-Google-Smtp-Source: AA6agR6pq6/5BSq4CaWRbJxbJM83sVxs/vJa49Jv+9WTGq8LBKkybac37W0U/KprF77qSCLjNdbxabv1HhYY X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a17:90b:3850:b0:1f5:609a:3ac6 with SMTP id nl16-20020a17090b385000b001f5609a3ac6mr6244589pjb.125.1659651529915; Thu, 04 Aug 2022 15:18:49 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:09 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-11-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 0ACF9C3F6B0 for ; Thu, 4 Aug 2022 22:20:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240144AbiHDWUD (ORCPT ); Thu, 4 Aug 2022 18:20:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240121AbiHDWTN (ORCPT ); Thu, 4 Aug 2022 18:19:13 -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 4EEC86FA14 for ; Thu, 4 Aug 2022 15:18:53 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id m5-20020a2598c5000000b0066faab590c5so604629ybo.7 for ; Thu, 04 Aug 2022 15:18:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=sxQ3NgaGvyZvqLsnvSuWrAEklghpO9eHvVo0+qiRlwk=; b=eCGMuF7hnql9EdwBvth8dRunrydqTYfauGRZ1iDr/M8VHI27TYViSnq9fyeo4H5JgV V6LGbOvcSxRFYepaPl664EYB+jKU10CtEkx4YjZA+KhvUwHnoAX/hW6DQ6LsOGnqb11K 9ySjaKJKCxLQYKrGyQ4t8WkWuFsGq8vuSaFOaKqAuCKs/vXPwvB/2Wz/I33z7Ztc8rxZ efi6mtUND4tQxj3CWZpCBo9aDXGsvY1PK5dVcuk+boRRBTBJ0knpiQo1PYnYiOUK7LYb jN7yOMhPZq4xlx85kK4BgobztVs842/pilcTOl3A8zjipZIyobnXz/9RC3rfV3R4lLwH EEjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=sxQ3NgaGvyZvqLsnvSuWrAEklghpO9eHvVo0+qiRlwk=; b=Ugbc0iZxOtF3L+ORs4SOYUV7KcVGlrRk9nQgjAEOVvGuBDsGQJG3IzcUQ6skfZr7kf EpthDF0D63VDrnbOjg0W/pSe7z4pn41Qdu7YkUPVzEEDlUXbCH00etPctKpvv77O9ph6 Z0dAxfrjBEeSmNOwtG5CRGj83vmzxjGWL0tgdO4otPWJppwyZ9fIU8MFLIW5QxldG3KW kPOyhYPt3dhcjZxT1hSpuuW9LrGOY5MTO5ZEA+n54/jJPHs+I72ljP7dkOSqsyeBJsQv qKAU18yNum7Rov+5tJx+qsv2HpUWo1RWUk3jybUhGKC88E0+GrtEec4Q/lXFSy8xIR1T Eqhg== X-Gm-Message-State: ACgBeo069uUZSBFP1I1a1Y7IbTXS7ZkqWCGqobdC9188w1RadY8IMMM3 H4+YW+iqWlY59TRJLMxgBuKLvgrMhvsn X-Google-Smtp-Source: AA6agR4l94lTAOWEwMCCSzuT/joWaQgFNgh/0L1pyiyzsEHL3p12erTz3j18xD0M0Oc7DlkXogsjaMBh2g8X X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:b9ce:0:b0:67a:6b58:2444 with SMTP id y14-20020a25b9ce000000b0067a6b582444mr3169101ybj.238.1659651532563; Thu, 04 Aug 2022 15:18:52 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:10 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-12-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 7B1ACC3F6B0 for ; Thu, 4 Aug 2022 22:20:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240062AbiHDWUF (ORCPT ); Thu, 4 Aug 2022 18:20:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240132AbiHDWTP (ORCPT ); Thu, 4 Aug 2022 18:19:15 -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 0710E71BCD for ; Thu, 4 Aug 2022 15:18:55 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id r4-20020a259a44000000b006775138624fso569357ybo.23 for ; Thu, 04 Aug 2022 15:18:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=WRzJvWRxYrANs6b5P5hXctmIEfbb7zbPwjhClYCaTdw=; b=EedUdYbJv7zdFBtr45yqAht3y7rqZ4fCvSTXftOYXm1k4fW4nMHX9jxJZNWHqdncMJ kFgVDuAWYz4JPJA2Nrf0rPgUWysazQfAs6AMt8QzsDUINNimrOux4W+OdaiagBiIcPnh 9aTH5EN8BuQ6FA4tpTEQz4H44mv5oaYd5L/+O7UN7wwHM9h9AuH4zDEhVyEIl8icEXxe 6vC0AKtxtv9EMduvxlCgh2YoLMtDzdtbDsGQyP3eRQ9lvAlKqk6LN8Esovr51foUZs9W mzalF+92zRWrQVfUtM2rpCzVjOACEWiEb4wcEVFdAVSEXLD6BpdlFxpCxBdxnKsHwC3m tp9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=WRzJvWRxYrANs6b5P5hXctmIEfbb7zbPwjhClYCaTdw=; b=yzG8V0YZ8HSUsJP8ARw88UIGqyYT5B3idVwTSPw6L4o1ybJVBri8SNhVQh/REHT9FF SHT+sz99KLbKtHqYev8ve2+UTiKuvK+QILFPpXcB66YSV+JtAjTciKUiWFHIytQMt58O Rm0bSFQW638Fatqj/I1PRIS22FhDRHDV0l/VWPKFwI9taj5HJ84YCWkD1NTFhsP4/Ttl fJtZOLSKBavHMaygovoeB9fSwUUUkBwh2WxkFOdjGslci5QyD+uY9DFRIM2fWznaw9Ez J0TbG8UIYx1ozFhTAMDD164wDqYBr0ztcMw7q2NVnvCIyI6xtz6lamzagyTRtJr8Vyhx y/Ww== X-Gm-Message-State: ACgBeo0xVhhY6xjCIfOr6ttwgOoYqO0DmyID1XYJCrzS7BfO7Nc5qfVR bz59Mr8pYmiCH8+L52vu03wsEcmpMIcq X-Google-Smtp-Source: AA6agR419IpSwckkR1hznAXQnajCcoc7OIST6/ndSKpKBf7IlBNo3OprHgypzwIj2mlOKudiPHOBZfvYY+8K X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a81:8607:0:b0:324:92a5:b809 with SMTP id w7-20020a818607000000b0032492a5b809mr3668375ywf.87.1659651535084; Thu, 04 Aug 2022 15:18:55 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:11 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-13-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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 Reviewed-by: John Garry --- .../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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 7CF19C25B06 for ; Thu, 4 Aug 2022 22:20:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240063AbiHDWUK (ORCPT ); Thu, 4 Aug 2022 18:20:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240140AbiHDWTP (ORCPT ); Thu, 4 Aug 2022 18:19:15 -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 2083672EC4 for ; Thu, 4 Aug 2022 15:18:58 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f58599ad3so6981107b3.20 for ; Thu, 04 Aug 2022 15:18:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=buQfuAYV6srkjKdCo6UV3mNN0x2luqHdC6z6WdoFZhs=; b=fWZFlrzx8vxc9xQrM6ZtLHwUX0ccBcMSdMNR2ggkfsWN1NIRDLHmIVq+oqFH0Y/CUO lJZJ+W7yxQ7gg2M/6HcroQObaGZb25Jk35/0V9UhvviPqUIxe/t3jcBsbo3a3SsSRdLC a3pU7Ov+3kYr78k9zZXhi2QkOfazVtTpp2wocSbHF0iM6NYqBtVdeF1hc80hddTiojFe zJJXAiCddAu7I6u9zJOAvFIP5QpMB15gcOd7neSKzEdQm1ksrDExXffqpwtz7Qi6j2tJ tibkByAi8ySLhG5FU1c0+gDUxsCaun7QM6CAXNYtQgdAtOpUOXqDJNGErSnlVP/fYmJS 5jIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=buQfuAYV6srkjKdCo6UV3mNN0x2luqHdC6z6WdoFZhs=; b=Up45kgeFMeZXhXPH0mCZOc6XKBtWn58bCffAhI3ogDV/uJ4LLnxX85b68//eUAGSb+ neLf89Y1K3BlgZiUmGHF0QP3ewxmBmyMZ5prIG2vIwzoDVoRBixgeIEBUSrFpXXQ7SSh TUBQY5OjUJuUCJKZmMPeeZ5ktX2QQClLh4wYMOhga/LETLqTxVuRn4DfG7o8OY274j8C 96+EwPOMfglcwjlUgSu8KvDUqVZk73j90p+KlrDXwEqOJWKPcc9uiI1S7b3W9BNkRCPw AhlXWLui7ISfxlRRIpcg5Bwa/+6BP6s7XRrNkXt3tcAK6g+CeI7Yxx1bFFRH0FW9e5ge 3z1A== X-Gm-Message-State: ACgBeo0zm4t8+Z68op7oWRqBsJziaCYiTpZh13/EKdVZX8dSiDZFA2Oz EJ7qcGorUna0k6Mm35awy5vJ5o2oHld+ X-Google-Smtp-Source: AA6agR5czhZhLekpql59UmyRwRG1k+V/2q4eEHoeBa5PmW/UqMA35yUxhbRl7c0ELA11mbWTDuI1s1HXdBP6 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:ca58:0:b0:677:3543:ca4a with SMTP id a85-20020a25ca58000000b006773543ca4amr3250822ybg.291.1659651537703; Thu, 04 Aug 2022 15:18:57 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:12 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-14-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 B4E4EC25B06 for ; Thu, 4 Aug 2022 22:20:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240215AbiHDWUR (ORCPT ); Thu, 4 Aug 2022 18:20:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240060AbiHDWTV (ORCPT ); Thu, 4 Aug 2022 18:19:21 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB85B71BCC for ; Thu, 4 Aug 2022 15:19:00 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id o21-20020a17090a9f9500b001f0574225faso3439742pjp.6 for ; Thu, 04 Aug 2022 15:19:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=iDTsGEaloA8F6T2uQwJmhdfAKv0wyG/O4ZDzV4+qrG4=; b=Mw2NgJfVXtIxdyjO5zjmfTEuj+3FTGv8rn7QL+oO7fOl4h3SLIl6MjfE3uZZK47Xfe QwGB9Hn7WdFZQkeFZDP5T9IKbSXoSGH0/uA02EJB/EMJU3Ifm1hM7ixCsR5/EOzLmhRJ EGoNasw2Fj+NyaXopFdijze/Uhiul5np5BaDzyc1+b497JDOGJQn4VIWuGBRCo0QOyGS +u64tYxOsvPFRHn/1TdGsAsfrzKk5qy8VwpFr34n83dBrLVfs31E99T27hF5LO3/YzT6 NHtb2geqLe4xJxXXrSqAuoYvdBDem1sG52IYq90/BK7//Mu2o3T9+hh0mmkGHs872Gsf +1+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=iDTsGEaloA8F6T2uQwJmhdfAKv0wyG/O4ZDzV4+qrG4=; b=78KOah4KrGpJHtXVqXzbRRPWnwV6MwHgT/D7Xz4+L6dK6Vz2zzMj9fMIwS0p/ft+kq P+F7jId1cDysxxks54970EVUM57/Pu5QSEaK4ECzY3ATqmm2oy/Rm+NLV3of4QtMKfd/ VUQat3WYbGF7bcXWfK9VIC8tVJnK7MG87kMEwGmG+s4SFVCrhMh0pLEbPWlePzGNhmGD 2C5m49V5rDBOXvTZVMV1or6kbH3UchuIsU3Q1YYzNQeP3vkJN1Op7USqFJALXD1oxToc 7AGZA8d0N27xMx3eHW6X+M/lypre2VSOlI8kVHJhP5EOD76RrcABOzcZQrvhluyzy0o3 lckQ== X-Gm-Message-State: ACgBeo30KlbmgWVvI/YIqccZqfnQh527gTKJdTg+jOH3wUQvUinG9gf7 BGt92hah+osR9D2VVPmjBoeietpoz7mi X-Google-Smtp-Source: AA6agR4cvFrSd0bKmQhyPiz+pSAQ7fy7Hg8EnqS30aVp61pj5w8CTvhfXeZXFTB3/t6tQOtwAtzR16MZmgeI X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a62:5441:0:b0:52b:ab93:1f05 with SMTP id i62-20020a625441000000b0052bab931f05mr3735532pfb.30.1659651540368; Thu, 04 Aug 2022 15:19:00 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:13 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-15-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 CA05AC25B06 for ; Thu, 4 Aug 2022 22:20:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240224AbiHDWU3 (ORCPT ); Thu, 4 Aug 2022 18:20:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240066AbiHDWT3 (ORCPT ); Thu, 4 Aug 2022 18:19:29 -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 C4D5172EDF for ; Thu, 4 Aug 2022 15:19:03 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-328c683e73aso6850817b3.23 for ; Thu, 04 Aug 2022 15:19:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=hKdXC3Dql13mKwUfJGBQkfcpnljE9PToPeTdbYeGres=; b=NDRI2Uda5JWymD6je14uVr3Oj4wbWv42Eh9kGopbOo78wrOR9Oky1i9ioN+9H1zn00 dOC4UJ7VRmSvi3YjHZ5kzjze2CeL6EbBuDwQpkR0+tv/agAoM1F0f9HZuZZ+5RxMKPau HifNxlWUlMcadc5JZszNLd97aYlUMEt4VfXYen+3xCeahJiQgSICQNiLedF0cVTz0ZgQ S1KfQvP2C0JXUzZPzgZlQ2uBGilDfyUAU6pUIIjh+3wgRhRs7QnW+mSdoLZ4csitiVur h/8UsGxCykGIbAyGE8zvqPeOIAIvXTyoQsv4cmktpWORHT1XxnjaaQ9FyWKrovNNWCQv yv/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=hKdXC3Dql13mKwUfJGBQkfcpnljE9PToPeTdbYeGres=; b=TeHmtyiKmgTohQyiyUf7AU7GrIC0peiFwVgy2QRIkfeengz5k/7jAjgVJuddd3xeLx u4okAAZiZ9GgM8HaqHk1TuCncSzJGuKa27NkdFHfpmpI9RcmtfFLMtXHm6W+CHnPPktx G+P3+GM92GxifET2Pc43qzTb+5ZGKs2Z2tNahO52LjIsenE4SBeIw46B0iR8agfReVMC +2VnkGrz/YYWnMoniPzATtBgePu3wghcwGdJo1z4Nbx8bBqxc1ChqEGGj+arCmjkhRgf IoYVMl1os+C/hdNClg/KoRkkZw5HiSTkhl5JGBcaizEVtozo1E7bAgiBYUPm17pLB9IL mq3w== X-Gm-Message-State: ACgBeo2UPxG7RPANu13BIeI+aDfKVDKj9eGjc8otIX+jyVbmFuealKyA xcHEFHdSMBgTGjtrT3MMHDzERIimxGe7 X-Google-Smtp-Source: AA6agR6YILN9N5BqtIbXvPAjFAUAHzL2OQeguWlk9vwwJWB+OjVa+SHBovChrFea7YNP+B1FzQKcXEFzMDp4 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a0d:ebc8:0:b0:31f:4f08:63aa with SMTP id u191-20020a0debc8000000b0031f4f0863aamr3495227ywe.145.1659651543035; Thu, 04 Aug 2022 15:19:03 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:14 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-16-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 995B5C25B07 for ; Thu, 4 Aug 2022 22:20:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240236AbiHDWUk (ORCPT ); Thu, 4 Aug 2022 18:20:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240167AbiHDWTj (ORCPT ); Thu, 4 Aug 2022 18:19:39 -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 88B7172EF0 for ; Thu, 4 Aug 2022 15:19:06 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-324966c28e5so7493347b3.3 for ; Thu, 04 Aug 2022 15:19:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=he3YFcCEA+FOKtL0ZP7LXeXSwmdugh+U3amWoB8Lcus=; b=YUMK04Gp6AVXrU99owp9m+uOBq2JooJcmTuTPEPwxgsnmsmlDYhEXCv/c8jOuH5VHB zYRDCcs3W8ye8dWhptBMLBMTU/lqbVOQGUKtshLoDr7lWUskpKkKChwvv2ywxPSL12BV /w+PRxb76Xm9Xmop4wNyfBhyPjZqKA/UynM+Ljm/ku62xLCxAV+CPr598FwKTnMGQzOZ ePXGZGiTKS/2sIzoeM70qhmpCVHS1GYNuzT0XHe1eygJDmKICngNvB86sw4PWPcfJbhF 5v1BuLjx+/gXMWiuM9BQhQuT91C9TIN+GF/K7v9QkZJiIiKA9pILx6EzaQBUadHObP2P He6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=he3YFcCEA+FOKtL0ZP7LXeXSwmdugh+U3amWoB8Lcus=; b=qrMOVhR0x2L9IQYqnG7LsIx75ZULWb6+1znx8NpBxw8aV7xh9XoR87zf9Ef7RVLoSo 4oM0B86MD0nVy0/Mc6cMqB0s+rTbALmrfRcnyF2EA/Vx3iYId93PjRVJPZF1YRPG6iOo FThdeCJWFc6pAKkoWaCalnNEsaC/NuILv115+RaHTJF19EBRThZKxE30rWvnVQ6llCQQ iHNgzCUdnGrfc2oznBuo8GGIPmBPHVF158IFxQCzmTfjLZ4/mLFeGnF3F8uoYoUnqbRH lnKl51wCFRm3hy+sChkAnXDamb60Nf20FJc3b8zMsClrpFYfb2PAmFkxGjk8ZChW+9jY 6C5w== X-Gm-Message-State: ACgBeo2lu9Xg+Y3lePs4miXAHPL5N4ta++XsW9fr4TGLWodaan1iWSAx ELj/ctXz9Rx/hKFxcrzs7YuXi8El6Zyi X-Google-Smtp-Source: AA6agR5hk5o9dkjZvv4EIc/Dh01WG8BStnzKoJ3oJodZCUutlj8ZmlMZrpknA65g5qmRGi8vRYRkkn3hMnRm X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:3ac7:0:b0:670:fa79:8f6b with SMTP id h190-20020a253ac7000000b00670fa798f6bmr3337585yba.290.1659651545479; Thu, 04 Aug 2022 15:19:05 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:15 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-17-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog From nobody Sat Apr 11 21:15:09 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 0EA6AC25B06 for ; Thu, 4 Aug 2022 22:20:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240115AbiHDWUt (ORCPT ); Thu, 4 Aug 2022 18:20:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240103AbiHDWTv (ORCPT ); Thu, 4 Aug 2022 18:19:51 -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 CE12372EE1 for ; Thu, 4 Aug 2022 15:19:08 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id w3-20020a258503000000b00676bd41edabso612938ybk.5 for ; Thu, 04 Aug 2022 15:19:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=content-transfer-encoding:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:from:to:cc; bh=4sKjIkmYkxcPgdqfn3mzo5ECG/fhrbPKoovcaQBneno=; b=RPm1sCjET5JP8rNcetK1qF6U3qw+w4oLLcGhOWWOu6L1nGDRTQOuOliumqxWh/gKIX /9yKGK/DBjlSzOJoAEnI8awONqJrPt8jJdDpabeEJsIpGx6Azhbs+NJ3l/6DHoaLnJAK iNfK+TCPk3sbqCiJXNNHG/RA1dtiLHE0H/Fd49d8eU7Sri+xugWbE1EhCKXlJdnmCTqB rbYIxHKfLk4UTPxs3M8dea/EN0OfJggsJJ/zVHHmz3o+JOprkTttk13fyYZ928dUigUh kDM7BJaruWI9v6ppGVYpxP7wIR9PEzOHNqqUA2nfkq0TcCOlbYuvMWFoY6ORd6dZg3zR P3cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:x-gm-message-state:from:to :cc; bh=4sKjIkmYkxcPgdqfn3mzo5ECG/fhrbPKoovcaQBneno=; b=aRFp7q0KWNm4MQ9UmtZGzODbG4xeowGw7a/BYi+yHmpXtoq9tqhAG6V7ldQsDUeh6G 5Q2Ux5LIzrjb+FrMrOnIk44O+eN/oALsEZgkEkvpYNqWcJA+S+obi2s53yIxrZXkKD6M d/JkNz3sIYSmrrpWZNXfgKArB4VFN1stQd8ueJwsFA+HPIW0xM8OxszfhcvreSC+Xz4O Nyc7Yq7mh89q2GVN3vy5hLuUQVJMHcWuHxxvbRZPMRtOIgw18OzK9MMqkuD5rQjqr6y8 F9Uc5uL8Z/GQqx3raPY25VergZzEE3LSNnlst/zpxzmo2TMPCzmNwwE/RZY/czeUraxc wqEg== X-Gm-Message-State: ACgBeo3MlT7fFUaM5JPigtCTxgSufmx049JfDBPsK0sZUlFpXboyVODV XX0HA6nXck9TmaJ9n5JXKWjMEhdTaLYm X-Google-Smtp-Source: AA6agR4FmNYXeclC++bbyZH3TZg+ZhvtAunrgtkYw8Z7YOjZT3L+beFF6zd42weYs5tFP9F2zwFabCWCQG6g X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a0d:c007:0:b0:324:8274:24cf with SMTP id b7-20020a0dc007000000b00324827424cfmr3627946ywd.213.1659651548135; Thu, 04 Aug 2022 15:19:08 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:16 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-18-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 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.559.g78731f0fdb-goog