From nobody Sat Apr 11 09:20:37 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 25181C00140 for ; Fri, 12 Aug 2022 23:10:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235218AbiHLXKC (ORCPT ); Fri, 12 Aug 2022 19:10:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234263AbiHLXJ6 (ORCPT ); Fri, 12 Aug 2022 19:09:58 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 302589AFD6 for ; Fri, 12 Aug 2022 16:09:57 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id o18-20020a17090aac1200b001f3252af009so4725779pjq.7 for ; Fri, 12 Aug 2022 16:09:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=J1wu3JAsrpYRW3cgbnPcwLgMmGyi8dVAgV2C+sDvGds=; b=rh6LOBQevZLZ3vjlPMTRWPF8/x1oYFTBC1amlh3vdubakAly13tyvHIphCXpoE+ygF 0ljVZrCvBBvQebqf12MCJjQJL+YcMz2oKz94qFTbXbtNBdQzcYwx+FyFxb+91HoKwYuv 1ESQPPfv5y49rWj7Wg999xeK63dZmlwoCHY0gb3nGBOSKd/UG3v0edSUc77VQNYd+dd7 2quwiVELU020RpXaVAIEGYSg1hQdUjBU3Hh9im/d4wTrSB0sweQPhEnwCPFuriLgv8xX Q8r1u4qHN5t9vlPh9CtL7GFTBdihryBcBRis127zMjKh/HQ7hRYA/JnC6BPMwkszLxmV zC6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=J1wu3JAsrpYRW3cgbnPcwLgMmGyi8dVAgV2C+sDvGds=; b=JA1P9bwFC/33fF8wSdkCxMrNOgyWoS7C3IBtN0rcHG1oL9pAPgR8Qi1a3QtXNOeM8W QC9pKIPtcQ5FMQIrTVDxDgQgN6HpEJbq3dXmL+iFG7WYKAGUy/diX7RmCU0JJ6qlZ0PA k2Fm2IrvAMFIjI9iPNMadxsErBLECHiYls4IW9geQW0/vEV6ut9oDA/O8a9usX1gpOVm fS4iF1p1iSfqTZYZVPjpOyeSaQ2CxQ0RVSLcahYs7tLaYGj8oAosTF4bakGQ1xqxKYW/ kFopDhOKwKJ/qLMQDz13uNGnqAWQJy/E7Lglu6meIoh3eURVRI+CMsCs9pXpRDcZRXCD X87w== X-Gm-Message-State: ACgBeo344C9vqVoy1NhiLb/1MYfoW9WF62IQ36vsBjh9R22SBI9Qdb/N bvL05QKqQs3FxfctZG1Z25bojeSvbBIS X-Google-Smtp-Source: AA6agR6Dv8jBtbUGYe76gOBJHziOxputlqFKuhWWu37vsoZ5E7Ol5MxYOQZVghCdEV3SbvNURAFq5YBBjJ7s X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a63:2bcc:0:b0:40c:95b5:46a4 with SMTP id r195-20020a632bcc000000b0040c95b546a4mr4861111pgr.535.1660345796625; Fri, 12 Aug 2022 16:09:56 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:36 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-2-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 01/14] perf jevent: Add an 'all' architecture argument From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When 'all' is passed as the architecture generate a mapping table for all architectures. This simplifies testing. To identify the table for an architecture add an arch variable to the pmu_events_map. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 2 + tools/perf/pmu-events/jevents.py | 70 +++++++++++++++--------- tools/perf/pmu-events/pmu-events.h | 1 + tools/perf/tests/pmu-events.c | 3 +- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 77e655c6f116..d8cf9283e486 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -110,12 +110,14 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { =20 const struct pmu_events_map pmu_events_map[] =3D { { + .arch =3D "testarch", .cpuid =3D "testcpu", .version =3D "v1", .type =3D "core", .table =3D pme_test_soc_cpu, }, { + .arch =3D 0, .cpuid =3D 0, .version =3D 0, .type =3D 0, diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index c5c9bb186abd..b49a0dd946b7 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 263cbb67c861..82192f1a7bf7 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -864,8 +864,7 @@ static void expr_failure(const char *msg, const struct pmu_events_map *map, const struct pmu_event *pe) { - pr_debug("%s for map %s %s %s\n", - msg, map->cpuid, map->version, map->type); + pr_debug("%s for map %s %s\n", msg, map->arch, map->cpuid); pr_debug("On metric %s\n", pe->metric_name); pr_debug("On expression %s\n", pe->metric_expr); } --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 88301C00140 for ; Fri, 12 Aug 2022 23:10:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236480AbiHLXKJ (ORCPT ); Fri, 12 Aug 2022 19:10:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45622 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235143AbiHLXKB (ORCPT ); Fri, 12 Aug 2022 19:10:01 -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 6E7D79BB7A for ; Fri, 12 Aug 2022 16:10:00 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id s15-20020a5b044f000000b00680c4eb89f1so1795817ybp.7 for ; Fri, 12 Aug 2022 16:10:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=YiyvC5KcLJL9/nnX+SFeTIrRtpkkdHYbCWBdgzmu8kY=; b=Da16TEv/4coRpuTFpJa27ZXTP77mj0yprgQil4DtOi02L2ulStByB/BXJn1UgSQSt2 ijc4vnzrQBDCVUlDRA6+lVypjyyZzeJqPXE+CyLmPMyLq00MgQM2ZrG4SYrw3I4Tr9Kg SF7DXRuh2OEB3Xwd9ZbjQhQYZsIosAlNNfpIesLnV6z6D/kOhbFp1j2t1H+UmtK2z6e5 ffyNv5Slc693/I/rscqd/qOlaGRqqONonCgtcvoinKGuoE4W0Jr4gyc8MhPJv4/jQ7fD Kzz2xVxdwSZqU9Un0j3QpcETvKwqaEdQYXMMzieTf9FuHf7WoMcIvEFQ4KCWCZ5T7TqW sdrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=YiyvC5KcLJL9/nnX+SFeTIrRtpkkdHYbCWBdgzmu8kY=; b=P1s6k+HKnB5vsukfPq4D08i9yRIf3VFdvKYJnZMxgs4Lj55sZO2gviNjk/32+6SP3O seUNTiXvQNyPs4rF7CSU9S/N2AHUE8HLO/wnyo4YURGOTfCx9IHKM1NX+ME45icr5tfU ezvvIV9MQ+qopvf2hjHvjOJcAvyhqa3WI8wk6qApFdDt6Ofr042//8wPpdBxzvcTh23S moQZ2zuL2gMXJOmBrQaaHWnQNOpvc/59iuAqQkmQNmCVewOc23fvNHsDafynlt6WYHWy iiy+GGnDPN7SyQMVfidawkwoNqyHBKB2HKof7f3Jvwu2v+xsJB0aL/gsg8hq8mzpkXrl VP4Q== X-Gm-Message-State: ACgBeo2AHFTbOYAt4SzKBx9yojb8Lk7vlM5re7IYXcBurUfV4YdPeVto I8haCq6NC8rW3+Gs1QgRFuZ+EmwokZvk X-Google-Smtp-Source: AA6agR5gweXDu/o9LyYcK9Rge043hhUd0+JgvYx1OMtiTLDz0icypzu5szu4NIxcrgHjRFsQXIapBAxkT+5f X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a81:144f:0:b0:31f:43ce:de37 with SMTP id 76-20020a81144f000000b0031f43cede37mr5830739ywu.142.1660345799751; Fri, 12 Aug 2022 16:09:59 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:37 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-3-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 02/14] 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 | 4 ---- tools/perf/pmu-events/jevents.py | 6 ------ tools/perf/pmu-events/pmu-events.h | 2 -- tools/perf/tests/expand-cgroup.c | 2 -- tools/perf/tests/parse-metric.c | 2 -- 5 files changed, 16 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index d8cf9283e486..4182a986f505 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -112,15 +112,11 @@ const struct pmu_events_map pmu_events_map[] =3D { { .arch =3D "testarch", .cpuid =3D "testcpu", - .version =3D "v1", - .type =3D "core", .table =3D pme_test_soc_cpu, }, { .arch =3D 0, .cpuid =3D 0, - .version =3D 0, - .type =3D 0, .table =3D 0, }, }; diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index b49a0dd946b7..8e8462cb359b 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.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 283CFC25B0F for ; Fri, 12 Aug 2022 23:10:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237653AbiHLXKP (ORCPT ); Fri, 12 Aug 2022 19:10:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234474AbiHLXKF (ORCPT ); Fri, 12 Aug 2022 19:10:05 -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 D43CA9C20E for ; Fri, 12 Aug 2022 16:10:02 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f46b4759bso18622377b3.0 for ; Fri, 12 Aug 2022 16:10:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=kPWsuFqycsY/yXV7nCgwsjWW6XxROqmLrLkaSuTFd4g=; b=rxjmjQpKDzS7G0C+9MAaUX4sdS40WxnORu9wsxkeSrzBbIrDyTkkvDdpH9Q4fDq8rv 1FOwsDUFhyxtnNTlFm6bk8FTSLFgIBQ165feaBrjBbixMZJwjPDgJ0CJj5Voqz+MkcQS OFgBH5grTkKZLqcw2VK454e2fsMWDO0JnCawPq2l1SUWr6xLR5EgVvfwE8fckI/afazp eqxmT0m8FcGQhtrYM4PiGWk3w7id6oFmXcUnSOtSY9RELqp668za8mOdYexpauzIhvId N/VBFb8oVV+dICkKxaQSjifY+Noxt1g+iTpl/iNknx39MS5junx0m4Esj/91UL3vvegX T50g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=kPWsuFqycsY/yXV7nCgwsjWW6XxROqmLrLkaSuTFd4g=; b=YfyQGBEEjQzvpgzGd/tNKqqyAzExJ3Pw67NRvFwXVr3DyqLiilAk9qMpRSY0O/w9us ByYCNySX62gpds4u/irsD3HKdOYQG68t/qTZfkuRM+vlmEGYMFYd4EkUw7Ym2VFWeYwo l3TvyGEyWM8bA553O77m49UoUmY3IdHGrQg2MZXGFF5GcbdATb1wDwFeaB40Nolu0r3r 6QGttLNzwILUJaUauDjSZ4KSd2NeD80aOPyx+unR3cZxwsnHtPeTLrMxmKDvTRUYZepx PYbyaTCmyaiYWtOIEKW4j3n+bq+owbFUs4GQoDiTM9GpmUZQjUt75GE8lfrxAIWCGbd7 5j/A== X-Gm-Message-State: ACgBeo36kWRS+BUSweo3OgEjDtRaMQ5Irp22bnmBnzwbKP3CA1dQB8g7 S5vkDDJrGH/iqEgYuQDRvSZn61ffxgF4 X-Google-Smtp-Source: AA6agR4VKEloBEmRShMw7+2nW0kl6o1FN+BGq8FKr+/u4UHKzqmgJpZpOlb1g2Fk8WRnCpI/DvA74SydZdIy X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a81:1016:0:b0:31e:63f8:483d with SMTP id 22-20020a811016000000b0031e63f8483dmr5606640ywq.199.1660345802166; Fri, 12 Aug 2022 16:10:02 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:38 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-4-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 03/14] 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 8e8462cb359b..31936eafa9ff 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.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 DCAB3C00140 for ; Fri, 12 Aug 2022 23:10:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238058AbiHLXKV (ORCPT ); Fri, 12 Aug 2022 19:10:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236887AbiHLXKK (ORCPT ); Fri, 12 Aug 2022 19:10:10 -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 A86D39C515 for ; Fri, 12 Aug 2022 16:10:05 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-329dc6c0d21so18295337b3.16 for ; Fri, 12 Aug 2022 16:10:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=vHc00R1etBBIHmVhT/J70GR1lgdExkJ5oc83QaUQWSc=; b=haQLiQ/QV0C7Rv0bIumzuWMIBSXjJVpYzLMonAWjASpxv8AO5rUFuyvFRAIeAxfdv8 z8WrIwm4SCDuURjdYmFHGBZvttLO6KVNdS4cUIl7ETIoWMlDkl+7Jp+yZ3Vu610eSRDF jqwzNi3uI0Z/aUgBxqffFLUFA+jbZsgkP6/lo4mt0cSytUDnt23zo3RjHgWMAmNIZ8Ch wfFCKY1BB6y6lM0hHIr8brvxjIlr4MZaN4Pfc1lTRdZMo/FoiwtYinPF1dzPDaXbgnA1 HvaVkjApIreWUdmCmMkWcNKPeosLuBU+VqG9+FG3b+2QCokdbmYHm3QWZNt87TjteZvS ux5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=vHc00R1etBBIHmVhT/J70GR1lgdExkJ5oc83QaUQWSc=; b=68s0+HoAOuMAjOCbO2PPn6HkEDeqvnWARwV6BkXc9vj1JGsR6zTAbc2PeJPQ+bEGDN 1YGJegB8hR9HHnpiYMBGbqWh4B9Pw/qtc0aYAQS4NjljJrBQjFVtdffQeL6AVtr0YPFH 4vBT6W7U28FVrS2pD9AwW5PdspsLTLupBShHTCcJMP5XxTL+RQKpz5/syWP5va4dTjNf F6Ff8jvEQz6cBQVZ46mIt3MmEbTz3ql5RfQARnXQo8QoKi+BNnXX0juBZx2qYNA4nlEJ g1Y3sH9v6O5T+n8X3WSHpFRTdHukqbGujwf/5rpXBnmaYofuUc85Tiwr+eF74HSXSNod n9KA== X-Gm-Message-State: ACgBeo3a1YZumtGfDp/yYpCx0EjBkFQhcEDriCM0vcH68VkavG3qtgKz Q+1vsHgzkDuX5FaGxy7pufwzr5uOeDJ0 X-Google-Smtp-Source: AA6agR7++xwE1+x1j8sC9gzVFlLoULkq6LLbqYrd8eV+7tKPFcLGTxp0wBOLbYmWNiEAXkoKbduxpmXUVnUu X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a81:a10b:0:b0:31f:5960:4e8c with SMTP id y11-20020a81a10b000000b0031f59604e8cmr5503815ywg.67.1660345804767; Fri, 12 Aug 2022 16:10:04 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:39 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-5-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 04/14] 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. Specifically, the sort order is given by the tuple: (not j.desc is None, fix_none(j.topic), fix_none(j.name), fix_none(j.pmu), fix_none(j.metric_name)) which is putting events with descriptions and topics before those without, then sorting by name, then pmu and finally metric_name 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 31936eafa9ff..84fbb0f384cc 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -18,6 +18,8 @@ _sys_event_tables =3D [] _arch_std_events =3D {} # Track whether an events table is currently being defined and needs closi= ng. _close_table =3D False +# Events to write out when the table is closed +_pending_events =3D [] =20 =20 def removesuffix(s: str, suffix: str) -> str: @@ -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.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 D3624C00140 for ; Fri, 12 Aug 2022 23:10:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237921AbiHLXKZ (ORCPT ); Fri, 12 Aug 2022 19:10:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45762 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234777AbiHLXKR (ORCPT ); Fri, 12 Aug 2022 19:10:17 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 555079E2EA for ; Fri, 12 Aug 2022 16:10:08 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id e11-20020a17090a630b00b001f8b2deb88dso2615764pjj.1 for ; Fri, 12 Aug 2022 16:10:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=xhF50+QBseJSGKZ9VkfqAcGwnWmb4rSoqzbtULTujMs=; b=moww+6+YRdPWxALS1+wArTMDcAORPG2Ly4fs1LL27nT72D9ko4UjmzJ6kydm7YhsYT UUUCfzaMxCVpSnRYQDD8Lsv4+yokm+45xLFoTU9s0geyfg0Kc7rjcvuxiLs0skXaDJ8W R1CCZuHFOSgAvmoNMFe3AO+PkXOlCxmF/XtHfs80wsEK3G3l2JneefK5TR/zCisu2OW+ 8ZD3e0/b+D0z2EzUj2eMlQMBvG1+Lr2LWHub6PTtoqSG8mDpZJfbgNVYCGUiemq8tkM2 +S+z3U0yjLRMWjAMsVNLG0rQJKhfZE5I9H/gk2OFMLHuUcPx+OWke6Dw82Y1EVRUJh1M n6dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=xhF50+QBseJSGKZ9VkfqAcGwnWmb4rSoqzbtULTujMs=; b=KP+Ne1pVAsVGns6+VHgixlhdD9oQIVINJRsj6HsnyN+Os+/AgAtdCsbk5HsSmd9W09 cIjCNNrdYNNfkVvCCslKrWE0l9qfY2JRT5DpuZ+wRFW3fmBr+QHHWgkvMvrpWiiU6mDa OdGHNCVhUSxbcFcrgSMsur3io0E1gAQg8IByB1g+bnrv92++vixgkUl3dKZv8Pty7or1 dh8UWR5Q+abvg2/DkqgtgsStDXmChmqWBhsgl7CDulpyzsLOfJvxspu33rRnYVbwMKPP Htl1tlvgZITxF/+C4pfQO3vT4FH1XSHm2Asv1uhNPBokiIb6stwe0KKWJlbTW5L9x/QT IXNQ== X-Gm-Message-State: ACgBeo0gL72hEww1uv5YrFzHlzyfPx2JomNHTI+Jz69U0Avvv/Qi/oK8 qzD6N/esTYLG8jnyp1mb485WcjI33TTb X-Google-Smtp-Source: AA6agR7onQEoCeXlmRdCyZVURXCYIcFg28AimeJhdEjnXZw7WG6VjQ/8pxgwmJ0SRNzHtyvoZit2wCHrq8wj X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a17:90b:1d0a:b0:1f5:76c0:f142 with SMTP id on10-20020a17090b1d0a00b001f576c0f142mr16061812pjb.192.1660345807513; Fri, 12 Aug 2022 16:10:07 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:40 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-6-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 05/14] 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 84fbb0f384cc..8f929dd3e065 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 82192f1a7bf7..a39a2c99ede6 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -286,18 +286,6 @@ static const struct pmu_events_map *__test_pmu_get_eve= nts_map(void) return NULL; } =20 -static const struct pmu_event *__test_pmu_get_sys_events_table(void) -{ - const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; - - for ( ; tables->name; tables++) { - if (!strcmp("pme_test_soc_sys", tables->name)) - return tables->table; - } - - return NULL; -} - static int compare_pmu_events(const struct pmu_event *e1, const struct pmu= _event *e2) { if (!is_same(e1->name, e2->name)) { @@ -451,7 +439,7 @@ static int compare_alias_to_test_event(struct perf_pmu_= alias *alias, static int test__pmu_event_table(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_event *sys_event_tables =3D __test_pmu_get_sys_events_ta= ble(); + const struct pmu_event *sys_event_tables =3D find_sys_events_table("pme_t= est_soc_sys"); const struct pmu_events_map *map =3D __test_pmu_get_events_map(); const struct pmu_event *table; int map_events =3D 0, expected_events; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 0112e1c36418..d8717c4548a4 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -868,33 +868,6 @@ static void pmu_add_cpu_aliases(struct list_head *head= , struct perf_pmu *pmu) pmu_add_cpu_aliases_map(head, pmu, map); } =20 -void pmu_for_each_sys_event(pmu_sys_event_iter_fn fn, void *data) -{ - int i =3D 0; - - while (1) { - const struct pmu_sys_events *event_table; - int j =3D 0; - - event_table =3D &pmu_sys_event_tables[i++]; - - if (!event_table->table) - break; - - while (1) { - const struct pmu_event *pe =3D &event_table->table[j++]; - int ret; - - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - - ret =3D fn(pe, data); - if (ret) - break; - } - } -} - struct pmu_sys_event_iter_data { struct list_head *head; struct perf_pmu *pmu; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 4b45fd8da5a3..7e667eec2a01 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -133,8 +133,6 @@ const struct pmu_events_map *pmu_events_map__find(void); bool pmu_uncore_alias_match(const char *pmu_name, const char *name); void perf_pmu_free_alias(struct perf_pmu_alias *alias); =20 -typedef int (*pmu_sys_event_iter_fn)(const struct pmu_event *pe, void *dat= a); -void pmu_for_each_sys_event(pmu_sys_event_iter_fn fn, void *data); int perf_pmu__convert_scale(const char *scale, char **end, double *sval); =20 int perf_pmu__caps_parse(struct perf_pmu *pmu); --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 A0069C00140 for ; Fri, 12 Aug 2022 23:10:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238451AbiHLXKa (ORCPT ); Fri, 12 Aug 2022 19:10:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237987AbiHLXKV (ORCPT ); Fri, 12 Aug 2022 19:10:21 -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 2863191 for ; Fri, 12 Aug 2022 16:10:11 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id 130-20020a250188000000b006777ce7728cso1816122ybb.4 for ; Fri, 12 Aug 2022 16:10:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=b+AhUtqJH20XiTc6zdTqiL+8IxjStec86po1XQhLnts=; b=ooFBS5dKdQbYwWlXR7qLUIk6KyCVLoOktOSBno+/YmhT1Rx7u1pblAWM/jWCPvUiat 2UyQGdOPspo7eKk7Ut8JMcwyPxPOhLlHo88ddJ6Yxq1aKs+BPRuhihLQ+3vYdQfHrk9R kUBQU9p9NjJNtJvTsrv+lySvAXGpGUynwfwxjaijMWOD7FQAkFoN4Zy/po+sYSXmV5wQ ai+kzbiaQ8Em1TjslkA2vr67CtV+fluIAL2M6XIlZSRdJ8Atf3eoIH5i801sK6xgIYdF bvs0DSol7I6k1Gsw64c/GZa7/lH3SwuJ5Gq7uipXg93pvidwNoUTwgFZUjLbN//25yMR BwyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=b+AhUtqJH20XiTc6zdTqiL+8IxjStec86po1XQhLnts=; b=rQJzh+vMk509fxgzuK6PgOjuZNO7jKuufUQONu4pdzQE0FdKQrG7qm68jYhGU/0Jrk x+6HDc3+tNeHS3TLiyJ3ZVbsRVjcaIMn4W/j1sKjQPgDNlsqosVUyatQ088nlejH/yDY x0c8lnYSVtcv4NE5lMZDuAvCXCKEoq0Zm476SybMjr+fKv2VnB3aQa5rv5IpQQ7nmMC7 S69GVCDc0Olm5I0274REuyfW1fD7VF+e8+MelshRrr0YcauEM/V/GjT2Z1TjVARdqPMx KNnlSMgGb4nUic5tSjzHXmclCrgwFsS4KVlRNUiT/Ird9HFSUTQORL/D37BvfdlCdjE4 uuXw== X-Gm-Message-State: ACgBeo2e1RkvX9J2njMTCTavMYtHWi5GDBuWBah7cNE1kV/xRtEbKJVE djp1f/GlBtT409jU0ApECiaLowRZECBn X-Google-Smtp-Source: AA6agR7SLy22UjuMI0KWo82vdmUnJBLz7Bx1B26fUJRv8/Z1szaVc+ZI8Nxm37PMtcr2KqSPw2w2Qg47paQU X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a25:ab6a:0:b0:67b:58c8:2465 with SMTP id u97-20020a25ab6a000000b0067b58c82465mr5225271ybi.410.1660345810339; Fri, 12 Aug 2022 16:10:10 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:41 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-7-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 06/14] 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. While modifying the function's types, rename pmu_events_map__find to pmu_events_table__find to match later encapsulation. Similarly rename pmu_add_cpu_aliases_map to pmu_add_cpu_aliases_table. 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 | 35 ++++++------- tools/perf/util/pmu.h | 8 +-- tools/perf/util/s390-sample-raw.c | 12 ++--- 9 files changed, 101 insertions(+), 120 deletions(-) diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/= pmu.c index 79124bba713e..92d774647f6e 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_table__find(void) { struct perf_pmu *pmu =3D NULL; =20 @@ -18,7 +18,7 @@ const struct pmu_events_map *pmu_events_map__find(void) if (pmu->cpus->nr !=3D cpu__max_cpu().cpu) return NULL; =20 - return perf_pmu__find_map(pmu); + return perf_pmu__find_table(pmu); } =20 return NULL; diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index dc4038f997d7..411fc578e5a4 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -195,16 +195,12 @@ static int expand_metric_events(void) .metric_name =3D NULL, }, }; - const struct pmu_events_map ev_map =3D { - .cpuid =3D "test", - .table =3D pme_test, - }; =20 evlist =3D evlist__new(); TEST_ASSERT_VAL("failed to get evlist", evlist); =20 rblist__init(&metric_events); - ret =3D metricgroup__parse_groups_test(evlist, &ev_map, metric_str, + ret =3D metricgroup__parse_groups_test(evlist, pme_test, metric_str, false, false, &metric_events); if (ret < 0) { pr_debug("failed to parse '%s' metric\n", metric_str); diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 1b811a26f4ee..7aebde7c37ec 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -79,11 +79,6 @@ static struct pmu_event pme_test[] =3D { } }; =20 -static const struct pmu_events_map map =3D { - .cpuid =3D "test", - .table =3D pme_test, -}; - struct value { const char *event; u64 val; @@ -166,7 +161,7 @@ static int __compute_metric(const char *name, struct va= lue *vals, runtime_stat__init(&st); =20 /* Parse the metric into metric_events list. */ - err =3D metricgroup__parse_groups_test(evlist, &map, name, + err =3D metricgroup__parse_groups_test(evlist, pme_test, name, false, false, &metric_events); if (err) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index a39a2c99ede6..5bba15350cdc 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_table(&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_table(&aliases, pmu, events_table); pmu_add_sys_aliases(&aliases, pmu); =20 /* Count how many aliases we generated */ @@ -848,13 +845,9 @@ static int check_parse_fake(const char *id) return ret; } =20 -static void expr_failure(const char *msg, - const struct pmu_events_map *map, - const struct pmu_event *pe) +static void expr_failure(const char *msg, const struct pmu_event *pe) { - pr_debug("%s for map %s %s\n", msg, map->arch, map->cpuid); - pr_debug("On metric %s\n", pe->metric_name); - pr_debug("On expression %s\n", pe->metric_expr); + pr_debug("%s\nOn metric %s\nOn expression %s\n", msg, pe->metric_name, pe= ->metric_expr); } =20 struct metric { @@ -864,7 +857,7 @@ struct metric { =20 static int resolve_metric_simple(struct expr_parse_ctx *pctx, struct list_head *compound_list, - const struct pmu_events_map *map, + const struct pmu_event *map, const char *metric_name) { struct hashmap_entry *cur, *cur_tmp; @@ -925,8 +918,7 @@ static int resolve_metric_simple(struct expr_parse_ctx = *pctx, static int test__parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_events_map *cpus_map =3D pmu_events_map__find(); - const struct pmu_events_map *map; + const struct pmu_event *cpus_table =3D pmu_events_table__find(); const struct pmu_event *pe; int i, j, k; int ret =3D 0; @@ -940,7 +932,8 @@ static int test__parsing(struct test_suite *test __mayb= e_unused, } i =3D 0; for (;;) { - map =3D &pmu_events_map[i++]; + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + if (!map->table) break; j =3D 0; @@ -957,14 +950,14 @@ static int test__parsing(struct test_suite *test __ma= ybe_unused, continue; expr__ctx_clear(ctx); if (expr__find_ids(pe->metric_expr, NULL, ctx) < 0) { - expr_failure("Parse find ids failed", map, pe); + expr_failure("Parse find ids failed", pe); ret++; continue; } =20 - if (resolve_metric_simple(ctx, &compound_list, map, + if (resolve_metric_simple(ctx, &compound_list, map->table, pe->metric_name)) { - expr_failure("Could not resolve metrics", map, pe); + expr_failure("Could not resolve metrics", pe); ret++; goto exit; /* Don't tolerate errors due to severity */ } @@ -979,7 +972,7 @@ static int test__parsing(struct test_suite *test __mayb= e_unused, expr__add_id_val(ctx, strdup(cur->key), k++); =20 hashmap__for_each_entry(ctx->ids, cur, bkt) { - if (check_parse_cpu(cur->key, map =3D=3D cpus_map, + if (check_parse_cpu(cur->key, map->table =3D=3D cpus_table, pe)) ret++; } @@ -999,7 +992,7 @@ static int test__parsing(struct test_suite *test __mayb= e_unused, hashmap__for_each_entry(ctx->ids, cur, bkt) expr__add_id_val(ctx, strdup(cur->key), k--); if (expr__parse(&result, ctx, pe->metric_expr)) { - expr_failure("Parse failed", map, pe); + expr_failure("Parse failed", pe); ret++; } } @@ -1088,8 +1081,6 @@ static int metric_parse_fake(const char *str) static int test__parsing_fake(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_events_map *map; - const struct pmu_event *pe; unsigned int i, j; int err =3D 0; =20 @@ -1101,12 +1092,14 @@ static int test__parsing_fake(struct test_suite *te= st __maybe_unused, =20 i =3D 0; for (;;) { - map =3D &pmu_events_map[i++]; + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + if (!map->table) break; j =3D 0; for (;;) { - pe =3D &map->table[j++]; + const struct pmu_event *pe =3D &map->table[j++]; + if (!pe->name && !pe->metric_group && !pe->metric_name) break; if (!pe->metric_expr) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8f7baeabc5cf..3c3510744dab 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_table__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_table__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_table__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..7874d67485ac 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -710,9 +710,9 @@ static char *perf_pmu__getcpuid(struct perf_pmu *pmu) return cpuid; } =20 -const struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu) +const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) { - const struct pmu_events_map *map; + const struct pmu_event *table =3D NULL; char *cpuid =3D perf_pmu__getcpuid(pmu); int i; =20 @@ -724,22 +724,23 @@ const struct pmu_events_map *perf_pmu__find_map(struc= t perf_pmu *pmu) =20 i =3D 0; for (;;) { - map =3D &pmu_events_map[i++]; - if (!map->table) { - map =3D NULL; + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + + if (!map->table) break; - } =20 - if (!strcmp_cpuid_str(map->cpuid, cpuid)) + if (!strcmp_cpuid_str(map->cpuid, cpuid)) { + table =3D map->table; break; + } } free(cpuid); - return map; + return table; } =20 -const struct pmu_events_map *__weak pmu_events_map__find(void) +__weak const struct pmu_event *pmu_events_table__find(void) { - return perf_pmu__find_map(NULL); + return perf_pmu__find_table(NULL); } =20 /* @@ -823,8 +824,8 @@ bool pmu_uncore_alias_match(const char *pmu_name, const= char *name) * to the current running CPU. Then, add all PMU events from that table * as aliases. */ -void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, - const struct pmu_events_map *map) +void pmu_add_cpu_aliases_table(struct list_head *head, struct perf_pmu *pm= u, + 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_table(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..d535a98c5998 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -125,11 +125,11 @@ int perf_pmu__scan_file(struct perf_pmu *pmu, const c= har *name, const char *fmt, 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); +void pmu_add_cpu_aliases_table(struct list_head *head, struct perf_pmu *pm= u, + const struct pmu_event *table); =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_table__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..dddd2be59827 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_table__find(); while (offset < len) { cep =3D (struct cf_ctrset_entry *)(buf + offset); =20 @@ -180,7 +180,7 @@ static void s390_cpumcfdg_dump(struct perf_sample *samp= le) color_fprintf(stdout, color, " [%#08zx] Counterset:%d" " Counters:%d\n", offset, ce.set, ce.ctr); for (i =3D 0, p =3D (u64 *)(cep + 1); i < ce.ctr; ++i, ++p) { - const char *ev_name =3D get_counter_name(ce.set, i, map); + const char *ev_name =3D get_counter_name(ce.set, i, table); =20 color_fprintf(stdout, color, "\tCounter:%03d %s Value:%#018lx\n", i, --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 34E35C00140 for ; Fri, 12 Aug 2022 23:10:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238540AbiHLXKg (ORCPT ); Fri, 12 Aug 2022 19:10:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238093AbiHLXKW (ORCPT ); Fri, 12 Aug 2022 19:10:22 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D6C0D2BDC for ; Fri, 12 Aug 2022 16:10:13 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id x18-20020a056a000bd200b0052e70ff090dso1036431pfu.18 for ; Fri, 12 Aug 2022 16:10:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=lJPQSG866HHkfWBWuf29/4A5gpmikJcrfdUzqFgoe8U=; b=LtoUmnsdbakXH9f9dnoAXLozMPt1h9y8JTdwP6ofcqAF2Izc24/y6Wwyw5jIdUUOcT hI5IPwg6o5fVtYVB/7f6pRurzinoLazEDqKmQ+3Dekl2NGsg5zPjQoofgl0wow7YRgAg h+CaRwfvtuBzI33Dg5zHp0SlEN0iktTkHM0USmsJxXCmuAe/q8uRVqHhCPszYONlb8B+ dVPJk0K6R6r7oBMDSYJxvxLVMkXda3V+GZ3vC15PIfUwU+IXb49+gXUl0TzkNFp8qufe VUsly3IWdB0tHneRz/laFPM6GfsmRSRcliYnLxMjWNxbfJEiRNuldww72ikKQJCt6yNZ SxUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=lJPQSG866HHkfWBWuf29/4A5gpmikJcrfdUzqFgoe8U=; b=5Wp0utaeDEhcuxDtSCPWsGlmHMLPEXW/+WVFKvK/r4evS13edPJ1IbdTEG/bEs44KQ HVrd3NFGPAp6Ox5FbBpP3gg1hlApqW3aH0IlBFmkKwL2WZLN1OrIl87mWRqI9xqCXwQq hrcNBqVf8i7L5i0FqNtuqkzmHFW3RulIarzbC0/tly+5RokUTuZJRp8umBcho/SKLx7u 0/Ja88qms1BXnNE+UehjgYovBRJdpMkxEXAAhS3XbT7hvNoP+9fG/iSTR3yyYi8MO/L3 EHMMWWRzK+abLgmh2/yB8ix51EjxU+WvC1+Ew1iJekhk6i4Fcg8XmPNRUoR3EmzKmTot 5Fow== X-Gm-Message-State: ACgBeo2xD2FEZ/GNeC/XDywctHVmbDuhxc9II14/KzAHLh2d1dbT9GpF mq4jrCT7Id7BxZV8yi4ubbels3C3dPyr X-Google-Smtp-Source: AA6agR5+o86C8MQNsHgfXc9N0qULppf0juoUoiE3/0Dw29V51fUnDcUetVU3+z+n/JXSYCC7zOmTPvEJaMWl X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a17:90b:3944:b0:1f5:4cc8:d46 with SMTP id oe4-20020a17090b394400b001f54cc80d46mr6298257pjb.95.1660345812891; Fri, 12 Aug 2022 16:10:12 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:42 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-8-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 07/14] 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 8f929dd3e065..1a04b848d736 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 5bba15350cdc..3ebea8f589c4 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_table(&aliases, pmu, events_table); @@ -845,11 +833,6 @@ static int check_parse_fake(const char *id) return ret; } =20 -static void expr_failure(const char *msg, const struct pmu_event *pe) -{ - pr_debug("%s\nOn metric %s\nOn expression %s\n", msg, pe->metric_name, pe= ->metric_expr); -} - struct metric { struct list_head list; struct metric_ref metric_ref; @@ -915,93 +898,100 @@ static int resolve_metric_simple(struct expr_parse_c= tx *pctx, =20 } =20 -static int test__parsing(struct test_suite *test __maybe_unused, - int subtest __maybe_unused) +static void expr_failure(const char *msg, const struct pmu_event *pe) { - const struct pmu_event *cpus_table =3D pmu_events_table__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_table__find(), + .ctx =3D expr__ctx_new(), + .failures =3D 0, + }; + + if (!data.ctx) { + pr_debug("expr__ctx_new failed"); + return TEST_FAIL; + } + pmu_for_each_core_event(test__parsing_callback, &data); + pmu_for_each_sys_event(test__parsing_callback, &data); + + expr__ctx_free(data.ctx); + return data.failures =3D=3D 0 ? TEST_OK : TEST_FAIL; } =20 struct test_metric { @@ -1073,6 +1063,16 @@ static int metric_parse_fake(const char *str) return ret; } =20 +static int test__parsing_fake_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data __maybe_unused) +{ + if (!pe->metric_expr) + return 0; + + return metric_parse_fake(pe->metric_expr); +} + /* * Parse all the metrics for current architecture, * or all defined cpus via the 'fake_pmu' @@ -1081,37 +1081,19 @@ static int metric_parse_fake(const char *str) static int test__parsing_fake(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - unsigned int i, j; int err =3D 0; =20 - for (i =3D 0; i < ARRAY_SIZE(metrics); i++) { + for (size_t i =3D 0; i < ARRAY_SIZE(metrics); i++) { err =3D metric_parse_fake(metrics[i].str); if (err) return err; } =20 - i =3D 0; - for (;;) { - const struct pmu_events_map *map =3D &pmu_events_map[i++]; + err =3D pmu_for_each_core_event(test__parsing_fake_callback, NULL); + if (err) + return err; =20 - if (!map->table) - break; - j =3D 0; - for (;;) { - const struct pmu_event *pe =3D &map->table[j++]; - - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - if (!pe->metric_expr) - continue; - pr_debug("Found metric '%s' for '%s'\n", pe->metric_name, map->cpuid); - err =3D metric_parse_fake(pe->metric_expr); - if (err) - return err; - } - } - - return 0; + return pmu_for_each_sys_event(test__parsing_fake_callback, NULL); } =20 static struct test_case pmu_events_tests[] =3D { diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 3c3510744dab..8d994539d6ea 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 7874d67485ac..f117324eb5f0 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -690,7 +690,7 @@ static int is_arm_pmu_core(const char *name) return file_available(path); } =20 -static char *perf_pmu__getcpuid(struct perf_pmu *pmu) +char *perf_pmu__getcpuid(struct perf_pmu *pmu) { char *cpuid; static bool printed; @@ -710,34 +710,6 @@ static char *perf_pmu__getcpuid(struct perf_pmu *pmu) return cpuid; } =20 -const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) -{ - const struct pmu_event *table =3D NULL; - char *cpuid =3D perf_pmu__getcpuid(pmu); - int i; - - /* on some platforms which uses cpus map, cpuid can be NULL for - * PMUs other than CORE PMUs. - */ - if (!cpuid) - return NULL; - - i =3D 0; - for (;;) { - const struct pmu_events_map *map =3D &pmu_events_map[i++]; - - if (!map->table) - break; - - if (!strcmp_cpuid_str(map->cpuid, cpuid)) { - table =3D map->table; - break; - } - } - free(cpuid); - return table; -} - __weak const struct pmu_event *pmu_events_table__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 d535a98c5998..f0aba1e462fa 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_table(struct list_head *head, struct perf_pmu *pm= u, const struct pmu_event *table); =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_table__find(void); bool pmu_uncore_alias_match(const char *pmu_name, const char *name); void perf_pmu_free_alias(struct perf_pmu_alias *alias); --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 140DFC00140 for ; Fri, 12 Aug 2022 23:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238718AbiHLXKz (ORCPT ); Fri, 12 Aug 2022 19:10:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238160AbiHLXKY (ORCPT ); Fri, 12 Aug 2022 19:10:24 -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 E9819E7A for ; Fri, 12 Aug 2022 16:10:16 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id x19-20020a25e013000000b0067c0cedc96bso1805611ybg.21 for ; Fri, 12 Aug 2022 16:10:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=pHD/zC33e9n+UuQc/qFKoZ+eX/BHu9hnOsRHfYhreBQ=; b=bkV34TJl4ZuHxkFJ/rAKl4OuOAHG2tgaV0GHeb52E8rMKFFbJurxONeg/y+vgoXJuF yehVxuCyH0bAyRenBs3F7gyyP0016V3U3FqoYbYTPTZ+FDUytk0/CaLvzlZW+YdhwDmG Wf55Sn+tZoE3XlyHZjEJYp/8s3tAOI5dpy0ObL7iGozC8VQF6x2LxgWxQfsbQ94vkkPx e37BF18nTWV6lFP0I6bQlIl2Zto5cCkkB5OqU5QBXN1J3wtX71zTNaU393SMuMMXMDcw nAdNlZfGD0PIqx9tN/1LFRFAaOo65kd9tV2wgDwNiSzCw/fJAYRl6HNfb+2FOWuLZz5n w2Sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=pHD/zC33e9n+UuQc/qFKoZ+eX/BHu9hnOsRHfYhreBQ=; b=FyY4eGe1XE0QHqBq46p5AscTisdq+06zrRg4tffA95xE16ERzgC7sHPgzaN1GlGVqw awKy1UUQNCA3SmPTDSGHE7i6WHH/1590a4Xt9NeS442aWlFneB6biODFPptp5JsWvX/E CIpYjmYly3dxiCgaec93bnnCkbx5OdtQz+NSuSxp3+qAl5UZVZ+UH4p92pGBECTo3hZq MrLURvWYxlk42r59IUZZRyBHk3U4NKR7OB5gV3++D3SPA4sDQ0qGyFpmzY9nw/6x0AFd a3E1TC9xdk2XQ989Eo6By1FmVvTeTyWwTLK4rWNeOlpze8/u7IKJsDkybF6jgXbjuGnw vBmQ== X-Gm-Message-State: ACgBeo3FpIcj+CmNaea2pATBfHwP/hm58alw7NfGov/eHxBP3GcqFUaT UpcDY+TKe3T37UkBSXzmNUrV0OYBhaSx X-Google-Smtp-Source: AA6agR4TPrpc8I6ZIfVLj3U+Vljc1TzJZSpUsRgGa1sSf7tqZ7vtEP6sUAWMY0u+TYDCLQ40JlXnUaPdyCK4 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a0d:d744:0:b0:321:fdb4:12a5 with SMTP id z65-20020a0dd744000000b00321fdb412a5mr5707123ywd.479.1660345815780; Fri, 12 Aug 2022 16:10:15 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:43 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-9-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 08/14] 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 3ebea8f589c4..a64497cb9fb2 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -9,10 +9,12 @@ #include #include "debug.h" #include "../pmu-events/pmu-events.h" +#include #include "util/evlist.h" #include "util/expr.h" #include "util/parse-events.h" #include "metricgroup.h" +#include "stat.h" =20 struct perf_pmu_test_event { /* used for matching against events from generated pmu-events.c */ @@ -801,27 +803,6 @@ static int check_parse_id(const char *id, struct parse= _events_error *error, return ret; } =20 -static int check_parse_cpu(const char *id, bool same_cpu, const struct pmu= _event *pe) -{ - struct parse_events_error error; - int ret; - - parse_events_error__init(&error); - ret =3D check_parse_id(id, &error, NULL); - if (ret && same_cpu) { - pr_warning("Parse event failed metric '%s' id '%s' expr '%s'\n", - pe->metric_name, id, pe->metric_expr); - pr_warning("Error string '%s' help '%s'\n", error.str, - error.help); - } else if (ret) { - pr_debug3("Parse event failed, but for an event that may not be supporte= d by this CPU.\nid '%s' metric '%s' expr '%s'\n", - id, pe->metric_name, pe->metric_expr); - ret =3D 0; - } - parse_events_error__exit(&error); - return ret; -} - static int check_parse_fake(const char *id) { struct parse_events_error error; @@ -838,160 +819,111 @@ struct metric { struct metric_ref metric_ref; }; =20 -static int resolve_metric_simple(struct expr_parse_ctx *pctx, - struct list_head *compound_list, - const struct pmu_event *map, - const char *metric_name) -{ - struct hashmap_entry *cur, *cur_tmp; - struct metric *metric, *tmp; - size_t bkt; - bool all; - int rc; - - do { - all =3D true; - hashmap__for_each_entry_safe(pctx->ids, cur, cur_tmp, bkt) { - struct metric_ref *ref; - const struct pmu_event *pe; - - pe =3D metricgroup__find_metric(cur->key, map); - if (!pe) - continue; - - if (!strcmp(metric_name, (char *)cur->key)) { - pr_warning("Recursion detected for metric %s\n", metric_name); - rc =3D -1; - goto out_err; - } - - all =3D false; - - /* The metric key itself needs to go out.. */ - expr__del_id(pctx, cur->key); - - metric =3D malloc(sizeof(*metric)); - if (!metric) { - rc =3D -ENOMEM; - goto out_err; - } - - ref =3D &metric->metric_ref; - ref->metric_name =3D pe->metric_name; - ref->metric_expr =3D pe->metric_expr; - list_add_tail(&metric->list, compound_list); - - rc =3D expr__find_ids(pe->metric_expr, NULL, pctx); - if (rc) - goto out_err; - break; /* The hashmap has been modified, so restart */ - } - } while (!all); - - return 0; - -out_err: - list_for_each_entry_safe(metric, tmp, compound_list, list) - free(metric); - - return rc; - -} - -static void expr_failure(const char *msg, const struct pmu_event *pe) -{ - pr_debug("%s\nOn metric %s\nOn expression %s\n", msg, pe->metric_name, pe= ->metric_expr); -} - - -struct test__parsing_data { - const struct pmu_event *cpus_table; - struct expr_parse_ctx *ctx; - int failures; -}; - static int test__parsing_callback(const struct pmu_event *pe, const struct= pmu_event *table, - void *vdata) + void *data) { - struct test__parsing_data *data =3D vdata; - struct metric *metric, *tmp; - struct hashmap_entry *cur; - LIST_HEAD(compound_list); - size_t bkt; + int *failures =3D data; int k; - double result; + struct evlist *evlist; + struct perf_cpu_map *cpus; + struct runtime_stat st; + struct evsel *evsel; + struct rblist metric_events =3D { + .nr_entries =3D 0, + }; + int err =3D 0; =20 if (!pe->metric_expr) return 0; =20 pr_debug("Found metric '%s'\n", pe->metric_name); + (*failures)++; =20 - expr__ctx_clear(data->ctx); - if (expr__find_ids(pe->metric_expr, NULL, data->ctx) < 0) { - expr_failure("Parse find ids failed", pe); - data->failures++; - return 0; + /* + * We need to prepare evlist for stat mode running on CPU 0 + * because that's where all the stats are going to be created. + */ + evlist =3D evlist__new(); + if (!evlist) + return -ENOMEM; + + cpus =3D perf_cpu_map__new("0"); + if (!cpus) { + evlist__delete(evlist); + return -ENOMEM; } =20 - if (resolve_metric_simple(data->ctx, &compound_list, table, - pe->metric_name)) { - expr_failure("Could not resolve metrics", pe); - data->failures++; - return TEST_FAIL; /* Don't tolerate errors due to severity */ + perf_evlist__set_maps(&evlist->core, cpus, NULL); + runtime_stat__init(&st); + + err =3D metricgroup__parse_groups_test(evlist, table, pe->metric_name, + false, false, + &metric_events); + if (err) { + if (!strcmp(pe->metric_name, "M1") || !strcmp(pe->metric_name, "M2") || + !strcmp(pe->metric_name, "M3")) { + (*failures)--; + pr_debug("Expected broken metric %s skipping\n", pe->metric_name); + err =3D 0; + } + goto out_err; } =20 + err =3D evlist__alloc_stats(evlist, false); + if (err) + goto out_err; /* * Add all ids with a made up value. The value may trigger divide by * zero when subtracted and so try to make them unique. */ k =3D 1; - hashmap__for_each_entry(data->ctx->ids, cur, bkt) - expr__add_id_val(data->ctx, strdup(cur->key), k++); - - hashmap__for_each_entry(data->ctx->ids, cur, bkt) { - if (check_parse_cpu(cur->key, table =3D=3D data->cpus_table, pe)) - data->failures++; + perf_stat__reset_shadow_stats(); + evlist__for_each_entry(evlist, evsel) { + perf_stat__update_shadow_stats(evsel, k, 0, &st); + if (!strcmp(evsel->name, "duration_time")) + update_stats(&walltime_nsecs_stats, k); + k++; } + evlist__for_each_entry(evlist, evsel) { + struct metric_event *me =3D metricgroup__lookup(&metric_events, evsel, f= alse); =20 - list_for_each_entry_safe(metric, tmp, &compound_list, list) { - expr__add_ref(data->ctx, &metric->metric_ref); - free(metric); - } + if (me !=3D NULL) { + struct metric_expr *mexp; =20 - if (expr__parse(&result, data->ctx, pe->metric_expr)) { - /* - * Parsing failed, make numbers go from large to small which can - * resolve divide by zero issues. - */ - k =3D 1024; - hashmap__for_each_entry(data->ctx->ids, cur, bkt) - expr__add_id_val(data->ctx, strdup(cur->key), k--); - if (expr__parse(&result, data->ctx, pe->metric_expr)) { - expr_failure("Parse failed", pe); - data->failures++; + list_for_each_entry (mexp, &me->head, nd) { + if (strcmp(mexp->metric_name, pe->metric_name)) + continue; + pr_debug("Result %f\n", test_generic_metric(mexp, 0, &st)); + err =3D 0; + (*failures)--; + goto out_err; + } } } - return 0; + pr_debug("Didn't find parsed metric %s", pe->metric_name); + err =3D 1; +out_err: + if (err) + pr_debug("Broken metric %s\n", pe->metric_name); + + /* ... cleanup. */ + metricgroup__rblist_exit(&metric_events); + runtime_stat__exit(&st); + evlist__free_stats(evlist); + perf_cpu_map__put(cpus); + evlist__delete(evlist); + return err; } =20 static int test__parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - struct test__parsing_data data =3D { - .cpus_table =3D pmu_events_table__find(), - .ctx =3D expr__ctx_new(), - .failures =3D 0, - }; + int failures =3D 0; =20 - if (!data.ctx) { - pr_debug("expr__ctx_new failed"); - return TEST_FAIL; - } - pmu_for_each_core_event(test__parsing_callback, &data); - pmu_for_each_sys_event(test__parsing_callback, &data); + pmu_for_each_core_event(test__parsing_callback, &failures); + pmu_for_each_sys_event(test__parsing_callback, &failures); =20 - expr__ctx_free(data.ctx); - return data.failures =3D=3D 0 ? TEST_OK : TEST_FAIL; + return failures =3D=3D 0 ? TEST_OK : TEST_FAIL; } =20 struct test_metric { --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 A6009C00140 for ; Fri, 12 Aug 2022 23:11:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238327AbiHLXK7 (ORCPT ); Fri, 12 Aug 2022 19:10:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238227AbiHLXKY (ORCPT ); Fri, 12 Aug 2022 19:10:24 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C5953DC for ; Fri, 12 Aug 2022 16:10:18 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-31f58599ad3so18410077b3.20 for ; Fri, 12 Aug 2022 16:10:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=sh297cGcNiOM+DSF6NOV/SZoJCZhIA8yBWiOo7MNppM=; b=guBO+fWjnBSeyC1tcVP76LdTPXZfgBFgI6pj1rSBpIHbsoZqv8ZZLASWh8mZ12d2d7 J/yrygnYBF67ZLNLWSo6SJ3czpvWkgxhP5o9t91GDIWxLZhLE0sMFcY7KgAt7ijpkKKt l10lThDL++OEF+DPdcy9UTHCd22qqk2uc3JwfY5/rlX5N69L8vFS7XZnxzGgrULToNWO Ac3TrM3u8vaVzn0VZPCYJSnWSYjer7qm0bmhG2WXPXs0EVCazYdhjHvYgXWb6O08NAOE AKaFbABA0H4ls3qfwPVGgV43V8ViJMaIRPQG2J1M7WhsOXm4aX1iH/RFhmyt3y3D74bL 9DgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=sh297cGcNiOM+DSF6NOV/SZoJCZhIA8yBWiOo7MNppM=; b=FBnYkHzD66TKhlJ8gmSy+4W74WOQN/jeccsX7UvA3WR19Q5aYANEg+uBUXHqGGJZgF CUj1Z9yIxYbk/BMoM++SdwIvcgto+Ie9rjazxcv9O9mva41OWZjrtRHpbtZLWJ9HTu1H amenge000GXsztvmZQbSPiGiZt3FW5qI9PgKcsOMALNj5OfiOEB6dV847BnXEmhJMGRd 70pIPwYDacBXbp0BHsqtqaGXdF61Lo8aAGdLE9FG4dRmd28czAmZJWCroQVdT9Fm9RDS axzITCVyNwN2VxyckVjkU2qPHv9V/AkObvx+AGuHSCtlMHPQvHwkPAh/aO2qSdeCTr+c 1B/w== X-Gm-Message-State: ACgBeo2BX28XLZs6vzPa9B2BEN+jY0MJ1xPm3kyt5AYVM9HW+zbLqkdH 1dalPmV5QS4v4YqlxolDADGbz3MswGjy X-Google-Smtp-Source: AA6agR4DrwHWjOb1uxndcZwM0Hn6akRz4VsjGhTUMliGtDkmwo3Hz/3zMb6+V8fOnQCY287fi8anRkqCHA17 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a81:100e:0:b0:324:9670:7241 with SMTP id 14-20020a81100e000000b0032496707241mr5762614ywq.95.1660345818345; Fri, 12 Aug 2022 16:10:18 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:44 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-10-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 09/14] perf pmu-events: Move test events/metrics to json From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move arrays of pmu_events into the json code so that it may be regenerated and modified by the jevents.py script. Signed-off-by: Ian Rogers --- .../arch/test/test_soc/cpu/metrics.json | 64 +++++++++++++++++ tools/perf/pmu-events/empty-pmu-events.c | 64 +++++++++++++++++ tools/perf/tests/expand-cgroup.c | 17 +---- tools/perf/tests/parse-metric.c | 68 +------------------ 4 files changed, 132 insertions(+), 81 deletions(-) create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.js= on diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.json b/to= ols/perf/pmu-events/arch/test/test_soc/cpu/metrics.json new file mode 100644 index 000000000000..42d9b5242fd7 --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/metrics.json @@ -0,0 +1,64 @@ +[ + { + "MetricExpr": "1 / IPC", + "MetricName": "CPI" + }, + { + "MetricExpr": "inst_retired.any / cpu_clk_unhalted.thread", + "MetricName": "IPC", + "MetricGroup": "group1" + }, + { + "MetricExpr": "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalte= d.thread / 2 ) * ( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalte= d.ref_xclk ) )))", + "MetricName": "Frontend_Bound_SMT" + }, + { + "MetricExpr": "l1d\\-loads\\-misses / inst_retired.any", + "MetricName": "dcache_miss_cpi" + }, + { + "MetricExpr": "l1i\\-loads\\-misses / inst_retired.any", + "MetricName": "icache_miss_cycles" + }, + { + "MetricExpr": "(dcache_miss_cpi + icache_miss_cycles)", + "MetricName": "cache_miss_cycles", + "MetricGroup": "group1" + }, + { + "MetricExpr": "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqst= s.rfo_hit", + "MetricName": "DCache_L2_All_Hits" + }, + { + "MetricExpr": "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_= rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss", + "MetricName": "DCache_L2_All_Miss" + }, + { + "MetricExpr": "dcache_l2_all_hits + dcache_l2_all_miss", + "MetricName": "DCache_L2_All" + }, + { + "MetricExpr": "d_ratio(dcache_l2_all_hits, dcache_l2_all)", + "MetricName": "DCache_L2_Hits" + }, + { + "MetricExpr": "d_ratio(dcache_l2_all_miss, dcache_l2_all)", + "MetricName": "DCache_L2_Misses" + }, + { + "MetricExpr": "ipc + M2", + "MetricName": "M1" + }, + { + "MetricExpr": "ipc + M1", + "MetricName": "M2" + }, + { + "MetricExpr": "1/M3", + "MetricName": "M3" + }, + { + "MetricExpr": "64 * l1d.replacement / 1000000000 / duration_time", + "MetricName": "L1D_Cache_Fill_BW" + } +] diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 8ef75aff996c..028f44efe48d 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -105,6 +105,70 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { .desc =3D "L2 BTB Correction", .topic =3D "branch", }, + { + .metric_expr =3D "1 / IPC", + .metric_name =3D "CPI", + }, + { + .metric_expr =3D "inst_retired.any / cpu_clk_unhalted.thread", + .metric_name =3D "IPC", + .metric_group =3D "group1", + }, + { + .metric_expr =3D "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalt= ed.thread / 2 ) * " + "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) = )))", + .metric_name =3D "Frontend_Bound_SMT", + }, + { + .metric_expr =3D "l1d\\-loads\\-misses / inst_retired.any", + .metric_name =3D "dcache_miss_cpi", + }, + { + .metric_expr =3D "l1i\\-loads\\-misses / inst_retired.any", + .metric_name =3D "icache_miss_cycles", + }, + { + .metric_expr =3D "(dcache_miss_cpi + icache_miss_cycles)", + .metric_name =3D "cache_miss_cycles", + .metric_group =3D "group1", + }, + { + .metric_expr =3D "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqs= ts.rfo_hit", + .metric_name =3D "DCache_L2_All_Hits", + }, + { + .metric_expr =3D "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data= _rd_hit, 0) + " + "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", + .metric_name =3D "DCache_L2_All_Miss", + }, + { + .metric_expr =3D "dcache_l2_all_hits + dcache_l2_all_miss", + .metric_name =3D "DCache_L2_All", + }, + { + .metric_expr =3D "d_ratio(dcache_l2_all_hits, dcache_l2_all)", + .metric_name =3D "DCache_L2_Hits", + }, + { + .metric_expr =3D "d_ratio(dcache_l2_all_miss, dcache_l2_all)", + .metric_name =3D "DCache_L2_Misses", + }, + { + .metric_expr =3D "ipc + M2", + .metric_name =3D "M1", + }, + { + .metric_expr =3D "ipc + M1", + .metric_name =3D "M2", + }, + { + .metric_expr =3D "1/M3", + .metric_name =3D "M3", + }, + { + .metric_expr =3D "64 * l1d.replacement / 1000000000 / duration_time", + .metric_name =3D "L1D_Cache_Fill_BW", + }, { .name =3D 0, .event =3D 0, diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index 411fc578e5a4..e79ee8621a90 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -180,26 +180,13 @@ static int expand_metric_events(void) struct evlist *evlist; struct rblist metric_events; const char metric_str[] =3D "CPI"; - - struct pmu_event pme_test[] =3D { - { - .metric_expr =3D "instructions / cycles", - .metric_name =3D "IPC", - }, - { - .metric_expr =3D "1 / IPC", - .metric_name =3D "CPI", - }, - { - .metric_expr =3D NULL, - .metric_name =3D NULL, - }, - }; + const struct pmu_event *pme_test; =20 evlist =3D evlist__new(); TEST_ASSERT_VAL("failed to get evlist", evlist); =20 rblist__init(&metric_events); + pme_test =3D find_core_events_table("testarch", "testcpu"); ret =3D metricgroup__parse_groups_test(evlist, pme_test, metric_str, false, false, &metric_events); if (ret < 0) { diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 7aebde7c37ec..30c7091857b8 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -13,72 +13,6 @@ #include "stat.h" #include "pmu.h" =20 -static struct pmu_event pme_test[] =3D { -{ - .metric_expr =3D "inst_retired.any / cpu_clk_unhalted.thread", - .metric_name =3D "IPC", - .metric_group =3D "group1", -}, -{ - .metric_expr =3D "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalte= d.thread / 2 ) * " - "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk= ) )))", - .metric_name =3D "Frontend_Bound_SMT", -}, -{ - .metric_expr =3D "l1d\\-loads\\-misses / inst_retired.any", - .metric_name =3D "dcache_miss_cpi", -}, -{ - .metric_expr =3D "l1i\\-loads\\-misses / inst_retired.any", - .metric_name =3D "icache_miss_cycles", -}, -{ - .metric_expr =3D "(dcache_miss_cpi + icache_miss_cycles)", - .metric_name =3D "cache_miss_cycles", - .metric_group =3D "group1", -}, -{ - .metric_expr =3D "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqst= s.rfo_hit", - .metric_name =3D "DCache_L2_All_Hits", -}, -{ - .metric_expr =3D "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_= rd_hit, 0) + " - "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", - .metric_name =3D "DCache_L2_All_Miss", -}, -{ - .metric_expr =3D "dcache_l2_all_hits + dcache_l2_all_miss", - .metric_name =3D "DCache_L2_All", -}, -{ - .metric_expr =3D "d_ratio(dcache_l2_all_hits, dcache_l2_all)", - .metric_name =3D "DCache_L2_Hits", -}, -{ - .metric_expr =3D "d_ratio(dcache_l2_all_miss, dcache_l2_all)", - .metric_name =3D "DCache_L2_Misses", -}, -{ - .metric_expr =3D "ipc + m2", - .metric_name =3D "M1", -}, -{ - .metric_expr =3D "ipc + m1", - .metric_name =3D "M2", -}, -{ - .metric_expr =3D "1/m3", - .metric_name =3D "M3", -}, -{ - .metric_expr =3D "64 * l1d.replacement / 1000000000 / duration_time", - .metric_name =3D "L1D_Cache_Fill_BW", -}, -{ - .name =3D NULL, -} -}; - struct value { const char *event; u64 val; @@ -138,6 +72,7 @@ static int __compute_metric(const char *name, struct val= ue *vals, struct rblist metric_events =3D { .nr_entries =3D 0, }; + const struct pmu_event *pme_test; struct perf_cpu_map *cpus; struct runtime_stat st; struct evlist *evlist; @@ -161,6 +96,7 @@ static int __compute_metric(const char *name, struct val= ue *vals, runtime_stat__init(&st); =20 /* Parse the metric into metric_events list. */ + pme_test =3D find_core_events_table("testarch", "testcpu"); err =3D metricgroup__parse_groups_test(evlist, pme_test, name, false, false, &metric_events); --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 D6F74C00140 for ; Fri, 12 Aug 2022 23:11:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238032AbiHLXLM (ORCPT ); Fri, 12 Aug 2022 19:11:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235497AbiHLXK1 (ORCPT ); Fri, 12 Aug 2022 19:10:27 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 392C5760F5 for ; Fri, 12 Aug 2022 16:10:21 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id i16-20020a17090adc1000b001f4e121847eso869275pjv.3 for ; Fri, 12 Aug 2022 16:10:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=RWi3UPFSGsQY4GuI/T+SCB+OSOqA102D0VW82BgaGmc=; b=sC3+94nzCo/Ic0I5DNr5+XGhKArvV9vkUPG9KLgslkJDtzREItg029bom0t/FzF4sM QNb3SOgYoq6F9++37RD6cWQzRyvEFTArDPQjvBbenBSMUoKX7J2rM4U3NjBmLrunVUgu NBaat3E/fZUdjZ17tc3iR2M2QK56dZO4sehADaH0/N5csNxC8ERXjm1xrWV6i1frHah+ vMB+6FcOOeR30dFe+81sEc6XoqlBHnRAtxyga5qWXaVb/nXLi1JBfbAkSva0bQhXaRem +zZlUWm+0zc/YQYmFPo0mHb+BIb+ya0lkuvbh1DFJSNmZJPzVx0gjSVstlQ7qz3f98bX d3Wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=RWi3UPFSGsQY4GuI/T+SCB+OSOqA102D0VW82BgaGmc=; b=FzCPEW0yDYMvx2EcpLLc3p5zx+IzfWY0wGrrxoDEe1h195FY7J6Q1GbvOXghELbN+y bws0hQbiH4hs/+MeCHRS1zi2OsU2qGn6RhyZaA3wh6aqcx6wh51fbSM/GiOejS4JYq7R sMyUpdGLv+zaD5lgXcp7jeF1kRVz46qMaOIHr/HTCeP6Rdp2rhAtyZOxw1BWNeZuLRIA yGC6auU9WIVvG7ZQZfT/wlGag4SDjGcPmuYu+zsSoHDI7jyEyeXuypE+5oCacohPHy+u CyUn63vo76TrFrYOWISCgj6ChkdKThxLTkcF2GtJkWlmZIgZpfPUZlryI36l7x2dsMkK +9Ng== X-Gm-Message-State: ACgBeo1jD8W4IMvgYxa5k+IyUtDPMeO7Q5viJJ4ojzqziLt3udBliLdW hsJO3AU0xrRy96TXdLdNm1rvLbUdsjz+ X-Google-Smtp-Source: AA6agR5/ArCvN+yP4l8b27gYTvg3+PjppBfgaMUVKiPdT81ysuiJ58QXRp2z0uodf7/NJDRUAx7jl0jyU0qH X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a63:3c52:0:b0:421:5af6:9902 with SMTP id i18-20020a633c52000000b004215af69902mr4683099pgn.548.1660345821206; Fri, 12 Aug 2022 16:10:21 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:45 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-11-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 10/14] 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 1a04b848d736..977f2061a990 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 a64497cb9fb2..e308d480f0fb 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 8d994539d6ea..cae97b6dc5bc 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_table__find(); pe; pe++) { + table =3D pmu_events_table__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_table__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 f117324eb5f0..dd1e171d7480 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_table(struct list_head *head, struct perf_pmu *pm= u, 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 dddd2be59827..235319d45d02 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -129,6 +129,28 @@ static int get_counterset_start(int setnr) } } =20 +struct get_counter_name_data { + int wanted; + const char *result; +}; + +static int get_counter_name_callback(const struct pmu_event *evp, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct get_counter_name_data *data =3D vdata; + int rc, event_nr; + + if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) + return 0; + rc =3D sscanf(evp->event, "event=3D%x", &event_nr); + if (rc =3D=3D 1 && event_nr =3D=3D data->wanted) { + data->result =3D evp->name; + return 1; /* Terminate the search. */ + } + return 0; +} + /* Scan the PMU table and extract the logical name of a counter from the * PMU events table. Input is the counter set and counter number with in t= he * set. Construct the event number and use this as key. If they match retu= rn @@ -137,20 +159,16 @@ static int get_counterset_start(int setnr) */ static const char *get_counter_name(int set, int nr, const struct pmu_even= t *table) { - int rc, event_nr, wanted =3D get_counterset_start(set) + nr; + struct get_counter_name_data data =3D { + .wanted =3D get_counterset_start(set) + nr, + .result =3D NULL, + }; =20 - if (table) { - const struct pmu_event *evp =3D table; + if (!table) + return NULL; =20 - for (; evp->name || evp->event || evp->desc; ++evp) { - if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) - continue; - rc =3D sscanf(evp->event, "event=3D%x", &event_nr); - if (rc =3D=3D 1 && event_nr =3D=3D wanted) - return evp->name; - } - } - return NULL; + pmu_events_table_for_each_event(table, get_counter_name_callback, &data); + return data.result; } =20 static void s390_cpumcfdg_dump(struct perf_sample *sample) --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 0F416C00140 for ; Fri, 12 Aug 2022 23:11:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238491AbiHLXLS (ORCPT ); Fri, 12 Aug 2022 19:11:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238097AbiHLXK3 (ORCPT ); Fri, 12 Aug 2022 19:10:29 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E3239D117 for ; Fri, 12 Aug 2022 16:10:24 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id j11-20020a05690212cb00b006454988d225so1828556ybu.10 for ; Fri, 12 Aug 2022 16:10:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=zprLe3z6GS8nmW2T+04nxrIBRrafJR/G9iUpcioBWxI=; b=dcZEL3cR1Azc7uP1/qAFxYhtku9U3I9OhhFGefft2NxD/BvtOD103q0GDjD+OdVDgj hZ0U0ZfmEbmjmB6iL6gmGIwYTABoSn7sUfUWLVaQ3Jn+NlIr9spbGiyqiHYnf9sO0RSp g4cn2carsPAlgE1615xTsq8qeq8mFDOlobxylV9rhTCieBbsZqL5WJykzFvS0HYokT+8 +y8ltmfO2lxEufCbtMaVhzdWjsO0fkeryU2YhJWKLa944Xc7azCjq+fykab02i5Xp/7Q t9/rKHQaURmjwQj8rjtUwCp4r2MfEGy4JOpumK+v/B9iPH2+bqeVG5F3sU01zCMpkFUQ aYIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=zprLe3z6GS8nmW2T+04nxrIBRrafJR/G9iUpcioBWxI=; b=Yld7/DsxiOsC8w9h9IjrSiTyimvkiUSWoM0HBwoh7k+82QJdJ0lqZPFlkl7CiQmbHE 5D9kHTqZBx99drKz+V3/ph8G1h9fprn+6c5bxdy/x//xx5BcD2nh8oRZkRFi7blf0JKa qWto0IIyHsTDp541x4+2lVRlYgYV61JU42w92i9E43UwJuKlr+hfqDRPf+l6P3bTsYUi nd2ym0cERnBw2U9DmJj491Ezt/mYexRpAquyyaQfIXvb3cyXAVAO3dxca+WaWKteq/Mh gHsx/yqy+IKGXXk8W+sm3MnaNlzhuuAbzo54Zq0u84ipkOhVSPnLQkb+JPDKZvijp7eh lNCw== X-Gm-Message-State: ACgBeo1tL1bmK2pWf9OANYcM/U+3+maTb/qu5+DnuXxM+1HlIxrBNDwU HFvCrEPKEPce6lS1zjId6Fs8+4wr+aR0 X-Google-Smtp-Source: AA6agR5oPW2xGQeIidUC15wyzZ/XWPatNKTsSkkTJML7GOSytjJ3utI07u2Ae+Til81DVLjpiKaWIWw+tZKA X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a25:9306:0:b0:683:75e4:e03f with SMTP id f6-20020a259306000000b0068375e4e03fmr3237759ybo.172.1660345824061; Fri, 12 Aug 2022 16:10:24 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:46 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-12-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 11/14] perf pmu-events: Hide the pmu_events From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hide that the pmu_event structs are an array with a new wrapper struct. Signed-off-by: Ian Rogers --- tools/perf/arch/arm64/util/pmu.c | 2 +- tools/perf/pmu-events/empty-pmu-events.c | 44 ++++++++++++---------- tools/perf/pmu-events/jevents.py | 47 +++++++++++++----------- tools/perf/pmu-events/pmu-events.h | 12 +++--- tools/perf/tests/expand-cgroup.c | 2 +- tools/perf/tests/parse-metric.c | 2 +- tools/perf/tests/pmu-events.c | 16 ++++---- tools/perf/util/metricgroup.c | 42 ++++++++++----------- tools/perf/util/metricgroup.h | 5 +-- tools/perf/util/pmu.c | 10 ++--- tools/perf/util/pmu.h | 4 +- tools/perf/util/s390-sample-raw.c | 6 +-- 12 files changed, 101 insertions(+), 91 deletions(-) diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/= pmu.c index 92d774647f6e..f849b1e88d43 100644 --- a/tools/perf/arch/arm64/util/pmu.c +++ b/tools/perf/arch/arm64/util/pmu.c @@ -3,7 +3,7 @@ #include "../../../util/cpumap.h" #include "../../../util/pmu.h" =20 -const struct pmu_event *pmu_events_table__find(void) +const struct pmu_events_table *pmu_events_table__find(void) { struct perf_pmu *pmu =3D NULL; =20 diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index bee1967baa2b..5ed8c0aa4817 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -176,6 +176,10 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { }, }; =20 +/* Struct used to make the PMU event table implementation opaque to caller= s. */ +struct pmu_events_table { + const struct pmu_event *entries; +}; =20 /* * Map a CPU to its table of PMU events. The CPU is identified by the @@ -188,7 +192,7 @@ static const struct pmu_event pme_test_soc_cpu[] =3D { struct pmu_events_map { const char *arch; const char *cpuid; - const struct pmu_event *table; + const struct pmu_events_table table; }; =20 /* @@ -199,12 +203,12 @@ static const struct pmu_events_map pmu_events_map[] = =3D { { .arch =3D "testarch", .cpuid =3D "testcpu", - .table =3D pme_test_soc_cpu, + .table =3D { pme_test_soc_cpu }, }, { .arch =3D 0, .cpuid =3D 0, - .table =3D 0, + .table =3D { 0 }, }, }; =20 @@ -234,23 +238,23 @@ static const struct pmu_event pme_test_soc_sys[] =3D { =20 struct pmu_sys_events { const char *name; - const struct pmu_event *table; + const struct pmu_events_table table; }; =20 static const struct pmu_sys_events pmu_sys_event_tables[] =3D { { - .table =3D pme_test_soc_sys, + .table =3D { pme_test_soc_sys }, .name =3D "pme_test_soc_sys", }, { - .table =3D 0 + .table =3D { 0 } }, }; =20 -int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, +int pmu_events_table_for_each_event(const struct pmu_events_table *table, = pmu_event_iter_fn fn, void *data) { - for (const struct pmu_event *pe =3D &table[0]; + for (const struct pmu_event *pe =3D &table->entries[0]; pe->name || pe->metric_group || pe->metric_name; pe++) { int ret =3D fn(pe, table, data); @@ -261,9 +265,9 @@ int pmu_events_table_for_each_event(const struct pmu_ev= ent *table, pmu_event_ite return 0; } =20 -const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) +const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu) { - const struct pmu_event *table =3D NULL; + const struct pmu_events_table *table =3D NULL; char *cpuid =3D perf_pmu__getcpuid(pmu); int i; =20 @@ -277,11 +281,11 @@ const struct pmu_event *perf_pmu__find_table(struct p= erf_pmu *pmu) for (;;) { const struct pmu_events_map *map =3D &pmu_events_map[i++]; =20 - if (!map->table) + if (!map->cpuid) break; =20 if (!strcmp_cpuid_str(map->cpuid, cpuid)) { - table =3D map->table; + table =3D &map->table; break; } } @@ -289,13 +293,13 @@ const struct pmu_event *perf_pmu__find_table(struct p= erf_pmu *pmu) return table; } =20 -const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid) +const struct pmu_events_table *find_core_events_table(const char *arch, co= nst char *cpuid) { for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; - tables->table; + tables->arch; tables++) { if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpui= d)) - return tables->table; + return &tables->table; } return NULL; } @@ -303,9 +307,9 @@ const struct pmu_event *find_core_events_table(const ch= ar *arch, const char *cpu int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) { for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; - tables->table; + tables->arch; tables++) { - int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); + int ret =3D pmu_events_table_for_each_event(&tables->table, fn, data); =20 if (ret) return ret; @@ -313,13 +317,13 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, voi= d *data) return 0; } =20 -const struct pmu_event *find_sys_events_table(const char *name) +const struct pmu_events_table *find_sys_events_table(const char *name) { for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; tables->name; tables++) { if (!strcmp(tables->name, name)) - return tables->table; + return &tables->table; } return NULL; } @@ -329,7 +333,7 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *= data) for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; tables->name; tables++) { - int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); + int ret =3D pmu_events_table_for_each_event(&tables->table, fn, data); =20 if (ret) return ret; diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 977f2061a990..4b7948ba57d6 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 e308d480f0fb..097e05c796ab 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -424,7 +424,7 @@ static int compare_alias_to_test_event(struct perf_pmu_= alias *alias, } =20 static int test__pmu_event_table_core_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data) { int *map_events =3D data; @@ -461,7 +461,7 @@ static int test__pmu_event_table_core_callback(const st= ruct pmu_event *pe, } =20 static int test__pmu_event_table_sys_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data) { int *map_events =3D data; @@ -495,8 +495,8 @@ static int test__pmu_event_table_sys_callback(const str= uct pmu_event *pe, static int test__pmu_event_table(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - const struct pmu_event *sys_event_table =3D find_sys_events_table("pme_te= st_soc_sys"); - const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); + const struct pmu_events_table *sys_event_table =3D find_sys_events_table(= "pme_test_soc_sys"); + const struct pmu_events_table *table =3D find_core_events_table("testarch= ", "testcpu"); int map_events =3D 0, expected_events, err; =20 /* ignore 3x sentinels */ @@ -544,7 +544,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name= , int *count) struct perf_pmu *pmu; LIST_HEAD(aliases); int res =3D 0; - const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); + const struct pmu_events_table *table =3D find_core_events_table("testarch= ", "testcpu"); struct perf_pmu_alias *a, *tmp; =20 if (!table) @@ -597,7 +597,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) struct perf_pmu *pmu =3D &test_pmu->pmu; const char *pmu_name =3D pmu->name; struct perf_pmu_alias *a, *tmp, *alias; - const struct pmu_event *events_table; + const struct pmu_events_table *events_table; LIST_HEAD(aliases); int res =3D 0; =20 @@ -839,7 +839,7 @@ struct metric { struct metric_ref metric_ref; }; =20 -static int test__parsing_callback(const struct pmu_event *pe, const struct= pmu_event *table, +static int test__parsing_callback(const struct pmu_event *pe, const struct= pmu_events_table *table, void *data) { int *failures =3D data; @@ -1016,7 +1016,7 @@ static int metric_parse_fake(const char *str) } =20 static int test__parsing_fake_callback(const struct pmu_event *pe, - const struct pmu_event *table __maybe_unused, + const struct pmu_events_table *table __maybe_unused, void *data __maybe_unused) { if (!pe->metric_expr) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index cae97b6dc5bc..42a5c8ae915e 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_table__find(); + const struct pmu_events_table *table =3D pmu_events_table__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_table__find(); + const struct pmu_events_table *table =3D pmu_events_table__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 dd1e171d7480..89655d53117a 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -710,7 +710,7 @@ char *perf_pmu__getcpuid(struct perf_pmu *pmu) return cpuid; } =20 -__weak const struct pmu_event *pmu_events_table__find(void) +__weak const struct pmu_events_table *pmu_events_table__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_table(struct list_head *head, struct perf_pmu *pm= u, - 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_table(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_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 f0aba1e462fa..a7b0f9507510 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_table(struct list_head *head, struct perf_pmu *pm= u, - const struct pmu_event *table); + const struct pmu_events_table *table); =20 char *perf_pmu__getcpuid(struct perf_pmu *pmu); -const struct pmu_event *pmu_events_table__find(void); +const struct pmu_events_table *pmu_events_table__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 235319d45d02..9a631d97471c 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_table__find(); --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 7FBE4C25B0F for ; Fri, 12 Aug 2022 23:11:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237734AbiHLXLa (ORCPT ); Fri, 12 Aug 2022 19:11:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238127AbiHLXKu (ORCPT ); Fri, 12 Aug 2022 19:10:50 -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 DB4A29FA8D for ; Fri, 12 Aug 2022 16:10:27 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-31f3959ba41so18542527b3.2 for ; Fri, 12 Aug 2022 16:10:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=L3NCVkU6UmNGTi4r6GGCKSqgXuvU9SIfIoFGeABj8Ww=; b=ETDW742cZj1CKv1exNN5guZhFRahQN+33+PQtwGgWD77JQRz2kNEAmbFHjsldbmUVb cspBkUR580GPTInNtvfyMx9nfUEtmT6qKsZztyst8hshsLJJq/t9G3JZucnHCsh8Q69C CHXtWV4Olnhnkb3m0a05Vqd96jaN/ORPOsw1lX87XU2aAE286EjU7ITcRmkdvzhjxARe o9y2DbRdPyLOmONtnoj1ttioVfFa5quKMKSXbt6VchqScpT/ElBOYoCYSUaeRY59AFf6 ePkHfm0LPKyt6gHD07a0vCmEXgvwL0uccQj1BtFISYkveMFgVHLR20Q+5qSgc9r/OMBt o39g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=L3NCVkU6UmNGTi4r6GGCKSqgXuvU9SIfIoFGeABj8Ww=; b=h0oPNAcR/4OFzUQc+fXstwzP5K21V7DcsU1tIHjoDNzKZJue5Uace6qRAhIKCIq3Sq pXdnuhOFI58GB+tNvKO0uWhb/xYQs7R85OafW8o+E75bRObBBrZklB27G6KhCHfWmYfZ PL57l9NkJtC6Yzdwqr24KJFEobKwjgN474gp/LUD1Ub4oLMaKq+GhQrRaXhyCT0dt03z Oys79d1bbRPFwcUu4/EKJ5eGquevzZZvspPSY6eu6frRGszA/kLTyqgNDQMp78goEV0f +C9T1KUwSTDh+TaYJd7knckFtl0E6vLJ+oIMXHTRwmJMhNewTWt2EF7INpSAlUwr/x9j Au9A== X-Gm-Message-State: ACgBeo2xQtWM/tzB+fgnvW8Mt9nwj8rxXsuKOmaTO3Uglh8yU/+JiHYu UypeT8yW9dxifnsVrpMpR1H5R9vEJXy+ X-Google-Smtp-Source: AA6agR6QSimwWeQzK/xHxfqJZ7SfTKWtl9RSmsfbBpCCuL3WiqcKFutPaGotbF3pR/Bpi/XjkzIr9332cAYb X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a25:55c5:0:b0:670:96cb:a295 with SMTP id j188-20020a2555c5000000b0067096cba295mr4680145ybb.449.1660345826657; Fri, 12 Aug 2022 16:10:26 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:47 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-13-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 12/14] 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 42a5c8ae915e..464475fd6b9a 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -879,6 +879,10 @@ struct metricgroup_add_iter_data { const struct pmu_events_table *table; }; =20 +static bool metricgroup__find_metric(const char *metric, + const struct pmu_events_table *table, + struct pmu_event *pe); + static int add_metric(struct list_head *metric_list, const struct pmu_event *pe, const char *modifier, @@ -914,7 +918,7 @@ static int resolve_metric(struct list_head *metric_list, size_t bkt; struct to_resolve { /* The metric to resolve. */ - const struct pmu_event *pe; + struct pmu_event pe; /* * The key in the IDs map, this may differ from in case, * etc. from pe->metric_name. @@ -928,16 +932,15 @@ static int resolve_metric(struct list_head *metric_li= st, * the pending array. */ hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) { - const struct pmu_event *pe; + struct pmu_event pe; =20 - pe =3D metricgroup__find_metric(cur->key, table); - if (pe) { + if (metricgroup__find_metric(cur->key, table, &pe)) { pending =3D realloc(pending, (pending_cnt + 1) * sizeof(struct to_resolve)); if (!pending) return -ENOMEM; =20 - pending[pending_cnt].pe =3D pe; + memcpy(&pending[pending_cnt].pe, &pe, sizeof(pe)); pending[pending_cnt].key =3D cur->key; pending_cnt++; } @@ -952,7 +955,7 @@ static int resolve_metric(struct list_head *metric_list, * context. */ for (i =3D 0; i < pending_cnt; i++) { - ret =3D add_metric(metric_list, pending[i].pe, modifier, metric_no_group, + ret =3D add_metric(metric_list, &pending[i].pe, modifier, metric_no_grou= p, root_metric, visited, table); if (ret) break; @@ -1073,7 +1076,7 @@ static int __add_metric(struct list_head *metric_list, =20 struct metricgroup__find_metric_data { const char *metric; - const struct pmu_event *pe; + struct pmu_event *pe; }; =20 static int metricgroup__find_metric_callback(const struct pmu_event *pe, @@ -1085,21 +1088,21 @@ static int metricgroup__find_metric_callback(const = struct pmu_event *pe, if (!match_metric(pe->metric_name, data->metric)) return 0; =20 - data->pe =3D pe; - return -1; + memcpy(data->pe, pe, sizeof(*pe)); + return 1; } =20 -const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_events_table *table) +static bool metricgroup__find_metric(const char *metric, + const struct pmu_events_table *table, + struct pmu_event *pe) { struct metricgroup__find_metric_data data =3D { .metric =3D metric, - .pe =3D NULL, + .pe =3D pe, }; =20 - pmu_events_table_for_each_event(table, metricgroup__find_metric_callback,= &data); - - return data.pe; + return pmu_events_table_for_each_event(table, metricgroup__find_metric_ca= llback, &data) + ? true : false; } =20 static int add_metric(struct list_head *metric_list, diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index f54d170043e9..016b3b1a289a 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -69,8 +69,6 @@ int metricgroup__parse_groups(const struct option *opt, bool metric_no_group, bool metric_no_merge, struct rblist *metric_events); -const struct pmu_event *metricgroup__find_metric(const char *metric, - const struct pmu_events_table *table); int metricgroup__parse_groups_test(struct evlist *evlist, const struct pmu_events_table *table, const char *str, --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 BF7DAC19F2D for ; Fri, 12 Aug 2022 23:11:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238732AbiHLXLf (ORCPT ); Fri, 12 Aug 2022 19:11:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46396 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238157AbiHLXKw (ORCPT ); Fri, 12 Aug 2022 19:10:52 -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 8633B9BB4B for ; Fri, 12 Aug 2022 16:10:30 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-329a474c437so18285007b3.18 for ; Fri, 12 Aug 2022 16:10:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=kEkkZgmgeGRAjvSLiOYPVSUDNqcN4cjGPRNtnVx0v4M=; b=mFy3hsjZsBMSPl4fQ5thvJ2IYF2OjBKv5eUqM3GPH3cd3LcVbcU65sYQct3Dquysyw iN2e7+mLVhrls6HOjMNSWXXAGyXfgS1LBnJodRuS5/Vg3630TQrPJ1BBch8wMsZCB1uX oNrs2kjydc3iaMTH7+BmY6DvaXqF714SVFQZSNZ/JLQfL+I31Fp1SFnQq3f+u07wo1tj LOmeagEKGQOXMYip/ZrnTYDRzEKB43rwkex0TVz40KUZmIh0io7M2a+2IUD1LLo18oaI ugk9D8+pDpKq24NdVaR/ttfqU2e4ft8Pg4PN+qHlofQ30ejWR4PVfSlJrIslT0vQlvwO 8U5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=kEkkZgmgeGRAjvSLiOYPVSUDNqcN4cjGPRNtnVx0v4M=; b=kDMUT4Wk/BjpaSj4cKep5cnOABHCGza7OQ39E1ctv8deQfahVfQtNLl7tqyJn3xo9k nnEIugQVFvoVdtAG0fEs8EGQ1XdYG8l/n68rPCif+FVlTb2Iz5nqIlPS9IfC/58/4KW+ YL2vgavHBZuAFyvOsdC3Ezik2bb2LLg0bgqCRLegflh9KVnpE3DITD/yYy9oPw6sIfsc b8lb3Qq0A44+6Wi2DvzGHn2Ds2nI6GPBoryZs9JrJs0PEe1JTccnHjQqnVhh2dRBPWdf 7zg/ebWYekSFFel5mB0feXtXDdDa/EvbAF/KGeQ2h/pa534fAZxi+QTQKjj+VpyxW6Ab yQ2Q== X-Gm-Message-State: ACgBeo1Vy/6Uz/5fgBQL2/s/v/RZ7sqRAH69jcwefm6bGaRhOekSqlNk iQJK/XjTcop22O+wCQWdC2/+QHLU0YGL X-Google-Smtp-Source: AA6agR7VsEGB0MTyNO/1utqQTY9epjQ0PNwlz0WQfoXmdpFrfBJGV1roFM10Vs5SwI4j4VQRHi7f0W56MxyM X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a0d:d9cc:0:b0:329:848f:712d with SMTP id b195-20020a0dd9cc000000b00329848f712dmr5874078ywe.38.1660345829598; Fri, 12 Aug 2022 16:10:29 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:48 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-14-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 13/14] perf jevents: Compress the pmu_events_table From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The pmu_events array requires 15 pointers per entry which in position independent code need relocating. Change the array to be an array of offsets within a big C string. Only the offset of the first variable is required, subsequent variables are stored in order after the \0 terminator (requiring a byte per variable rather than 4 bytes per offset). The file size savings are: no jevents - the same 19,788,464bytes x86 jevents - ~16.7% file size saving 23,744,288bytes vs 28,502,632bytes all jevents - ~19.5% file size saving 24,469,056bytes vs 30,379,920bytes default build options plus NO_LIBBFD=3D1. For example, the x86 build savings come from .rela.dyn and .data.rel.ro becoming smaller by 3,157,032bytes and 3,042,016bytes respectively. .rodata increases by 1,432,448bytes, giving an overall 4,766,600bytes saving. To make metric strings more shareable, the topic is changed from say 'skx metrics' to just 'metrics'. To try to help with the memory layout the pmu_events are ordered as used by perf qsort comparator functions. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 207 ++++++++++++++++++++++++------- 1 file changed, 162 insertions(+), 45 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 4b7948ba57d6..d722fcba2d9f 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -6,7 +6,8 @@ import csv import json import os import sys -from typing import (Callable, Optional, Sequence) +from typing import (Callable, Dict, Optional, Sequence, Set, Tuple) +import collections =20 # Global command line arguments. _args =3D None @@ -20,6 +21,19 @@ _arch_std_events =3D {} _close_table =3D False # Events to write out when the table is closed _pending_events =3D [] +# Global BigCString shared by all structures. +_bcs =3D None +# Order specific JsonEvent attributes will be visited. +_json_event_attributes =3D [ + # cmp_sevent related attributes. + 'name', 'pmu', 'topic', 'desc', 'metric_name', 'metric_group', + # Seems useful, put it early. + 'event', + # Short things in alphabetical order. + 'aggr_mode', 'compat', 'deprecated', 'perpkg', 'unit', + # Longer things (the last won't be iterated over during decompress). + 'metric_constraint', 'metric_expr', 'long_desc' +] =20 =20 def removesuffix(s: str, suffix: str) -> str: @@ -39,6 +53,66 @@ def file_name_to_table_name(parents: Sequence[str], dirn= ame: str) -> str: tblname +=3D '_' + dirname return tblname.replace('-', '_') =20 +def c_len(s: str) -> int: + """Return the length of s a C string + + This doesn't handle all escape characters properly. It first assumes + all \ are for escaping, it then adjusts as it will have over counted + \\. The code uses \000 rather than \0 as a terminator as an adjacent + number would be folded into a string of \0 (ie. "\0" + "5" doesn't + equal a terminator followed by the number 5 but the escape of + \05). The code adjusts for \000 but not properly for all octal, hex + or unicode values. + """ + try: + utf =3D s.encode(encoding=3D'utf-8',errors=3D'strict') + except: + print(f'broken string {s}') + raise + return len(utf) - utf.count(b'\\') + utf.count(b'\\\\') - (utf.count(b'\= \000') * 2) + +class BigCString: + """A class to hold many strings concatenated together. + + Generating a large number of stand-alone C strings creates a large + number of relocations in position independent code. The BigCString + is a helper for this case. It builds a single string which within it + are all the other C strings (to avoid memory issues the string + itself is held as a list of strings). The offsets within the big + string are recorded and when stored to disk these don't need + relocation. + """ + strings: Set[str] + big_string: Sequence[str] + offsets: Dict[str, int] + + def __init__(self): + self.strings =3D set() + + def add(self, s: str) -> None: + """Called to add to the big string.""" + self.strings.add(s) + + def compute(self) -> None: + """Called once all strings are added to compute the string and offsets= .""" + + # big_string_offset is the current location within the C string + # being appended to - comments, etc. don't count. big_string is + # the string contents represented as a list. Strings are immutable + # in Python and so appending to one causes memory issues, while + # lists are mutable. + big_string_offset =3D 0 + self.big_string =3D [] + self.offsets =3D {} + # Emit all strings in a sorted manner. + for s in sorted(self.strings): + self.offsets[s] =3D big_string_offset + self.big_string.append(f'/* offset=3D{big_string_offset} */ "') + self.big_string.append(s) + self.big_string.append('"\n') + big_string_offset +=3D c_len(s) + +_bcs =3D BigCString() =20 class JsonEvent: """Representation of an event loaded from a json file dictionary.""" @@ -203,26 +277,18 @@ class JsonEvent: s +=3D f'\t{attr} =3D {value},\n' return s + '}' =20 + def build_c_string(self) -> str: + s =3D '' + for attr in _json_event_attributes: + x =3D getattr(self, attr) + s +=3D f'{x}\\000' if x else '\\000' + return s + def to_c_string(self) -> str: """Representation of the event as a C struct initializer.""" =20 - def attr_string(attr: str, value: str) -> str: - return f'\t.{attr} =3D \"{value}\",\n' - - def str_if_present(self, attr: str) -> str: - if not getattr(self, attr): - return '' - return attr_string(attr, getattr(self, attr)) - - s =3D '{\n' - for attr in [ - 'aggr_mode', 'compat', 'deprecated', 'desc', 'event', 'long_desc', - 'metric_constraint', 'metric_expr', 'metric_group', 'metric_name', - 'name', 'perpkg', 'pmu', 'topic', 'unit' - ]: - s +=3D str_if_present(self, attr) - s +=3D '},\n' - return s + s =3D self.build_c_string() + return f'{{ { _bcs.offsets[s] } }}, /* {s} */\n' =20 =20 def read_json_events(path: str, topic: str) -> Sequence[JsonEvent]: @@ -237,7 +303,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 +318,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 @@ -268,13 +333,13 @@ def add_events_table_entries(item: os.DirEntry, topic= : str) -> None: def print_events_table_suffix() -> None: """Optionally close events table.""" =20 - def event_cmp_key(j: JsonEvent): - def fix_none(s: str): + def event_cmp_key(j: JsonEvent) -> Tuple[bool, str, str, str, str]: + def fix_none(s: Optional[str]) -> str: if s is None: return '' return s =20 - return (not j.desc is None, fix_none(j.topic), fix_none(j.name), fix_n= one(j.pmu), + return (j.desc is not None, fix_none(j.topic), fix_none(j.name), fix_n= one(j.pmu), fix_none(j.metric_name)) =20 global _close_table @@ -286,23 +351,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 +416,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 +445,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 +463,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 +474,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 +492,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 +635,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 +645,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 +664,15 @@ def main() -> None: for arch in archs: arch_path =3D f'{_args.starting_dir}/{arch}' preprocess_arch_std_files(arch_path) + ftw(arch_path, [], preprocess_one_file) + + _bcs.compute() + _args.output_file.write('static const char *const big_c_string =3D\n') + for s in _bcs.big_string: + _args.output_file.write(s) + _args.output_file.write(';\n\n') + for arch in archs: + arch_path =3D f'{_args.starting_dir}/{arch}' ftw(arch_path, [], process_one_file) print_events_table_suffix() =20 --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 09:20:37 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 832E2C00140 for ; Fri, 12 Aug 2022 23:11:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238997AbiHLXLt (ORCPT ); Fri, 12 Aug 2022 19:11:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238764AbiHLXK6 (ORCPT ); Fri, 12 Aug 2022 19:10:58 -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 42645A262C for ; Fri, 12 Aug 2022 16:10:33 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 137-20020a250b8f000000b0067a5a14d730so1806433ybl.12 for ; Fri, 12 Aug 2022 16:10:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=content-transfer-encoding:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:from:to:cc; bh=jZOzQ8/cjxO+jmOM/T4yZoES9QnypFGOepiGDeweX0Y=; b=RJO4FqpdnDqxJsx06M6lmWaX7oizy+rw9/HhJWXJx5ZdNTbitqkx4QHn2QF4uYNITM 0vnHOvZp43OQ6Kd3g82E2bGI5LZIAa7jfUE2+bDPZ0eBXY6DN16zVgPGv8Wtmng9lY+x n07Y+g5R0+Suy19iAfu+Ds/JzLIYGD0bQSD8J00yuYf8Mq2uLt3AgPIlMbfAWYyseRhV hz/jvdadPxf27jS1jJneXUCY3F7dTcMdq8qwqw+rKsnU07YSKRJLdlDzGKs46kUATkpl fN8dEOctLjQssCfjHGU/MBCck+36zlzWE9pLI6qA7mggUnW2qv2N4K3JK1Fh7FFEqEIG OdBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:x-gm-message-state:from:to :cc; bh=jZOzQ8/cjxO+jmOM/T4yZoES9QnypFGOepiGDeweX0Y=; b=fQtxEjZu3SifA26etizulYMOz2w0UT93MYKvROw3EBthReYJiZDYroofFJUyPSjdK1 Gkq1r9StzYQKEUEg6buN4WNIsrGv8pl87GAmFYB/3yozj9CftjSNk7hDUaoILV3iAaG4 0rtjA8D2NOGSeF/Umt/Xq01Raich5iwGzCMz2GuV+xGXVLmF/h0fkKjp7nCUN67qkdbZ 9uuInX1DdM6iypKvYFdnqSyqeLeiW2NRwkb/qTr4jGrBdOHDX4XyESfHiaI95m0gTOM/ IOF8IJ13hw+9ia/Bu+5WpzZ/Z7BSSv8m90b/3NRDPouqXa/OFNBl1ksdVgYTYzy/ovHY 3X8A== X-Gm-Message-State: ACgBeo03b/u3OA8SjvuCrJXwFTC5uUKsg4shboDEDzTGqyADL6LyeWyi CHDoPwlMB5zsoZ8JYta8/Q/JT1P4ICQY X-Google-Smtp-Source: AA6agR4JX/0Hi07MegusXtIqA4W9pZ0BOeAGXxQUl7a1pjGzkLhiVnawBPSTGCCN8lWQmKjYSuesLdrODo63 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:d668:2937:8218:c5ec]) (user=irogers job=sendgmr) by 2002:a05:6902:150c:b0:676:c807:6cb2 with SMTP id q12-20020a056902150c00b00676c8076cb2mr5285892ybu.488.1660345832252; Fri, 12 Aug 2022 16:10:32 -0700 (PDT) Date: Fri, 12 Aug 2022 16:09:49 -0700 In-Reply-To: <20220812230949.683239-1-irogers@google.com> Message-Id: <20220812230949.683239-15-irogers@google.com> Mime-Version: 1.0 References: <20220812230949.683239-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v5 14/14] perf jevents: Fold strings optimization From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" If a shorter string ends a longer string then the shorter string may reuse the longer string at an offset. For example, on x86 the event arith.cycles_div_busy and cycles_div_busy can be folded, even though they have difference names the strings are identical after 6 characters. cycles_div_busy can reuse the arith.cycles_div_busy string at an offset of 6. In pmu-events.c this looks like the following where the 'also:' lists folded strings: /* offset=3D177541 */ "arith.cycles_div_busy\000\000pipeline\000Cycles the = divider is busy\000\000\000event=3D0x14,period=3D2000000,umask=3D0x1\000\00= 0\000\000\000\000\000\000\000" /* also: cycles_div_busy\000\000pipeline\000= Cycles the divider is busy\000\000\000event=3D0x14,period=3D2000000,umask= =3D0x1\000\000\000\000\000\000\000\000\000 */ As jevents.py combines multiple strings for an event into a larger string, the amount of folding is minimal as all parts of the event must align. Other organizations can benefit more from folding, but lose space by say recording more offsets. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 55 ++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index d722fcba2d9f..0daa3e007528 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -80,7 +80,9 @@ class BigCString: are all the other C strings (to avoid memory issues the string itself is held as a list of strings). The offsets within the big string are recorded and when stored to disk these don't need - relocation. + relocation. To reduce the size of the string further, identical + strings are merged. If a longer string ends-with the same value as a + shorter string, these entries are also merged. """ strings: Set[str] big_string: Sequence[str] @@ -96,6 +98,33 @@ class BigCString: def compute(self) -> None: """Called once all strings are added to compute the string and offsets= .""" =20 + folded_strings =3D {} + # Determine if two strings can be folded, ie. let 1 string use the + # end of another. First reverse all strings and sort them. + sorted_reversed_strings =3D sorted([x[::-1] for x in self.strings]) + + # Strings 'xyz' and 'yz' will now be [ 'zy', 'zyx' ]. Scan forward + # for each string to see if there is a better candidate to fold it + # into, in the example rather than using 'yz' we can use'xyz' at + # an offset of 1. We record which string can be folded into which + # in folded_strings, we don't need to record the offset as it is + # trivially computed from the string lengths. + for pos,s in enumerate(sorted_reversed_strings): + best_pos =3D pos + for check_pos in range(pos + 1, len(sorted_reversed_strings)): + if sorted_reversed_strings[check_pos].startswith(s): + best_pos =3D check_pos + else: + break + if pos !=3D best_pos: + folded_strings[s[::-1]] =3D sorted_reversed_strings[best_pos][::-1] + + # Compute reverse mappings for debugging. + fold_into_strings =3D collections.defaultdict(set) + for key, val in folded_strings.items(): + if key !=3D val: + fold_into_strings[val].add(key) + # big_string_offset is the current location within the C string # being appended to - comments, etc. don't count. big_string is # the string contents represented as a list. Strings are immutable @@ -104,13 +133,25 @@ class BigCString: big_string_offset =3D 0 self.big_string =3D [] self.offsets =3D {} - # Emit all strings in a sorted manner. + + # Emit all strings that aren't folded in a sorted manner. for s in sorted(self.strings): - self.offsets[s] =3D big_string_offset - self.big_string.append(f'/* offset=3D{big_string_offset} */ "') - self.big_string.append(s) - self.big_string.append('"\n') - big_string_offset +=3D c_len(s) + if s not in folded_strings: + self.offsets[s] =3D big_string_offset + self.big_string.append(f'/* offset=3D{big_string_offset} */ "') + self.big_string.append(s) + self.big_string.append('"') + if s in fold_into_strings: + self.big_string.append(' /* also: ' + ', '.join(fold_into_string= s[s]) + ' */') + self.big_string.append('\n') + big_string_offset +=3D c_len(s) + continue + + # Compute the offsets of the folded strings. + for s in folded_strings.keys(): + assert s not in self.offsets + folded_s =3D folded_strings[s] + self.offsets[s] =3D self.offsets[folded_s] + c_len(folded_s) - c_len= (s) =20 _bcs =3D BigCString() =20 --=20 2.37.1.595.g718a3a8f04-goog