From nobody Sat Apr 18 09:23:34 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 C609DC433EF for ; Fri, 15 Jul 2022 06:37:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230443AbiGOGhY (ORCPT ); Fri, 15 Jul 2022 02:37:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229881AbiGOGhS (ORCPT ); Fri, 15 Jul 2022 02:37:18 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DCAA442AC8 for ; Thu, 14 Jul 2022 23:37:16 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id m5-20020a2598c5000000b0066faab590c5so3303472ybo.7 for ; Thu, 14 Jul 2022 23:37:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=I8mIXVo9Jr2k+tlsqaJg0nYaaYQybo0siO3CB03II98=; b=agKGOIE1vqPjt1tgqd8riMq+O+VFoi11uiX3rz3x8Jm+lIy4iadKYc3u30xQ+YSN5b PlepmeeZhyElM5S1c7iEPQA36JF5TderemYVFZqRAfi8zwefjKxI9QbyjsYdlnuAsBpY LrfjS9e8RGKVxPeUKva4IFt4BRv4lk2qxIUKBjo2hYJsur0cyVkISvNa1cMPSz4dNY6D AWbzJHUJ6553kNi39z2+D+lHExBkt4ycqqlGBP/3eKjW+0gqoL1n0aCkXrV6onAE1FVF Gwh1XqzEEoaBgYFcSWefu22J9nHLz6vZg74FF8ozFDtpJdOKy8hXyLsbw9Tq/hvaV2hA MD3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=I8mIXVo9Jr2k+tlsqaJg0nYaaYQybo0siO3CB03II98=; b=C90mesXTqtST17E25ZK/LamrYl75ZP32v2PmTGjzMib4Sr6RO2E4c/iaRDvd6O/usx jYuGgm8dKjTbgvetbgRBCNhMM2K6NRA2V8LUojVpqv7uBX4XsUsyODhT2BSq60M0ogCw 3ICEmWL8nkoUMyEIXzuEWGqPh+BtAcuAqjtkYaMmJ9VtXcEmy8wPEwjsyLDfckTRgqv/ oM9/QhARtyyVRdqSiupSPKjg9Qlr8HAcReHp2UX3pjWEiVmQHzRI0kBRFPKcwgw6awDA oFRK6z9j3Va5StLT7GH9rwhpuYzHmOjV7gFFxHHEXWFPp9CVdAgBfResYX34SaCg1edt 4cbw== X-Gm-Message-State: AJIora8gDhAx3Cwe2pmPRVsDGCC0pE+mmty+QbENxrzVJKtyvalEaBVt sPhWUHvPq3Rh04nF6XsnNyyLN4MCT9Ts X-Google-Smtp-Source: AGRyM1vWw2+R3+LXTeD6M1RrxELOEjWl7BVzVgogGej1aWKtKZtiRk+SNJ4lUGbI/jz/nlU28rJ+WgAxmB9n X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a25:730a:0:b0:66e:698b:37bd with SMTP id o10-20020a25730a000000b0066e698b37bdmr12397283ybc.485.1657867036179; Thu, 14 Jul 2022 23:37:16 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:39 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-2-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 01/15] 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 83e0dcbeac9a..4a170f23bd67 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -204,7 +204,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): @@ -212,17 +212,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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 8CA2FC43334 for ; Fri, 15 Jul 2022 06:37:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231124AbiGOGh0 (ORCPT ); Fri, 15 Jul 2022 02:37:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230355AbiGOGhU (ORCPT ); Fri, 15 Jul 2022 02:37:20 -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 5147542AC7 for ; Thu, 14 Jul 2022 23:37:19 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-317f6128c86so33983067b3.22 for ; Thu, 14 Jul 2022 23:37:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7M+GYYtNjRF6j9wlPTn7oQQUyE7jpd1eRRPdaQ7NUb0=; b=G8OsOx9NQ5S44AxvV1eJpCSFqDL7WyhFawmnWQt1pl7AmVtgiowr6ISKMfY4j8r/1P ckki4/iFRs4CG9NEIx376vxZ+loqvCECslcc9KyPV3/iRMIJun/nesiLtQUzTfODVxPT dxcCAHnqRdtkaxrIJrXc3CQF9c6qM9USh1x1ciJy/4CAWpJi6PXo74x+CT3JtvG++2Io 3gOaD0buaEquSfph1KhrsfodvXeiiILEc+KnJNq+vcjuXhA1MD03r/aCABrc4NJZZ6ru MODpbXHXW54ZODRLWyXZC3DLDzMPV97SQB+gNFbjT0QqJ3CqjObdWU28iHLpmpIoFS5s lWCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7M+GYYtNjRF6j9wlPTn7oQQUyE7jpd1eRRPdaQ7NUb0=; b=Fx3MnBI9pzymD5wVtAZr5fNQ1DzsJXwvw5iwaL5WwnZQG2Qk5KZNUt4SfL00z0gL22 KqWSJprNgwBkAPEEHWY/zG1k2mTFhT6lrWGu+32l19JVGIFua7ADeEijRRyd97SI6fDp iQHWGxG7B+H2U38wgmkr+y1qABZzvqC64BUIkCfvY+subY8tr/zt7Q4gbykhYjQDWtnr WF/NiVIEtPx2vGOCMuwziS9YEIFlQla9Nx4JjvqhdxgFdJ3swL+v+xjG5IjalQttSO5J YawTPM7Lw9ceU10d9Mb1WZ97fJ2cDQpM3+cCzfLuDSYahVR+IgKVlBvgYL0WGcDYuepv kA7Q== X-Gm-Message-State: AJIora9BjOb2KpWg52/F58vfXJMQlxoWX2OoPLT+VPcn4bsRTGF3uhnn fb8RUpP8n63c5l3ZMCxIigJdXmT7PxT8 X-Google-Smtp-Source: AGRyM1sfq076xPFf7fCPFMLcz7pfQitfffjVWX1mfD0w39Vf5Q+0y+4WjiioFd8z497Furdboc0OdtrVApRe X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a25:d7d6:0:b0:66e:47b3:35be with SMTP id o205-20020a25d7d6000000b0066e47b335bemr12494781ybg.140.1657867038611; Thu, 14 Jul 2022 23:37:18 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:40 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-3-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 02/15] perf jevents: Add JEVENTS_ARCH make option From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow the architecture built into pmu-events.c to be set on the make command line with JEVENTS_ARCH. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/Build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build index 28a9d01b08af..04ef95174660 100644 --- a/tools/perf/pmu-events/Build +++ b/tools/perf/pmu-events/Build @@ -7,6 +7,10 @@ JSON_TEST =3D $(shell [ -d $(JDIR_TEST) ] && \ find $(JDIR_TEST) -name '*.json') JEVENTS_PY =3D pmu-events/jevents.py =20 +ifeq ($(JEVENTS_ARCH),) +JEVENTS_ARCH=3D$(SRCARCH) +endif + # # Locate/process JSON files in pmu-events/arch/ # directory and create tables in pmu-events.c. @@ -19,5 +23,5 @@ $(OUTPUT)pmu-events/pmu-events.c: pmu-events/empty-pmu-ev= ents.c else $(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(SRCARCH) pmu-events/arc= h $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) pmu-event= s/arch $@ endif --=20 2.37.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 3509CC433EF for ; Fri, 15 Jul 2022 06:37:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230161AbiGOGhe (ORCPT ); Fri, 15 Jul 2022 02:37:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230431AbiGOGhX (ORCPT ); Fri, 15 Jul 2022 02:37:23 -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 E48DE39BA8 for ; Thu, 14 Jul 2022 23:37:21 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31c8a5d51adso33928187b3.14 for ; Thu, 14 Jul 2022 23:37:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=L4iowk5wYqRaAGjNPtLjJJhNjdR47ELfV75N84bSpCk=; b=N9ncQpK7YRAq8GE173zVLt1JksQ3A31a5rUJgBmzZiCVx3bNads+WIg1XnimaaZZ9f T8eLBus1gQR5WBc70JH+c47e2E//tC3NMb5C8QA2Gw0yNASZzPcjlIp8H76modkRyF8h ZH2roRndB1fIcyjjKMtrvqjuA/uvaaMmoGVT2onoc3+ReW/6bZWLXQcmk0YCH8pGmfkb S6ktJ7Oo/4CpoGO20G8eN13XAFt7weHAsvbXAQrxjwHwo9+CWN7FzMQPDmbTBdzOGwEh E5mXxUY7KoHgpH4cESq3cVTBgBRL3WzUEgk2f+N9Jxnngg66fQsVyXO7i+M8Ah9gVXzV XVNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=L4iowk5wYqRaAGjNPtLjJJhNjdR47ELfV75N84bSpCk=; b=RvQRZdQ9pJK6bi7B2eD/RoUWlhbNjwM6lR5vhmqeTHfD7MMVolW4xc+DyRGma8bcVh AtjRHOtqCH7SzaYQLuHVTH3JEILEiIsPmLz+O592i+/Htv6xm/f3Rc/P5Bit1pji8wxx oKJqT4W3nrSRIRMGXRb/PmxIFOBYXeYfSGO/XB9VUDggdIz58QMO0jySccMa44Q0Lt7H bFJ9D3axJ3HiZtF2SO3TKPUDOlzO+eQetouaLgBR4P2sao3rGqK6bvrnp6Za8F92YCOM ltDzHugf/Ik0lgZ1A4Llbm8Lm20XQMBt6e0FZ9TZdRKG1saio/Ikl4UK+gB8niwPrqfn TrXA== X-Gm-Message-State: AJIora8jzniHx/+cPgUAoP1e+EoOVfH5jx0RRxMk1xZR6x4GcZGIa0ZL 76zckBLp6cxqvHrV/0jqSqO807pNSRsi X-Google-Smtp-Source: AGRyM1swL9lZ/OFGz/mUSm+HvcI5O3CXjv9RYoofejL5lzQ3Q9NAc5Rk0Xz7/w9goTjhFM3nrLEtFueMWzic X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a5b:9c5:0:b0:66e:cbbf:2904 with SMTP id y5-20020a5b09c5000000b0066ecbbf2904mr11861191ybq.220.1657867041212; Thu, 14 Jul 2022 23:37:21 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:41 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-4-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 03/15] perf jevent: Add an 'all' architecture argument From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When 'all' is passed as the architecture generate a mapping table for all architectures. This simplifies testing. To identify the table for an architecture add an arch variable to the pmu_events_map. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 70 ++++++++++++++++++------------ tools/perf/pmu-events/pmu-events.h | 1 + tools/perf/tests/pmu-events.c | 3 +- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 4a170f23bd67..2a9a1a086dee 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -305,38 +305,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 @@ -387,15 +394,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 478b33825790..0c9439cf77e1 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -855,8 +855,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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 BB802C43334 for ; Fri, 15 Jul 2022 06:37:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230355AbiGOGhi (ORCPT ); Fri, 15 Jul 2022 02:37:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230520AbiGOGh0 (ORCPT ); Fri, 15 Jul 2022 02:37:26 -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 91367459A5 for ; Thu, 14 Jul 2022 23:37:24 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31d17879672so33994647b3.8 for ; Thu, 14 Jul 2022 23:37:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=iTECb6Mg2TpLhaSw4nsYf3B3pkIu1Oc8fpNqlu+eD8g=; b=EG3JmQlm7C4iHUe9v6uHAbu+lKQCnHxibfDJGoXHrJ++HtVCsacBt+Lcd4mKW45BxF 2MkrPG2NZSlexuGFwkKoL2Ax8zodlRAP7WQQTujWZcHJS2tNn5KimMkkRIz9vo+MAl8t a6OXUdic+gZwgjuyx8raYNLJM1GYNeLqt+XkuDrw/gKiD25KSEHRXkMmV6ZsGGVgCjfp QKeidEDD5+T6eWqO+pnuUeAxBu2RTjmL0isTMW6urRJ65yXbGGCfYefiDBxMIwCR0+/u l0ywPiq3Cb1W2Ac8uazzJWq4/60oyCQWGOgpxpvjemC2rvMG1FZQ940LDMlSYvAtEAX4 ww5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=iTECb6Mg2TpLhaSw4nsYf3B3pkIu1Oc8fpNqlu+eD8g=; b=yxtTZXKnJVyaO5F6tO4pg5Lnza6+dsI5Jip/S+GnnPS/yNxLFG0ZQQtfUi2qijxg3v 7aIy/ubBM9AoO5+26ZNCglXNo/HPYfVy/AKHg8QdS6jcWldcHT6bi6iSJF5UBtnSCNU4 /YpWOz/4dOamlBQRPVsAJH9VcAzZ8YUWKskk6O2Nlub2zLSpUfbbDzEO6yo3fUtYArSv eqBiISi1qIWYDN5pBXNwkorQ3ylwpJYoJUuVROKmY3MgxylIsc253YCwsP0+j5+cjWRu ct5fhi7P4ZqOguDQ9Py5XGxniiE/4zx1B+JucGkyM1IbxG/XOLr+pw9zMlV7POagrCa0 /nQA== X-Gm-Message-State: AJIora81GT7QW666cFoaRg8TLIw2U1B9p13y6ZNMogPq71O55PoJ1XTA z1ehOgJRAfugaaWST69pjMveaD+cI6DW X-Google-Smtp-Source: AGRyM1skxuFPbwf3y0CFyGreJp4mNzxjKkWHySbqDDCcd4FomQaZiqj9KHEgZcuOEpz/0oYUPjMgXACGAwZz X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a5b:24a:0:b0:66f:939c:a643 with SMTP id g10-20020a5b024a000000b0066f939ca643mr12579689ybp.415.1657867043840; Thu, 14 Jul 2022 23:37:23 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:42 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-5-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 04/15] 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 --- tools/perf/pmu-events/empty-pmu-events.c | 6 ++---- tools/perf/pmu-events/jevents.py | 6 ------ tools/perf/pmu-events/pmu-events.h | 2 -- tools/perf/tests/expand-cgroup.c | 2 -- tools/perf/tests/parse-metric.c | 2 -- 5 files changed, 2 insertions(+), 16 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 77e655c6f116..4182a986f505 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -110,15 +110,13 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { =20 const struct pmu_events_map pmu_events_map[] =3D { { + .arch =3D "testarch", .cpuid =3D "testcpu", - .version =3D "v1", - .type =3D "core", .table =3D pme_test_soc_cpu, }, { + .arch =3D 0, .cpuid =3D 0, - .version =3D 0, - .type =3D 0, .table =3D 0, }, }; diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 2a9a1a086dee..c53c744da56b 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -313,8 +313,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, }, """) @@ -330,8 +328,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} }}, """) @@ -340,8 +336,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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 86161C43334 for ; Fri, 15 Jul 2022 06:37:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231329AbiGOGhw (ORCPT ); Fri, 15 Jul 2022 02:37:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231187AbiGOGhh (ORCPT ); Fri, 15 Jul 2022 02:37:37 -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 56C794F18D for ; Thu, 14 Jul 2022 23:37:27 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-31cbe6ad44fso34389217b3.10 for ; Thu, 14 Jul 2022 23:37:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=oNv4/zk1+mjyJIqC7KPNbf+jkGA2kI+7rQYeIFSNhZY=; b=Mpd1GjFJ9InS1ooJdyFxyNnJqwScVucDO7ehk16fZYUtOO6hqoqzN/DHXWInmUD1aK mGDqogxpxrmTlutbkwRfyGYoCIqUOhhUz4hcw7CiMRDBTFtBxiWaHp4ijjCHfRVC/TrX UDTPrUhfylNHbSepVnUZomdkuvy9HCqKGoQ/bSrQFnwdMCBtyzVEnMflByoNccWF+GsR CdVmGrTWaPVZI/PuSu/ng6tcVX9SZGx1vzDsJGLnbXuzwEgDYfGPchfz2Aqgn8GDdBX/ Qoni9TFh7w4lyPt0QnNdmI63icwlKFgpnAwTY7NYfEJc2gL7Ghe7dZh8+q0v18IVoG64 3Kww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=oNv4/zk1+mjyJIqC7KPNbf+jkGA2kI+7rQYeIFSNhZY=; b=PGjvhTwjHE13JUuADkdbE4MHbZ7m7+qlCcLzwzn9XPwVSiuugbT+c9+IFc0YUEqMqj QljvPRd9ukmwlOzTv+BTFQBuDShMLs2BKPJuJj0MneHpHWEGbNbYfEh27Lj92H10rRvV VuGzeqEndZWE1s13yGcRz1A6aq/NxVfNVcukmuGDg7Nsvu8UVuHcMuFeBkLPyt0a8zQm 6FxmtMuZN3IzhEmmexP47oNFjJx6Q0gFOxfV8Zais/ZYj5GROHq3mUBgfWeFgJFoLO08 VMzZ+7SD3Hizu5d3amkvUZrAZGujsr1wa0lK/FYPrHpDGkcg8M2W3XlrnXBAsmr/YYYH i4pw== X-Gm-Message-State: AJIora8G04+gPoxW9fOlQbOqyATM7w7MDNFe+7F+s+DatDeoHz04Azu+ M0n6yWmb3kImT3WcBnMGjVEFBMF71F1F X-Google-Smtp-Source: AGRyM1t7KCgLWCt2hEcOCq4fDH+oYV3WDSVG9zEdbtZELrdsky27kk4fzOhKyzwMgRxo9S+WlVPNS4PjAqu7 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a0d:e60d:0:b0:31c:8046:8ff with SMTP id p13-20020a0de60d000000b0031c804608ffmr14288131ywe.412.1657867046502; Thu, 14 Jul 2022 23:37:26 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:43 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-6-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 05/15] 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 c53c744da56b..7d5110327468 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -225,7 +225,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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 70B2EC433EF for ; Fri, 15 Jul 2022 06:38:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231234AbiGOGh6 (ORCPT ); Fri, 15 Jul 2022 02:37:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231143AbiGOGhl (ORCPT ); Fri, 15 Jul 2022 02:37:41 -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 12C37459A5 for ; Thu, 14 Jul 2022 23:37:30 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id c7-20020a258807000000b0066d6839741eso3333299ybl.23 for ; Thu, 14 Jul 2022 23:37:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=BQOq8tI7v/9y+QMAqaMpaqm2Xp9AyZrTad9dwfFKcVU=; b=PFzOr1FQLZgNd2HR2tTjmO57G8WnWtt5/5Vj6vZn3H4pSMGTWgBNAERwBM4xWGNLPd B7vfUnwM+IZZw1aiXG+z0xOeBr+A9QqpfpkxVFHkR/Iu4zd/s8NNCEHW+sqdXizBlMuZ lQteI/QzWO1F7YiYekustMZjvPj4yG5Y2lZjY73Np3JS9CLIF9rp73QwvxoxqjQn52IZ Dkiv8w4dpd4nnPORDd8y6BuaXrlpjmnQTgNKsf+Ko5mkPilxLb2vj2+cAMx6SichBS+H o9A+JOMK28oO7mJJ9uN/gZ0CktGuidG4iccTQGZcn+jctbx+jEq1fxsvEXrOUmUbaKAE RgYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=BQOq8tI7v/9y+QMAqaMpaqm2Xp9AyZrTad9dwfFKcVU=; b=UhkB0qqcuB5W+ky5XsGZ9qq6Q474k3MXUIVb/skZziHg96Slo64MTM1HWBtMO9q2lc LCNN1RyK+pk1rjJF105izuy1kdjQs/t4HVC7w2bmFN6yhEvb3QElzk+9LeePG9Jt3zZL HAumlz6YWF0y1jYM7EEDYzGam5vmHqeMCG7nGPImyIxn7bN77w08yngBnGmCkQ0xQRao V/FhAv8ofelaugLbavHrYuj8/+Hz8WiMVMCsjYlEEwZ0pyQEgoFCysphOGxDJfZRhRfY 5V+unRYnXRC/ZKmyPNDdZUbxtjaTVef3rUO8aBC41y+OATZKioF8zlJsDt3fNMaejC2X qJoA== X-Gm-Message-State: AJIora+4sTPgSiU8muXRRP2fqVLs17KV4kEyrMHjHfbsYKzatGme9HRn oZg+CwpShoygsxLwb3XVHjuQ3omKN6tT X-Google-Smtp-Source: AGRyM1uR4mKPIELBdushcXM6s6Uu2N3ypdN0Dmka3SkFzgZIDT3qjc/ibhT/QK0XOo9ewq3oB8aF2AYYvdMf X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a0d:dfd7:0:b0:31d:6466:3485 with SMTP id i206-20020a0ddfd7000000b0031d64663485mr14422731ywe.509.1657867048955; Thu, 14 Jul 2022 23:37:28 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:44 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-7-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 06/15] 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 7d5110327468..34b686d27cef 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -19,6 +19,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: @@ -128,6 +130,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')) @@ -200,7 +203,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: @@ -212,25 +215,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: @@ -238,7 +243,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 @@ -252,19 +257,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, @@ -307,7 +329,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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 56FE3C433EF for ; Fri, 15 Jul 2022 06:38:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231142AbiGOGiU (ORCPT ); Fri, 15 Jul 2022 02:38:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231251AbiGOGht (ORCPT ); Fri, 15 Jul 2022 02:37:49 -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 5631C60526 for ; Thu, 14 Jul 2022 23:37:32 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31c9f68d48cso34258627b3.0 for ; Thu, 14 Jul 2022 23:37:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=kcxF1w4r9aBOkpbQLeFudp2yTxjxFQuyMbzQFLMUmAg=; b=NOY3joczGCi6r//rAMntvAhAO3xOSCFSUDKpss33aYZvk48OMCst9NFS0o03APhTw/ Wr68ZJvZe5HIrsLuCbVzyJXPlbkQr4F/Dbd9SDdv7JA6mkdzSDHpo1EUt4TmmVZKZZno YQXSzdCU78Bp1UQ5x+kX5+Q6FdqfXkm5J1nq5TNAeia5c+CvkFeq36cmVzzfTLoRteAq P+CkHUqXstJTuq0NWhDBfPUHrroGvR23FXxx/eyXCuPMDuqkezaDeNKeAIO62IhrF5fe KqpmzTCo5HTiF8iGmVHN4MwUL/bKgdqgnvsEIqOEKYKkOLf4/p1REfPpSqN5uQBSIMZM 9lng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=kcxF1w4r9aBOkpbQLeFudp2yTxjxFQuyMbzQFLMUmAg=; b=2JEr9bQUvng6V9E4yEABZzL90OP9+HoYi/pNMzbLLANZnslGsUA0XrYUvcCtxeeFSN q+YYPXJb47X/Ij1as2zeyKL4Uid7kQVs1DC57x7NlZeWV7DIJXcByhiO7T390LXUCzIY BFTKFFq3MzT7WJpTTaHrP+vmyLs2uYwh18NeQZQsGMpPcTPMqWDIetAe/Qu/G+XXmYeI D+r7GD4P3s+MVbW9UotT9ED0rHsQSezsvg2Exl17nq05WCNV1/xVq/AtzFrq/0hcmuln wU/RrAHbublj5kG0bwsx6J9Y1QuieYSJnNIbqpehIsby6z6zYOiveuowEqmmtNX0D+2a b2UA== X-Gm-Message-State: AJIora/7nFplV3ny0a5yNr6USEA2BSC6CTfpqUEjfcQxuwqtmRSRaM2Q hoVtat5KsEuiheaMK/xAfPGzde38yiN3 X-Google-Smtp-Source: AGRyM1uD7CHiGe5XAOZbEevtqwCNXSZBqC812AvNiQ4ugArj57f6g3h9AUTy6S4lLNfcc2+SyHVeAAoN86BP X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a25:6044:0:b0:66f:5acc:e893 with SMTP id u65-20020a256044000000b0066f5acce893mr11824286ybb.343.1657867051563; Thu, 14 Jul 2022 23:37:31 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:45 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-8-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 07/15] perf pmu-events: Hide pmu_sys_event_tables From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move usage of the table to pmu-events.c so it may be hidden. By abstracting the table the implementation can later be changed. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 37 ++++++++++++++++++- tools/perf/pmu-events/jevents.py | 45 ++++++++++++++++++++++-- tools/perf/pmu-events/pmu-events.h | 11 +++--- tools/perf/tests/pmu-events.c | 14 +------- tools/perf/util/pmu.c | 27 -------------- tools/perf/util/pmu.h | 2 -- 6 files changed, 84 insertions(+), 52 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 4182a986f505..216ea0482c37 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -6,6 +6,8 @@ * The test cpu/soc is provided for testing. */ #include "pmu-events/pmu-events.h" +#include +#include =20 static const struct pmu_event pme_test_soc_cpu[] =3D { { @@ -145,7 +147,12 @@ static const struct pmu_event pme_test_soc_sys[] =3D { }, }; =20 -const struct pmu_sys_events pmu_sys_event_tables[] =3D { +struct pmu_sys_events { + const char *name; + const struct pmu_event *table; +}; + +static const struct pmu_sys_events pmu_sys_event_tables[] =3D { { .table =3D pme_test_soc_sys, .name =3D "pme_test_soc_sys", @@ -154,3 +161,31 @@ const struct pmu_sys_events pmu_sys_event_tables[] =3D= { .table =3D 0 }, }; + +const struct pmu_event *find_sys_events_table(const char *name) +{ + for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; + tables->name; + tables++) { + if (!strcmp(tables->name, name)) + return tables->table; + } + return NULL; +} + +int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) +{ + for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; + tables->name; + tables++) { + for (const struct pmu_event *pe =3D &tables->table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, data); + + if (ret) + return ret; + } + } + return 0; +} diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 34b686d27cef..432ecb5a33f5 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -371,8 +371,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}, @@ -383,6 +389,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 @@ -414,7 +448,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 0c9439cf77e1..4a7dee4ca7da 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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 50156CCA480 for ; Fri, 15 Jul 2022 06:38:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230241AbiGOGii (ORCPT ); Fri, 15 Jul 2022 02:38:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231324AbiGOGhv (ORCPT ); Fri, 15 Jul 2022 02:37: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 E14C366AE8 for ; Thu, 14 Jul 2022 23:37:34 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id y4-20020a25b9c4000000b0066e573fb0fcso3342721ybj.21 for ; Thu, 14 Jul 2022 23:37:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=e7+QWhCfZO7ckYc4IvpTlLbIpLWqok1CMqNGGWHFPvs=; b=o3+8bI5RsLcfROYpnxmNo8JqusV7KQGyh8w7UOZg8HZ/DWjryyQ/nWmAcvvQZIsBqP /31Baw1VnO+zA946kMqSb5ubFBpyXGoQvIphzptZ+hLzcnT0GAu/PjhL8lvJ5OLn6PGc sqe3zTBTDP0aHirx5EL/ix1g2qFHhYVwyl67BetNcs34M7bUt0sZ5M8W6bJ1ycra6vlp 4tfbGCdMELUgXyuQT5bx+s0X9pKnIO+twPPahIhm5KCWhVjVhEYCv4+eXZga4DQ1ihQu uVy2QyV/nV3/E34xhiwAvJh/UvYkNStQxe2cP43ZlVDPTtY62laUgSYc/EA0hYCUWq9Q /mbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=e7+QWhCfZO7ckYc4IvpTlLbIpLWqok1CMqNGGWHFPvs=; b=jU+sAnwLWESMzPP67ALu92XXgQoKqiTvAcY9MboV2RjXYktxv5SwPuyJl98Ow97MUA LM5Yo9XsTlvX1AZ6c0rBCaHbMJDWKF/vJyCZk2YhkIEWmpl1NBto8DAdxWS01dONfz7d zEZ7apWeZVXwQU8Ror2ys2EYP8E1a4qKtO2YuXAZ6BFKMNTSSxp8c7hxtHAiJnP/vH6+ 0k7nPWpDztQR+5beKLjVoC4j/8HBVbKJPnNZRUi+Q4xgJF6QVBY9ohyGuSMycAjRD9Rr GxBobIO7wJjSMdtR8v9K826DLZFjhOrKfn9JCQ4JBfUZ0OTpZ2QIG6+2rI82urv8yqTt Z/hw== X-Gm-Message-State: AJIora9Z41KyQqzu+n3YW8m0Ab7sEPFWbEOg4oi2+5TqOEogDDTQA0n0 CFaOWVairuBMTLMWvtRa62yFVMJovNm7 X-Google-Smtp-Source: AGRyM1to22h3RpR0ihq2EIU+Gvte6RVJRbPig6rgmRGhjR/EV+MUxBcY8DJbFC1Z2EjLNM+eusNqS8RhSxqs X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a81:f0d:0:b0:31c:8860:c59f with SMTP id 13-20020a810f0d000000b0031c8860c59fmr15120763ywp.31.1657867054082; Thu, 14 Jul 2022 23:37:34 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:46 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-9-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 08/15] perf pmu-events: Avoid passing pmu_events_map From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Preparation for hiding pmu_events_map as an implementation detail. While the map is passed, the table of events is all that is normally wanted. Signed-off-by: Ian Rogers --- tools/perf/arch/arm64/util/pmu.c | 4 +- tools/perf/tests/expand-cgroup.c | 6 +-- tools/perf/tests/parse-metric.c | 7 +-- tools/perf/tests/pmu-events.c | 63 +++++++++++------------- tools/perf/util/metricgroup.c | 82 +++++++++++++++---------------- tools/perf/util/metricgroup.h | 4 +- tools/perf/util/pmu.c | 33 +++++++------ tools/perf/util/pmu.h | 6 +-- tools/perf/util/s390-sample-raw.c | 12 ++--- 9 files changed, 99 insertions(+), 118 deletions(-) diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/= pmu.c index 79124bba713e..646af8603227 100644 --- a/tools/perf/arch/arm64/util/pmu.c +++ b/tools/perf/arch/arm64/util/pmu.c @@ -3,7 +3,7 @@ #include "../../../util/cpumap.h" #include "../../../util/pmu.h" =20 -const struct pmu_events_map *pmu_events_map__find(void) +const struct pmu_event *pmu_events_map__find(void) { struct perf_pmu *pmu =3D NULL; =20 @@ -18,7 +18,7 @@ const struct pmu_events_map *pmu_events_map__find(void) if (pmu->cpus->nr !=3D cpu__max_cpu().cpu) return NULL; =20 - return perf_pmu__find_map(pmu); + return perf_pmu__find_table(pmu); } =20 return NULL; diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index dc4038f997d7..411fc578e5a4 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -195,16 +195,12 @@ static int expand_metric_events(void) .metric_name =3D NULL, }, }; - const struct pmu_events_map ev_map =3D { - .cpuid =3D "test", - .table =3D pme_test, - }; =20 evlist =3D evlist__new(); TEST_ASSERT_VAL("failed to get evlist", evlist); =20 rblist__init(&metric_events); - ret =3D metricgroup__parse_groups_test(evlist, &ev_map, metric_str, + ret =3D metricgroup__parse_groups_test(evlist, pme_test, metric_str, false, false, &metric_events); if (ret < 0) { pr_debug("failed to parse '%s' metric\n", metric_str); diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 1b811a26f4ee..7aebde7c37ec 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -79,11 +79,6 @@ static struct pmu_event pme_test[] =3D { } }; =20 -static const struct pmu_events_map map =3D { - .cpuid =3D "test", - .table =3D pme_test, -}; - struct value { const char *event; u64 val; @@ -166,7 +161,7 @@ static int __compute_metric(const char *name, struct va= lue *vals, runtime_stat__init(&st); =20 /* Parse the metric into metric_events list. */ - err =3D metricgroup__parse_groups_test(evlist, &map, name, + err =3D metricgroup__parse_groups_test(evlist, pme_test, name, false, false, &metric_events); if (err) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 4a7dee4ca7da..6c3d22d00219 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 */ @@ -839,13 +836,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 { @@ -855,7 +848,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; @@ -916,8 +909,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; @@ -931,7 +923,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; @@ -948,14 +941,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 */ } @@ -970,7 +963,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++; } @@ -990,7 +983,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++; } } @@ -1079,8 +1072,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 @@ -1092,12 +1083,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..6dd533106156 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) +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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 8D861C433EF for ; Fri, 15 Jul 2022 06:38:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231575AbiGOGiY (ORCPT ); Fri, 15 Jul 2022 02:38:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231356AbiGOGhw (ORCPT ); Fri, 15 Jul 2022 02:37:52 -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 75BAF675A0 for ; Thu, 14 Jul 2022 23:37:37 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id j2-20020a2597c2000000b0064b3e54191aso3367174ybo.20 for ; Thu, 14 Jul 2022 23:37:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Z9xTFRxAbsalmBAh8aaG1sGBphgh09dtR9lwa15eXZE=; b=D422lL+jg65vnEDoVO0nwAQk1n1l2e9Cs3fOdNChQD4L7VQjBuT8+f0bkqEvMhaXs9 KOAyhD4PvpQBIZ2W6KO/95lAPxVHya6U5NaA62gYJD0YZuX+/iTVjDLVyEuv5MiDnBEa IMWKQa0tJQcaEICRP7Nvq4vR2k43NbILtb1aHxVVPGbrEGc5pVhvbUnXRAGFKhayM+Fu yokduYexmTN5j2qsDh3qO3Gaxnrm8W+bXhNP8WOqqR/wPJpl+G+CagiyCMKasbiZ2l/y 1AKRiL/SgZFLLtMtwqP7KGO8ylxcBdWmUzduo9JFBd7odf7sgOY2QAX8DaeY5fow7kl6 0R4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Z9xTFRxAbsalmBAh8aaG1sGBphgh09dtR9lwa15eXZE=; b=jVBpBuok26zmSs9o3UwG1wrFWeU9d5ZCd8Gs1Y573uUAOyxnl67Jo5BMOj3KKrNx8D GwEQauIpqOFPFgTFvXR01s+c+S36AeTw29NxJzlx9u9ey91E1FxTbgKfzC2DtghOYLM0 JaKrNNi8eRP784hwKbGQNDB1mMl1ZIDEcIxFAgTcQuJOG1A7R+y90QAJeap7JyCmkW6x G1XgxAQ/mMgq66UNRtgBHdMAATvkXp4zCL5wEvC1ZUVWHH73r7E3u9YK2VcRs30n23i/ ss2zkslFQ8fMJLqMRowqj7GI9i+r95p+h0Whp8yNq3/wOrz33833UCtc/vBY1ft0sZqU Lxbg== X-Gm-Message-State: AJIora/8PTplQrF0hGMzSXAzb0L8rSK4dRjCaLAcmrPjd3dM7Y0ril5o FiRPLAJeyixBlNW1zY56WZFl4FEVg45t X-Google-Smtp-Source: AGRyM1s6yorOIQnW6oCrz6vS+65nPHWdPdTf6qoeXtxnBu8a9eC0o9WZokksDQkIRk193GSmVuCP32laP9PY X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a05:6902:1184:b0:66e:756d:3baa with SMTP id m4-20020a056902118400b0066e756d3baamr12308695ybu.533.1657867056537; Thu, 14 Jul 2022 23:37:36 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:47 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-10-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 09/15] 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 432ecb5a33f5..800db6364078 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -334,7 +334,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("""{ @@ -390,6 +410,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]; @@ -409,7 +484,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; @@ -450,6 +525,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 6c3d22d00219..62e41b9c67dd 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); @@ -836,11 +824,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; @@ -906,93 +889,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 { @@ -1064,6 +1054,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' @@ -1072,37 +1072,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 6dd533106156..893cc0ff7758 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; -} - 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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 C4791CCA480 for ; Fri, 15 Jul 2022 06:38:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231478AbiGOGi2 (ORCPT ); Fri, 15 Jul 2022 02:38:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47658 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231228AbiGOGh6 (ORCPT ); Fri, 15 Jul 2022 02:37:58 -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 1BBFD6A9C7 for ; Thu, 14 Jul 2022 23:37:39 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31dfe25bd47so1029887b3.18 for ; Thu, 14 Jul 2022 23:37:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=heM+cYHlj6vP221hxJBcWNj4VjfXKtGYwQwPpYWB198=; b=JrG0JMAzXe7dvFygrnJt3fZ7vRSFbR8eW8Okqca1BNxTJJFa9/hvFIFoERMTjlvLTy osiGbL9NXBKF6xV6MJ6qsrcw082WHZ9k29za5kQUGw1OwdHjPfbKVTnvEskww0xXrRSm Tx3GteU4uQtNgVHZ0vBKrylHve+1VRetFuZ9adP7LSpett44WcHLMhRlvnnA7I2i6oT0 EoaEGQjxOIWD79Kghj7UefsupZSn28oN5+TONjPaS/XdzJCi5VeEWDcbsxTa5dPWMcVv 0iqZBR0/Z7nXAiDUtVC6Jk+KO7anHu/UkzZb2yrKTqig7CUlD5WW+UCIwcMxhvYwA7Nt kJwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=heM+cYHlj6vP221hxJBcWNj4VjfXKtGYwQwPpYWB198=; b=7ajatZkPtRcRSO2sNUYcu8U0oJCv3ylrR/rex7YPGjiIYvdccpPO62VX2bTBppbYZl SLkXLkwaKbEuQ6i9hlYIAggDRmTtS083xCJkaj7XZIKlKnC5qm22Ia6FWP16ju9OBC3T kzcrMP+mb6S4vSVvLTr3+mKTe/1IJnqkG0tv823sBNOrXa0kHuyA5zaGD+MbvLNzwFkr ieSYYOyrLBPfnvm9E1s9pAEOABIJAqst3UP0OgsS5N4qQpWxmo3rtCZPH8CPwp1TnhuC Ccxg23bIcJ42ZGi6U9LdATX5iqr0N3E6mkWon3g8q5XDMQPyITpdp2hRLPBosPhysmJ8 bRqA== X-Gm-Message-State: AJIora9RXXGmNerQqj198/TojMRCFN8W4A+TFmL30rFb/UsleguXqWOp yDyqV5GuzeiAmHsKgTZTvp+9wmwM17Pz X-Google-Smtp-Source: AGRyM1u7paE8z2b/HR/0D6RZuBLguyUxsags1T1DZeWNY+7dyKwGqOLtna4VlkaoLAH/yGqfAgtf2u1x/P2j X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a25:9f87:0:b0:669:4345:a8c0 with SMTP id u7-20020a259f87000000b006694345a8c0mr12581178ybq.472.1657867058918; Thu, 14 Jul 2022 23:37:38 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:48 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-11-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 10/15] 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 62e41b9c67dd..ccbf1057ba4c 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 */ @@ -792,27 +794,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; @@ -829,160 +810,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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 308D8C43334 for ; Fri, 15 Jul 2022 06:38:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230093AbiGOGic (ORCPT ); Fri, 15 Jul 2022 02:38:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231143AbiGOGiJ (ORCPT ); Fri, 15 Jul 2022 02:38:09 -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 D1DB448C95 for ; Thu, 14 Jul 2022 23:37:41 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id y4-20020a25b9c4000000b0066e573fb0fcso3342929ybj.21 for ; Thu, 14 Jul 2022 23:37:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=tm2t2KCIZFIssrtFM24eNdKhMbqKtqurn1jWHOn+RPM=; b=Z5eJBvu/QoDSb8Ch+ZE2Eza3nIyNP4Fp7u+sZOOV+enN83gCHY7mKC8IPSqyupTNmv umzDQ/8rSw+/H/mVq541fAbtIDfSUr0w80Vhxl36hFEc75TVUQaTmdq6Il4l2ri+Oay7 yiZm6dyc5h/f8hl8apSoZTJSk7wItKpOj2thSjjmr7eBGo9cwZOcPv8zRZqNafn/pocG msRGU+yLPkiWHPZuO0HigTDh2nSShHxCwzgjJYNZfKXQiRWi3Vng33GBB+zXmBOF19WD hquPmSGpqH3O0r8+1cKDLfzgMG6x/8NMlURX7PGuK1AQkhkGsOo7dXs6btkXWjKgR3wv vHZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=tm2t2KCIZFIssrtFM24eNdKhMbqKtqurn1jWHOn+RPM=; b=a4jf9kvgZ51Jkrvwc/1kxMO07zEWMhChEWo8dReUdR2h7nEzQkWWo8TRm2Rzp11wO4 X4DtDLZgBhLKA0blIyvxyhcTsHUCVsdGAShoau6C+uGdkUULaWtyNGnhXvj/Kf63hUH6 9poUdvlStNXgdyLlyL29fFrIU6UhhWK99p/LWxWffbjhtOjOiKvYYDQ/+jabyogS7+Wl BHTxnYVkGopwGZV9cCa8/+7SOmZXdtV2ufXYd0PhwRgzLOX2Et3wo/9L5IL+N/r7k8wG vRQQ5VdN+wpaChGgq/oDGdTFqty7t5KYBcaJZ31QaywoVxtqson8DTeV6NBXuENe1uRP tezA== X-Gm-Message-State: AJIora+zOnBBeqep5Nazw6d3cqEjyL9V6qd3EDIGT76qHL916u66sMjU BAD5cLAR3U2s/1ViVkEn3vwm07O4geOL X-Google-Smtp-Source: AGRyM1v++opXK5X0crZThndFTV5cy8SwyhNBLAsRiJL2tla9LHDXWdPjAU6ja/X3a6OhHecMjjWzLYHOPLNh X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a25:8b02:0:b0:66e:239a:8f69 with SMTP id i2-20020a258b02000000b0066e239a8f69mr12691327ybl.4.1657867061402; Thu, 14 Jul 2022 23:37:41 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:49 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-12-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 11/15] perf pmu-events: Move test events/metrics to json From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move arrays of pmu_events into the json code so that it may be regenerated and modified by the jevents.py script. Signed-off-by: Ian Rogers --- .../arch/test/test_soc/cpu/metrics.json | 64 +++++++++++++++++ tools/perf/pmu-events/empty-pmu-events.c | 64 +++++++++++++++++ tools/perf/tests/expand-cgroup.c | 17 +---- tools/perf/tests/parse-metric.c | 68 +------------------ 4 files changed, 132 insertions(+), 81 deletions(-) create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.js= on diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.json b/to= ols/perf/pmu-events/arch/test/test_soc/cpu/metrics.json new file mode 100644 index 000000000000..42d9b5242fd7 --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.json @@ -0,0 +1,64 @@ +[ + { + "MetricExpr": "1 / IPC", + "MetricName": "CPI" + }, + { + "MetricExpr": "inst_retired.any / cpu_clk_unhalted.thread", + "MetricName": "IPC", + "MetricGroup": "group1" + }, + { + "MetricExpr": "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalte= d.thread / 2 ) * ( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalte= d.ref_xclk ) )))", + "MetricName": "Frontend_Bound_SMT" + }, + { + "MetricExpr": "l1d\\-loads\\-misses / inst_retired.any", + "MetricName": "dcache_miss_cpi" + }, + { + "MetricExpr": "l1i\\-loads\\-misses / inst_retired.any", + "MetricName": "icache_miss_cycles" + }, + { + "MetricExpr": "(dcache_miss_cpi + icache_miss_cycles)", + "MetricName": "cache_miss_cycles", + "MetricGroup": "group1" + }, + { + "MetricExpr": "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqst= s.rfo_hit", + "MetricName": "DCache_L2_All_Hits" + }, + { + "MetricExpr": "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_= rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss", + "MetricName": "DCache_L2_All_Miss" + }, + { + "MetricExpr": "dcache_l2_all_hits + dcache_l2_all_miss", + "MetricName": "DCache_L2_All" + }, + { + "MetricExpr": "d_ratio(dcache_l2_all_hits, dcache_l2_all)", + "MetricName": "DCache_L2_Hits" + }, + { + "MetricExpr": "d_ratio(dcache_l2_all_miss, dcache_l2_all)", + "MetricName": "DCache_L2_Misses" + }, + { + "MetricExpr": "ipc + M2", + "MetricName": "M1" + }, + { + "MetricExpr": "ipc + M1", + "MetricName": "M2" + }, + { + "MetricExpr": "1/M3", + "MetricName": "M3" + }, + { + "MetricExpr": "64 * l1d.replacement / 1000000000 / duration_time", + "MetricName": "L1D_Cache_Fill_BW" + } +] diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 8ef75aff996c..028f44efe48d 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -105,6 +105,70 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { .desc =3D "L2 BTB Correction", .topic =3D "branch", }, + { + .metric_expr =3D "1 / IPC", + .metric_name =3D "CPI", + }, + { + .metric_expr =3D "inst_retired.any / cpu_clk_unhalted.thread", + .metric_name =3D "IPC", + .metric_group =3D "group1", + }, + { + .metric_expr =3D "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalt= ed.thread / 2 ) * " + "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) = )))", + .metric_name =3D "Frontend_Bound_SMT", + }, + { + .metric_expr =3D "l1d\\-loads\\-misses / inst_retired.any", + .metric_name =3D "dcache_miss_cpi", + }, + { + .metric_expr =3D "l1i\\-loads\\-misses / inst_retired.any", + .metric_name =3D "icache_miss_cycles", + }, + { + .metric_expr =3D "(dcache_miss_cpi + icache_miss_cycles)", + .metric_name =3D "cache_miss_cycles", + .metric_group =3D "group1", + }, + { + .metric_expr =3D "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqs= ts.rfo_hit", + .metric_name =3D "DCache_L2_All_Hits", + }, + { + .metric_expr =3D "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data= _rd_hit, 0) + " + "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", + .metric_name =3D "DCache_L2_All_Miss", + }, + { + .metric_expr =3D "dcache_l2_all_hits + dcache_l2_all_miss", + .metric_name =3D "DCache_L2_All", + }, + { + .metric_expr =3D "d_ratio(dcache_l2_all_hits, dcache_l2_all)", + .metric_name =3D "DCache_L2_Hits", + }, + { + .metric_expr =3D "d_ratio(dcache_l2_all_miss, dcache_l2_all)", + .metric_name =3D "DCache_L2_Misses", + }, + { + .metric_expr =3D "ipc + M2", + .metric_name =3D "M1", + }, + { + .metric_expr =3D "ipc + M1", + .metric_name =3D "M2", + }, + { + .metric_expr =3D "1/M3", + .metric_name =3D "M3", + }, + { + .metric_expr =3D "64 * l1d.replacement / 1000000000 / duration_time", + .metric_name =3D "L1D_Cache_Fill_BW", + }, { .name =3D 0, .event =3D 0, diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index 411fc578e5a4..e79ee8621a90 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -180,26 +180,13 @@ static int expand_metric_events(void) struct evlist *evlist; struct rblist metric_events; const char metric_str[] =3D "CPI"; - - struct pmu_event pme_test[] =3D { - { - .metric_expr =3D "instructions / cycles", - .metric_name =3D "IPC", - }, - { - .metric_expr =3D "1 / IPC", - .metric_name =3D "CPI", - }, - { - .metric_expr =3D NULL, - .metric_name =3D NULL, - }, - }; + const struct pmu_event *pme_test; =20 evlist =3D evlist__new(); TEST_ASSERT_VAL("failed to get evlist", evlist); =20 rblist__init(&metric_events); + pme_test =3D find_core_events_table("testarch", "testcpu"); ret =3D metricgroup__parse_groups_test(evlist, pme_test, metric_str, false, false, &metric_events); if (ret < 0) { diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 7aebde7c37ec..30c7091857b8 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -13,72 +13,6 @@ #include "stat.h" #include "pmu.h" =20 -static struct pmu_event pme_test[] =3D { -{ - .metric_expr =3D "inst_retired.any / cpu_clk_unhalted.thread", - .metric_name =3D "IPC", - .metric_group =3D "group1", -}, -{ - .metric_expr =3D "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalte= d.thread / 2 ) * " - "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk= ) )))", - .metric_name =3D "Frontend_Bound_SMT", -}, -{ - .metric_expr =3D "l1d\\-loads\\-misses / inst_retired.any", - .metric_name =3D "dcache_miss_cpi", -}, -{ - .metric_expr =3D "l1i\\-loads\\-misses / inst_retired.any", - .metric_name =3D "icache_miss_cycles", -}, -{ - .metric_expr =3D "(dcache_miss_cpi + icache_miss_cycles)", - .metric_name =3D "cache_miss_cycles", - .metric_group =3D "group1", -}, -{ - .metric_expr =3D "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqst= s.rfo_hit", - .metric_name =3D "DCache_L2_All_Hits", -}, -{ - .metric_expr =3D "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_= rd_hit, 0) + " - "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", - .metric_name =3D "DCache_L2_All_Miss", -}, -{ - .metric_expr =3D "dcache_l2_all_hits + dcache_l2_all_miss", - .metric_name =3D "DCache_L2_All", -}, -{ - .metric_expr =3D "d_ratio(dcache_l2_all_hits, dcache_l2_all)", - .metric_name =3D "DCache_L2_Hits", -}, -{ - .metric_expr =3D "d_ratio(dcache_l2_all_miss, dcache_l2_all)", - .metric_name =3D "DCache_L2_Misses", -}, -{ - .metric_expr =3D "ipc + m2", - .metric_name =3D "M1", -}, -{ - .metric_expr =3D "ipc + m1", - .metric_name =3D "M2", -}, -{ - .metric_expr =3D "1/m3", - .metric_name =3D "M3", -}, -{ - .metric_expr =3D "64 * l1d.replacement / 1000000000 / duration_time", - .metric_name =3D "L1D_Cache_Fill_BW", -}, -{ - .name =3D NULL, -} -}; - struct value { const char *event; u64 val; @@ -138,6 +72,7 @@ static int __compute_metric(const char *name, struct val= ue *vals, struct rblist metric_events =3D { .nr_entries =3D 0, }; + const struct pmu_event *pme_test; struct perf_cpu_map *cpus; struct runtime_stat st; struct evlist *evlist; @@ -161,6 +96,7 @@ static int __compute_metric(const char *name, struct val= ue *vals, runtime_stat__init(&st); =20 /* Parse the metric into metric_events list. */ + pme_test =3D find_core_events_table("testarch", "testcpu"); err =3D metricgroup__parse_groups_test(evlist, pme_test, name, false, false, &metric_events); --=20 2.37.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 4690CC433EF for ; Fri, 15 Jul 2022 06:39:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229945AbiGOGjB (ORCPT ); Fri, 15 Jul 2022 02:39:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231244AbiGOGiO (ORCPT ); Fri, 15 Jul 2022 02:38:14 -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 C744A77A4F for ; Thu, 14 Jul 2022 23:37:44 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-31decb2c9cbso19565327b3.17 for ; Thu, 14 Jul 2022 23:37:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=FKBmITwflNjUMeSv3iJ/EBya5U2H6wfrJ0UankXXrIY=; b=iaSXXv02hv6mVartLw/vJRJMdyzu27BLLFj+bFdce6uQZpgMhi/BKGkI80XrTI2VVJ VMmlVq+jybGea1ixd2LtrVOG90SjMlyHod6EV7zOZ8DSjYCd3g4mJO0GQ5hoqjwczyIm tqG4PlbVuGOdqR5t3f84tNWGWTunQ6RIt6C6VcozPvOd3hghcpgAf9aYeJJZdp4ep7OB TIMy1oFvfnyxkb8/DxkSQh1RabpV+s86A44PSpAIXaBMqU7kz4eFcCg3U8IYUKnheEwt Fw3XjGwcSAggeN+c3ieyv47l2gKsE2ssL18VPcSvpl8qAva3008HOifk8f05o4ht+69H udKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=FKBmITwflNjUMeSv3iJ/EBya5U2H6wfrJ0UankXXrIY=; b=cChSqj1LwvM7oSrCEjlV4CyPw/WCR/KsypZEPvJieobJ0nmW6PxOJd1nTq4lxpyL4l 6VT6wotfbJgw70X+YF9Y+zxbBz1OoBypDmJrgFHjtNns8MIv9n/LKYkbtCMRoXBgFshw QK963BulVn2L/VLaJuf+oJSsbAENt/p6qQzGQkikRPXnV7qVOxQUofUG8jGjnjXL4Ne4 393pY0SJ4m3kmJNjS8cceDXHVAR64H7uf74CgqZ+oFOUDvmujQR1n+YBxngNjPU+BOCN s1g4GC+T3jaT2Y4ZRB9d9Paf5A4b2645NlqV4a+pV7W0Lbi3eaZS8SCt2R/P2fYpE8ct CZnQ== X-Gm-Message-State: AJIora9197ineZWObCRW5haL2PXxNl6z2Z13p4AfBlmYquQVFF2qkepP 2rPktPEfvA18om8qCNTYP9Vlw0rMpHQP X-Google-Smtp-Source: AGRyM1v6cbe/lH7fDBMgXBU+//2Bqo3UkfQsnjZQoMzONHQ9akAApo48c55I5jImrL+qgs99kwLDocP5ByQw X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a81:70e:0:b0:31c:8204:26ac with SMTP id 14-20020a81070e000000b0031c820426acmr13881197ywh.175.1657867063812; Thu, 14 Jul 2022 23:37:43 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:50 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-13-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 12/15] 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 800db6364078..3cb8a196a76d 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -410,6 +410,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; @@ -453,14 +467,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; } @@ -481,14 +491,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 ccbf1057ba4c..a9808932f9b5 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 893cc0ff7758..7398a277c742 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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 19096C433EF for ; Fri, 15 Jul 2022 06:39:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230340AbiGOGj1 (ORCPT ); Fri, 15 Jul 2022 02:39:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231722AbiGOGiR (ORCPT ); Fri, 15 Jul 2022 02:38:17 -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 BA4AE4B4AB for ; Thu, 14 Jul 2022 23:37:47 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id k13-20020a056902024d00b0066fa7f50b97so3318226ybs.6 for ; Thu, 14 Jul 2022 23:37:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=K96RlQ0qRZGt3haZZzpXIAOeweTjt+K2/e4OHfQBVSo=; b=ItClMmJEQuMDAutl0aohybMkP04l16blur6MFQrdrLGanaYx/eblXFuRExN/4I7Wwi IjESIfOb2JtgaMi/ggbb7JvZYXXKTCQYJgWWzXr77luW7cCGlxYuG7rL6TtUTnjZBYbE O82iAtjx762Hg3dnZCIA8Kryu9OYsobG6/aJ6EpqtsmmL13Cr/+yul8/KLoVX+2Arftq fwcXj5ZGY/YExkHTB9gKCm1X567xVWTxxeYfemd3Th4aKh5Th6npWp+E6Vn1FUBy0jmp JWiEtWIXr9TOGgnl5kQR8ayrU0zbUVDJGtddOyy9oR2aKohgYCGeWfvrK28DG+J8kGJ3 cb7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=K96RlQ0qRZGt3haZZzpXIAOeweTjt+K2/e4OHfQBVSo=; b=D+s9FjOyXoZmMmfqYmWNSYZrONQvUXMDFmAiJmi+rtffk6fmiD8BRANOWTt43R43Wm mP2WHvkk1tESa8pZn9XpqbmNn3vEqkhyu9SZyuFWgFqrKVZucPDKbPMuhtftxSZ1DjpU BHLF7qe+WJ3IidMDKiQd/cbqoPFLhv3uMNk9n595krmxsdNP1hgQWP8OcKy3LcjIKD7M GkZjOFeunLK5pV650vmT7xsfIkfKm2ngNd9sPYB+HD7U880ViY3s/26H6jLACN8qbLLm Ub7gXhgJOG/KUDmBdOP4VXxPZ7Atoys+j7M+k773pXQb+HTSdNTRckxbzJkhmYLygCmX lQSA== X-Gm-Message-State: AJIora9jRdaPYmTDeaWD0z3i5qM/YUc7GOmuECaqZ7dRlB4Mh53AjIhm oUMebFSMiKEMM4v5N4liePzTpqznmZUg X-Google-Smtp-Source: AGRyM1sS6jkvATzlKclpVj8nlk7OSNkOJvfEYgGiI2QfR2aViaMuTxDftMDgwJ8UOliiUhOMCxMWbl1+REh3 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a81:cc3:0:b0:31c:dff0:3505 with SMTP id 186-20020a810cc3000000b0031cdff03505mr14123718ywm.499.1657867066438; Thu, 14 Jul 2022 23:37:46 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:51 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-14-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 13/15] 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/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 +-- 11 files changed, 100 insertions(+), 90 deletions(-) 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 3cb8a196a76d..d7e03864ca6a 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -335,6 +335,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. @@ -346,7 +351,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 /* @@ -360,7 +365,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: @@ -375,7 +380,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 @@ -383,7 +388,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 }, } }; """) @@ -394,26 +399,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); @@ -424,9 +429,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 @@ -439,11 +444,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; } } @@ -451,13 +456,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; } @@ -465,9 +470,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; @@ -475,13 +480,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; } @@ -491,7 +496,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 a9808932f9b5..4259e6f7d1ed 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 @@ -830,7 +830,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; @@ -1007,7 +1007,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 7398a277c742..a23e6595a281 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 -const struct pmu_event *pmu_events_map__find(void) +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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 DF102C433EF for ; Fri, 15 Jul 2022 06:39:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231129AbiGOGjd (ORCPT ); Fri, 15 Jul 2022 02:39:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231307AbiGOGiT (ORCPT ); Fri, 15 Jul 2022 02:38:19 -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 BE8284D161 for ; Thu, 14 Jul 2022 23:37:49 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id j11-20020a05690212cb00b006454988d225so3364835ybu.10 for ; Thu, 14 Jul 2022 23:37:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=zRY4q8dGu1/hQr60xv0fzIHPiiQD0Rve6HsFB3hsbJk=; b=AJi1iXRo01uKEFISeKI3HajnGrt0gt02mv4Vy4WtJ1TCuImtAZAWRiloR+sTyW7HeI QQVbdkFBZ4E0v3QBE4YOBmFbwTBLl2snB12NDtrJ22TbVj8NhFzET12RHwMXYNG1Scc4 l1ueN/93t69/EIXH5G+VjObmwt6WWV1z7a85EFgtSLq355vNiM3p37CpT1BlIYFT6aDN VCCmZ2Kj/U8/P3bXH4atEWTHgLdWf8ToMX3usp9xzhgF32AqGFhPjmViPACvSYpS8Fhm BxJthOgOWyKbcF4teHyyPeWREdkbt+Uq9vW89Ni+Jwz5IoTegbw4j18bND2xvZ2Oz5gA uPGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=zRY4q8dGu1/hQr60xv0fzIHPiiQD0Rve6HsFB3hsbJk=; b=GzN53xPld6hVhKi29cyB+bngGhMUmLq/PlwQjdG+lbhz08uXjR6FaZRWyKeFklKPTW NqnLoVsg9TMCURD71noQFcO1ZQ00zeB/mTdhSg7Gu6Luute/ixp1LvgokugV7t7oZVXx UMMqQ6gmQMva93jomt9vFwfod40OmqVuPBsRJaeJlEYU3VJDW1AAyE+gL0u72D0SPFNM P5zrWBe6oXSO7PPHds/aHA/HyslfR0nxn6uphx9k79aufQzh1FimS54bc/W3Dsh1dkvp CawY6k0AZOkCtw4anyi+Sv2s4Z654e9exoahgFS/RNrZUUoNDXcHfX52x4StYL15YnJB cQLw== X-Gm-Message-State: AJIora8N2ExbeUY5K77+OM81fasi2mTcSQGvgxcHAZNtfd6d3P3qIVKf gjuFCBxIFQP33xXFGp1aHS45fVB1LtZU X-Google-Smtp-Source: AGRyM1s9U2WGZvSsdr/Y3vq4x60yOs1ZiOiNMMnYoJyQNsjTcwuj+5f84KosQYEXShYBFhmQB8yNcQKZT6RJ X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a25:3b95:0:b0:66e:316c:159 with SMTP id i143-20020a253b95000000b0066e316c0159mr12911831yba.297.1657867068756; Thu, 14 Jul 2022 23:37:48 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:52 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-15-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 14/15] 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.0.170.g444d1eabd0-goog From nobody Sat Apr 18 09:23:34 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 DDC01C43334 for ; Fri, 15 Jul 2022 06:39:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231286AbiGOGjj (ORCPT ); Fri, 15 Jul 2022 02:39:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231344AbiGOGiU (ORCPT ); Fri, 15 Jul 2022 02:38:20 -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 A63D339BA8 for ; Thu, 14 Jul 2022 23:37:51 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-31cdce3ed04so34248887b3.13 for ; Thu, 14 Jul 2022 23:37:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=beKV48gy99vIAwtgAeGtaSuKZ54r5ACAI0HyC9yoOg8=; b=A/v6fiMJrcGC08KOVhEOEeV0kEpa0YZRkzC69081qaFQ4mHBxhCxhgPIiKj3WpIryD gzt0ipqMPjlwi1ySAlQPAkiDj/2wOaHaMTXEXeq/lMhaOrZbiga6Y69MKiJR2zLBpvGG jDA0STw/ftyogFYMTV+7uUDkQm6ckWZAvRqmSkW6ijyQGXIS7BtENAd87rsnE9QhOJwB 90dWfjwTOCcWeYgbD3yHMjVDFVL3ceB74AigawOBSfrTvxgCS+uvoBWUNm5Y0bFIepwa GhAfLuZ/+VNeIGgfoqI92qdOyDVztO7jhCTofTrL6p8XROtFoW0sl2txKRf1FHo0F8bR Zp6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=beKV48gy99vIAwtgAeGtaSuKZ54r5ACAI0HyC9yoOg8=; b=rC8GZJjse/caWEu61NOIIPOUHHMhmcdWW5DSjpumlEiLT595F5jAkD57X8ZTudX5bB 8/75iW61CI7HvV3+A2+VK1VV1GKiE7cK0S8TgwFBfhj1M9CxtUkQKTCYRZ9T/mbYtav8 U/2mxvzXdptRphCCk/xlSkbH6CUZ2m3GZxulcdHhCgKOz4DfFtLwdIQr/dVVXjZU+8hx +LqBPPkCrJ5u4s/SFC9huxx2h0YLYz3W0+iRJ3koNhjVuIgLaT/L/7DS/hWggzazhG8D FZmZLv9sPsaFSBaIwsS2KSHXBAoGBx/9HA+2VKMvEugl9WoEcoY0DTE+5xY7cwIb3ScO 3L3g== X-Gm-Message-State: AJIora+kTTFj/Qpz6VVYxCfjMTCCUr6uB5gHc5w7c3db+OBDxCNP+Abt NyGAO70ge3r5iGWDaRdL5vmjCQZuASU8 X-Google-Smtp-Source: AGRyM1uSn12IaxfKgrkafNp/45Xlxh6eQ05Z3qPqMRHLh4liPu9tvulwtacZnOv4SZcCsVjWtY7UdSH99GjP X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:e8fe:2a8e:e0f6:318d]) (user=irogers job=sendgmr) by 2002:a05:6902:102f:b0:66f:1145:af6e with SMTP id x15-20020a056902102f00b0066f1145af6emr12321111ybt.509.1657867071409; Thu, 14 Jul 2022 23:37:51 -0700 (PDT) Date: Thu, 14 Jul 2022 23:36:53 -0700 In-Reply-To: <20220715063653.3203761-1-irogers@google.com> Message-Id: <20220715063653.3203761-16-irogers@google.com> Mime-Version: 1.0 References: <20220715063653.3203761-1-irogers@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [PATCH v1 15/15] 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,579,104bytes x86 jevents - ~12.5% file size saving 22,088,944bytes vs 25,235,048bytes all jevents - ~15.8% file size saving 22,821,896bytes vs 27,106,648bytes default build options plus NO_LIBBFD=3D1. For example, the x86 build savings come from .rela.dyn and .data.rel.ro becoming smaller by 1,911,072bytes and 2,022,656bytes respectively. .rodata increases by 789,600bytes, giving an overall 3,146,104bytes 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 | 236 +++++++++++++++++++++++++------ 1 file changed, 193 insertions(+), 43 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index d7e03864ca6a..b5bc25790695 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -6,8 +6,8 @@ import csv import json import os import sys -from typing import Callable -from typing import Sequence +from typing import (Callable, Dict, Sequence, Set) +import collections =20 # Global command line arguments. _args =3D None @@ -21,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: @@ -40,6 +53,100 @@ def file_name_to_table_name(parents: Sequence[str], dir= name: 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. 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] + 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= .""" + + 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. + 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 + # 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 that aren't folded in a sorted manner. + for s in sorted(self.strings): + 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) + +_bcs =3D BigCString() =20 class JsonEvent: """Representation of an event loaded from a json file dictionary.""" @@ -203,26 +310,18 @@ class JsonEvent: s +=3D f'\t{attr} =3D {value},\n' return s + '}' =20 + def build_c_string(self): + 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]: @@ -237,7 +336,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 @@ -253,7 +351,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 @@ -286,23 +384,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(): @@ -337,7 +449,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 /* @@ -365,7 +478,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: @@ -380,7 +496,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 @@ -388,7 +507,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 }, } }; """) @@ -406,23 +525,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; } @@ -531,7 +668,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(""" @@ -541,6 +678,10 @@ def main() -> None: #include #include =20 +struct compact_pmu_event { + int offset; +}; + """) archs =3D [] for item in os.scandir(_args.starting_dir): @@ -556,6 +697,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.0.170.g444d1eabd0-goog