From nobody Tue Dec 16 19:54:49 2025 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 D580BC7EE2C for ; Thu, 24 Aug 2023 04:14:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240025AbjHXEN7 (ORCPT ); Thu, 24 Aug 2023 00:13:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55314 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239891AbjHXENp (ORCPT ); Thu, 24 Aug 2023 00:13:45 -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 D2D7D10C4 for ; Wed, 23 Aug 2023 21:13:41 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-58daaa2ba65so81975777b3.1 for ; Wed, 23 Aug 2023 21:13:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850421; x=1693455221; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=t3FkZtk24eVZPBJL4lg4GGb1/7Xpt8aSUak5SLWJZY8=; b=jxbq6n1Y/JCOGfr3UmCU8NPdmHhY1AMklvN2ablxD/gVypqFbfrU2Wmz9JSoVqx274 08qCNC/fWLrfwHjAhM7qM2mks8Xn3oSEWSQVRoMIpkNIQjLdjCj6ywYlqRtq9RZ1Neb6 CZkyH9qe+9eBk8CYbT6BX7XRjlA+8l33dkaJUcjtGFkQ7jgA9bgSNB1oDfwUZ2dnZHy7 bcCnWu2OVGTEzBUexqKnx29Nb9UPjRivs/H6amKP6Iz5QWsjDZwopAT5gdA0yywaSz0m PCz8m8efa9GDsxNBOGjXGLGz6t1fZ4j0242wHPVpOkbfOLJMi63Fyo6ZFoNw7cD/BMPs LRXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850421; x=1693455221; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=t3FkZtk24eVZPBJL4lg4GGb1/7Xpt8aSUak5SLWJZY8=; b=NMxw9GWwrITFEuuqTU1NrsoqllPCgMOxMGxy6yCuiPRF2P71sdUM/LA3YTc3uERFu6 lyIE0ACtMMWtZFSBmr8nl1Bf6epl1lrblleYv61PIiUlqm589nWYDjs/G6gKTBqHF9eD gs8SBI/cfMWVMHeAIwtW3rSTfNL+JMPNCW1p/cDvkHcGl2UApjnYU/u7n+XmNsANEjzQ xLPkeQvbswPS8/1oQURu1rnXsJ+BHoW5q67nnw8TMSCby+OV0K/WM6+bWPjN6GHCAXiX sVtS9f37Dr3juy9YmTOQLuimbQYuEBrPVCl2Ty3fb+afwOxLaPYeXC10lsXO9j2kQKfb 0SzQ== X-Gm-Message-State: AOJu0YzcqScfptky6Y75abHJD9fXxDpLwrimmOla2f5pdFtuccSB7VZg h7EaVVT+94TPHbwF/ERQYudqy11XrHeW X-Google-Smtp-Source: AGHT+IFELTbtRvGgeXP4JpFZSHqQbtQQqwBD1lLrRLrS2eUkBS3uzkr0/Aw9SNiqXJDafDgnqi+QQmZ6i9nc X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a81:af16:0:b0:57a:793:7fb0 with SMTP id n22-20020a81af16000000b0057a07937fb0mr215495ywh.3.1692850421082; Wed, 23 Aug 2023 21:13:41 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:13 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-2-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 01/18] perf pmu: Make the loading of formats lazy From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org 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 sysfs format files are loaded eagerly in a PMU. Add a flag so that we create the format but only load the contents when necessary. Reduce the size of the value in struct perf_pmu_format and avoid holes so there is no additional space requirement. For "perf stat -e cycles true" this reduces the number of openat calls from 648 to 573 (about 12%). The benchmark pmu scan speed is improved by roughly 5%. Before: $ perf bench internals pmu-scan Computing performance of sysfs PMU event scan for 100 times Average core PMU scanning took: 1061.100 usec (+- 9.965 usec) Average PMU scanning took: 4725.300 usec (+- 260.599 usec) After: $ perf bench internals pmu-scan Computing performance of sysfs PMU event scan for 100 times Average core PMU scanning took: 989.170 usec (+- 6.873 usec) Average PMU scanning took: 4520.960 usec (+- 251.272 usec) Signed-off-by: Ian Rogers --- tools/perf/tests/pmu.c | 2 +- tools/perf/util/pmu.c | 144 +++++++++++++++++++++++++++-------------- tools/perf/util/pmu.h | 5 +- tools/perf/util/pmu.y | 20 ++---- 4 files changed, 106 insertions(+), 65 deletions(-) diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index 2c1c349a42e2..c204ed1f1a8b 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -171,7 +171,7 @@ static int test__pmu(struct test_suite *test __maybe_un= used, int subtest __maybe } =20 pmu->name =3D strdup("perf-pmu-test"); - ret =3D perf_pmu__format_parse(pmu, fd); + ret =3D perf_pmu__format_parse(pmu, fd, /*eager_load=3D*/true); if (ret) goto out; =20 diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 42f3249994ab..3cfd3e58da23 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -40,6 +40,10 @@ struct perf_pmu perf_pmu__fake; * value=3DPERF_PMU_FORMAT_VALUE_CONFIG and bits 0 to 7 will be set. */ struct perf_pmu_format { + /** @list: Element on list within struct perf_pmu. */ + struct list_head list; + /** @bits: Which config bits are set by this format value. */ + DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); /** @name: The modifier/file name. */ char *name; /** @@ -47,18 +51,79 @@ struct perf_pmu_format { * are from PERF_PMU_FORMAT_VALUE_CONFIG to * PERF_PMU_FORMAT_VALUE_CONFIG_END. */ - int value; - /** @bits: Which config bits are set by this format value. */ - DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); - /** @list: Element on list within struct perf_pmu. */ - struct list_head list; + u16 value; + /** @loaded: Has the contents been loaded/parsed. */ + bool loaded; }; =20 +static struct perf_pmu_format *perf_pmu__new_format(struct list_head *list= , char *name) +{ + struct perf_pmu_format *format; + + format =3D zalloc(sizeof(*format)); + if (!format) + return NULL; + + format->name =3D strdup(name); + if (!format->name) { + free(format); + return NULL; + } + list_add_tail(&format->list, list); + return format; +} + +/* Called at the end of parsing a format. */ +void perf_pmu_format__set_value(void *vformat, int config, unsigned long *= bits) +{ + struct perf_pmu_format *format =3D vformat; + + format->value =3D config; + memcpy(format->bits, bits, sizeof(format->bits)); +} + +static void __perf_pmu_format__load(struct perf_pmu_format *format, FILE *= file) +{ + void *scanner; + int ret; + + ret =3D perf_pmu_lex_init(&scanner); + if (ret) + return; + + perf_pmu_set_in(file, scanner); + ret =3D perf_pmu_parse(format, scanner); + perf_pmu_lex_destroy(scanner); + format->loaded =3D true; +} + +static void perf_pmu_format__load(struct perf_pmu *pmu, struct perf_pmu_fo= rmat *format) +{ + char path[PATH_MAX]; + FILE *file =3D NULL; + + if (format->loaded) + return; + + if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, "format"= )) + return; + + assert(strlen(path) + strlen(format->name) + 2 < sizeof(path)); + strcat(path, "/"); + strcat(path, format->name); + + file =3D fopen(path, "r"); + if (!file) + return; + __perf_pmu_format__load(format, file); + fclose(file); +} + /* * Parse & process all the sysfs attributes located under * the directory specified in 'dir' parameter. */ -int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd) +int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_loa= d) { struct dirent *evt_ent; DIR *format_dir; @@ -68,37 +133,35 @@ int perf_pmu__format_parse(struct perf_pmu *pmu, int d= irfd) if (!format_dir) return -EINVAL; =20 - while (!ret && (evt_ent =3D readdir(format_dir))) { + while ((evt_ent =3D readdir(format_dir)) !=3D NULL) { + struct perf_pmu_format *format; char *name =3D evt_ent->d_name; - int fd; - void *scanner; - FILE *file; =20 if (!strcmp(name, ".") || !strcmp(name, "..")) continue; =20 - - ret =3D -EINVAL; - fd =3D openat(dirfd, name, O_RDONLY); - if (fd < 0) - break; - - file =3D fdopen(fd, "r"); - if (!file) { - close(fd); + format =3D perf_pmu__new_format(&pmu->format, name); + if (!format) { + ret =3D -ENOMEM; break; } =20 - ret =3D perf_pmu_lex_init(&scanner); - if (ret) { + if (eager_load) { + FILE *file; + int fd =3D openat(dirfd, name, O_RDONLY); + + if (fd < 0) { + ret =3D -errno; + break; + } + file =3D fdopen(fd, "r"); + if (!file) { + close(fd); + break; + } + __perf_pmu_format__load(format, file); fclose(file); - break; } - - perf_pmu_set_in(file, scanner); - ret =3D perf_pmu_parse(&pmu->format, name, scanner); - perf_pmu_lex_destroy(scanner); - fclose(file); } =20 closedir(format_dir); @@ -119,7 +182,7 @@ static int pmu_format(struct perf_pmu *pmu, int dirfd, = const char *name) return 0; =20 /* it'll close the fd */ - if (perf_pmu__format_parse(pmu, fd)) + if (perf_pmu__format_parse(pmu, fd, /*eager_load=3D*/false)) return -1; =20 return 0; @@ -962,13 +1025,15 @@ void perf_pmu__warn_invalid_formats(struct perf_pmu = *pmu) if (pmu =3D=3D &perf_pmu__fake) return; =20 - list_for_each_entry(format, &pmu->format, list) + list_for_each_entry(format, &pmu->format, list) { + perf_pmu_format__load(pmu, format); if (format->value >=3D PERF_PMU_FORMAT_VALUE_CONFIG_END) { pr_warning("WARNING: '%s' format '%s' requires 'perf_event_attr::config= %d'" "which is not supported by this version of perf!\n", pmu->name, format->name, format->value); return; } + } } =20 bool evsel__is_aux_event(const struct evsel *evsel) @@ -1041,6 +1106,7 @@ int perf_pmu__format_type(struct perf_pmu *pmu, const= char *name) if (!format) return -1; =20 + perf_pmu_format__load(pmu, format); return format->value; } =20 @@ -1177,7 +1243,7 @@ static int pmu_config_term(struct perf_pmu *pmu, free(pmu_term); return -EINVAL; } - + perf_pmu_format__load(pmu, format); switch (format->value) { case PERF_PMU_FORMAT_VALUE_CONFIG: vp =3D &attr->config; @@ -1403,24 +1469,6 @@ struct perf_pmu_alias *perf_pmu__find_alias(struct p= erf_pmu *pmu, const char *ev =20 return NULL; } - -int perf_pmu__new_format(struct list_head *list, char *name, - int config, unsigned long *bits) -{ - struct perf_pmu_format *format; - - format =3D zalloc(sizeof(*format)); - if (!format) - return -ENOMEM; - - format->name =3D strdup(name); - format->value =3D config; - memcpy(format->bits, bits, sizeof(format->bits)); - - list_add_tail(&format->list, list); - return 0; -} - static void perf_pmu__del_formats(struct list_head *formats) { struct perf_pmu_format *fmt, *tmp; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index c4268053c979..675c9b97f7bf 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -227,9 +227,8 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct = list_head *head_terms, struct perf_pmu_info *info); struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu, const ch= ar *event); =20 -int perf_pmu__new_format(struct list_head *list, char *name, - int config, unsigned long *bits); -int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd); +int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_loa= d); +void perf_pmu_format__set_value(void *format, int config, unsigned long *b= its); bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name); =20 bool is_pmu_core(const char *name); diff --git a/tools/perf/util/pmu.y b/tools/perf/util/pmu.y index d861a5bfa3bd..600c8c158c8e 100644 --- a/tools/perf/util/pmu.y +++ b/tools/perf/util/pmu.y @@ -1,6 +1,5 @@ %define api.pure full -%parse-param {struct list_head *format} -%parse-param {char *name} +%parse-param {void *format} %parse-param {void *scanner} %lex-param {void* scanner} =20 @@ -21,7 +20,7 @@ do { \ YYABORT; \ } while (0) =20 -static void perf_pmu_error(struct list_head *list, char *name, void *scann= er, char const *msg); +static void perf_pmu_error(void *format, void *scanner, const char *msg); =20 static void perf_pmu__set_format(unsigned long *bits, long from, long to) { @@ -59,16 +58,12 @@ format_term format_term: PP_CONFIG ':' bits { - ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG, - $3)); + perf_pmu_format__set_value(format, PERF_PMU_FORMAT_VALUE_CONFIG, $3); } | PP_CONFIG PP_VALUE ':' bits { - ABORT_ON(perf_pmu__new_format(format, name, - $2, - $4)); + perf_pmu_format__set_value(format, $2, $4); } =20 bits: @@ -95,9 +90,8 @@ PP_VALUE =20 %% =20 -static void perf_pmu_error(struct list_head *list __maybe_unused, - char *name __maybe_unused, - void *scanner __maybe_unused, - char const *msg __maybe_unused) +static void perf_pmu_error(void *format __maybe_unused, + void *scanner __maybe_unused, + const char *msg __maybe_unused) { } --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 3CDA2C7EE43 for ; Thu, 24 Aug 2023 04:14:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240019AbjHXEO1 (ORCPT ); Thu, 24 Aug 2023 00:14:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239149AbjHXENt (ORCPT ); Thu, 24 Aug 2023 00:13:49 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E98710E0 for ; Wed, 23 Aug 2023 21:13:45 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id 98e67ed59e1d1-26fb3f2edc9so1486150a91.3 for ; Wed, 23 Aug 2023 21:13:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850424; x=1693455224; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=1otLsZ50JATqaktK/83lv6xdMkX+qLytyneAi8TL6Lw=; b=hPNsHicZXAyGIc4H3aHMX7l2EfNcWQludd7rJHtuN9zLMCNMkcSPWprDAAeoCCIkC7 R+wHkT4/sNKnx1I89hv2PGGXVfmTkFEE8BQI5miKAw9B2G5+ZzgVXe5VKu6DmGPuKiyR K/1R4eLhT5ruOyd3mUiVrzyAJ7Vi1oNl8J4f4I1QrLGeF3XytwQOWFvGiHLwpZDXZG+q 0HJeKCi0VIzd/WDCAvfctrqwe5s091NSCs1E9yAMgWaG82DHs6a+XE/+R59VgA2JBeeL imbep6G9vemWPOLFji2JiAIazNlZ4b+HVbA5Lm2vwrO09I/CWVKwd1JKszZYb3U+phae MIUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850424; x=1693455224; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1otLsZ50JATqaktK/83lv6xdMkX+qLytyneAi8TL6Lw=; b=SJHvjWN9zhtcNErj6F4bvYPk91QkoJVL3SyX9017lqVNy0XezpoDYivpMK1FLPzPLD qNYPgugc/cbi2d8iVCA6kkqN7/QwuF3XuySpFKgGzOIYcHgjLUoWiIwjDCDpryvwFIOw haYNI+SKUQh4vGNWWTVrreuJvh/FkvwjCPnT3rm3BjjgVeZDXSiGOek8yZlhXgZXcb4v PTH1jhK/mZ48B7qSpfpQ9WNgEb5t1/1h9G7fwFrjQlaQbXSBGXXwIRUw2j4Y3bA94EPN hlNItxbhamy6hRkTZr1qi/ccV2ZsfYecXOdctujn0iQZHR1oQ3Xsc8VhR46ZY1r5s9Tr DGWw== X-Gm-Message-State: AOJu0YzGr2+WJt6nYDahCgsl5/GGJtotEUv5DnBiv8BxFVeRzThrC/dV kzjBk8ENpAZs2HT7XbkD9tPyTz33acW1 X-Google-Smtp-Source: AGHT+IEPG0RT8QgvBvF+bEYqcbnDoIgi3/KJ0sFdTrrIqfMw8x6pzVXQnBzhNcuUBcuw/qH588aKEO6ahByK X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a17:90a:d48b:b0:26b:5405:d5ee with SMTP id s11-20020a17090ad48b00b0026b5405d5eemr3392660pju.3.1692850424523; Wed, 23 Aug 2023 21:13:44 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:14 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-3-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 02/18] perf pmu: Abstract alias/event struct From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In order to be able to lazily compute aliases/events for a PMU, move the struct perf_pmu_alias into pmu.c. Add perf_pmu__find_event and perf_pmu__for_each_event that take a callback that is called for the found event or for each event. The layout of struct pmu and the event/alias list is unchanged but the API is altered so that aliases are no longer directly accessed, allowing for later changes. Signed-off-by: Ian Rogers --- tools/perf/bench/pmu-scan.c | 8 +- tools/perf/tests/pmu-events.c | 101 +++++++-------- tools/perf/util/parse-events.c | 67 ++++------ tools/perf/util/pmu.c | 212 +++++++++++++++++++++++++++--- tools/perf/util/pmu.h | 71 +++------- tools/perf/util/pmus.c | 230 +++++++++++---------------------- 6 files changed, 366 insertions(+), 323 deletions(-) diff --git a/tools/perf/bench/pmu-scan.c b/tools/perf/bench/pmu-scan.c index c7d207f8e13c..9e4d36486f62 100644 --- a/tools/perf/bench/pmu-scan.c +++ b/tools/perf/bench/pmu-scan.c @@ -57,9 +57,7 @@ static int save_result(void) r->is_core =3D pmu->is_core; r->nr_caps =3D pmu->nr_caps; =20 - r->nr_aliases =3D 0; - list_for_each(list, &pmu->aliases) - r->nr_aliases++; + r->nr_aliases =3D perf_pmu__num_events(pmu); =20 r->nr_formats =3D 0; list_for_each(list, &pmu->format) @@ -98,9 +96,7 @@ static int check_result(bool core_only) return -1; } =20 - nr =3D 0; - list_for_each(list, &pmu->aliases) - nr++; + nr =3D perf_pmu__num_events(pmu); if (nr !=3D r->nr_aliases) { pr_err("Unmatched number of event aliases in %s: expect %d vs got %d\n", pmu->name, r->nr_aliases, nr); diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 05d6e6e21c6f..dc87e66fb118 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -341,7 +341,7 @@ static int compare_pmu_events(const struct pmu_event *e= 1, const struct pmu_event return 0; } =20 -static int compare_alias_to_test_event(struct perf_pmu_alias *alias, +static int compare_alias_to_test_event(struct pmu_event_info *alias, struct perf_pmu_test_event const *test_event, char const *pmu_name) { @@ -496,6 +496,23 @@ static int test__pmu_event_table(struct test_suite *te= st __maybe_unused, return 0; } =20 +struct test_core_pmu_event_aliases_cb_args { + struct perf_pmu_test_event const *test_event; + int *count; +}; + +static int test_core_pmu_event_aliases_cb(void *state, struct pmu_event_in= fo *alias) +{ + struct test_core_pmu_event_aliases_cb_args *args =3D state; + + if (compare_alias_to_test_event(alias, args->test_event, alias->pmu->name= )) + return -1; + (*args->count)++; + pr_debug2("testing aliases core PMU %s: matched event %s\n", + alias->pmu_name, alias->name); + return 0; +} + /* Verify aliases are as expected */ static int __test_core_pmu_event_aliases(char *pmu_name, int *count) { @@ -522,25 +539,19 @@ static int __test_core_pmu_event_aliases(char *pmu_na= me, int *count) pmu_add_cpu_aliases_table(pmu, table); =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; - struct perf_pmu_alias *alias =3D perf_pmu__find_alias(pmu, event->name); - - if (!alias) { - pr_debug("testing aliases core PMU %s: no alias, alias_table->name=3D%s= \n", - pmu_name, event->name); - res =3D -1; - break; - } - - if (compare_alias_to_test_event(alias, test_event, pmu_name)) { - res =3D -1; - break; - } - - (*count)++; - pr_debug2("testing aliases core PMU %s: matched event %s\n", - pmu_name, alias->name); + struct perf_pmu_test_event test_event =3D **test_event_table; + struct pmu_event const *event =3D &test_event.event; + struct test_core_pmu_event_aliases_cb_args args =3D { + .test_event =3D &test_event, + .count =3D count, + }; + int err; + + test_event.event.pmu =3D pmu_name; + err =3D perf_pmu__find_event(pmu, event->name, &args, + test_core_pmu_event_aliases_cb); + if (err) + res =3D err; } perf_pmu__delete(pmu); =20 @@ -553,7 +564,6 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) struct perf_pmu_test_event const **table; 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_table *events_table; int res =3D 0; =20 @@ -564,8 +574,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) pmu_add_sys_aliases(pmu); =20 /* Count how many aliases we generated */ - list_for_each_entry(alias, &pmu->aliases, list) - alias_count++; + alias_count =3D perf_pmu__num_events(pmu); =20 /* Count how many aliases we expect from the known table */ for (table =3D &test_pmu->aliases[0]; *table; table++) @@ -574,33 +583,25 @@ static int __test_uncore_pmu_event_aliases(struct per= f_pmu_test_pmu *test_pmu) if (alias_count !=3D to_match_count) { pr_debug("testing aliases uncore PMU %s: mismatch expected aliases (%d) = vs found (%d)\n", pmu_name, to_match_count, alias_count); - res =3D -1; - goto out; + return -1; } =20 - list_for_each_entry(alias, &pmu->aliases, list) { - bool matched =3D false; - - for (table =3D &test_pmu->aliases[0]; *table; table++) { - struct perf_pmu_test_event const *test_event =3D *table; - struct pmu_event const *event =3D &test_event->event; - - if (!strcmp(event->name, alias->name)) { - if (compare_alias_to_test_event(alias, - test_event, - pmu_name)) { - continue; - } - matched =3D true; - matched_count++; - } - } - - if (matched =3D=3D false) { + for (table =3D &test_pmu->aliases[0]; *table; table++) { + struct perf_pmu_test_event test_event =3D **table; + struct pmu_event const *event =3D &test_event.event; + int err; + struct test_core_pmu_event_aliases_cb_args args =3D { + .test_event =3D &test_event, + .count =3D &matched_count, + }; + + err =3D perf_pmu__find_event(pmu, event->name, &args, + test_core_pmu_event_aliases_cb); + if (err) { + res =3D err; pr_debug("testing aliases uncore PMU %s: could not match alias %s\n", - pmu_name, alias->name); - res =3D -1; - goto out; + pmu_name, event->name); + return -1; } } =20 @@ -609,12 +610,6 @@ static int __test_uncore_pmu_event_aliases(struct perf= _pmu_test_pmu *test_pmu) pmu_name, matched_count, alias_count); res =3D -1; } - -out: - list_for_each_entry_safe(a, tmp, &pmu->aliases, list) { - list_del(&a->list); - perf_pmu_free_alias(a); - } return res; } =20 diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 7d9d687d9191..7cad82a9f578 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -193,38 +193,31 @@ static void fix_raw(struct list_head *config_terms, s= truct perf_pmu *pmu) struct parse_events_term *term; =20 list_for_each_entry(term, config_terms, list) { - struct perf_pmu_alias *alias; - bool matched =3D false; + u64 num; =20 if (term->type_term !=3D PARSE_EVENTS__TERM_TYPE_RAW) continue; =20 - list_for_each_entry(alias, &pmu->aliases, list) { - if (!strcmp(alias->name, term->val.str)) { - free(term->config); - term->config =3D term->val.str; - term->type_val =3D PARSE_EVENTS__TERM_TYPE_NUM; - term->type_term =3D PARSE_EVENTS__TERM_TYPE_USER; - term->val.num =3D 1; - term->no_value =3D true; - matched =3D true; - break; - } - } - if (!matched) { - u64 num; - + if (perf_pmu__have_event(pmu, term->val.str)) { free(term->config); - term->config =3D strdup("config"); - errno =3D 0; - num =3D strtoull(term->val.str + 1, NULL, 16); - assert(errno =3D=3D 0); - free(term->val.str); + term->config =3D term->val.str; term->type_val =3D PARSE_EVENTS__TERM_TYPE_NUM; - term->type_term =3D PARSE_EVENTS__TERM_TYPE_CONFIG; - term->val.num =3D num; - term->no_value =3D false; + term->type_term =3D PARSE_EVENTS__TERM_TYPE_USER; + term->val.num =3D 1; + term->no_value =3D true; + continue; } + + free(term->config); + term->config =3D strdup("config"); + errno =3D 0; + num =3D strtoull(term->val.str + 1, NULL, 16); + assert(errno =3D=3D 0); + free(term->val.str); + term->type_val =3D PARSE_EVENTS__TERM_TYPE_NUM; + term->type_term =3D PARSE_EVENTS__TERM_TYPE_CONFIG; + term->val.num =3D num; + term->no_value =3D false; } } =20 @@ -1458,28 +1451,22 @@ int parse_events_multi_pmu_add(struct parse_events_= state *parse_state, INIT_LIST_HEAD(list); =20 while ((pmu =3D perf_pmus__scan(pmu)) !=3D NULL) { - struct perf_pmu_alias *alias; bool auto_merge_stats; =20 if (parse_events__filter_pmu(parse_state, pmu)) continue; =20 - auto_merge_stats =3D perf_pmu__auto_merge_stats(pmu); + if (!perf_pmu__have_event(pmu, str)) + continue; =20 - list_for_each_entry(alias, &pmu->aliases, list) { - if (!strcasecmp(alias->name, str)) { - parse_events_copy_term_list(head, &orig_head); - if (!parse_events_add_pmu(parse_state, list, - pmu->name, orig_head, - auto_merge_stats, loc)) { - pr_debug("%s -> %s/%s/\n", str, - pmu->name, alias->str); - parse_state->wild_card_pmus =3D true; - ok++; - } - parse_events_terms__delete(orig_head); - } + auto_merge_stats =3D perf_pmu__auto_merge_stats(pmu); + parse_events_copy_term_list(head, &orig_head); + if (!parse_events_add_pmu(parse_state, list, pmu->name, + orig_head, auto_merge_stats, loc)) { + pr_debug("%s -> %s/%s/\n", str, pmu->name, str); + ok++; } + parse_events_terms__delete(orig_head); } =20 if (parse_state->fake_pmu) { diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 3cfd3e58da23..268aaebfa70c 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -31,6 +31,61 @@ =20 struct perf_pmu perf_pmu__fake; =20 +#define UNIT_MAX_LEN 31 /* max length for event unit name */ + +/** + * struct perf_pmu_alias - An event either read from sysfs or builtin in + * pmu-events.c, created by parsing the pmu-events json files. + */ +struct perf_pmu_alias { + /** @name: Name of the event like "mem-loads". */ + char *name; + /** @desc: Optional short description of the event. */ + char *desc; + /** @long_desc: Optional long description. */ + char *long_desc; + /** + * @topic: Optional topic such as cache or pipeline, particularly for + * json events. + */ + char *topic; + /** + * @str: Comma separated parameter list like + * "event=3D0xcd,umask=3D0x1,ldlat=3D0x3". + */ + char *str; + /** @terms: Owned list of the original parsed parameters. */ + struct list_head terms; + /** @list: List element of struct perf_pmu aliases. */ + struct list_head list; + /** @unit: Units for the event, such as bytes or cache lines. */ + char unit[UNIT_MAX_LEN+1]; + /** @scale: Value to scale read counter values by. */ + double scale; + /** + * @per_pkg: Does the file + * /bus/event_source/devices//events/.per-pkg or + * equivalent json value exist and have the value 1. + */ + bool per_pkg; + /** + * @snapshot: Does the file + * /bus/event_source/devices//events/.snapshot + * exist and have the value 1. + */ + bool snapshot; + /** + * @deprecated: Is the event hidden and so not shown in perf list by + * default. + */ + bool deprecated; + /** + * @pmu_name: The name copied from the json struct pmu_event. This can + * differ from the PMU name as it won't have suffixes. + */ + char *pmu_name; +}; + /** * struct perf_pmu_format - Values from a format file read from * /devices/cpu/format/ held in struct perf_pmu. @@ -355,7 +410,7 @@ static void perf_pmu_update_alias(struct perf_pmu_alias= *old, } =20 /* Delete an alias entry. */ -void perf_pmu_free_alias(struct perf_pmu_alias *newalias) +static void perf_pmu_free_alias(struct perf_pmu_alias *newalias) { zfree(&newalias->name); zfree(&newalias->desc); @@ -1349,10 +1404,20 @@ int perf_pmu__config(struct perf_pmu *pmu, struct p= erf_event_attr *attr, return perf_pmu__config_terms(pmu, attr, head_terms, zero, err); } =20 +static struct perf_pmu_alias *perf_pmu__find_alias(const struct perf_pmu *= pmu, const char *str) +{ + struct perf_pmu_alias *alias; + + list_for_each_entry(alias, &pmu->aliases, list) { + if (!strcasecmp(alias->name, str)) + return alias; + } + return NULL; +} + static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, struct parse_events_term *term) { - struct perf_pmu_alias *alias; char *name; =20 if (parse_events__is_hardcoded_term(term)) @@ -1364,6 +1429,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct p= erf_pmu *pmu, if (pmu_find_format(&pmu->format, term->config)) return NULL; name =3D term->config; + } else if (term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_STR) { if (strcasecmp(term->config, "event")) return NULL; @@ -1372,11 +1438,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct = perf_pmu *pmu, return NULL; } =20 - list_for_each_entry(alias, &pmu->aliases, list) { - if (!strcasecmp(alias->name, name)) - return alias; - } - return NULL; + return perf_pmu__find_alias(pmu, name); } =20 =20 @@ -1459,16 +1521,33 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, str= uct list_head *head_terms, return 0; } =20 -struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu, const ch= ar *event) +struct find_event_args { + const char *event; + void *state; + pmu_event_callback cb; +}; + +static int find_event_callback(void *state, struct pmu_event_info *info) { - struct perf_pmu_alias *alias; + struct find_event_args *args =3D state; =20 - list_for_each_entry(alias, &pmu->aliases, list) - if (!strcmp(event, alias->name)) - return alias; + if (!strcmp(args->event, info->name)) + return args->cb(args->state, info); =20 - return NULL; + return 0; } + +int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *st= ate, pmu_event_callback cb) +{ + struct find_event_args args =3D { + .event =3D event, + .state =3D state, + .cb =3D cb, + }; + + return perf_pmu__for_each_event(pmu, &args, find_event_callback); +} + static void perf_pmu__del_formats(struct list_head *formats) { struct perf_pmu_format *fmt, *tmp; @@ -1508,13 +1587,110 @@ bool perf_pmu__auto_merge_stats(const struct perf_= pmu *pmu) =20 bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name) { - struct perf_pmu_alias *alias; + return perf_pmu__find_alias(pmu, name) !=3D NULL; +} =20 - list_for_each_entry(alias, &pmu->aliases, list) { - if (!strcmp(alias->name, name)) - return true; +size_t perf_pmu__num_events(const struct perf_pmu *pmu) +{ + struct list_head *list; + size_t nr =3D 0; + + list_for_each(list, &pmu->aliases) + nr++; + + return pmu->selectable ? nr + 1 : nr; +} + +static int sub_non_neg(int a, int b) +{ + if (b > a) + return 0; + return a - b; +} + +static char *format_alias(char *buf, int len, const struct perf_pmu *pmu, + const struct perf_pmu_alias *alias) +{ + struct parse_events_term *term; + int used =3D snprintf(buf, len, "%s/%s", pmu->name, alias->name); + + list_for_each_entry(term, &alias->terms, list) { + if (term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_STR) + used +=3D snprintf(buf + used, sub_non_neg(len, used), + ",%s=3D%s", term->config, + term->val.str); } - return false; + + if (sub_non_neg(len, used) > 0) { + buf[used] =3D '/'; + used++; + } + if (sub_non_neg(len, used) > 0) { + buf[used] =3D '\0'; + used++; + } else + buf[len - 1] =3D '\0'; + + return buf; +} + +int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_= event_callback cb) +{ + char buf[1024]; + struct perf_pmu_alias *event; + struct pmu_event_info info =3D { + .pmu =3D pmu, + }; + int ret =3D 0; + + list_for_each_entry(event, &pmu->aliases, list) { + size_t buf_used; + + info.pmu_name =3D event->pmu_name ?: pmu->name; + info.alias =3D NULL; + if (event->desc) { + info.name =3D event->name; + buf_used =3D 0; + } else { + info.name =3D format_alias(buf, sizeof(buf), pmu, event); + if (pmu->is_core) { + info.alias =3D info.name; + info.name =3D event->name; + } + buf_used =3D strlen(buf) + 1; + } + info.scale_unit =3D NULL; + if (strlen(event->unit) || event->scale !=3D 1.0) { + info.scale_unit =3D buf + buf_used; + buf_used +=3D snprintf(buf + buf_used, sizeof(buf) - buf_used, + "%G%s", event->scale, event->unit) + 1; + } + info.desc =3D event->desc; + info.long_desc =3D event->long_desc; + info.encoding_desc =3D buf + buf_used; + buf_used +=3D snprintf(buf + buf_used, sizeof(buf) - buf_used, + "%s/%s/", info.pmu_name, event->str) + 1; + info.topic =3D event->topic; + info.str =3D event->str; + info.deprecated =3D event->deprecated; + ret =3D cb(state, &info); + if (ret) + return ret; + } + if (pmu->selectable) { + info.name =3D buf; + snprintf(buf, sizeof(buf), "%s//", pmu->name); + info.alias =3D NULL; + info.scale_unit =3D NULL; + info.desc =3D NULL; + info.long_desc =3D NULL; + info.encoding_desc =3D NULL; + info.topic =3D NULL; + info.pmu_name =3D pmu->name; + info.deprecated =3D false; + ret =3D cb(state, &info); + } + return ret; } =20 bool perf_pmu__is_software(const struct perf_pmu *pmu) diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 675c9b97f7bf..f37e3d75094f 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -158,61 +158,22 @@ struct perf_pmu_info { bool snapshot; }; =20 -#define UNIT_MAX_LEN 31 /* max length for event unit name */ - -/** - * struct perf_pmu_alias - An event either read from sysfs or builtin in - * pmu-events.c, created by parsing the pmu-events json files. - */ -struct perf_pmu_alias { - /** @name: Name of the event like "mem-loads". */ - char *name; - /** @desc: Optional short description of the event. */ - char *desc; - /** @long_desc: Optional long description. */ - char *long_desc; - /** - * @topic: Optional topic such as cache or pipeline, particularly for - * json events. - */ - char *topic; - /** - * @str: Comma separated parameter list like - * "event=3D0xcd,umask=3D0x1,ldlat=3D0x3". - */ - char *str; - /** @terms: Owned list of the original parsed parameters. */ - struct list_head terms; - /** @list: List element of struct perf_pmu aliases. */ - struct list_head list; - /** @unit: Units for the event, such as bytes or cache lines. */ - char unit[UNIT_MAX_LEN+1]; - /** @scale: Value to scale read counter values by. */ - double scale; - /** - * @per_pkg: Does the file - * /bus/event_source/devices//events/.per-pkg or - * equivalent json value exist and have the value 1. - */ - bool per_pkg; - /** - * @snapshot: Does the file - * /bus/event_source/devices//events/.snapshot - * exist and have the value 1. - */ - bool snapshot; - /** - * @deprecated: Is the event hidden and so not shown in perf list by - * default. - */ +struct pmu_event_info { + const struct perf_pmu *pmu; + const char *name; + const char* alias; + const char *scale_unit; + const char *desc; + const char *long_desc; + const char *encoding_desc; + const char *topic; + const char *pmu_name; + const char *str; bool deprecated; - /** - * @pmu_name: The name copied from the json struct pmu_event. This can - * differ from the PMU name as it won't have suffixes. - */ - char *pmu_name; }; =20 +typedef int (*pmu_event_callback)(void *state, struct pmu_event_info *info= ); + void pmu_add_sys_aliases(struct perf_pmu *pmu); int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms, @@ -225,7 +186,7 @@ __u64 perf_pmu__format_bits(struct perf_pmu *pmu, const= char *name); int perf_pmu__format_type(struct perf_pmu *pmu, const char *name); int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_ter= ms, struct perf_pmu_info *info); -struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu, const ch= ar *event); +int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *st= ate, pmu_event_callback cb); =20 int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_loa= d); void perf_pmu_format__set_value(void *format, int config, unsigned long *b= its); @@ -235,6 +196,9 @@ bool is_pmu_core(const char *name); bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu); bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu); bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name); +size_t perf_pmu__num_events(const struct perf_pmu *pmu); +int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_= event_callback cb); + /** * perf_pmu_is_software - is the PMU a software PMU as in it uses the * perf_sw_context in the kernel? @@ -259,7 +223,6 @@ void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, char *perf_pmu__getcpuid(struct perf_pmu *pmu); const struct pmu_events_table *pmu_events_table__find(void); const struct pmu_metrics_table *pmu_metrics_table__find(void); -void perf_pmu_free_alias(struct perf_pmu_alias *alias); =20 int perf_pmu__convert_scale(const char *scale, char **end, double *sval); =20 diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c index c58ba9fb6a36..4dd5912617ff 100644 --- a/tools/perf/util/pmus.c +++ b/tools/perf/util/pmus.c @@ -258,219 +258,145 @@ int __weak perf_pmus__num_mem_pmus(void) struct sevent { /** PMU for event. */ const struct perf_pmu *pmu; - /** - * Optional event for name, desc, etc. If not present then this is a - * selectable PMU and the event name is shown as "//". - */ - const struct perf_pmu_alias *event; - /** Is the PMU for the CPU? */ - bool is_cpu; + const char *name; + const char* alias; + const char *scale_unit; + const char *desc; + const char *long_desc; + const char *encoding_desc; + const char *topic; + const char *pmu_name; + bool deprecated; }; =20 static int cmp_sevent(const void *a, const void *b) { const struct sevent *as =3D a; const struct sevent *bs =3D b; - const char *a_pmu_name =3D NULL, *b_pmu_name =3D NULL; - const char *a_name =3D "//", *a_desc =3D NULL, *a_topic =3D ""; - const char *b_name =3D "//", *b_desc =3D NULL, *b_topic =3D ""; + bool a_iscpu, b_iscpu; int ret; =20 - if (as->event) { - a_name =3D as->event->name; - a_desc =3D as->event->desc; - a_topic =3D as->event->topic ?: ""; - a_pmu_name =3D as->event->pmu_name; - } - if (bs->event) { - b_name =3D bs->event->name; - b_desc =3D bs->event->desc; - b_topic =3D bs->event->topic ?: ""; - b_pmu_name =3D bs->event->pmu_name; - } /* Put extra events last. */ - if (!!a_desc !=3D !!b_desc) - return !!a_desc - !!b_desc; + if (!!as->desc !=3D !!bs->desc) + return !!as->desc - !!bs->desc; =20 /* Order by topics. */ - ret =3D strcmp(a_topic, b_topic); + ret =3D strcmp(as->topic ?: "", bs->topic ?: ""); if (ret) return ret; =20 /* Order CPU core events to be first */ - if (as->is_cpu !=3D bs->is_cpu) - return as->is_cpu ? -1 : 1; + a_iscpu =3D as->pmu ? as->pmu->is_core : true; + b_iscpu =3D bs->pmu ? bs->pmu->is_core : true; + if (a_iscpu !=3D b_iscpu) + return a_iscpu ? -1 : 1; =20 /* Order by PMU name. */ if (as->pmu !=3D bs->pmu) { - a_pmu_name =3D a_pmu_name ?: (as->pmu->name ?: ""); - b_pmu_name =3D b_pmu_name ?: (bs->pmu->name ?: ""); - ret =3D strcmp(a_pmu_name, b_pmu_name); + ret =3D strcmp(as->pmu_name ?: "", bs->pmu_name ?: ""); if (ret) return ret; } =20 /* Order by event name. */ - return strcmp(a_name, b_name); + return strcmp(as->name, bs->name); } =20 -static bool pmu_alias_is_duplicate(struct sevent *alias_a, - struct sevent *alias_b) +static bool pmu_alias_is_duplicate(struct sevent *a, struct sevent *b) { - const char *a_pmu_name =3D NULL, *b_pmu_name =3D NULL; - const char *a_name =3D "//", *b_name =3D "//"; - - - if (alias_a->event) { - a_name =3D alias_a->event->name; - a_pmu_name =3D alias_a->event->pmu_name; - } - if (alias_b->event) { - b_name =3D alias_b->event->name; - b_pmu_name =3D alias_b->event->pmu_name; - } - /* Different names -> never duplicates */ - if (strcmp(a_name, b_name)) + if (strcmp(a->name ?: "//", b->name ?: "//")) return false; =20 /* Don't remove duplicates for different PMUs */ - a_pmu_name =3D a_pmu_name ?: (alias_a->pmu->name ?: ""); - b_pmu_name =3D b_pmu_name ?: (alias_b->pmu->name ?: ""); - return strcmp(a_pmu_name, b_pmu_name) =3D=3D 0; + return strcmp(a->pmu_name, b->pmu_name) =3D=3D 0; } =20 -static int sub_non_neg(int a, int b) -{ - if (b > a) - return 0; - return a - b; -} +struct events_callback_state { + struct sevent *aliases; + size_t aliases_len; + size_t index; +}; =20 -static char *format_alias(char *buf, int len, const struct perf_pmu *pmu, - const struct perf_pmu_alias *alias) +static int perf_pmus__print_pmu_events__callback(void *vstate, + struct pmu_event_info *info) { - struct parse_events_term *term; - int used =3D snprintf(buf, len, "%s/%s", pmu->name, alias->name); - - list_for_each_entry(term, &alias->terms, list) { - if (term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_STR) - used +=3D snprintf(buf + used, sub_non_neg(len, used), - ",%s=3D%s", term->config, - term->val.str); - } + struct events_callback_state *state =3D vstate; + struct sevent *s; =20 - if (sub_non_neg(len, used) > 0) { - buf[used] =3D '/'; - used++; + if (state->index >=3D state->aliases_len) { + pr_err("Unexpected event %s/%s/\n", info->pmu->name, info->name); + return 1; } - if (sub_non_neg(len, used) > 0) { - buf[used] =3D '\0'; - used++; - } else - buf[len - 1] =3D '\0'; - - return buf; + s =3D &state->aliases[state->index]; + s->pmu =3D info->pmu; +#define COPY_STR(str) s->str =3D info->str ? strdup(info->str) : NULL + COPY_STR(name); + COPY_STR(alias); + COPY_STR(scale_unit); + COPY_STR(desc); + COPY_STR(long_desc); + COPY_STR(encoding_desc); + COPY_STR(topic); + COPY_STR(pmu_name); +#undef COPY_STR + s->deprecated =3D info->deprecated; + state->index++; + return 0; } =20 void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, v= oid *print_state) { struct perf_pmu *pmu; - struct perf_pmu_alias *event; - char buf[1024]; int printed =3D 0; - int len, j; + int len; struct sevent *aliases; + struct events_callback_state state; =20 pmu =3D NULL; len =3D 0; - while ((pmu =3D perf_pmus__scan(pmu)) !=3D NULL) { - list_for_each_entry(event, &pmu->aliases, list) - len++; - if (pmu->selectable) - len++; - } + while ((pmu =3D perf_pmus__scan(pmu)) !=3D NULL) + len +=3D perf_pmu__num_events(pmu); + aliases =3D zalloc(sizeof(struct sevent) * len); if (!aliases) { pr_err("FATAL: not enough memory to print PMU events\n"); return; } pmu =3D NULL; - j =3D 0; + state =3D (struct events_callback_state) { + .aliases =3D aliases, + .aliases_len =3D len, + .index =3D 0, + }; while ((pmu =3D perf_pmus__scan(pmu)) !=3D NULL) { - bool is_cpu =3D pmu->is_core; - - list_for_each_entry(event, &pmu->aliases, list) { - aliases[j].event =3D event; - aliases[j].pmu =3D pmu; - aliases[j].is_cpu =3D is_cpu; - j++; - } - if (pmu->selectable) { - aliases[j].event =3D NULL; - aliases[j].pmu =3D pmu; - aliases[j].is_cpu =3D is_cpu; - j++; - } + perf_pmu__for_each_event(pmu, &state, perf_pmus__print_pmu_events__callb= ack); } - len =3D j; qsort(aliases, len, sizeof(struct sevent), cmp_sevent); - for (j =3D 0; j < len; j++) { - const char *name, *alias =3D NULL, *scale_unit =3D NULL, - *desc =3D NULL, *long_desc =3D NULL, - *encoding_desc =3D NULL, *topic =3D NULL, - *pmu_name =3D NULL; - bool deprecated =3D false; - size_t buf_used; - + for (int j =3D 0; j < len; j++) { /* Skip duplicates */ if (j > 0 && pmu_alias_is_duplicate(&aliases[j], &aliases[j - 1])) continue; =20 - if (!aliases[j].event) { - /* A selectable event. */ - pmu_name =3D aliases[j].pmu->name; - buf_used =3D snprintf(buf, sizeof(buf), "%s//", pmu_name) + 1; - name =3D buf; - } else { - if (aliases[j].event->desc) { - name =3D aliases[j].event->name; - buf_used =3D 0; - } else { - name =3D format_alias(buf, sizeof(buf), aliases[j].pmu, - aliases[j].event); - if (aliases[j].is_cpu) { - alias =3D name; - name =3D aliases[j].event->name; - } - buf_used =3D strlen(buf) + 1; - } - pmu_name =3D aliases[j].event->pmu_name ?: (aliases[j].pmu->name ?: ""); - if (strlen(aliases[j].event->unit) || aliases[j].event->scale !=3D 1.0)= { - scale_unit =3D buf + buf_used; - buf_used +=3D snprintf(buf + buf_used, sizeof(buf) - buf_used, - "%G%s", aliases[j].event->scale, - aliases[j].event->unit) + 1; - } - desc =3D aliases[j].event->desc; - long_desc =3D aliases[j].event->long_desc; - topic =3D aliases[j].event->topic; - encoding_desc =3D buf + buf_used; - buf_used +=3D snprintf(buf + buf_used, sizeof(buf) - buf_used, - "%s/%s/", pmu_name, aliases[j].event->str) + 1; - deprecated =3D aliases[j].event->deprecated; - } print_cb->print_event(print_state, - pmu_name, - topic, - name, - alias, - scale_unit, - deprecated, + aliases[j].pmu_name, + aliases[j].topic, + aliases[j].name, + aliases[j].alias, + aliases[j].scale_unit, + aliases[j].deprecated, "Kernel PMU event", - desc, - long_desc, - encoding_desc); + aliases[j].desc, + aliases[j].long_desc, + aliases[j].encoding_desc); + zfree(&aliases[j].name); + zfree(&aliases[j].alias); + zfree(&aliases[j].scale_unit); + zfree(&aliases[j].desc); + zfree(&aliases[j].long_desc); + zfree(&aliases[j].encoding_desc); + zfree(&aliases[j].topic); + zfree(&aliases[j].pmu_name); } if (printed && pager_in_use()) printf("\n"); --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 9AB9BEE49A6 for ; Thu, 24 Aug 2023 04:14:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240052AbjHXEO3 (ORCPT ); Thu, 24 Aug 2023 00:14:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239885AbjHXENv (ORCPT ); Thu, 24 Aug 2023 00:13:51 -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 7922E10C4 for ; Wed, 23 Aug 2023 21:13:48 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-5925f39aa5cso9861397b3.1 for ; Wed, 23 Aug 2023 21:13:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850427; x=1693455227; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=vidwpQVtDg+nsMorfnSSpTNR26f6Ss+rFWesfZXB9VY=; b=3F1TL04ywJL5vypns2Jb9R29aqSKg/txZdIM6WYWZH/G3mq9fKwJkCbGJpOCHbe9so QnO4BYS/BVa3LIvYPAAhQKBJfhnjfcj6JnplAj4LhdIXj4yZGJRiBpBFaoRYoTfqeC8k ykV6RWwoEY3w13h9g/Kko6jYBRizIHgiUd0G23FLA0IjEYWJFqrx08YPllWcJZ6LxsKn 88AsVTpg2SC38KwkBEgg4cSGB8g+jSSY0qRuKnuY6cckOVcRDq3GcDi3Uc7pz6qGlz8Q OmsuHFqT4C40Zv3Lnq9HKJwRr/vCvsOrbzjaAw/bDyH1CBqp0ftx2cWCN+ydTWj+u8SX Xk4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850427; x=1693455227; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vidwpQVtDg+nsMorfnSSpTNR26f6Ss+rFWesfZXB9VY=; b=OFHWNONycPRxv2ClUeo4qh/wEi/MH28elZz7CFpCEKj2+68G4TJOWNHi1DWiaj2G8c E9ljMv9JNEhjt0ZpH7xpr2i7/1oMbXbWeA2IBmHqPE5WDeG/t3f2wVmtU4pWJ5OLESJk xZKZSzh+uNhWlwMyvtHwuLI8EzVufPI8a/UTc9uzs5ouzF5dmHm4JJo5Uwi/YwfZXM12 bW/VDqEs4+GWFB1kOtjygTEz7ouIe4Agaa/ojFto5hSg4W3B5XlmzkW8wwThHzy4SqBG T230wjPpMkd187tY8DccMAspPbQD0PCITFXpJJPwnWt/4jJTMf15Rmh+aCdNGUk+P4JK IjMQ== X-Gm-Message-State: AOJu0YxkBq73Ic1is5fXZ3Owg5eNLBcARMUsv98+xk9ZySf2ZOJ+81lX mae21NE6HzSD0/AKRSCvx8XzSjwVLTsZ X-Google-Smtp-Source: AGHT+IEUHfhrPgqscGGuHzM23N1Nfy5/5Gx+u6lVa+IeriqzL3Lxa19wb2x+rlBhrNkd3gZa16UZHE5ZX+VO X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a05:690c:2f87:b0:586:e91a:46c2 with SMTP id ew7-20020a05690c2f8700b00586e91a46c2mr264893ywb.4.1692850427738; Wed, 23 Aug 2023 21:13:47 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:15 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-4-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 03/18] perf pmu-events: Add extra underscore to function names From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add extra underscore before "for" of pmu_events_table_for_each_event and pmu_metrics_table_for_each_metric. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 10 +++++----- tools/perf/pmu-events/jevents.py | 12 ++++++------ tools/perf/pmu-events/pmu-events.h | 4 ++-- tools/perf/tests/pmu-events.c | 4 ++-- tools/perf/util/metricgroup.c | 10 +++++----- tools/perf/util/pmu.c | 2 +- tools/perf/util/s390-sample-raw.c | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index a630c617e879..807f2e55c17c 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -266,7 +266,7 @@ static const struct pmu_sys_events pmu_sys_event_tables= [] =3D { }, }; =20 -int pmu_events_table_for_each_event(const struct pmu_events_table *table, = pmu_event_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->entries[0]; pe->name; pe++) { @@ -278,7 +278,7 @@ int pmu_events_table_for_each_event(const struct pmu_ev= ents_table *table, pmu_ev return 0; } =20 -int pmu_metrics_table_for_each_metric(const struct pmu_metrics_table *tabl= e, pmu_metric_iter_fn fn, +int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data) { for (const struct pmu_metric *pm =3D &table->entries[0]; pm->metric_expr;= pm++) { @@ -371,7 +371,7 @@ const struct pmu_metrics_table *find_core_metrics_table= (const char *arch, const 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->= arch; tables++) { - int ret =3D pmu_events_table_for_each_event(&tables->event_table, fn, da= ta); + int ret =3D pmu_events_table__for_each_event(&tables->event_table, fn, d= ata); =20 if (ret) return ret; @@ -384,7 +384,7 @@ int pmu_for_each_core_metric(pmu_metric_iter_fn fn, voi= d *data) for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; tables->arch; tables++) { - int ret =3D pmu_metrics_table_for_each_metric(&tables->metric_table, fn,= data); + int ret =3D pmu_metrics_table__for_each_metric(&tables->metric_table, fn= , data); =20 if (ret) return ret; @@ -408,7 +408,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 98cccc3fcbbd..aae5334099b1 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -753,7 +753,7 @@ static void decompress_metric(int offset, struct pmu_me= tric *pm) _args.output_file.write('\twhile (*p++);') _args.output_file.write("""} =20 -int pmu_events_table_for_each_event(const struct pmu_events_table *table, +int pmu_events_table__for_each_event(const struct pmu_events_table *table, pmu_event_iter_fn fn, void *data) { @@ -771,7 +771,7 @@ int pmu_events_table_for_each_event(const struct pmu_ev= ents_table *table, return 0; } =20 -int pmu_metrics_table_for_each_metric(const struct pmu_metrics_table *tabl= e, +int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data) { @@ -870,7 +870,7 @@ 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->arch; tables++) { - int ret =3D pmu_events_table_for_each_event(&tables->event= _table, fn, data); + int ret =3D pmu_events_table__for_each_event(&tables->even= t_table, fn, data); =20 if (ret) return ret; @@ -883,7 +883,7 @@ int pmu_for_each_core_metric(pmu_metric_iter_fn fn, voi= d *data) for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; tables->arch; tables++) { - int ret =3D pmu_metrics_table_for_each_metric(&tables->met= ric_table, fn, data); + int ret =3D pmu_metrics_table__for_each_metric(&tables->me= tric_table, fn, data); =20 if (ret) return ret; @@ -907,7 +907,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->event= _table, fn, data); + int ret =3D pmu_events_table__for_each_event(&tables->even= t_table, fn, data); =20 if (ret) return ret; @@ -920,7 +920,7 @@ int pmu_for_each_sys_metric(pmu_metric_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_metrics_table_for_each_metric(&tables->met= ric_table, fn, data); + int ret =3D pmu_metrics_table__for_each_metric(&tables->me= tric_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 caf59f23cd64..6557381b7de1 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -77,9 +77,9 @@ typedef int (*pmu_metric_iter_fn)(const struct pmu_metric= *pm, const struct pmu_metrics_table *table, void *data); =20 -int pmu_events_table_for_each_event(const struct pmu_events_table *table, = pmu_event_iter_fn fn, +int pmu_events_table__for_each_event(const struct pmu_events_table *table,= pmu_event_iter_fn fn, void *data); -int pmu_metrics_table_for_each_metric(const struct pmu_metrics_table *tabl= e, pmu_metric_iter_fn fn, +int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data); =20 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu= *pmu); diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index dc87e66fb118..5f541eadc088 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -477,12 +477,12 @@ static int test__pmu_event_table(struct test_suite *t= est __maybe_unused, if (!table || !sys_event_table) return -1; =20 - err =3D pmu_events_table_for_each_event(table, test__pmu_event_table_core= _callback, + err =3D pmu_events_table__for_each_event(table, test__pmu_event_table_cor= e_callback, &map_events); if (err) return err; =20 - err =3D pmu_events_table_for_each_event(sys_event_table, test__pmu_event_= table_sys_callback, + err =3D pmu_events_table__for_each_event(sys_event_table, test__pmu_event= _table_sys_callback, &map_events); if (err) return err; diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index a6a5ed44a679..6231044a491e 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -527,7 +527,7 @@ void metricgroup__print(const struct print_callbacks *p= rint_cb, void *print_stat groups.node_delete =3D mep_delete; table =3D pmu_metrics_table__find(); if (table) { - pmu_metrics_table_for_each_metric(table, + pmu_metrics_table__for_each_metric(table, metricgroup__add_to_mep_groups_callback, &groups); } @@ -1069,7 +1069,7 @@ static bool metricgroup__find_metric(const char *pmu, .pm =3D pm, }; =20 - return pmu_metrics_table_for_each_metric(table, metricgroup__find_metric_= callback, &data) + return pmu_metrics_table__for_each_metric(table, metricgroup__find_metric= _callback, &data) ? true : false; } =20 @@ -1255,7 +1255,7 @@ static int metricgroup__add_metric(const char *pmu, c= onst char *metric_name, con * 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_metrics_table_for_each_metric(table, metricgroup__add_metric= _callback, + ret =3D pmu_metrics_table__for_each_metric(table, metricgroup__add_metri= c_callback, &data); if (ret) goto out; @@ -1740,7 +1740,7 @@ bool metricgroup__has_metric(const char *pmu, const c= har *metric) if (!table) return false; =20 - return pmu_metrics_table_for_each_metric(table, metricgroup__has_metric_c= allback, &data) + return pmu_metrics_table__for_each_metric(table, metricgroup__has_metric_= callback, &data) ? true : false; } =20 @@ -1770,7 +1770,7 @@ unsigned int metricgroups__topdown_max_level(void) if (!table) return false; =20 - pmu_metrics_table_for_each_metric(table, metricgroup__topdown_max_level_c= allback, + pmu_metrics_table__for_each_metric(table, metricgroup__topdown_max_level_= callback, &max_level); return max_level; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 268aaebfa70c..d91367155e29 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -896,7 +896,7 @@ void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, co= nst struct pmu_events_tab .pmu =3D pmu, }; =20 - pmu_events_table_for_each_event(table, pmu_add_cpu_aliases_map_callback, = &data); + pmu_events_table__for_each_event(table, pmu_add_cpu_aliases_map_callback,= &data); free(data.default_pmu_name); } =20 diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index c10b891dbad6..91330c874170 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -168,7 +168,7 @@ static const char *get_counter_name(int set, int nr, co= nst struct pmu_events_tab if (!table) return NULL; =20 - pmu_events_table_for_each_event(table, get_counter_name_callback, &data); + pmu_events_table__for_each_event(table, get_counter_name_callback, &data); return data.result; } =20 --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 BADCFEE49AD for ; Thu, 24 Aug 2023 04:14:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240067AbjHXEOb (ORCPT ); Thu, 24 Aug 2023 00:14:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240032AbjHXEN7 (ORCPT ); Thu, 24 Aug 2023 00:13:59 -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 9F07110F4 for ; Wed, 23 Aug 2023 21:13:51 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-d74a012e6a6so4533007276.2 for ; Wed, 23 Aug 2023 21:13:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850430; x=1693455230; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=C6U9uX7oueEa74oKkTWivvvrk8HCA+9h1GuvSCMbKhg=; b=mzRhGhRyhRNrZvPyG/oRhuDnKjxVCGxq8LGfJECSZx3RBzbVnibDN5e0YSpxUw2Ebu f6yFsxgO46Wwhs5JfvDU82JhitNmedSbpTeHp9JCrUab8MZXL0tp6N515+gHzRZRVfiq jOptpNkF4I6s4CSBmtaQH/FJh3ZYmkE9mLvG/XzjZd5wWzg6G+EkUaDiCMbXHeGIUaNP sYyWJCDiN/LVqiynOhGzeg9m4AKKxMTpl74GKlFw+Cl+S2sZxDbKwzArzS9R10Dnqz3Y vxwsKrc84ped2WiUhP9mpdvC+yK/6BXHu0ZsopBYo6g1vjLc3whkJHrLiO4Hv0Ftvg4F avyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850430; x=1693455230; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=C6U9uX7oueEa74oKkTWivvvrk8HCA+9h1GuvSCMbKhg=; b=B838e4sniL32mWrF0W6A5pIa4Y4mb8VaS3726pF3+noftCXpfesQLasQlwOpS0y1N+ 0AIWVlH11lXeYNof8FsaO9Htxehn6H20JEkumvlRkD8B8ASGz5QzeS74xYO6kiQOA8qz 46A/Axsr6jfaHNTj5TCRNTbm6+NODgTY0XPFCusy+P5qTGY48wf/7qYo1oCxeJ1Mn6Zf sGoAifxFN+2OYBeRvSZROK0OesEhspw8U4/y/qJZ/k45fVzCUxMOZf90SIzEOYX0csrN 5Na/PH2YFrCEQFgNATsI+7IBcRaYwbbju7pJTSKmaDcGSIOX59iriLTsaUiVoIKa9t1n +DcQ== X-Gm-Message-State: AOJu0YxenVv0sbxxd/hPXYdjx0BSH6M2DH006IbmC7XaT6IT3ww3YMhl yw0uWFD8aiu2AGZNAI5hz6YVZS3j6SLB X-Google-Smtp-Source: AGHT+IHh0rxED6moqxzB8ubpfaWdx4CHqSbO6Fo3RDy5r2iK8mTIM+frOshgfv4FslxlT1tgD8AuY9nWpkOy X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a25:9383:0:b0:cfe:74cf:e61a with SMTP id a3-20020a259383000000b00cfe74cfe61amr180121ybm.6.1692850430795; Wed, 23 Aug 2023 21:13:50 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:16 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-5-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 04/18] perf jevents: Group events by PMU From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Prior to this change a cpuid would map to a list of events where the PMU would be encoded alongside the event information. This change breaks apart each group of events so that there is a group per PMU. A new table is added with the PMU's name and the list of events, the original table now holding an array of these per PMU tables. These changes are to make it easier to get per PMU information about events, rather than the current approach of scanning all events. The perf binary size with BPF skeletons on x86 is reduced by about 1%. The unidentified PMU is now always expanded to "cpu". Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 181 +++++++++++++++++++++++-------- tools/perf/tests/pmu-events.c | 30 +++-- 2 files changed, 154 insertions(+), 57 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index aae5334099b1..1ad20140114c 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -42,7 +42,7 @@ _metricgroups =3D {} # Order specific JsonEvent attributes will be visited. _json_event_attributes =3D [ # cmp_sevent related attributes. - 'name', 'pmu', 'topic', 'desc', + 'name', 'topic', 'desc', # Seems useful, put it early. 'event', # Short things in alphabetical order. @@ -53,7 +53,7 @@ _json_event_attributes =3D [ =20 # Attributes that are in pmu_metric rather than pmu_event. _json_metric_attributes =3D [ - 'pmu', 'metric_name', 'metric_group', 'metric_expr', 'metric_threshold= ', + 'metric_name', 'metric_group', 'metric_expr', 'metric_threshold', 'desc', 'long_desc', 'unit', 'compat', 'metricgroup_no_group', 'default_metricgroup_name', 'aggr_mode', 'event_grouping' ] @@ -252,7 +252,7 @@ class JsonEvent: def unit_to_pmu(unit: str) -> Optional[str]: """Convert a JSON Unit to Linux PMU name.""" if not unit: - return None + return 'cpu' # Comment brought over from jevents.c: # it's not realistic to keep adding these, we need something more sc= alable ... table =3D { @@ -343,10 +343,13 @@ class JsonEvent: self.desc +=3D extra_desc if self.long_desc and extra_desc: self.long_desc +=3D extra_desc - if self.pmu: - if self.desc and not self.desc.endswith('. '): - self.desc +=3D '. ' - self.desc =3D (self.desc if self.desc else '') + ('Unit: ' + self.pm= u + ' ') + if self.pmu and self.pmu !=3D 'cpu': + if not self.desc: + self.desc =3D 'Unit: ' + self.pmu + else: + if not self.desc.endswith('. '): + self.desc +=3D '. ' + self.desc +=3D 'Unit: ' + self.pmu if arch_std: if arch_std.lower() in _arch_std_events: event =3D _arch_std_events[arch_std.lower()].event @@ -437,13 +440,13 @@ def add_events_table_entries(item: os.DirEntry, topic= : str) -> None: def print_pending_events() -> None: """Optionally close events table.""" =20 - def event_cmp_key(j: JsonEvent) -> Tuple[bool, str, str, str, str]: + def event_cmp_key(j: JsonEvent) -> Tuple[str, str, bool, str, str]: def fix_none(s: Optional[str]) -> str: if s is None: return '' return s =20 - return (j.desc is not None, fix_none(j.topic), fix_none(j.name), fix_n= one(j.pmu), + return (fix_none(j.pmu).replace(',','_'), fix_none(j.name), j.desc is = not None, fix_none(j.topic), fix_none(j.metric_name)) =20 global _pending_events @@ -458,13 +461,36 @@ def print_pending_events() -> None: global event_tables _event_tables.append(_pending_events_tblname) =20 - _args.output_file.write( - f'static const struct compact_pmu_event {_pending_events_tblname}[] = =3D {{\n') - + first =3D True + last_pmu =3D None + pmus =3D set() for event in sorted(_pending_events, key=3Devent_cmp_key): + if event.pmu !=3D last_pmu: + if not first: + _args.output_file.write('};\n') + pmu_name =3D event.pmu.replace(',', '_') + _args.output_file.write( + f'static const struct compact_pmu_event {_pending_events_tblname= }_{pmu_name}[] =3D {{\n') + first =3D False + last_pmu =3D event.pmu + pmus.add((event.pmu, pmu_name)) + _args.output_file.write(event.to_c_string(metric=3DFalse)) _pending_events =3D [] =20 + _args.output_file.write(f""" +}}; + +const struct pmu_table_entry {_pending_events_tblname}[] =3D {{ +""") + for (pmu, tbl_pmu) in sorted(pmus): + pmu_name =3D f"{pmu}\\000" + _args.output_file.write(f"""{{ + .entries =3D {_pending_events_tblname}_{tbl_pmu}, + .num_entries =3D ARRAY_SIZE({_pending_events_tblname}_{tbl_pmu}), + .pmu_name =3D {{ {_bcs.offsets[pmu_name]} /* {pmu_name} */ }}, +}}, +""") _args.output_file.write('};\n\n') =20 def print_pending_metrics() -> None: @@ -490,13 +516,36 @@ def print_pending_metrics() -> None: global metric_tables _metric_tables.append(_pending_metrics_tblname) =20 - _args.output_file.write( - f'static const struct compact_pmu_event {_pending_metrics_tblname}[]= =3D {{\n') - + first =3D True + last_pmu =3D None + pmus =3D set() for metric in sorted(_pending_metrics, key=3Dmetric_cmp_key): + if metric.pmu !=3D last_pmu: + if not first: + _args.output_file.write('};\n') + pmu_name =3D metric.pmu.replace(',', '_') + _args.output_file.write( + f'static const struct compact_pmu_event {_pending_metrics_tblnam= e}_{pmu_name}[] =3D {{\n') + first =3D False + last_pmu =3D metric.pmu + pmus.add((metric.pmu, pmu_name)) + _args.output_file.write(metric.to_c_string(metric=3DTrue)) _pending_metrics =3D [] =20 + _args.output_file.write(f""" +}}; + +const struct pmu_table_entry {_pending_metrics_tblname}[] =3D {{ +""") + for (pmu, tbl_pmu) in sorted(pmus): + pmu_name =3D f"{pmu}\\000" + _args.output_file.write(f"""{{ + .entries =3D {_pending_metrics_tblname}_{tbl_pmu}, + .num_entries =3D ARRAY_SIZE({_pending_metrics_tblname}_{tbl_pmu}), + .pmu_name =3D {{ {_bcs.offsets[pmu_name]} /* {pmu_name} */ }}, +}}, +""") _args.output_file.write('};\n\n') =20 def get_topic(topic: str) -> str: @@ -532,6 +581,8 @@ def preprocess_one_file(parents: Sequence[str], item: o= s.DirEntry) -> None: =20 topic =3D get_topic(item.name) for event in read_json_events(item.path, topic): + pmu_name =3D f"{event.pmu}\\000" + _bcs.add(pmu_name) if event.name: _bcs.add(event.build_c_string(metric=3DFalse)) if event.metric_name: @@ -577,14 +628,14 @@ 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 compact_pmu_event *entries; - size_t length; + const struct pmu_table_entry *pmus; + uint32_t num_pmus; }; =20 /* Struct used to make the PMU metric table implementation opaque to calle= rs. */ struct pmu_metrics_table { - const struct compact_pmu_event *entries; - size_t length; + const struct pmu_table_entry *pmus; + uint32_t num_pmus; }; =20 /* @@ -614,12 +665,12 @@ const struct pmu_events_map pmu_events_map[] =3D { \t.arch =3D "testarch", \t.cpuid =3D "testcpu", \t.event_table =3D { -\t\t.entries =3D pmu_events__test_soc_cpu, -\t\t.length =3D ARRAY_SIZE(pmu_events__test_soc_cpu), +\t\t.pmus =3D pmu_events__test_soc_cpu, +\t\t.num_pmus =3D ARRAY_SIZE(pmu_events__test_soc_cpu), \t}, \t.metric_table =3D { -\t\t.entries =3D pmu_metrics__test_soc_cpu, -\t\t.length =3D ARRAY_SIZE(pmu_metrics__test_soc_cpu), +\t\t.pmus =3D pmu_metrics__test_soc_cpu, +\t\t.num_pmus =3D ARRAY_SIZE(pmu_metrics__test_soc_cpu), \t} }, """) @@ -649,12 +700,12 @@ const struct pmu_events_map pmu_events_map[] =3D { \t.arch =3D "{arch}", \t.cpuid =3D "{cpuid}", \t.event_table =3D {{ -\t\t.entries =3D {event_tblname}, -\t\t.length =3D {event_size} +\t\t.pmus =3D {event_tblname}, +\t\t.num_pmus =3D {event_size} \t}}, \t.metric_table =3D {{ -\t\t.entries =3D {metric_tblname}, -\t\t.length =3D {metric_size} +\t\t.pmus =3D {metric_tblname}, +\t\t.num_pmus =3D {metric_size} \t}} }}, """) @@ -685,15 +736,15 @@ 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.event_table =3D {{ -\t\t\t.entries =3D {tblname}, -\t\t\t.length =3D ARRAY_SIZE({tblname}) +\t\t\t.pmus =3D {tblname}, +\t\t\t.num_pmus =3D ARRAY_SIZE({tblname}) \t\t}},""") metric_tblname =3D _sys_event_table_to_metric_table_mapping[tblname] if metric_tblname in _sys_metric_tables: _args.output_file.write(f""" \t\t.metric_table =3D {{ -\t\t\t.entries =3D {metric_tblname}, -\t\t\t.length =3D ARRAY_SIZE({metric_tblname}) +\t\t\t.pmus =3D {metric_tblname}, +\t\t\t.num_pmus =3D ARRAY_SIZE({metric_tblname}) \t\t}},""") printed_metric_tables.append(metric_tblname) _args.output_file.write(f""" @@ -753,18 +804,56 @@ static void decompress_metric(int offset, struct pmu_= metric *pm) _args.output_file.write('\twhile (*p++);') _args.output_file.write("""} =20 +static int pmu_events_table__for_each_event_pmu(const struct pmu_events_ta= ble *table, + const struct pmu_table_ent= ry *pmu, + pmu_event_iter_fn fn, + void *data) +{ + int ret; + struct pmu_event pe =3D { + .pmu =3D &big_c_string[pmu->pmu_name.offset], + }; + + for (uint32_t i =3D 0; i < pmu->num_entries; i++) { + decompress_event(pmu->entries[i].offset, &pe); + if (!pe.name) + continue; + ret =3D fn(&pe, table, data); + if (ret) + return ret; + } + return 0; + } + int pmu_events_table__for_each_event(const struct pmu_events_table *table, pmu_event_iter_fn fn, void *data) { - for (size_t i =3D 0; i < table->length; i++) { - struct pmu_event pe; - int ret; + for (size_t i =3D 0; i < table->num_pmus; i++) { + int ret =3D pmu_events_table__for_each_event_pmu(table, &t= able->pmus[i], + fn, data); =20 - decompress_event(table->entries[i].offset, &pe); - if (!pe.name) + if (ret) + return ret; + } + return 0; +} + +static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics= _table *table, + const struct pmu_table_ent= ry *pmu, + pmu_metric_iter_fn fn, + void *data) +{ + int ret; + struct pmu_metric pm =3D { + .pmu =3D &big_c_string[pmu->pmu_name.offset], + }; + + for (uint32_t i =3D 0; i < pmu->num_entries; i++) { + decompress_metric(pmu->entries[i].offset, &pm); + if (!pm.metric_expr) continue; - ret =3D fn(&pe, table, data); + ret =3D fn(&pm, table, data); if (ret) return ret; } @@ -775,14 +864,10 @@ int pmu_metrics_table__for_each_metric(const struct p= mu_metrics_table *table, pmu_metric_iter_fn fn, void *data) { - for (size_t i =3D 0; i < table->length; i++) { - struct pmu_metric pm; - int ret; + for (size_t i =3D 0; i < table->num_pmus; i++) { + int ret =3D pmu_metrics_table__for_each_metric_pmu(table, = &table->pmus[i], + fn, data); =20 - decompress_metric(table->entries[i].offset, &pm); - if (!pm.metric_expr) - continue; - ret =3D fn(&pm, table, data); if (ret) return ret; } @@ -1010,7 +1095,13 @@ such as "arm/cortex-a34".''', #include =20 struct compact_pmu_event { - int offset; + int offset; +}; + +struct pmu_table_entry { + const struct compact_pmu_event *entries; + uint32_t num_entries; + struct compact_pmu_event pmu_name; }; =20 """) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 5f541eadc088..0b6efabc3d20 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -44,6 +44,7 @@ struct perf_pmu_test_pmu { =20 static const struct perf_pmu_test_event bp_l1_btb_correct =3D { .event =3D { + .pmu =3D "cpu", .name =3D "bp_l1_btb_correct", .event =3D "event=3D0x8a", .desc =3D "L1 BTB Correction", @@ -55,6 +56,7 @@ static const struct perf_pmu_test_event bp_l1_btb_correct= =3D { =20 static const struct perf_pmu_test_event bp_l2_btb_correct =3D { .event =3D { + .pmu =3D "cpu", .name =3D "bp_l2_btb_correct", .event =3D "event=3D0x8b", .desc =3D "L2 BTB Correction", @@ -66,6 +68,7 @@ static const struct perf_pmu_test_event bp_l2_btb_correct= =3D { =20 static const struct perf_pmu_test_event segment_reg_loads_any =3D { .event =3D { + .pmu =3D "cpu", .name =3D "segment_reg_loads.any", .event =3D "event=3D0x6,period=3D200000,umask=3D0x80", .desc =3D "Number of segment register loads", @@ -77,6 +80,7 @@ static const struct perf_pmu_test_event segment_reg_loads= _any =3D { =20 static const struct perf_pmu_test_event dispatch_blocked_any =3D { .event =3D { + .pmu =3D "cpu", .name =3D "dispatch_blocked.any", .event =3D "event=3D0x9,period=3D200000,umask=3D0x20", .desc =3D "Memory cluster signals to block micro-op dispatch for any rea= son", @@ -88,6 +92,7 @@ static const struct perf_pmu_test_event dispatch_blocked_= any =3D { =20 static const struct perf_pmu_test_event eist_trans =3D { .event =3D { + .pmu =3D "cpu", .name =3D "eist_trans", .event =3D "event=3D0x3a,period=3D200000,umask=3D0x0", .desc =3D "Number of Enhanced Intel SpeedStep(R) Technology (EIST) trans= itions", @@ -99,6 +104,7 @@ static const struct perf_pmu_test_event eist_trans =3D { =20 static const struct perf_pmu_test_event l3_cache_rd =3D { .event =3D { + .pmu =3D "cpu", .name =3D "l3_cache_rd", .event =3D "event=3D0x40", .desc =3D "L3 cache access, read", @@ -123,7 +129,7 @@ static const struct perf_pmu_test_event uncore_hisi_ddr= c_flux_wcmd =3D { .event =3D { .name =3D "uncore_hisi_ddrc.flux_wcmd", .event =3D "event=3D0x2", - .desc =3D "DDRC write commands. Unit: hisi_sccl,ddrc ", + .desc =3D "DDRC write commands. Unit: hisi_sccl,ddrc", .topic =3D "uncore", .long_desc =3D "DDRC write commands", .pmu =3D "hisi_sccl,ddrc", @@ -137,7 +143,7 @@ static const struct perf_pmu_test_event unc_cbo_xsnp_re= sponse_miss_eviction =3D { .event =3D { .name =3D "unc_cbo_xsnp_response.miss_eviction", .event =3D "event=3D0x22,umask=3D0x81", - .desc =3D "A cross-core snoop resulted from L3 Eviction which misses in = some processor core. Unit: uncore_cbox ", + .desc =3D "A cross-core snoop resulted from L3 Eviction which misses in = some processor core. Unit: uncore_cbox", .topic =3D "uncore", .long_desc =3D "A cross-core snoop resulted from L3 Eviction which misse= s in some processor core", .pmu =3D "uncore_cbox", @@ -151,7 +157,7 @@ static const struct perf_pmu_test_event uncore_hyphen = =3D { .event =3D { .name =3D "event-hyphen", .event =3D "event=3D0xe0,umask=3D0x00", - .desc =3D "UNC_CBO_HYPHEN. Unit: uncore_cbox ", + .desc =3D "UNC_CBO_HYPHEN. Unit: uncore_cbox", .topic =3D "uncore", .long_desc =3D "UNC_CBO_HYPHEN", .pmu =3D "uncore_cbox", @@ -165,7 +171,7 @@ static const struct perf_pmu_test_event uncore_two_hyph= =3D { .event =3D { .name =3D "event-two-hyph", .event =3D "event=3D0xc0,umask=3D0x00", - .desc =3D "UNC_CBO_TWO_HYPH. Unit: uncore_cbox ", + .desc =3D "UNC_CBO_TWO_HYPH. Unit: uncore_cbox", .topic =3D "uncore", .long_desc =3D "UNC_CBO_TWO_HYPH", .pmu =3D "uncore_cbox", @@ -179,7 +185,7 @@ static const struct perf_pmu_test_event uncore_hisi_l3c= _rd_hit_cpipe =3D { .event =3D { .name =3D "uncore_hisi_l3c.rd_hit_cpipe", .event =3D "event=3D0x7", - .desc =3D "Total read hits. Unit: hisi_sccl,l3c ", + .desc =3D "Total read hits. Unit: hisi_sccl,l3c", .topic =3D "uncore", .long_desc =3D "Total read hits", .pmu =3D "hisi_sccl,l3c", @@ -193,7 +199,7 @@ static const struct perf_pmu_test_event uncore_imc_free= _running_cache_miss =3D { .event =3D { .name =3D "uncore_imc_free_running.cache_miss", .event =3D "event=3D0x12", - .desc =3D "Total cache misses. Unit: uncore_imc_free_running ", + .desc =3D "Total cache misses. Unit: uncore_imc_free_running", .topic =3D "uncore", .long_desc =3D "Total cache misses", .pmu =3D "uncore_imc_free_running", @@ -207,7 +213,7 @@ static const struct perf_pmu_test_event uncore_imc_cach= e_hits =3D { .event =3D { .name =3D "uncore_imc.cache_hits", .event =3D "event=3D0x34", - .desc =3D "Total cache hits. Unit: uncore_imc ", + .desc =3D "Total cache hits. Unit: uncore_imc", .topic =3D "uncore", .long_desc =3D "Total cache hits", .pmu =3D "uncore_imc", @@ -232,13 +238,13 @@ static const struct perf_pmu_test_event sys_ddr_pmu_w= rite_cycles =3D { .event =3D { .name =3D "sys_ddr_pmu.write_cycles", .event =3D "event=3D0x2b", - .desc =3D "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", + .desc =3D "ddr write-cycles event. Unit: uncore_sys_ddr_pmu", .topic =3D "uncore", .pmu =3D "uncore_sys_ddr_pmu", .compat =3D "v8", }, .alias_str =3D "event=3D0x2b", - .alias_long_desc =3D "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", + .alias_long_desc =3D "ddr write-cycles event. Unit: uncore_sys_ddr_pmu", .matching_pmu =3D "uncore_sys_ddr_pmu", }; =20 @@ -246,13 +252,13 @@ static const struct perf_pmu_test_event sys_ccn_pmu_r= ead_cycles =3D { .event =3D { .name =3D "sys_ccn_pmu.read_cycles", .event =3D "config=3D0x2c", - .desc =3D "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ", + .desc =3D "ccn read-cycles event. Unit: uncore_sys_ccn_pmu", .topic =3D "uncore", .pmu =3D "uncore_sys_ccn_pmu", .compat =3D "0x01", }, .alias_str =3D "config=3D0x2c", - .alias_long_desc =3D "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ", + .alias_long_desc =3D "ccn read-cycles event. Unit: uncore_sys_ccn_pmu", .matching_pmu =3D "uncore_sys_ccn_pmu", }; =20 @@ -403,7 +409,7 @@ static int test__pmu_event_table_core_callback(const st= ruct pmu_event *pe, struct perf_pmu_test_event const **test_event_table; bool found =3D false; =20 - if (pe->pmu) + if (strcmp(pe->pmu, "cpu")) test_event_table =3D &uncore_events[0]; else test_event_table =3D &core_events[0]; --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 EC175EE49B3 for ; Thu, 24 Aug 2023 04:14:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239073AbjHXEOh (ORCPT ); Thu, 24 Aug 2023 00:14:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240059AbjHXEOD (ORCPT ); Thu, 24 Aug 2023 00:14:03 -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 545441709 for ; Wed, 23 Aug 2023 21:13:54 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-58daaa2ba65so81977167b3.1 for ; Wed, 23 Aug 2023 21:13:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850433; x=1693455233; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=Ya/35txba4PAMPm8mMBnt/qSzsiHQTJEwaXtI6KarCw=; b=3VJfTM8kygD1T1PhmetM3PcBE1gQOcO3+ThUAN3fhGzT28M9PgychNxNpP8peY3l/g k9+S2Se3TL+up6K3bfFmxk1xOnuF1cgcM2yIFbQvyrLPjU8Ft0xRNjCskCm0lsM288DD ACZrScqJDpli5CCdWIHkT1NdEb/pj6wefraP7EBz5lTS3s24jmfIAGCARmB6Q1uYIL2J deXcbqUmoSWMIDh83MmYyXKLdpouS5M2bMGZqtEIRfHnfE6+mhzycoAS7dAA1WCN9LkB Tsrb5E1MJTU1BKSMcQuOyF7txVS9AK2kogzSobXJyFlhzxLCuQbeP4sJpc758bYbmEt0 A6Vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850433; x=1693455233; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ya/35txba4PAMPm8mMBnt/qSzsiHQTJEwaXtI6KarCw=; b=DFVwrl580P4IVSsLm8Fq0ZiY26lmRg7UsLiThRIEgl5L/Fax686w3f8Q5Wq6yEbLxf jLGuh9jW42dtvj0TIKsBxLX9oJFlIyx7ZITI/n3P7IJxfoRXWiSrLa72IMerKU48RYEz DBzVflEuHam09uI15rbTeUh4UBlRD4H5qTiMg4JW9ZjckIEmOTWDX9IeePqqIspufkOl jyr6gtElTlhwO4yXP+7S6ibJ6ZWFb6vMG06oQgLW4jNRG+5lfhv6o1iCcV8tXIp9fX1m JvcrGleWdRMnTown44U2ZLQOEnOO2W+yKoSzEM0p7Vxi6LifO7Hc1IkRuFLX68yHpznY JksQ== X-Gm-Message-State: AOJu0YwPvAaZH3nCCs7bt0zFGlKC6nMX7Ag2CQEHZ0eSYAdcybbRYlER yH0uLQLmRbYtLzSWPut+hXlUis3dhmYB X-Google-Smtp-Source: AGHT+IE7hk7aF5+o9K3xOuDaJwbkY2h6VIkgNVR7fuUCCjnbEaQYcnKDvLAmGG0IIa2nrQLjSHBXq2VjRk1S X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a81:ad43:0:b0:576:af04:3495 with SMTP id l3-20020a81ad43000000b00576af043495mr201866ywk.9.1692850433482; Wed, 23 Aug 2023 21:13:53 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:17 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-6-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 05/18] perf parse-events: Improve error message for double setting From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Double setting information for an event would produce an error message associated with the PMU rather than the term that was double setting. Improve the error message to be on the term. Before: ``` $ perf stat -e 'cpu/inst_retired.any,inst_retired.any/' true event syntax error: 'cpu/inst_retired.any,inst_retired.any/' \___ Bad event or PMU Unabled to find PMU or event on a PMU of 'cpu' Run 'perf list' for a list of valid events ``` After: ``` $ perf stat -e 'cpu/inst_retired.any,inst_retired.any/' true event syntax error: '..etired.any,inst_retired.any/' \___ Bad event or PMU Unabled to find PMU or event on a PMU of 'cpu' Initial error: event syntax error: '..etired.any,inst_retired.any/' \___ Attempt to set event's scale twice Run 'perf list' for a list of valid events ``` Signed-off-by: Ian Rogers --- tools/perf/util/parse-events.c | 2 +- tools/perf/util/pmu.c | 34 +++++++++++++++++++++++++++------- tools/perf/util/pmu.h | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 7cad82a9f578..781747bedc3e 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1348,7 +1348,7 @@ int parse_events_add_pmu(struct parse_events_state *p= arse_state, return evsel ? 0 : -ENOMEM; } =20 - if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &in= fo)) + if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &in= fo, err)) return -EINVAL; =20 if (verbose > 1) { diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d91367155e29..0c82bbeea7d6 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1443,17 +1443,33 @@ static struct perf_pmu_alias *pmu_find_alias(struct= perf_pmu *pmu, =20 =20 static int check_info_data(struct perf_pmu_alias *alias, - struct perf_pmu_info *info) + struct perf_pmu_info *info, + struct parse_events_error *err, + int column) { /* * Only one term in event definition can * define unit, scale and snapshot, fail * if there's more than one. */ - if ((info->unit && alias->unit[0]) || - (info->scale && alias->scale) || - (info->snapshot && alias->snapshot)) + if (info->unit && alias->unit[0]) { + parse_events_error__handle(err, column, + strdup("Attempt to set event's unit twice"), + NULL); + return -EINVAL; + } + if (info->scale && alias->scale) { + parse_events_error__handle(err, column, + strdup("Attempt to set event's scale twice"), + NULL); + return -EINVAL; + } + if (info->snapshot && alias->snapshot) { + parse_events_error__handle(err, column, + strdup("Attempt to set event snapshot twice"), + NULL); return -EINVAL; + } =20 if (alias->unit[0]) info->unit =3D alias->unit; @@ -1472,7 +1488,7 @@ static int check_info_data(struct perf_pmu_alias *ali= as, * defined for the alias */ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_ter= ms, - struct perf_pmu_info *info) + struct perf_pmu_info *info, struct parse_events_error *err) { struct parse_events_term *term, *h; struct perf_pmu_alias *alias; @@ -1493,10 +1509,14 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, str= uct list_head *head_terms, if (!alias) continue; ret =3D pmu_alias_terms(alias, &term->list); - if (ret) + if (ret) { + parse_events_error__handle(err, term->err_term, + strdup("Failure to duplicate terms"), + NULL); return ret; + } =20 - ret =3D check_info_data(alias, info); + ret =3D check_info_data(alias, info, err, term->err_term); if (ret) return ret; =20 diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index f37e3d75094f..03211de345c1 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -185,7 +185,7 @@ int perf_pmu__config_terms(struct perf_pmu *pmu, __u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name); int perf_pmu__format_type(struct perf_pmu *pmu, const char *name); int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_ter= ms, - struct perf_pmu_info *info); + struct perf_pmu_info *info, struct parse_events_error *err); int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *st= ate, pmu_event_callback cb); =20 int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_loa= d); --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 DB787EE49B0 for ; Thu, 24 Aug 2023 04:14:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240075AbjHXEOe (ORCPT ); Thu, 24 Aug 2023 00:14:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240074AbjHXEOD (ORCPT ); Thu, 24 Aug 2023 00:14:03 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29E0F1713 for ; Wed, 23 Aug 2023 21:13:57 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 41be03b00d2f7-56c4e3441f0so3414752a12.1 for ; Wed, 23 Aug 2023 21:13:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850436; x=1693455236; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=2BhHz8yEC3pLTHC5QxPQtooiXn41z8hQeFyuHW+faxU=; b=5w0PmB8jTlGIO6l6Zpmp5jK22kd9GWITqHQyjbKGRdZcCGdCPsigR34nfN6+4tnhxT dnD95ihtffYI9ukp7ATsglhTrCW5D8ZsgF18W6LExTrBwdv+bVEMNSr+/qgnEeXN4HqN +5X8Kn23Cy2HzlKRGCLSZRN5piWmlS3squ8Px5XB2zrfY2VR8N5xkKlzsALS3kdCwskI 2x8JC6rX28d66hv10ndvlco4pwgDOdoQ7VSGBZloPwMQY4WP5+xCP7EJjZKDc0v79LXS msZSSCyRi5sgS89CaPJTEgW0R95rDfTKPBThDZZ3D9MorJa43JoOKegi1SOdAP2s0+ec xcVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850436; x=1693455236; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2BhHz8yEC3pLTHC5QxPQtooiXn41z8hQeFyuHW+faxU=; b=bHBZpRjnb2pc6FdKJTRbVzUMpP/bGbyKVnWkMl9VWIUlTli14TCyzRV+4MaMvpKBbK EV0V1Likn7L0Qe3yvgFt2x08T/xOJJkF40UCnGkHKCLXaptdA1/Rw9GrzRJqmTfrpHg/ bsImxJaw9Rix0hMG6KqOif7jXfX79sPQOEoaZM2/dkGAYwMvnaIP9hErRoEWvzSoWcGc tqaLPES3QRIXFVufU5j0eLrDTQCiTmrfQNSU/lUJp3gwXRpXbPmR9KZp+ML3ZfP1JmsN um73/ADRhqi76xQNCEEO50sJUB39/A87TasgxKfcgP+Z4rwNkJ6vJ6Oq9mLPuTe9RKsX eLOw== X-Gm-Message-State: AOJu0YzzlPHjDPHbRTAfFVJljMpwjfCXu3BKhuHRAaJNXubVgd1ZX76l yMhoy5WfX2+SMvJThoiBgbAGumMujduW X-Google-Smtp-Source: AGHT+IGUi6LS5pUmuPAExD0diPuK2wX3IZnkRAIaW7HOWdNG1KsUu72YQfpTzNbinwYI8ZlJyOoYKJ1dSiJn X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a65:6a87:0:b0:563:e825:7f3a with SMTP id q7-20020a656a87000000b00563e8257f3amr2463561pgu.11.1692850436670; Wed, 23 Aug 2023 21:13:56 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:18 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-7-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 06/18] perf s390 s390_cpumcfdg_dump: Don't scan all PMUs From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rather than scanning all PMUs for a counter name, scan the PMU associated with the evsel of the sample. This is done to remove a dependence on pmu-events.h. Signed-off-by: Ian Rogers --- tools/perf/util/s390-sample-raw.c | 50 ++++++++++++++++--------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index 91330c874170..dc1ed3e95d4d 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -27,7 +27,7 @@ #include "color.h" #include "sample-raw.h" #include "s390-cpumcf-kernel.h" -#include "pmu-events/pmu-events.h" +#include "util/pmu.h" #include "util/sample.h" =20 static size_t ctrset_size(struct cf_ctrset_entry *set) @@ -132,56 +132,57 @@ static int get_counterset_start(int setnr) =20 struct get_counter_name_data { int wanted; - const char *result; + char *result; }; =20 -static int get_counter_name_callback(const struct pmu_event *evp, - const struct pmu_events_table *table __maybe_unused, - void *vdata) +static int get_counter_name_callback(void *vdata, struct pmu_event_info *i= nfo) { struct get_counter_name_data *data =3D vdata; int rc, event_nr; + const char *event_str; =20 - if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) + if (info->str =3D=3D NULL) return 0; - rc =3D sscanf(evp->event, "event=3D%x", &event_nr); + + event_str =3D strstr(info->str, "event=3D"); + if (!event_str) + return 0; + + rc =3D sscanf(event_str, "event=3D%x", &event_nr); if (rc =3D=3D 1 && event_nr =3D=3D data->wanted) { - data->result =3D evp->name; + data->result =3D strdup(info->name); return 1; /* Terminate the search. */ } return 0; } =20 -/* 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 - * the name of this counter. +/* Scan the PMU and extract the logical name of a counter from the event. = Input + * is the counter set and counter number with in the set. Construct the ev= ent + * number and use this as key. If they match return the name of this count= er. * 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_table *table) +static char *get_counter_name(int set, int nr, struct perf_pmu *pmu) { struct get_counter_name_data data =3D { .wanted =3D get_counterset_start(set) + nr, .result =3D NULL, }; =20 - if (!table) + if (!pmu) return NULL; =20 - pmu_events_table__for_each_event(table, get_counter_name_callback, &data); + perf_pmu__for_each_event(pmu, &data, get_counter_name_callback); return data.result; } =20 -static void s390_cpumcfdg_dump(struct perf_sample *sample) +static void s390_cpumcfdg_dump(struct perf_pmu *pmu, struct perf_sample *s= ample) { size_t i, len =3D sample->raw_size, offset =3D 0; unsigned char *buf =3D sample->raw_data; const char *color =3D PERF_COLOR_BLUE; struct cf_ctrset_entry *cep, ce; - const struct pmu_events_table *table; u64 *p; =20 - table =3D pmu_events_table__find(); while (offset < len) { cep =3D (struct cf_ctrset_entry *)(buf + offset); =20 @@ -199,11 +200,12 @@ static void s390_cpumcfdg_dump(struct perf_sample *sa= mple) 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, table); + char *ev_name =3D get_counter_name(ce.set, i, pmu); =20 color_fprintf(stdout, color, "\tCounter:%03d %s Value:%#018lx\n", i, ev_name ?: "", be64_to_cpu(*p)); + free(ev_name); } offset +=3D ctrset_size(&ce); } @@ -216,14 +218,14 @@ static void s390_cpumcfdg_dump(struct perf_sample *sa= mple) */ void evlist__s390_sample_raw(struct evlist *evlist, union perf_event *even= t, struct perf_sample *sample) { - struct evsel *ev_bc000; + struct evsel *evsel; =20 if (event->header.type !=3D PERF_RECORD_SAMPLE) return; =20 - ev_bc000 =3D evlist__event2evsel(evlist, event); - if (ev_bc000 =3D=3D NULL || - ev_bc000->core.attr.config !=3D PERF_EVENT_CPUM_CF_DIAG) + evsel =3D evlist__event2evsel(evlist, event); + if (evsel =3D=3D NULL || + evsel->core.attr.config !=3D PERF_EVENT_CPUM_CF_DIAG) return; =20 /* Display raw data on screen */ @@ -231,5 +233,5 @@ void evlist__s390_sample_raw(struct evlist *evlist, uni= on perf_event *event, str pr_err("Invalid counter set data encountered\n"); return; } - s390_cpumcfdg_dump(sample); + s390_cpumcfdg_dump(evsel->pmu, sample); } --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 0938BEE49B4 for ; Thu, 24 Aug 2023 04:14:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240220AbjHXEOr (ORCPT ); Thu, 24 Aug 2023 00:14:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240093AbjHXEOD (ORCPT ); Thu, 24 Aug 2023 00:14:03 -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 D098B171F for ; Wed, 23 Aug 2023 21:13:59 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-59204757627so53062907b3.1 for ; Wed, 23 Aug 2023 21:13:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850439; x=1693455239; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=1ZewI3nPpImqbFJqNAvX0ZQHNd9oa0t1rOfrNdK6f64=; b=s6czWNqa6SS0Dx6G/QxxsR/83VjVVuFMvCQY7Qtx2OPqx+fCQ5MTYJ/GHGaxYFuFlx peHgarO4gV3dOEYTL1LwKetnL72ezJIbll3TbQ2zeaWXizmAFpFkqYKLdGYiBJAtvCMg qUF/wIWhnNPDOUxteSx/TH/AuF/AmYCVKMyYj9jHH+YjU1LMpk4qEx4cgjiSDJE+Jr1t +G/Z2l5drDPsDLwS/DlHaRkwy5IFXotVLgXbGm+JF5q3Ub8oUZCQkJS+P93C+zxyczdq TI5XavO62wF+stP1CMkk4lw/38zCGL4/Ydl6h4ZAWA89QtOVfRxQNxLZGifkNzIGmkHA SfyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850439; x=1693455239; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1ZewI3nPpImqbFJqNAvX0ZQHNd9oa0t1rOfrNdK6f64=; b=SsUD7Kt6ViXu+5gvL8s+Jw9tr5T6GdBfE3/5mVMVUimj1wo/MAdmhqQrKl6Y9PnCSS RdLm7dVUk7NkFM9/0MK+zpzaPobgtXGYLBiqCk2OqjmIheC2uehebI8q9SjMuwxkQbRO W0+CNt8aUsEUdDfJe5UfBLeVx1Dq/zMXSMfIF86KRRJkeKyg2otVfvwOT1wnjOhhPV7q h5Leut2SEmU63H6X+leNmiaF4Jlha3SiNRE6AKq/lYpsuXh+GJVyK+x35Xt6updV/+8k mEst7RkSYp6rWvIpBnzKB1wNXhkxr7sPyGVnfzPdENoX23pWt/xynQNPIR448MOzfIhT CJ8w== X-Gm-Message-State: AOJu0Yw2qe2sfDt1UJiym0qmXd7xtSDy6Nyb22HEqHfTDg2dMfiU9sli tIkNqKV+tBwefTcHOFBOGZuQ5NgTgEa6 X-Google-Smtp-Source: AGHT+IEfdGl2oTHV/ZWECik+jy5EjUwahwoDcJYpBY96quefyzLUIaPWFY5kuZB9wop7VGom14iuNFslqqcQ X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a05:6902:290:b0:d48:c04:f256 with SMTP id v16-20020a056902029000b00d480c04f256mr195838ybh.11.1692850438995; Wed, 23 Aug 2023 21:13:58 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:19 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-8-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 07/18] perf pmu-events: Reduce processed events by passing PMU From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Pass the PMU to pmu_events_table__for_each_event so that entries that don't match don't need to be processed by callback. If a NULL PMU is passed then all PMUs are processed. perf bench internals pmu-scan "Average PMU scanning" performance is reduced by about 5% on an Intel tigerlake. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 15 ++++++---- tools/perf/pmu-events/jevents.py | 18 ++++++++---- tools/perf/pmu-events/pmu-events.h | 4 ++- tools/perf/tests/pmu-events.c | 6 ++-- tools/perf/util/pmu.c | 35 +++++++----------------- tools/perf/util/pmu.h | 1 + 6 files changed, 41 insertions(+), 38 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 807f2e55c17c..2d6f748280ac 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -266,12 +266,16 @@ static const struct pmu_sys_events pmu_sys_event_tabl= es[] =3D { }, }; =20 -int pmu_events_table__for_each_event(const struct pmu_events_table *table,= pmu_event_iter_fn fn, - void *data) +int pmu_events_table__for_each_event(const struct pmu_events_table *table,= struct perf_pmu *pmu, + pmu_event_iter_fn fn, void *data) { for (const struct pmu_event *pe =3D &table->entries[0]; pe->name; pe++) { - int ret =3D fn(pe, table, data); + int ret; =20 + if (pmu && !pmu__name_match(pmu, pe->pmu)) + continue; + + ret =3D fn(pe, table, data); if (ret) return ret; } @@ -371,7 +375,8 @@ const struct pmu_metrics_table *find_core_metrics_table= (const char *arch, const 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->= arch; tables++) { - int ret =3D pmu_events_table__for_each_event(&tables->event_table, fn, d= ata); + int ret =3D pmu_events_table__for_each_event(&tables->event_table, + /*pmu=3D*/ NULL, fn, data); =20 if (ret) return ret; @@ -408,7 +413,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, /*pmu=3D*/ = NULL, 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 1ad20140114c..396af53e0e45 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -826,14 +826,20 @@ static int pmu_events_table__for_each_event_pmu(const= struct pmu_events_table *t } =20 int pmu_events_table__for_each_event(const struct pmu_events_table *table, + struct perf_pmu *pmu, pmu_event_iter_fn fn, void *data) { for (size_t i =3D 0; i < table->num_pmus; i++) { - int ret =3D pmu_events_table__for_each_event_pmu(table, &t= able->pmus[i], - fn, data); + const struct pmu_table_entry *table_pmu =3D &table->pmus[i= ]; + const char *pmu_name =3D &big_c_string[table_pmu->pmu_name= .offset]; + int ret; =20 - if (ret) + if (pmu && !pmu__name_match(pmu, pmu_name)) + continue; + + ret =3D pmu_events_table__for_each_event_pmu(table, table_= pmu, fn, data); + if (pmu || ret) return ret; } return 0; @@ -955,7 +961,8 @@ 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->arch; tables++) { - int ret =3D pmu_events_table__for_each_event(&tables->even= t_table, fn, data); + int ret =3D pmu_events_table__for_each_event(&tables->even= t_table, + /*pmu=3D*/ NULL= , fn, data); =20 if (ret) return ret; @@ -992,7 +999,8 @@ 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->even= t_table, fn, data); + int ret =3D pmu_events_table__for_each_event(&tables->even= t_table, + /*pmu=3D*/ NULL= , 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 6557381b7de1..c0303ba42e97 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -77,7 +77,9 @@ typedef int (*pmu_metric_iter_fn)(const struct pmu_metric= *pm, const struct pmu_metrics_table *table, void *data); =20 -int pmu_events_table__for_each_event(const struct pmu_events_table *table,= pmu_event_iter_fn fn, +int pmu_events_table__for_each_event(const struct pmu_events_table *table, + struct perf_pmu *pmu, + pmu_event_iter_fn fn, void *data); int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data); diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 0b6efabc3d20..92d1f6f0e666 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -483,12 +483,14 @@ static int test__pmu_event_table(struct test_suite *t= est __maybe_unused, if (!table || !sys_event_table) return -1; =20 - err =3D pmu_events_table__for_each_event(table, test__pmu_event_table_cor= e_callback, + err =3D pmu_events_table__for_each_event(table, /*pmu=3D*/ NULL, + test__pmu_event_table_core_callback, &map_events); if (err) return err; =20 - err =3D pmu_events_table__for_each_event(sys_event_table, test__pmu_event= _table_sys_callback, + err =3D pmu_events_table__for_each_event(sys_event_table, /*pmu=3D*/ NULL, + test__pmu_event_table_sys_callback, &map_events); if (err) return err; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 0c82bbeea7d6..9ba9ac3d3d96 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -859,28 +859,14 @@ static bool pmu_uncore_alias_match(const char *pmu_na= me, const char *name) return res; } =20 -struct pmu_add_cpu_aliases_map_data { - /* List being added to. */ - struct list_head *head; - /* If a pmu_event lacks a given PMU the default used. */ - char *default_pmu_name; - /* The PMU that we're searching for events for. */ - struct perf_pmu *pmu; -}; - static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe, const struct pmu_events_table *table __maybe_unused, void *vdata) { - struct pmu_add_cpu_aliases_map_data *data =3D vdata; - const char *pname =3D pe->pmu ?: data->default_pmu_name; + struct list_head *head =3D vdata; =20 - if (!strcmp(pname, data->pmu->name) || - (data->pmu->is_uncore && pmu_uncore_alias_match(pname, data->pmu->nam= e))) { - /* need type casts to override 'const' */ - __perf_pmu__new_alias(data->head, -1, (char *)pe->name, (char *)pe->desc, - (char *)pe->event, pe); - } + /* need type casts to override 'const' */ + __perf_pmu__new_alias(head, -1, (char *)pe->name, (char *)pe->desc, (char= *)pe->event, pe); return 0; } =20 @@ -890,14 +876,7 @@ static int pmu_add_cpu_aliases_map_callback(const stru= ct pmu_event *pe, */ void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, const struct pmu_even= ts_table *table) { - struct pmu_add_cpu_aliases_map_data data =3D { - .head =3D &pmu->aliases, - .default_pmu_name =3D perf_pmus__default_pmu_name(), - .pmu =3D pmu, - }; - - pmu_events_table__for_each_event(table, pmu_add_cpu_aliases_map_callback,= &data); - free(data.default_pmu_name); + pmu_events_table__for_each_event(table, pmu, pmu_add_cpu_aliases_map_call= back, &pmu->aliases); } =20 static void pmu_add_cpu_aliases(struct perf_pmu *pmu) @@ -1713,6 +1692,12 @@ int perf_pmu__for_each_event(const struct perf_pmu *= pmu, void *state, pmu_event_ return ret; } =20 +bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name) +{ + return !strcmp(pmu->name, pmu_name) || + (pmu->is_uncore && pmu_uncore_alias_match(pmu_name, pmu->name)); +} + bool perf_pmu__is_software(const struct perf_pmu *pmu) { if (pmu->is_core || pmu->is_uncore || pmu->auxtrace) diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 03211de345c1..2b1730152bc0 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -198,6 +198,7 @@ bool perf_pmu__auto_merge_stats(const struct perf_pmu *= pmu); bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name); size_t perf_pmu__num_events(const struct perf_pmu *pmu); int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_= event_callback cb); +bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name); =20 /** * perf_pmu_is_software - is the PMU a software PMU as in it uses the --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 4C4DAEE49B2 for ; Thu, 24 Aug 2023 04:14:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240227AbjHXEOu (ORCPT ); Thu, 24 Aug 2023 00:14:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45544 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240100AbjHXEOE (ORCPT ); Thu, 24 Aug 2023 00:14:04 -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 0CBC610D3 for ; Wed, 23 Aug 2023 21:14:02 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-58c9d29588aso80596747b3.0 for ; Wed, 23 Aug 2023 21:14:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850441; x=1693455241; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=thiR0red1e/TKgvXPJgbac9qLA8eyvIz0R2RRqFEpHo=; b=KuAatxxaPWqZiaJMcynl0wnH/7QYU2bCodav06EVZFsT0Axs/EhhiuVsYjweEa+qQj 0KSCyPLJ1z1OEANEd8/5Kv/jDgqnewcE4w1XP2PlDR77dzoYcunGuIPXTyQl7Zs2WXMp 4P6n2bGVDCEJh5cHhe4w3jY0M84QmRKsKAIOkuJQQnu1rhfNLP4Tsu6funSNrH4cnwq/ cO6+cPvXvh4wKWWitDD93IGVw3YhO0rHlHtNnVwmOlCFydxkEwqJnQsqPBu/5xR81Pyq 0jnRxi/Z4x9nUjhKAogkCTAXmbbUTfRhAV/09kBLUeOavNThZ02WGmYmssJcHkM/fJkx iNAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850441; x=1693455241; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=thiR0red1e/TKgvXPJgbac9qLA8eyvIz0R2RRqFEpHo=; b=RdtBL46hk2yd4WjsZhTEE3/19d4+WQ4oo8p3pRI+NaicIuoEeTaNJQf4Zus/uSo0Jb NalOouBm9O8ouAk9c+ZHBJUuqjZ2u9RwDlHwimXYWG2Y9caa/ywSzTlXkFKDJJw/WLR4 KOBX34t2u9/zyo0pjjm7oNc3DUUeCYo++4KL92yqE8Dk20GqKxl6v8uJbAySoSMuDUVq OuzowtOGRoIx8s9yyEJY6tGTlXRKwW1T/f8CDDjXlcjTg6kBCsCPGiDd6iVKXZw/xG/7 2OKABV629aUeTOtmKXaaEaFIE3EIYQmQBowghf0pin0EYi7FoDkB5GxDmZkJ0PGwMWMI 9Q3Q== X-Gm-Message-State: AOJu0YxoXeUAhE1hgZ3LsHfDBTE+FNz4N2Fu3bc4mhO5Wv8K/VY1C1Z2 DW54t4zF4hyX7mw5+F6lCv8YfOHcS2Qo X-Google-Smtp-Source: AGHT+IGVieYHWFSwxUoXO0fYTzVaYMdJYQ+4v07AN1lUT7XmCg3GuIl2/WxWo7lrlcojBdPU1J08ek9KwfXc X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a81:af0c:0:b0:589:a997:f9ce with SMTP id n12-20020a81af0c000000b00589a997f9cemr198887ywh.2.1692850441260; Wed, 23 Aug 2023 21:14:01 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:20 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-9-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 08/18] perf pmu-events: Add pmu_events_table__find_event From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" jevents stores events sorted by name. Add a find function that will binary search event names avoiding the need to linearly search through events. Add a test in tests/pmu-events.c. If the PMU or event aren't found -1000 is returned. If the event is found but no callback function given, 0 is returned. This allows the find function also act as a test for existence. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 16 ++++++ tools/perf/pmu-events/jevents.py | 64 ++++++++++++++++++++++++ tools/perf/pmu-events/pmu-events.h | 5 ++ tools/perf/tests/pmu-events.c | 5 ++ 4 files changed, 90 insertions(+) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 2d6f748280ac..ef18d403f25f 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -282,6 +282,22 @@ int pmu_events_table__for_each_event(const struct pmu_= events_table *table, struc return 0; } =20 +int pmu_events_table__find_event(const struct pmu_events_table *table, + struct perf_pmu *pmu, + const char *name, + pmu_event_iter_fn fn, + void *data) +{ + for (const struct pmu_event *pe =3D &table->entries[0]; pe->name; pe++) { + if (pmu && !pmu__name_match(pmu, pe->pmu)) + continue; + + if (!strcasecmp(pe->name, name)) + return fn(pe, table, data); + } + return -1000; +} + int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data) { diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 396af53e0e45..991fcf6cca64 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -825,6 +825,49 @@ static int pmu_events_table__for_each_event_pmu(const = struct pmu_events_table *t return 0; } =20 +static int pmu_events_table__find_event_pmu(const struct pmu_events_table = *table, + const struct pmu_table_entry *= pmu, + const char *name, + pmu_event_iter_fn fn, + void *data) +{ + struct pmu_event pe =3D { + .pmu =3D &big_c_string[pmu->pmu_name.offset], + }; + int low =3D 0, high =3D pmu->num_entries - 1; + + while (low <=3D high) { + int cmp, mid =3D (low + high) / 2; + + decompress_event(pmu->entries[mid].offset, &pe); + + if (!pe.name && !name) + goto do_call; + + if (!pe.name && name) { + low =3D mid + 1; + continue; + } + if (pe.name && !name) { + high =3D mid - 1; + continue; + } + + cmp =3D strcasecmp(pe.name, name); + if (cmp < 0) { + low =3D mid + 1; + continue; + } + if (cmp > 0) { + high =3D mid - 1; + continue; + } + do_call: + return fn ? fn(&pe, table, data) : 0; + } + return -1000; +} + int pmu_events_table__for_each_event(const struct pmu_events_table *table, struct perf_pmu *pmu, pmu_event_iter_fn fn, @@ -845,6 +888,27 @@ int pmu_events_table__for_each_event(const struct pmu_= events_table *table, return 0; } =20 +int pmu_events_table__find_event(const struct pmu_events_table *table, + struct perf_pmu *pmu, + const char *name, + pmu_event_iter_fn fn, + void *data) +{ + for (size_t i =3D 0; i < table->num_pmus; i++) { + const struct pmu_table_entry *table_pmu =3D &table->pmus[i= ]; + const char *pmu_name =3D &big_c_string[table_pmu->pmu_name= .offset]; + int ret; + + if (!pmu__name_match(pmu, pmu_name)) + continue; + + ret =3D pmu_events_table__find_event_pmu(table, table_pmu,= name, fn, data); + if (ret !=3D -1000) + return ret; + } + return -1000; +} + static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics= _table *table, const struct pmu_table_ent= ry *pmu, pmu_metric_iter_fn fn, diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index c0303ba42e97..9882b7125761 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -81,6 +81,11 @@ int pmu_events_table__for_each_event(const struct pmu_ev= ents_table *table, struct perf_pmu *pmu, pmu_event_iter_fn fn, void *data); +int pmu_events_table__find_event(const struct pmu_events_table *table, + struct perf_pmu *pmu, + const char *name, + pmu_event_iter_fn fn, + void *data); int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data); =20 diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 92d1f6f0e666..34f0de182fa9 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -546,6 +546,11 @@ static int __test_core_pmu_event_aliases(char *pmu_nam= e, int *count) =20 pmu_add_cpu_aliases_table(pmu, table); =20 + res =3D pmu_events_table__find_event(table, pmu, "bp_l1_btb_correct", NUL= L, NULL); + if (res !=3D 0) { + pr_debug("Missing test event in test architecture"); + return res; + } for (; *test_event_table; test_event_table++) { struct perf_pmu_test_event test_event =3D **test_event_table; struct pmu_event const *event =3D &test_event.event; --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 064FCC27C40 for ; Thu, 24 Aug 2023 04:15:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239092AbjHXEOy (ORCPT ); Thu, 24 Aug 2023 00:14:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240113AbjHXEOI (ORCPT ); Thu, 24 Aug 2023 00:14:08 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 036CE10F8 for ; Wed, 23 Aug 2023 21:14:04 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id d2e1a72fcca58-68bec4380edso684194b3a.1 for ; Wed, 23 Aug 2023 21:14:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850444; x=1693455244; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ku/PeRxKaif+dkdteyruZlpIYwvGD2n5K2YcrlXrw2Y=; b=tJaB+f3U3NDQihRCgujIS/E+HcUmmfCazkrt8v7cXpvYqp+B/jOtJdaI40vNmv2x1b ESvfh3C+qKP98m4ezaJkauMbTLYfNckoDKPnipiY7yMatx2OIrQhDOBj87YsHICvh36P bejc+Q6+RgvhLNUFWe6IJDAYOXzAzuord4VNne+xfnUcVS9bcriE1FKNQYJQCF4RgFsK YnMXq2kv5dwu2fTZAywoor7KyFkNm/H0KRyCTKH5ja8zj9u6tEFx1WUHEMahK3gLfvBD OKkHfQEv5gByGfKzN5LWxWGFQq7inJ9vaB8G9vDdtya36lK/+yxWZBYQpfWO8YD9xFTU OqEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850444; x=1693455244; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ku/PeRxKaif+dkdteyruZlpIYwvGD2n5K2YcrlXrw2Y=; b=lyMuhrfjSQVR+SZ/1xoBR5CqPP8s+89jt1t3MxtljqCJj1hp/SgUyEfG9SLNGRuJAw i1+JC4rtp2DHSJqjWedb6eb0d5By8L87mltX57JsxxYf0036XF9PhNcXZ1nXdM2mHZ8H 8mBH2zhjiGrXrko9Wvh/efA1g1AHXPs7XOqMjznFWgAx9pxot2rWHZbmyVVy5dheWvuS zKv6xyXxlV0P7Q34SOnfBbGwtVbG4QtXA70MGciBasOh4yI+FJ0heq5FcAE46xN0UZdj GTkRD6FDfgKH6sq+TjV4+R7ysTU0KK98/XUfcoTEJfmeAvOhCVarKW3OlB9PUPl4pfqK OCMw== X-Gm-Message-State: AOJu0Yw0fJrEB0YxCMB2MS59r/t6Ww7GRg+/A2d88MQz9Awsh30Y+0Cq 9pKnv6MKRoiEg187xdXGKP8uWzoySHwD X-Google-Smtp-Source: AGHT+IHOGhZ77r+ppBYQE2gKe2KzEGzY2KEBeQYg80WYkmpW9p1SGvNmvEGaS0gILNjRMxbz55ij0Afi7sAF X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a05:6a00:27ab:b0:68a:5e6f:9975 with SMTP id bd43-20020a056a0027ab00b0068a5e6f9975mr2216084pfb.1.1692850444397; Wed, 23 Aug 2023 21:14:04 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:21 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-10-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 09/18] perf pmu: Parse sysfs events directly from a file From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rather than read a sysfs events file into a 256 byte char buffer, pass the FILE* directly to the lex/yacc parser. This avoids there being a maximum events file size. While changing the API, constify some arguments to remove unnecessary casts. Allocating the read buffer decreases the performance of pmu-scan by around 3%. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/tests/parse-events.c | 2 +- tools/perf/util/parse-events.c | 18 +++++++---- tools/perf/util/parse-events.h | 3 +- tools/perf/util/pmu.c | 48 ++++++++++------------------- 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util= /intel-pt.c index 27944c15ac14..31807791589e 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -74,7 +74,7 @@ static int intel_pt_parse_terms_with_default(struct perf_= pmu *pmu, =20 INIT_LIST_HEAD(terms); =20 - err =3D parse_events_terms(terms, str); + err =3D parse_events_terms(terms, str, /*input=3D*/ NULL); if (err) goto out_free; =20 diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-event= s.c index 658fb9599d95..d86076d575ed 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -2472,7 +2472,7 @@ static int test_term(const struct terms_test *t) =20 INIT_LIST_HEAD(&terms); =20 - ret =3D parse_events_terms(&terms, t->str); + ret =3D parse_events_terms(&terms, t->str, /*input=3D*/ NULL); if (ret) { pr_debug("failed to parse terms '%s', err %d\n", t->str , ret); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 781747bedc3e..c71e135d7335 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1715,6 +1715,7 @@ int parse_events_name(struct list_head *list, const c= har *name) } =20 static int parse_events__scanner(const char *str, + FILE *input, struct parse_events_state *parse_state) { YY_BUFFER_STATE buffer; @@ -1725,7 +1726,10 @@ static int parse_events__scanner(const char *str, if (ret) return ret; =20 - buffer =3D parse_events__scan_string(str, scanner); + if (str) + buffer =3D parse_events__scan_string(str, scanner); + else + parse_events_set_in(input, scanner); =20 #ifdef PARSER_DEBUG parse_events_debug =3D 1; @@ -1733,8 +1737,10 @@ static int parse_events__scanner(const char *str, #endif ret =3D parse_events_parse(parse_state, scanner); =20 - parse_events__flush_buffer(buffer, scanner); - parse_events__delete_buffer(buffer, scanner); + if (str) { + parse_events__flush_buffer(buffer, scanner); + parse_events__delete_buffer(buffer, scanner); + } parse_events_lex_destroy(scanner); return ret; } @@ -1742,7 +1748,7 @@ static int parse_events__scanner(const char *str, /* * parse event config string, return a list of event terms. */ -int parse_events_terms(struct list_head *terms, const char *str) +int parse_events_terms(struct list_head *terms, const char *str, FILE *inp= ut) { struct parse_events_state parse_state =3D { .terms =3D NULL, @@ -1750,7 +1756,7 @@ int parse_events_terms(struct list_head *terms, const= char *str) }; int ret; =20 - ret =3D parse_events__scanner(str, &parse_state); + ret =3D parse_events__scanner(str, input, &parse_state); =20 if (!ret) { list_splice(parse_state.terms, terms); @@ -2001,7 +2007,7 @@ int __parse_events(struct evlist *evlist, const char = *str, const char *pmu_filte }; int ret, ret2; =20 - ret =3D parse_events__scanner(str, &parse_state); + ret =3D parse_events__scanner(str, /*input=3D*/ NULL, &parse_state); =20 if (!ret && list_empty(&parse_state.list)) { WARN_ONCE(true, "WARNING: event parser found nothing\n"); diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 411f69b2ac3a..c7f779420723 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -9,6 +9,7 @@ #include #include #include +#include #include =20 struct evsel; @@ -42,7 +43,7 @@ static inline int parse_events(struct evlist *evlist, con= st char *str, =20 int parse_event(struct evlist *evlist, const char *str); =20 -int parse_events_terms(struct list_head *terms, const char *str); +int parse_events_terms(struct list_head *terms, const char *str, FILE *inp= ut); int parse_filter(const struct option *opt, const char *str, int unset); int exclude_perf(const struct option *opt, const char *arg, int unset); =20 diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 9ba9ac3d3d96..263c63eabc2e 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -280,7 +280,7 @@ int perf_pmu__convert_scale(const char *scale, char **e= nd, double *sval) return ret; } =20 -static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, int dirfd, = char *name) +static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, int dirfd, = const char *name) { struct stat st; ssize_t sret; @@ -312,7 +312,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias = *alias, int dirfd, char * return ret; } =20 -static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, int dirfd, c= har *name) +static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, int dirfd, c= onst char *name) { char path[PATH_MAX]; ssize_t sret; @@ -343,7 +343,7 @@ static int perf_pmu__parse_unit(struct perf_pmu_alias *= alias, int dirfd, char *n } =20 static int -perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, int dirfd, char *nam= e) +perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, int dirfd, const cha= r *name) { char path[PATH_MAX]; int fd; @@ -361,7 +361,7 @@ perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, i= nt dirfd, char *name) } =20 static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, - int dirfd, char *name) + int dirfd, const char *name) { char path[PATH_MAX]; int fd; @@ -454,8 +454,9 @@ static bool perf_pmu_merge_alias(struct perf_pmu_alias = *newalias, return false; } =20 -static int __perf_pmu__new_alias(struct list_head *list, int dirfd, char *= name, - char *desc, char *val, const struct pmu_event *pe) +static int perf_pmu__new_alias(struct list_head *list, int dirfd, const ch= ar *name, + const char *desc, const char *val, FILE *val_fd, + const struct pmu_event *pe) { struct parse_events_term *term; struct perf_pmu_alias *alias; @@ -484,7 +485,7 @@ static int __perf_pmu__new_alias(struct list_head *list= , int dirfd, char *name, alias->snapshot =3D false; alias->deprecated =3D deprecated; =20 - ret =3D parse_events_terms(&alias->terms, val); + ret =3D parse_events_terms(&alias->terms, val, val_fd); if (ret) { pr_err("Cannot parse alias %s: %d\n", val, ret); free(alias); @@ -541,23 +542,6 @@ static int __perf_pmu__new_alias(struct list_head *lis= t, int dirfd, char *name, return 0; } =20 -static int perf_pmu__new_alias(struct list_head *list, int dirfd, char *na= me, FILE *file) -{ - char buf[256]; - int ret; - - ret =3D fread(buf, 1, sizeof(buf), file); - if (ret =3D=3D 0) - return -EINVAL; - - buf[ret] =3D 0; - - /* Remove trailing newline from sysfs file */ - strim(buf); - - return __perf_pmu__new_alias(list, dirfd, name, NULL, buf, NULL); -} - static inline bool pmu_alias_info_file(char *name) { size_t len; @@ -613,7 +597,8 @@ static int pmu_aliases_parse(int dirfd, struct list_hea= d *head) continue; } =20 - if (perf_pmu__new_alias(head, dirfd, name, file) < 0) + if (perf_pmu__new_alias(head, dirfd, name, /*desc=3D*/ NULL, + /*val=3D*/ NULL, file, /*pe=3D*/ NULL) < 0) pr_debug("Cannot set up %s\n", name); fclose(file); } @@ -866,7 +851,7 @@ static int pmu_add_cpu_aliases_map_callback(const struc= t pmu_event *pe, struct list_head *head =3D vdata; =20 /* need type casts to override 'const' */ - __perf_pmu__new_alias(head, -1, (char *)pe->name, (char *)pe->desc, (char= *)pe->event, pe); + perf_pmu__new_alias(head, -1, pe->name, pe->desc, pe->event, /*val_fd=3D*= / NULL, pe); return 0; } =20 @@ -907,11 +892,12 @@ static int pmu_add_sys_aliases_iter_fn(const struct p= mu_event *pe, =20 if (!strcmp(pmu->id, pe->compat) && pmu_uncore_alias_match(pe->pmu, pmu->name)) { - __perf_pmu__new_alias(idata->head, -1, - (char *)pe->name, - (char *)pe->desc, - (char *)pe->event, - pe); + perf_pmu__new_alias(idata->head, -1, + pe->name, + pe->desc, + pe->event, + /*val_fd=3D*/ NULL, + pe); } =20 return 0; --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 79BF1C88CB2 for ; Thu, 24 Aug 2023 04:15:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240088AbjHXEO6 (ORCPT ); Thu, 24 Aug 2023 00:14:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240123AbjHXEOL (ORCPT ); Thu, 24 Aug 2023 00:14:11 -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 2633F10F2 for ; Wed, 23 Aug 2023 21:14:08 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-58ee4df08fbso84050287b3.3 for ; Wed, 23 Aug 2023 21:14:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850447; x=1693455247; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=nozX82LYkob4etjayWOPWotsGY16fgNQEBA5J9h7kqw=; b=7YqvCxcA2mHCu0e1kY99F65qxhuhYLFTf6tAMV9fXOtD74PP2yMEGjmXnfnAuMt6m2 zHrr98CBLi4iexFuOWanfDp2Gbo3mdkbDkJzLgjuw6NF6+2+pHIzyK5mqAXCYNoQEpDh wXCgIXEUgZolWK/Kc9M8atpA/35EJ2FdNym80jUJHKKe/uM1LcKWHf1Kno8psyjOKFww Xj52XFEHU+XZDkFjLl9ngkh6mcNmtnJ/eRvvBVATmfQ7oXrtzpYdUmsQoI0EhJNIjEvD CeAz897WnAMOV5hxFx6Zyu9fmq378N3c1O3JGkTM0sr7VlqTxN0Eu1Fw9zp+2PjdaANd FODA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850447; x=1693455247; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nozX82LYkob4etjayWOPWotsGY16fgNQEBA5J9h7kqw=; b=kg/u4Adzm30LaOEGaPqcn35HkcFYkMYtV3bBW+WYjj3fqp9ingA4ZWqEDMXAwa839q 0pJRdWASTSYeE43kVJRrhMf3XPfCG2T0n4dIX8gxFIt6pmhMjP0D77gfOQWhDIBj+Cd9 8uoITmZKkPlr8q/qNBgqb6txG5/00Om/7exUh6BD9bFFDm5wHqB5jw5Mv3QlyCOBlyE+ di1GhnUpRNVTKCXPJEIwnZi9va5u5Axbz7E7+2lZyR0jvv3J/J0GUAmg+kEL2qD+qugQ PsTtii4ottnlALZZyhzaNnt6MsKWDiap/FKct6/kBV9M/LU0VE528iEeOjxU+YjtfXrY enFg== X-Gm-Message-State: AOJu0YyriLATsELHbOCPV3DTnyDJ807jK0w9gEvnMiGgkmR1pbmlfzei QfoTzN/tFLhetZrfQqR9chL7lE2pr0Bt X-Google-Smtp-Source: AGHT+IGRkvANlsRtSIEn7dTLGDtKZtdJDNqrEV9GAp9+8SMGYu/k1HMMD9hBeJRKxtOIvVrn3ITDSzM962GP X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a25:41c1:0:b0:d45:daf4:1fc5 with SMTP id o184-20020a2541c1000000b00d45daf41fc5mr186638yba.3.1692850447358; Wed, 23 Aug 2023 21:14:07 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:22 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-11-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 10/18] perf pmu: Prefer passing pmu to aliases list From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org 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 aliases list is part of the PMU. Rather than pass the aliases list, pass the full PMU simplifying some callbacks. Signed-off-by: Ian Rogers --- tools/perf/util/pmu.c | 44 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 263c63eabc2e..c37d98a11861 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -435,12 +435,12 @@ static void perf_pmu__del_aliases(struct perf_pmu *pm= u) /* Merge an alias, search in alias list. If this name is already * present merge both of them to combine all information. */ -static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias, - struct list_head *alist) +static bool perf_pmu_merge_alias(struct perf_pmu *pmu, + struct perf_pmu_alias *newalias) { struct perf_pmu_alias *a; =20 - list_for_each_entry(a, alist, list) { + list_for_each_entry(a, &pmu->aliases, list) { if (!strcasecmp(newalias->name, a->name)) { if (newalias->pmu_name && a->pmu_name && !strcasecmp(newalias->pmu_name, a->pmu_name)) { @@ -454,7 +454,7 @@ static bool perf_pmu_merge_alias(struct perf_pmu_alias = *newalias, return false; } =20 -static int perf_pmu__new_alias(struct list_head *list, int dirfd, const ch= ar *name, +static int perf_pmu__new_alias(struct perf_pmu *pmu, int dirfd, const char= *name, const char *desc, const char *val, FILE *val_fd, const struct pmu_event *pe) { @@ -536,8 +536,8 @@ static int perf_pmu__new_alias(struct list_head *list, = int dirfd, const char *na alias->str =3D strdup(newval); alias->pmu_name =3D pmu_name ? strdup(pmu_name) : NULL; =20 - if (!perf_pmu_merge_alias(alias, list)) - list_add_tail(&alias->list, list); + if (!perf_pmu_merge_alias(pmu, alias)) + list_add_tail(&alias->list, &pmu->aliases); =20 return 0; } @@ -563,7 +563,7 @@ static inline bool pmu_alias_info_file(char *name) * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. */ -static int pmu_aliases_parse(int dirfd, struct list_head *head) +static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd) { struct dirent *evt_ent; DIR *event_dir; @@ -597,7 +597,7 @@ static int pmu_aliases_parse(int dirfd, struct list_hea= d *head) continue; } =20 - if (perf_pmu__new_alias(head, dirfd, name, /*desc=3D*/ NULL, + if (perf_pmu__new_alias(pmu, dirfd, name, /*desc=3D*/ NULL, /*val=3D*/ NULL, file, /*pe=3D*/ NULL) < 0) pr_debug("Cannot set up %s\n", name); fclose(file); @@ -620,7 +620,7 @@ static int pmu_aliases(struct perf_pmu *pmu, int dirfd,= const char *name) return 0; =20 /* it'll close the fd */ - if (pmu_aliases_parse(fd, &pmu->aliases)) + if (pmu_aliases_parse(pmu, fd)) return -1; =20 return 0; @@ -848,10 +848,9 @@ static int pmu_add_cpu_aliases_map_callback(const stru= ct pmu_event *pe, const struct pmu_events_table *table __maybe_unused, void *vdata) { - struct list_head *head =3D vdata; + struct perf_pmu *pmu =3D vdata; =20 - /* need type casts to override 'const' */ - perf_pmu__new_alias(head, -1, pe->name, pe->desc, pe->event, /*val_fd=3D*= / NULL, pe); + perf_pmu__new_alias(pmu, -1, pe->name, pe->desc, pe->event, /*val_fd=3D*/= NULL, pe); return 0; } =20 @@ -861,7 +860,7 @@ static int pmu_add_cpu_aliases_map_callback(const struc= t pmu_event *pe, */ void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, const struct pmu_even= ts_table *table) { - pmu_events_table__for_each_event(table, pmu, pmu_add_cpu_aliases_map_call= back, &pmu->aliases); + pmu_events_table__for_each_event(table, pmu, pmu_add_cpu_aliases_map_call= back, pmu); } =20 static void pmu_add_cpu_aliases(struct perf_pmu *pmu) @@ -875,24 +874,18 @@ static void pmu_add_cpu_aliases(struct perf_pmu *pmu) pmu_add_cpu_aliases_table(pmu, table); } =20 -struct pmu_sys_event_iter_data { - struct list_head *head; - struct perf_pmu *pmu; -}; - static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe, const struct pmu_events_table *table __maybe_unused, - void *data) + void *vdata) { - struct pmu_sys_event_iter_data *idata =3D data; - struct perf_pmu *pmu =3D idata->pmu; + struct perf_pmu *pmu =3D vdata; =20 if (!pe->compat || !pe->pmu) return 0; =20 if (!strcmp(pmu->id, pe->compat) && pmu_uncore_alias_match(pe->pmu, pmu->name)) { - perf_pmu__new_alias(idata->head, -1, + perf_pmu__new_alias(pmu, -1, pe->name, pe->desc, pe->event, @@ -905,15 +898,10 @@ static int pmu_add_sys_aliases_iter_fn(const struct p= mu_event *pe, =20 void pmu_add_sys_aliases(struct perf_pmu *pmu) { - struct pmu_sys_event_iter_data idata =3D { - .head =3D &pmu->aliases, - .pmu =3D pmu, - }; - if (!pmu->id) return; =20 - pmu_for_each_sys_event(pmu_add_sys_aliases_iter_fn, &idata); + pmu_for_each_sys_event(pmu_add_sys_aliases_iter_fn, pmu); } =20 struct perf_event_attr * __weak --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 B3D8AEE49A5 for ; Thu, 24 Aug 2023 04:15:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240101AbjHXEPA (ORCPT ); Thu, 24 Aug 2023 00:15:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240137AbjHXEON (ORCPT ); Thu, 24 Aug 2023 00:14:13 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34979E68 for ; Wed, 23 Aug 2023 21:14:11 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-d74829dd58fso5442364276.1 for ; Wed, 23 Aug 2023 21:14:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850450; x=1693455250; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=NK3LD+ngVatRnaq7AGvk0nBXAd5n2kVF1Dp9U1zb0Ws=; b=5aHfd+BperI5esvurISThuZ0yd6CuVY+RMhltU16V4A4bcSFGYtTvJ4hggcgEQ3BZu VXJlzgbmmKVsiBVKfa3XgMo6a6he4YbzoOrWBTnO1gDCTYjPpYbdXXWY4la9/c5wUCgO Bph/XSj2C/2RIodMyYlIxzE4CqML8g0GE51Z2ff6k5VAW987tmY3W5L1dI6KjlaO3xZn tcaugah/L2u6CLSnwVDKqOTwdOYuOMQjHGsDhdw9uEDCL4w2lsXKvEkVXlcWjolZlFQq 4vgWh5uAyQFy9YiUwasWnnF3cyZd+Pf6WTkmbM69jE0QfubbI9jxPCPtvSloU2k4dd8W FdVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850450; x=1693455250; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NK3LD+ngVatRnaq7AGvk0nBXAd5n2kVF1Dp9U1zb0Ws=; b=eZK8j3+fQ5MZRIwypUYm4BMDjCGwLx67KW/H0pOYyd6GNgJnK4wyFnJmQoKEvW6df8 /c/V/Tn/9ja+Nlk57TMEmm2I1eXB9krMia7ROTpwc2ynIYz0QVULvj9AjUZ+4DKwhmD4 5eI+nf6ueKMmEEmitPFOC9DU5jiaCQjgzHUj8+Mq63CvNJJYpUBPWZ5kKQGc4ph/0hNw yWdP9eqMrBTk3qUXRdttTjrc9e8DCEJExvSuP6BSmgDnU9fpfaimiKQR3pv4oXTJCOsP u/3UmwqTPj0K4758+nXwUVMh61YisvTEyBkKCJ450eG5rto88oHH1PU7qMEyq204F0gX jNiQ== X-Gm-Message-State: AOJu0Yx9feUajiHOiWcEkEivdtXYOnhINtvtSLd0T/eWJ99sClvsDpT5 dN5L4MU1Hz8fb0melQNuUf2cMbDD6Lws X-Google-Smtp-Source: AGHT+IHqYtd9KhHwFHCrhfYfNGhhNP7f62hU1/4dxQ7yYFSJA0Xz7EJlowTv5yVv1Ha8Y4Nq9/UvHy/PAV2q X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a05:6902:1141:b0:d58:6cea:84de with SMTP id p1-20020a056902114100b00d586cea84demr290715ybu.11.1692850450445; Wed, 23 Aug 2023 21:14:10 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:23 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-12-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 11/18] perf pmu: Merge json events with sysfs at load time From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rather than load all sysfs events then parsing all json events and merging with ones that already exist. When a sysfs event is loaded, look for a corresponding json event and merge immediately. To simplify the logic, early exit the perf_pmu__new_alias function if an alias is attempted to be added twice - as merging has already been explicitly handled. Fix the copying of terms to a merged alias and some ENOMEM paths. Signed-off-by: Ian Rogers --- tools/perf/util/pmu.c | 177 +++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 89 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index c37d98a11861..bc2dd8f94bcf 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -377,38 +377,6 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_al= ias *alias, return 0; } =20 -static void perf_pmu_assign_str(char *name, const char *field, char **old_= str, - char **new_str) -{ - if (!*old_str) - goto set_new; - - if (*new_str) { /* Have new string, check with old */ - if (strcasecmp(*old_str, *new_str)) - pr_debug("alias %s differs in field '%s'\n", - name, field); - zfree(old_str); - } else /* Nothing new --> keep old string */ - return; -set_new: - *old_str =3D *new_str; - *new_str =3D NULL; -} - -static void perf_pmu_update_alias(struct perf_pmu_alias *old, - struct perf_pmu_alias *newalias) -{ - perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc); - perf_pmu_assign_str(old->name, "long_desc", &old->long_desc, - &newalias->long_desc); - perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic); - perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str); - old->scale =3D newalias->scale; - old->per_pkg =3D newalias->per_pkg; - old->snapshot =3D newalias->snapshot; - memcpy(old->unit, newalias->unit, sizeof(old->unit)); -} - /* Delete an alias entry. */ static void perf_pmu_free_alias(struct perf_pmu_alias *newalias) { @@ -432,26 +400,58 @@ static void perf_pmu__del_aliases(struct perf_pmu *pm= u) } } =20 -/* Merge an alias, search in alias list. If this name is already - * present merge both of them to combine all information. - */ -static bool perf_pmu_merge_alias(struct perf_pmu *pmu, - struct perf_pmu_alias *newalias) +static struct perf_pmu_alias *perf_pmu__find_alias(const struct perf_pmu *= pmu, const char *name) { - struct perf_pmu_alias *a; + struct perf_pmu_alias *alias; =20 - list_for_each_entry(a, &pmu->aliases, list) { - if (!strcasecmp(newalias->name, a->name)) { - if (newalias->pmu_name && a->pmu_name && - !strcasecmp(newalias->pmu_name, a->pmu_name)) { - continue; - } - perf_pmu_update_alias(a, newalias); - perf_pmu_free_alias(newalias); - return true; - } + list_for_each_entry(alias, &pmu->aliases, list) { + if (!strcasecmp(alias->name, name)) + return alias; } - return false; + return NULL; +} + +static bool assign_str(const char *name, const char *field, char **old_str, + const char *new_str) +{ + if (!*old_str && new_str) { + *old_str =3D strdup(new_str); + return true; + } + + if (!new_str || !strcasecmp(*old_str, new_str)) + return false; /* Nothing to update. */ + + pr_debug("alias %s differs in field '%s' ('%s' !=3D '%s')\n", + name, field, *old_str, new_str); + zfree(old_str); + *old_str =3D strdup(new_str); + return true; +} + +static int update_alias(const struct pmu_event *pe, + const struct pmu_events_table *table __maybe_unused, + void *vdata) +{ + struct perf_pmu_alias *alias =3D vdata; + int ret =3D 0; + + assign_str(pe->name, "desc", &alias->desc, pe->desc); + assign_str(pe->name, "long_desc", &alias->long_desc, pe->long_desc); + assign_str(pe->name, "topic", &alias->topic, pe->topic); + alias->per_pkg =3D pe->perpkg; + if (assign_str(pe->name, "value", &alias->str, pe->event)) { + parse_events_terms__purge(&alias->terms); + ret =3D parse_events_terms(&alias->terms, pe->event, /*input=3D*/NULL); + } + if (!ret && pe->unit) { + char *unit; + + ret =3D perf_pmu__convert_scale(pe->unit, &unit, &alias->scale); + if (!ret) + snprintf(alias->unit, sizeof(alias->unit), "%s", unit); + } + return ret; } =20 static int perf_pmu__new_alias(struct perf_pmu *pmu, int dirfd, const char= *name, @@ -465,6 +465,11 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, i= nt dirfd, const char *name const char *long_desc =3D NULL, *topic =3D NULL, *unit =3D NULL, *pmu_nam= e =3D NULL; bool deprecated =3D false, perpkg =3D false; =20 + if (perf_pmu__find_alias(pmu, name)) { + /* Alias was already created/loaded. */ + return 0; + } + if (pe) { long_desc =3D pe->long_desc; topic =3D pe->topic; @@ -492,27 +497,6 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, i= nt dirfd, const char *name return ret; } =20 - /* Scan event and remove leading zeroes, spaces, newlines, some - * platforms have terms specified as - * event=3D0x0091 (read from files ..//events/ - * and terms specified as event=3D0x91 (read from JSON files). - * - * Rebuild string to make alias->str member comparable. - */ - memset(newval, 0, sizeof(newval)); - ret =3D 0; - list_for_each_entry(term, &alias->terms, list) { - if (ret) - ret +=3D scnprintf(newval + ret, sizeof(newval) - ret, - ","); - if (term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_NUM) - ret +=3D scnprintf(newval + ret, sizeof(newval) - ret, - "%s=3D%#x", term->config, term->val.num); - else if (term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_STR) - ret +=3D scnprintf(newval + ret, sizeof(newval) - ret, - "%s=3D%s", term->config, term->val.str); - } - alias->name =3D strdup(name); if (dirfd >=3D 0) { /* @@ -528,17 +512,43 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, = int dirfd, const char *name alias->long_desc =3D long_desc ? strdup(long_desc) : desc ? strdup(desc) : NULL; alias->topic =3D topic ? strdup(topic) : NULL; + alias->pmu_name =3D pmu_name ? strdup(pmu_name) : NULL; if (unit) { - if (perf_pmu__convert_scale(unit, (char **)&unit, &alias->scale) < 0) + if (perf_pmu__convert_scale(unit, (char **)&unit, &alias->scale) < 0) { + perf_pmu_free_alias(alias); return -1; + } snprintf(alias->unit, sizeof(alias->unit), "%s", unit); } - alias->str =3D strdup(newval); - alias->pmu_name =3D pmu_name ? strdup(pmu_name) : NULL; + if (!pe) { + /* Update an event from sysfs with json data. */ + const struct pmu_events_table *table =3D perf_pmu__find_events_table(pmu= ); =20 - if (!perf_pmu_merge_alias(pmu, alias)) - list_add_tail(&alias->list, &pmu->aliases); + if (table) + pmu_events_table__find_event(table, pmu, name, update_alias, alias); + } =20 + /* Scan event and remove leading zeroes, spaces, newlines, some + * platforms have terms specified as + * event=3D0x0091 (read from files ..//events/ + * and terms specified as event=3D0x91 (read from JSON files). + * + * Rebuild string to make alias->str member comparable. + */ + ret =3D 0; + list_for_each_entry(term, &alias->terms, list) { + if (ret) + ret +=3D scnprintf(newval + ret, sizeof(newval) - ret, + ","); + if (term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_NUM) + ret +=3D scnprintf(newval + ret, sizeof(newval) - ret, + "%s=3D%#x", term->config, term->val.num); + else if (term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_STR) + ret +=3D scnprintf(newval + ret, sizeof(newval) - ret, + "%s=3D%s", term->config, term->val.str); + } + alias->str =3D strdup(newval); + list_add_tail(&alias->list, &pmu->aliases); return 0; } =20 @@ -944,6 +954,9 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmu= s, int dirfd, const char INIT_LIST_HEAD(&pmu->format); INIT_LIST_HEAD(&pmu->aliases); INIT_LIST_HEAD(&pmu->caps); + pmu->name =3D strdup(name); + if (!pmu->name) + goto err; /* * The pmu data we store & need consists of the pmu * type value and format definitions. Load both right @@ -962,9 +975,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmu= s, int dirfd, const char } pmu->is_core =3D is_pmu_core(name); pmu->cpus =3D pmu_cpumask(dirfd, name, pmu->is_core); - pmu->name =3D strdup(name); - if (!pmu->name) - goto err; =20 /* Read type, and ensure that type value is successfully assigned (return= 1) */ if (perf_pmu__scan_file_at(pmu, dirfd, "type", "%u", &type) !=3D 1) @@ -1357,17 +1367,6 @@ int perf_pmu__config(struct perf_pmu *pmu, struct pe= rf_event_attr *attr, return perf_pmu__config_terms(pmu, attr, head_terms, zero, err); } =20 -static struct perf_pmu_alias *perf_pmu__find_alias(const struct perf_pmu *= pmu, const char *str) -{ - struct perf_pmu_alias *alias; - - list_for_each_entry(alias, &pmu->aliases, list) { - if (!strcasecmp(alias->name, str)) - return alias; - } - return NULL; -} - static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, struct parse_events_term *term) { --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 61772C7EE43 for ; Thu, 24 Aug 2023 04:15:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240113AbjHXEPH (ORCPT ); Thu, 24 Aug 2023 00:15:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240153AbjHXEOQ (ORCPT ); Thu, 24 Aug 2023 00:14:16 -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 45C5710C4 for ; Wed, 23 Aug 2023 21:14:14 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-591138c0978so54859307b3.1 for ; Wed, 23 Aug 2023 21:14:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850453; x=1693455253; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=XBwLMLKJCYv4PjzpijbZ5QEB0J7EgzXqXuvGjcNNjMg=; b=YpA22ufBJ40L0tFpmTZUdRNm9nXzndqEhhLcZJDP9SxcVdAABpavpRZFs+93KGCVSG 3JhLpzc0f/2M+z4q7pH0MJnvdFjADtVTxRmBUyq73rvYX1lkhEDNgdcNDKi+bEYwB5At /OWw3ZWzfNaGYz+eAb9Duj0vqqUJjbKv7h+v44nigvQZGBdBK7S7alDIQABMiIfMPwaC 9KQBNPRJIhZ8jaYN9E5s6CQfN5GemAejHQha8ZNyRQghtFsVEJ7F28IExMxMqOOppG9Z CZDBF7KJoybrbUs+lsNN0LyLOGrPyS5J0Mqi7AKysJj+uLBGxPQjub5XnSJz1AzQv0RF q6Ag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850453; x=1693455253; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=XBwLMLKJCYv4PjzpijbZ5QEB0J7EgzXqXuvGjcNNjMg=; b=dQPgYMY6aufoDKNW/f3ckrJdklPrN4EFDviuJqMK3r3hEGWmbMsCNjwozlRaN5zrjL c7gcTAzNNxd6lKnXb7mRYdvbqFWKhAhfmdjPtZ7zmCv9RzFb1+klZ6nLX5NA1Nv6d3FD VXj0xNm4dZJyDDOej2SfUMV80wnIDy12FZW1Ompf+n+/wnAvxv8SEQWQMw7y+etYTxl5 yELVZA4qychvi0BsbJCDZl08IDPjoGrSaJ2vrGDaLIuYxMH67eo+9jPAEvrpQsw0DR58 50RhzbOcz2Xj3cFXfck9An22rUT6u6VnjV725GSMbBkPjcoSTk++4z3uNbpUq2+oxXX5 IuoQ== X-Gm-Message-State: AOJu0Yw+lHquBBvPjzMqFgZx6eSYkwBQrpjypesR8Wv0r9eSZG4Bj/Ij cFw7XxtYU4AOiJGv9LWR6zvU4AXrSyOx X-Google-Smtp-Source: AGHT+IF7xRVc2r3KxWkbIkCWv31O+OU7P/dE1Z04f4HUkNLe1WV4gdaTWlFtjAZmDWdkS/JUvcTE3N6W8Xeg X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a81:4303:0:b0:583:4f82:b9d9 with SMTP id q3-20020a814303000000b005834f82b9d9mr225721ywa.5.1692850453440; Wed, 23 Aug 2023 21:14:13 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:24 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-13-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 12/18] perf pmu: Cache json events table From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Cache the json events table so that finding it isn't done per event/alias. Change the events table find so that when the PMU is given, if the PMU has no json events return null. Update usage to always use the PMU variable. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 14 ++++++++++++-- tools/perf/tests/pmu-events.c | 2 ++ tools/perf/util/pmu.c | 16 +++++++--------- tools/perf/util/pmu.h | 4 ++++ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 991fcf6cca64..f07864fabd54 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -948,7 +948,7 @@ const struct pmu_events_table *perf_pmu__find_events_ta= ble(struct perf_pmu *pmu) { const struct pmu_events_table *table =3D NULL; char *cpuid =3D perf_pmu__getcpuid(pmu); - int i; + size_t i; =20 /* on some platforms which uses cpus map, cpuid can be NULL for * PMUs other than CORE PMUs. @@ -968,7 +968,17 @@ const struct pmu_events_table *perf_pmu__find_events_t= able(struct perf_pmu *pmu) } } free(cpuid); - return table; + if (!pmu) + return table; + + for (i =3D 0; i < table->num_pmus; i++) { + const struct pmu_table_entry *table_pmu =3D &table->pmus[i= ]; + const char *pmu_name =3D &big_c_string[table_pmu->pmu_name= .offset]; + + if (pmu__name_match(pmu, pmu_name)) + return table; + } + return NULL; } =20 const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_p= mu *pmu) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 34f0de182fa9..4fcb84fd1f65 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -544,6 +544,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name= , int *count) INIT_LIST_HEAD(&pmu->list); pmu->name =3D strdup(pmu_name); =20 + pmu->events_table =3D table; pmu_add_cpu_aliases_table(pmu, table); =20 res =3D pmu_events_table__find_event(table, pmu, "bp_l1_btb_correct", NUL= L, NULL); @@ -583,6 +584,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) events_table =3D find_core_events_table("testarch", "testcpu"); if (!events_table) return -1; + pmu->events_table =3D events_table; pmu_add_cpu_aliases_table(pmu, events_table); pmu_add_sys_aliases(pmu); =20 diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index bc2dd8f94bcf..685903c1970b 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -522,10 +522,10 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, = int dirfd, const char *name } if (!pe) { /* Update an event from sysfs with json data. */ - const struct pmu_events_table *table =3D perf_pmu__find_events_table(pmu= ); - - if (table) - pmu_events_table__find_event(table, pmu, name, update_alias, alias); + if (pmu->events_table) { + pmu_events_table__find_event(pmu->events_table, pmu, name, + update_alias, alias); + } } =20 /* Scan event and remove leading zeroes, spaces, newlines, some @@ -875,13 +875,10 @@ void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, = const struct pmu_events_tab =20 static void pmu_add_cpu_aliases(struct perf_pmu *pmu) { - const struct pmu_events_table *table; - - table =3D perf_pmu__find_events_table(pmu); - if (!table) + if (!pmu->events_table) return; =20 - pmu_add_cpu_aliases_table(pmu, table); + pmu_add_cpu_aliases_table(pmu, pmu->events_table); } =20 static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe, @@ -992,6 +989,7 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmu= s, int dirfd, const char if (pmu->is_uncore) pmu->id =3D pmu_id(name); pmu->max_precise =3D pmu_max_precise(dirfd, pmu); + pmu->events_table =3D perf_pmu__find_events_table(pmu); pmu_add_cpu_aliases(pmu); pmu_add_sys_aliases(pmu); list_add_tail(&pmu->list, pmus); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 2b1730152bc0..6bf0fbde4e85 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -114,6 +114,10 @@ struct perf_pmu { * from json events in pmu-events.c. */ struct list_head aliases; + /** + * @events_table: The events table for json events in pmu-events.c. + */ + const struct pmu_events_table *events_table; /** @caps_initialized: Has the list caps been initialized? */ bool caps_initialized; /** @nr_caps: The length of the list caps. */ --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 19F67EE49B2 for ; Thu, 24 Aug 2023 04:15:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240107AbjHXEPE (ORCPT ); Thu, 24 Aug 2023 00:15:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240155AbjHXEOT (ORCPT ); Thu, 24 Aug 2023 00:14:19 -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 BE79610D3 for ; Wed, 23 Aug 2023 21:14:16 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-5840ea40c59so80237347b3.2 for ; Wed, 23 Aug 2023 21:14:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850456; x=1693455256; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=iBOZX0I21RNlbaOmyE1OFvH/y3TB68ZzbJZaWpbHFe0=; b=4NOW3dpx9qa73CbVpBAG0qbfaJOx/etOkFLFKrSX2DIjSNB39FzMN8uSjYsXDMHa+t xI90Ph+dizTc+7f/vT3Ws0w8EHnBuWCzcEsP83hYBsZSYh+p1sQsYWi+Jjx4M0H5LSjx djZhNidDtlIY/TtDUzMLmGvokNHM+Qq7yUEIpO6xO/63CgI63XmRghExdgSwMrWnzCoM gg9qGPheUD6y6bbAnDopsJUPGAIIqdAuI+Mb3Vs8TsNGpdxCiq68mD+KEOGWbUwZvXN+ 1TIxSfcO6ntlv5MJmoeb3DT+FARD4B13jFIL/HCa2rC2T5NNlNhezOsGA/YCo0S8EI3M /tWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850456; x=1693455256; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=iBOZX0I21RNlbaOmyE1OFvH/y3TB68ZzbJZaWpbHFe0=; b=CMwA14Zf81WLj4d3pnBc+S1Sr4Zu472nFwp/m2sJpBZrl+CJ99VJUC7FOscyR1Vbv/ 4/b3mkW89jdGufeJU8+Nlyhql5EZIHa3glBnINY1XYv5W/fUb1WdaduJHT1Fvh2gDw5x WR/WDXIvViwo6LbrAc/lgi6pI9+mzA7Ev3bS1/nql2OioUfiB/Y8F+pBX49JfVn+3+Xh xIkhBPFzUelYSbGfWVX/GjUxrSMZjJZs13P/mNRglLzMkMy9uX0DrsBffz8V500jvb32 Mb/spF6gBhxUVH2Hx7FyQhnPj+boSQEzr1j8pEgB00D2+qwmMOMTke1wY2Gfs8JUfBN+ Y35g== X-Gm-Message-State: AOJu0YxsA6WrijlES9R2M24gU5FPeWaaWGwVgbN5Q+NzXhUnDEeaFKnf YBL8ytYCYw9ADoI514oBGs+hW8on5BVk X-Google-Smtp-Source: AGHT+IHL01tjChYXDvehm2MTSrHE8lSIYBYzTaMmjiLSwkJBCjgWqTExg0OxL3eJVjV8e5M3ca84cWpGOURD X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a81:af4d:0:b0:586:896e:58b1 with SMTP id x13-20020a81af4d000000b00586896e58b1mr201131ywj.0.1692850456019; Wed, 23 Aug 2023 21:14:16 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:25 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-14-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 13/18] perf pmu: Lazily add json events From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rather than scanning all json events and adding them when a PMU is created, add the alias when the json event is needed. Average core PMU scanning run time reduced by 60.2%. Average PMU scanning run time reduced by 15%. Page faults with no events reduced by 74 page faults, 4% of total. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 14 +++++++ tools/perf/pmu-events/jevents.py | 15 +++++++ tools/perf/pmu-events/pmu-events.h | 4 ++ tools/perf/tests/pmu-events.c | 2 + tools/perf/util/pmu.c | 50 ++++++++++++++++++------ tools/perf/util/pmu.h | 15 +++++-- 6 files changed, 85 insertions(+), 15 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index ef18d403f25f..12bd043a05e3 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -298,6 +298,20 @@ int pmu_events_table__find_event(const struct pmu_even= ts_table *table, return -1000; } =20 +size_t pmu_events_table__num_events(const struct pmu_events_table *table, + struct perf_pmu *pmu) +{ + size_t count =3D 0; + + for (const struct pmu_event *pe =3D &table->entries[0]; pe->name; pe++) { + if (pmu && !pmu__name_match(pmu, pe->pmu)) + continue; + + count++; + } + return count; +} + int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data) { diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index f07864fabd54..01335a452e70 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -909,6 +909,21 @@ int pmu_events_table__find_event(const struct pmu_even= ts_table *table, return -1000; } =20 +size_t pmu_events_table__num_events(const struct pmu_events_table *table, + struct perf_pmu *pmu) +{ + size_t count =3D 0; + + for (size_t i =3D 0; i < table->num_pmus; i++) { + const struct pmu_table_entry *table_pmu =3D &table->pmus[i= ]; + const char *pmu_name =3D &big_c_string[table_pmu->pmu_name= .offset]; + + if (pmu__name_match(pmu, pmu_name)) + count +=3D table_pmu->num_entries; + } + return count; +} + static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics= _table *table, const struct pmu_table_ent= ry *pmu, pmu_metric_iter_fn fn, diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 9882b7125761..f5aa96f1685c 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -3,6 +3,7 @@ #define PMU_EVENTS_H =20 #include +#include =20 struct perf_pmu; =20 @@ -86,6 +87,9 @@ int pmu_events_table__find_event(const struct pmu_events_= table *table, const char *name, pmu_event_iter_fn fn, void *data); +size_t pmu_events_table__num_events(const struct pmu_events_table *table, + struct perf_pmu *pmu); + int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *tab= le, pmu_metric_iter_fn fn, void *data); =20 diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 4fcb84fd1f65..9ac893ae5f0d 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -546,6 +546,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name= , int *count) =20 pmu->events_table =3D table; pmu_add_cpu_aliases_table(pmu, table); + pmu->cpu_aliases_added =3D true; =20 res =3D pmu_events_table__find_event(table, pmu, "bp_l1_btb_correct", NUL= L, NULL); if (res !=3D 0) { @@ -586,6 +587,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) return -1; pmu->events_table =3D events_table; pmu_add_cpu_aliases_table(pmu, events_table); + pmu->cpu_aliases_added =3D true; pmu_add_sys_aliases(pmu); =20 /* Count how many aliases we generated */ diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 685903c1970b..b6a118226541 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -523,8 +523,9 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, in= t dirfd, const char *name if (!pe) { /* Update an event from sysfs with json data. */ if (pmu->events_table) { - pmu_events_table__find_event(pmu->events_table, pmu, name, - update_alias, alias); + if (pmu_events_table__find_event(pmu->events_table, pmu, name, + update_alias, alias) =3D=3D 0) + pmu->loaded_json_aliases++; } } =20 @@ -548,6 +549,10 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, i= nt dirfd, const char *name "%s=3D%s", term->config, term->val.str); } alias->str =3D strdup(newval); + if (!pe) + pmu->sysfs_aliases++; + else + pmu->loaded_json_aliases++; list_add_tail(&alias->list, &pmu->aliases); return 0; } @@ -878,7 +883,11 @@ static void pmu_add_cpu_aliases(struct perf_pmu *pmu) if (!pmu->events_table) return; =20 + if (pmu->cpu_aliases_added) + return; + pmu_add_cpu_aliases_table(pmu, pmu->events_table); + pmu->cpu_aliases_added =3D true; } =20 static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe, @@ -990,7 +999,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmu= s, int dirfd, const char pmu->id =3D pmu_id(name); pmu->max_precise =3D pmu_max_precise(dirfd, pmu); pmu->events_table =3D perf_pmu__find_events_table(pmu); - pmu_add_cpu_aliases(pmu); pmu_add_sys_aliases(pmu); list_add_tail(&pmu->list, pmus); =20 @@ -1368,6 +1376,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct per= f_event_attr *attr, static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, struct parse_events_term *term) { + struct perf_pmu_alias *alias; char *name; =20 if (parse_events__is_hardcoded_term(term)) @@ -1388,7 +1397,18 @@ static struct perf_pmu_alias *pmu_find_alias(struct = perf_pmu *pmu, return NULL; } =20 - return perf_pmu__find_alias(pmu, name); + alias =3D perf_pmu__find_alias(pmu, name); + if (alias || pmu->cpu_aliases_added) + return alias; + + /* Alias doesn't exist, try to get it from the json events. */ + if (pmu->events_table && + pmu_events_table__find_event(pmu->events_table, pmu, name, + pmu_add_cpu_aliases_map_callback, + pmu) =3D=3D 0) { + alias =3D perf_pmu__find_alias(pmu, name); + } + return alias; } =20 =20 @@ -1555,18 +1575,23 @@ bool perf_pmu__auto_merge_stats(const struct perf_p= mu *pmu) return !pmu->is_core || perf_pmus__num_core_pmus() =3D=3D 1; } =20 -bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name) +bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name) { - return perf_pmu__find_alias(pmu, name) !=3D NULL; + if (perf_pmu__find_alias(pmu, name) !=3D NULL) + return true; + if (pmu->cpu_aliases_added || !pmu->events_table) + return false; + return pmu_events_table__find_event(pmu->events_table, pmu, name, NULL, N= ULL) =3D=3D 0; } =20 -size_t perf_pmu__num_events(const struct perf_pmu *pmu) +size_t perf_pmu__num_events(struct perf_pmu *pmu) { - struct list_head *list; - size_t nr =3D 0; + size_t nr =3D pmu->sysfs_aliases; =20 - list_for_each(list, &pmu->aliases) - nr++; + if (pmu->cpu_aliases_added) + nr +=3D pmu->loaded_json_aliases; + else if (pmu->events_table) + nr +=3D pmu_events_table__num_events(pmu->events_table, pmu) - pmu->load= ed_json_aliases; =20 return pmu->selectable ? nr + 1 : nr; } @@ -1604,7 +1629,7 @@ static char *format_alias(char *buf, int len, const s= truct perf_pmu *pmu, return buf; } =20 -int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_= event_callback cb) +int perf_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_= callback cb) { char buf[1024]; struct perf_pmu_alias *event; @@ -1613,6 +1638,7 @@ int perf_pmu__for_each_event(const struct perf_pmu *p= mu, void *state, pmu_event_ }; int ret =3D 0; =20 + pmu_add_cpu_aliases(pmu); list_for_each_entry(event, &pmu->aliases, list) { size_t buf_used; =20 diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 6bf0fbde4e85..288d2908382a 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -118,6 +118,15 @@ struct perf_pmu { * @events_table: The events table for json events in pmu-events.c. */ const struct pmu_events_table *events_table; + /** @sysfs_aliases: Number of sysfs aliases loaded. */ + uint32_t sysfs_aliases; + /** @sysfs_aliases: Number of json event aliases loaded. */ + uint32_t loaded_json_aliases; + /** + * @cpu_aliases_added: Have all json events table entries for the PMU + * been added? + */ + bool cpu_aliases_added; /** @caps_initialized: Has the list caps been initialized? */ bool caps_initialized; /** @nr_caps: The length of the list caps. */ @@ -199,9 +208,9 @@ bool perf_pmu__has_format(const struct perf_pmu *pmu, c= onst char *name); bool is_pmu_core(const char *name); bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu); bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu); -bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name); -size_t perf_pmu__num_events(const struct perf_pmu *pmu); -int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_= event_callback cb); +bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name); +size_t perf_pmu__num_events(struct perf_pmu *pmu); +int perf_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_= callback cb); bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name); =20 /** --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 9313DEE49A0 for ; Thu, 24 Aug 2023 04:15:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240241AbjHXEPP (ORCPT ); Thu, 24 Aug 2023 00:15:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240163AbjHXEOV (ORCPT ); Thu, 24 Aug 2023 00:14:21 -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 8EBB810F3 for ; Wed, 23 Aug 2023 21:14:19 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-59224c40275so39662497b3.3 for ; Wed, 23 Aug 2023 21:14:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850459; x=1693455259; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=4ScEv4GX5A4Io0po//7S7PvWnFzmCqkRHzJYnXAt+bY=; b=r8VSBW4qdoFWgdyFcw0Sn10q8onBDQmJf0aih/aqmXo8WHsheh/ylVTvf/6mOrFCL2 qMDBt5AltI9qZ5eeMutQFVdZNW/xohjsKntv2HDkKPW9ABtV+b/Z/EkjYnVdhpoLXZNi p6tCrf2LwZxraNvuHHqPe4UiqAZ84rmmBDP70FEh0Q8KxWGGBMfG0UhiXGwU1jz/Oj4K EicHYGdtkg9aZSVLOt2rp/wpI5Psmu5qapxieMghJQpzDZ86fbLw6mGOyIDJXGdzoqKD wMa13Qk7oxnnHCkaHzzHKP1KTKsK12pDvsu9xVVl3y1nFQpl2ADL44gL7JF8IDa79QYa AcBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850459; x=1693455259; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=4ScEv4GX5A4Io0po//7S7PvWnFzmCqkRHzJYnXAt+bY=; b=SBACFvPJHtfuSRvY/+vqVyC2cYth89qxqvJr2836hBQ9HUbXJRLtx+QSXdDNZzLqF1 7Q8wRePG8DkxKUbBlxHIDi4feT/oXg3rlrDzdO69j/N3TTRRZ5RDSi/JDTTJa7bBS1PA yzADYPLX09BwKH+wODODBb+UbCoEdJv6BIVCLmdTmdyUh47HOj2eBtPzH3XRL6501qgg JwY5wrYyPqBnZlW8vDnLxIdkLQ8XhCyAb2IpR/UvuaHUP/ZwhwrcDmCndei+UOsN2DiW bSv0viIW/9B00Nxwlb9yo0ZyPzoF2pICS+IlYYluV4t2QYo4Jhmoop3q3wzRpq38pLhr yDyw== X-Gm-Message-State: AOJu0YxpfUGogNmVBkAG+d9R3mkE5cChm+6xhtpa1bUMKVgESNvlPFTV BXZ4NUZw5czhFvfIdNlvK06c623sE0oW X-Google-Smtp-Source: AGHT+IGLEEHEeCmx11MwTgaezBT64VhjVTmHANbZExv2smPbeqft6cHfLwu/s4hF4lr/HZGGWEU4nFI7uzrM X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a81:ad23:0:b0:581:3899:91bc with SMTP id l35-20020a81ad23000000b00581389991bcmr197582ywh.6.1692850458760; Wed, 23 Aug 2023 21:14:18 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:26 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-15-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 14/18] perf pmu: Scan type early to fail an invalid PMU quickly From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Scan sysfs PMU's type early so that format and aliases aren't attempted to be loaded if the PMU name is invalid. This is the case for event_pmu tokens in parse-events.y where a wildcard name is first assumed to be a PMU name. Signed-off-by: Ian Rogers --- tools/perf/util/pmu.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index b6a118226541..9e3b72d84168 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -957,12 +957,21 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *p= mus, int dirfd, const char if (!pmu) return NULL; =20 - INIT_LIST_HEAD(&pmu->format); - INIT_LIST_HEAD(&pmu->aliases); - INIT_LIST_HEAD(&pmu->caps); pmu->name =3D strdup(name); if (!pmu->name) goto err; + + /* + * Read type early to fail fast if a lookup name isn't a PMU. Ensure + * that type value is successfully assigned (return 1). + */ + if (perf_pmu__scan_file_at(pmu, dirfd, "type", "%u", &type) !=3D 1) + goto err; + + INIT_LIST_HEAD(&pmu->format); + INIT_LIST_HEAD(&pmu->aliases); + INIT_LIST_HEAD(&pmu->caps); + /* * The pmu data we store & need consists of the pmu * type value and format definitions. Load both right @@ -982,10 +991,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pm= us, int dirfd, const char pmu->is_core =3D is_pmu_core(name); pmu->cpus =3D pmu_cpumask(dirfd, name, pmu->is_core); =20 - /* Read type, and ensure that type value is successfully assigned (return= 1) */ - if (perf_pmu__scan_file_at(pmu, dirfd, "type", "%u", &type) !=3D 1) - goto err; - alias_name =3D pmu_find_alias_name(name); if (alias_name) { pmu->alias_name =3D strdup(alias_name); --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:49 2025 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 42620C83003 for ; Thu, 24 Aug 2023 04:15:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240155AbjHXEPN (ORCPT ); Thu, 24 Aug 2023 00:15:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239977AbjHXEOZ (ORCPT ); Thu, 24 Aug 2023 00:14:25 -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 E901110F8 for ; Wed, 23 Aug 2023 21:14:22 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-58c8b2d6784so84343177b3.3 for ; Wed, 23 Aug 2023 21:14:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850462; x=1693455262; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=d5aK29bVjoAy4Lg42V+uHrKm1O4Ro++evLmNFf4Bj+4=; b=Ej47e+lD/6RUF8E+q/OUQboUGSy2GppKYeKdXAutMPAcnUr7Oca2I73HS0yMkqvY5h y2Yxb0wZ7ScRzX0SnUqDplzs24HAFOEwAmn2mCsGXqmUfM3hwlahCn0u1QhA7mK6c8gU B5gFziscdZojWeWII4OGzloZcOiq59cxPW5rPgR/JheuX0dkckaHIQTBK9HBQs07Fyzc J7SCcFy9whThNyXSRk1H0UPmzj5gFSTLYmaiaUftdNUFZvRrkDujO9yQIzD7e+WTmqCg C4XSZs4UaRILWM/KRW7hjR5qsGIs8h+lLjBk9kZIQIMysbgVI8ahGgEiFAa082FUxTv8 /jHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850462; x=1693455262; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=d5aK29bVjoAy4Lg42V+uHrKm1O4Ro++evLmNFf4Bj+4=; b=JTERxrr20fBJUMDo79ESbvk9jTXcj/dMz/rDYA8r8r9Et2XuBnx3JeKtx2tvOnPDfv Gm3cac3AgWN40TxXR0B26rSiTHSQl4C9jetlK1/9xj5uofFVdQMsbFTmt1G7hdw2ZTCk tKvspJLZb83aMeOlR8AAbNHsd4NsrCKzO/fRSoN/WkZ6jOzLlxBjwo+F0h4RE5I9xtZg JyQZuwvAvNEoRJB+UNu/dwpUf2+USrVTdb5avMtA+FNgv8Pd/+YmhZVXf/7MpX0pld8h uyd8ug1x/L5oS5/kKIU78ouy3P/+qZ1UG4+Jqw1d56ILQzWGi8nfN0rd9l9K31gSTYh2 ez6A== X-Gm-Message-State: AOJu0Yws2JeJQ7e77lXw2YtvH7xcGG1zWXVB31AfFyGUVJH/oku5cYJF 05D1EFpOSTfYFlcLkheWCcp+1yqEyWcF X-Google-Smtp-Source: AGHT+IFnH0XPJnTREa9Kk0vTe/JHpq8PlttbOJfotvZXiFY17QPpGIDOlBQNjC+LqyK4y+pRGiO5kl4zlOYR X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a25:2442:0:b0:d11:6816:2d31 with SMTP id k63-20020a252442000000b00d1168162d31mr184546ybk.7.1692850462167; Wed, 23 Aug 2023 21:14:22 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:27 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-16-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 15/18] perf pmu: Be lazy about loading event info files from sysfs From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Event info is only needed when an event is parsed or when merging data from an json and sysfs event. Be lazy in its loading to reduce file accesses. Signed-off-by: Ian Rogers --- tools/perf/util/pmu.c | 128 +++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 45 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 9e3b72d84168..493d3e59fd50 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -58,6 +58,11 @@ struct perf_pmu_alias { struct list_head terms; /** @list: List element of struct perf_pmu aliases. */ struct list_head list; + /** + * @pmu_name: The name copied from the json struct pmu_event. This can + * differ from the PMU name as it won't have suffixes. + */ + char *pmu_name; /** @unit: Units for the event, such as bytes or cache lines. */ char unit[UNIT_MAX_LEN+1]; /** @scale: Value to scale read counter values by. */ @@ -79,11 +84,10 @@ struct perf_pmu_alias { * default. */ bool deprecated; - /** - * @pmu_name: The name copied from the json struct pmu_event. This can - * differ from the PMU name as it won't have suffixes. - */ - char *pmu_name; + /** @from_sysfs: Was the alias from sysfs or a json event? */ + bool from_sysfs; + /** @info_loaded: Have the scale, unit and other values been read from di= sk? */ + bool info_loaded; }; =20 /** @@ -280,17 +284,21 @@ int perf_pmu__convert_scale(const char *scale, char *= *end, double *sval) return ret; } =20 -static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, int dirfd, = const char *name) +static int perf_pmu__parse_scale(struct perf_pmu *pmu, struct perf_pmu_ali= as *alias) { struct stat st; ssize_t sret; + size_t len; char scale[128]; int fd, ret =3D -1; char path[PATH_MAX]; =20 - scnprintf(path, PATH_MAX, "%s.scale", name); + len =3D perf_pmu__event_source_devices_scnprintf(path, sizeof(path)); + if (!len) + return 0; + scnprintf(path + len, sizeof(path) - len, "%s/%s.scale", pmu->name, alias= ->name); =20 - fd =3D openat(dirfd, path, O_RDONLY); + fd =3D open(path, O_RDONLY); if (fd =3D=3D -1) return -1; =20 @@ -312,15 +320,20 @@ static int perf_pmu__parse_scale(struct perf_pmu_alia= s *alias, int dirfd, const return ret; } =20 -static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, int dirfd, c= onst char *name) +static int perf_pmu__parse_unit(struct perf_pmu *pmu, struct perf_pmu_alia= s *alias) { char path[PATH_MAX]; + size_t len; ssize_t sret; int fd; =20 - scnprintf(path, PATH_MAX, "%s.unit", name); =20 - fd =3D openat(dirfd, path, O_RDONLY); + len =3D perf_pmu__event_source_devices_scnprintf(path, sizeof(path)); + if (!len) + return 0; + scnprintf(path + len, sizeof(path) - len, "%s/%s.unit", pmu->name, alias-= >name); + + fd =3D open(path, O_RDONLY); if (fd =3D=3D -1) return -1; =20 @@ -343,14 +356,18 @@ static int perf_pmu__parse_unit(struct perf_pmu_alias= *alias, int dirfd, const c } =20 static int -perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, int dirfd, const cha= r *name) +perf_pmu__parse_per_pkg(struct perf_pmu *pmu, struct perf_pmu_alias *alias) { char path[PATH_MAX]; + size_t len; int fd; =20 - scnprintf(path, PATH_MAX, "%s.per-pkg", name); + len =3D perf_pmu__event_source_devices_scnprintf(path, sizeof(path)); + if (!len) + return 0; + scnprintf(path + len, sizeof(path) - len, "%s/%s.per-pkg", pmu->name, ali= as->name); =20 - fd =3D openat(dirfd, path, O_RDONLY); + fd =3D open(path, O_RDONLY); if (fd =3D=3D -1) return -1; =20 @@ -360,15 +377,18 @@ perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias,= int dirfd, const char *nam return 0; } =20 -static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, - int dirfd, const char *name) +static int perf_pmu__parse_snapshot(struct perf_pmu *pmu, struct perf_pmu_= alias *alias) { char path[PATH_MAX]; + size_t len; int fd; =20 - scnprintf(path, PATH_MAX, "%s.snapshot", name); + len =3D perf_pmu__event_source_devices_scnprintf(path, sizeof(path)); + if (!len) + return 0; + scnprintf(path + len, sizeof(path) - len, "%s/%s.snapshot", pmu->name, al= ias->name); =20 - fd =3D openat(dirfd, path, O_RDONLY); + fd =3D open(path, O_RDONLY); if (fd =3D=3D -1) return -1; =20 @@ -429,32 +449,52 @@ static bool assign_str(const char *name, const char *= field, char **old_str, return true; } =20 +static void read_alias_info(struct perf_pmu *pmu, struct perf_pmu_alias *a= lias) +{ + if (!alias->from_sysfs || alias->info_loaded) + return; + + /* + * load unit name and scale if available + */ + perf_pmu__parse_unit(pmu, alias); + perf_pmu__parse_scale(pmu, alias); + perf_pmu__parse_per_pkg(pmu, alias); + perf_pmu__parse_snapshot(pmu, alias); +} + +struct update_alias_data { + struct perf_pmu *pmu; + struct perf_pmu_alias *alias; +}; + static int update_alias(const struct pmu_event *pe, const struct pmu_events_table *table __maybe_unused, void *vdata) { - struct perf_pmu_alias *alias =3D vdata; + struct update_alias_data *data =3D vdata; int ret =3D 0; =20 - assign_str(pe->name, "desc", &alias->desc, pe->desc); - assign_str(pe->name, "long_desc", &alias->long_desc, pe->long_desc); - assign_str(pe->name, "topic", &alias->topic, pe->topic); - alias->per_pkg =3D pe->perpkg; - if (assign_str(pe->name, "value", &alias->str, pe->event)) { - parse_events_terms__purge(&alias->terms); - ret =3D parse_events_terms(&alias->terms, pe->event, /*input=3D*/NULL); + read_alias_info(data->pmu, data->alias); + assign_str(pe->name, "desc", &data->alias->desc, pe->desc); + assign_str(pe->name, "long_desc", &data->alias->long_desc, pe->long_desc); + assign_str(pe->name, "topic", &data->alias->topic, pe->topic); + data->alias->per_pkg =3D pe->perpkg; + if (assign_str(pe->name, "value", &data->alias->str, pe->event)) { + parse_events_terms__purge(&data->alias->terms); + ret =3D parse_events_terms(&data->alias->terms, pe->event, /*input=3D*/N= ULL); } if (!ret && pe->unit) { char *unit; =20 - ret =3D perf_pmu__convert_scale(pe->unit, &unit, &alias->scale); + ret =3D perf_pmu__convert_scale(pe->unit, &unit, &data->alias->scale); if (!ret) - snprintf(alias->unit, sizeof(alias->unit), "%s", unit); + snprintf(data->alias->unit, sizeof(data->alias->unit), "%s", unit); } return ret; } =20 -static int perf_pmu__new_alias(struct perf_pmu *pmu, int dirfd, const char= *name, +static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name, const char *desc, const char *val, FILE *val_fd, const struct pmu_event *pe) { @@ -498,16 +538,6 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, i= nt dirfd, const char *name } =20 alias->name =3D strdup(name); - if (dirfd >=3D 0) { - /* - * load unit name and scale if available - */ - perf_pmu__parse_unit(alias, dirfd, name); - perf_pmu__parse_scale(alias, dirfd, name); - perf_pmu__parse_per_pkg(alias, dirfd, name); - perf_pmu__parse_snapshot(alias, dirfd, name); - } - alias->desc =3D desc ? strdup(desc) : NULL; alias->long_desc =3D long_desc ? strdup(long_desc) : desc ? strdup(desc) : NULL; @@ -522,9 +552,15 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, i= nt dirfd, const char *name } if (!pe) { /* Update an event from sysfs with json data. */ + struct update_alias_data data =3D { + .pmu =3D pmu, + .alias =3D alias, + }; + + alias->from_sysfs =3D true; if (pmu->events_table) { if (pmu_events_table__find_event(pmu->events_table, pmu, name, - update_alias, alias) =3D=3D 0) + update_alias, &data) =3D=3D 0) pmu->loaded_json_aliases++; } } @@ -612,7 +648,7 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int = dirfd) continue; } =20 - if (perf_pmu__new_alias(pmu, dirfd, name, /*desc=3D*/ NULL, + if (perf_pmu__new_alias(pmu, name, /*desc=3D*/ NULL, /*val=3D*/ NULL, file, /*pe=3D*/ NULL) < 0) pr_debug("Cannot set up %s\n", name); fclose(file); @@ -865,7 +901,7 @@ static int pmu_add_cpu_aliases_map_callback(const struc= t pmu_event *pe, { struct perf_pmu *pmu =3D vdata; =20 - perf_pmu__new_alias(pmu, -1, pe->name, pe->desc, pe->event, /*val_fd=3D*/= NULL, pe); + perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, /*val_fd=3D*/ NUL= L, pe); return 0; } =20 @@ -901,7 +937,7 @@ static int pmu_add_sys_aliases_iter_fn(const struct pmu= _event *pe, =20 if (!strcmp(pmu->id, pe->compat) && pmu_uncore_alias_match(pe->pmu, pmu->name)) { - perf_pmu__new_alias(pmu, -1, + perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, @@ -1417,11 +1453,13 @@ static struct perf_pmu_alias *pmu_find_alias(struct= perf_pmu *pmu, } =20 =20 -static int check_info_data(struct perf_pmu_alias *alias, +static int check_info_data(struct perf_pmu *pmu, + struct perf_pmu_alias *alias, struct perf_pmu_info *info, struct parse_events_error *err, int column) { + read_alias_info(pmu, alias); /* * Only one term in event definition can * define unit, scale and snapshot, fail @@ -1491,7 +1529,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struc= t list_head *head_terms, return ret; } =20 - ret =3D check_info_data(alias, info, err, term->err_term); + ret =3D check_info_data(pmu, alias, info, err, term->err_term); if (ret) return ret; =20 --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:50 2025 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 1B4BFC7EE2C for ; Thu, 24 Aug 2023 04:15:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240139AbjHXEPL (ORCPT ); Thu, 24 Aug 2023 00:15:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53610 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240091AbjHXEOf (ORCPT ); Thu, 24 Aug 2023 00:14:35 -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 0B5351705 for ; Wed, 23 Aug 2023 21:14:26 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5840ea40c59so80238527b3.2 for ; Wed, 23 Aug 2023 21:14:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850465; x=1693455265; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=dhLY8gK9oeuyTDYV8WtY+2nLQ54HCnAec1jEe35/qZQ=; b=bsMXGUlUBGtmKbYNPKkyap8LhCAm8bDl/oh7NCAsXk3uaTlkLoydJF/+oQfOJRWJOO ZQO33i9gQUo4JoQLnff9WyCybi4vXx2ODyS1CCV2W1KrMygpQLfCcsPrrAvynsJfmSgH ShbFfEbIOc3A8ZSfIeQ493ZkqJAyqcjGXobmafohPFmXME8bDkPtHDLPT7LDMRKrWb+J 2uOVHhw+/LkNwj0cL6rsXFL0+ctthYfXUSCWFWiAY3oNu3agGoxTqzhdjm/G4JI/6e4X OWhzKtjyP59Y0USxE5ehDGCTvM5UbNn5VZHBRUrzXVVenk2316Uv0UqYXC4MAkI6hkWN 9mhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850465; x=1693455265; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=dhLY8gK9oeuyTDYV8WtY+2nLQ54HCnAec1jEe35/qZQ=; b=PAdwyMv9+es6nGtTvVmMC3bFN2tBWGQ7BoCEJUl9PLiFqNp1DERw0Ylr4a8R9G1VzK PsoELyfVLJk7CMBXAvUYmHpax+SQdG3o5u8akZ3G4d4TDfxaTR0AIknYoK835l0oaLW6 OsbppvtUHJLog0NCXs0xGCx3rjkUXV9weycnY1YXD9BhfxtMpR/TsJXVA6u0w05KALQ8 tGrrPNVM4rdU+LHK4+7OCMSOYP9ajv1cV0BWN/OfQEYRCDc9YeiVB4ZaJOcPq6BTi6Fr 4YRRHbaRhdJi3qD1P2bxi0yQEL57Dy/72A0b9FHDmxRWWY+ZWQdT/gXve0dbzu+YA8Qh Iuiw== X-Gm-Message-State: AOJu0Yxdl9JZASnyYPbyRdmIXPNIxXGFTnQPXZmGjSmBbC1KY6hwg3mA k3oFKWRTZPkYjVzICWXsFhpqFL9vQcEb X-Google-Smtp-Source: AGHT+IHbgwi5mNLjU7UxDor2tEU+FutvcE3PACKd29okmkzXn5tA6i/oMVSTBA0NEf88ybIQ7n8ZLfzgwAsO X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a81:ac47:0:b0:58c:7cb1:10f with SMTP id z7-20020a81ac47000000b0058c7cb1010fmr199534ywj.9.1692850465251; Wed, 23 Aug 2023 21:14:25 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:28 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-17-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 16/18] perf pmu: Lazily load sysfs aliases From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Don't load sysfs aliases for a PMU when the PMU is first created, defer until an alias needs to be found. For the pmu-scan benchmark, average core PMU scanning is reduced by 30.8%, and average PMU scanning by 12.6%. Signed-off-by: Ian Rogers --- tools/perf/tests/pmu-events.c | 2 + tools/perf/util/pmu.c | 81 ++++++++++++++++++----------------- tools/perf/util/pmu.h | 2 + 3 files changed, 46 insertions(+), 39 deletions(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 9ac893ae5f0d..3dc1ebee4d9f 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -547,6 +547,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name= , int *count) pmu->events_table =3D table; pmu_add_cpu_aliases_table(pmu, table); pmu->cpu_aliases_added =3D true; + pmu->sysfs_aliases_loaded =3D true; =20 res =3D pmu_events_table__find_event(table, pmu, "bp_l1_btb_correct", NUL= L, NULL); if (res !=3D 0) { @@ -588,6 +589,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_= pmu_test_pmu *test_pmu) pmu->events_table =3D events_table; pmu_add_cpu_aliases_table(pmu, events_table); pmu->cpu_aliases_added =3D true; + pmu->sysfs_aliases_loaded =3D true; pmu_add_sys_aliases(pmu); =20 /* Count how many aliases we generated */ diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 493d3e59fd50..bb2ca29cd7bd 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -115,6 +115,8 @@ struct perf_pmu_format { bool loaded; }; =20 +static int pmu_aliases_parse(struct perf_pmu *pmu); + static struct perf_pmu_format *perf_pmu__new_format(struct list_head *list= , char *name) { struct perf_pmu_format *format; @@ -420,10 +422,15 @@ static void perf_pmu__del_aliases(struct perf_pmu *pm= u) } } =20 -static struct perf_pmu_alias *perf_pmu__find_alias(const struct perf_pmu *= pmu, const char *name) +static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu, + const char *name, + bool load) { struct perf_pmu_alias *alias; =20 + if (load && !pmu->sysfs_aliases_loaded) + pmu_aliases_parse(pmu); + list_for_each_entry(alias, &pmu->aliases, list) { if (!strcasecmp(alias->name, name)) return alias; @@ -505,7 +512,7 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, co= nst char *name, const char *long_desc =3D NULL, *topic =3D NULL, *unit =3D NULL, *pmu_nam= e =3D NULL; bool deprecated =3D false, perpkg =3D false; =20 - if (perf_pmu__find_alias(pmu, name)) { + if (perf_pmu__find_alias(pmu, name, /*load=3D*/ false)) { /* Alias was already created/loaded. */ return 0; } @@ -611,18 +618,33 @@ static inline bool pmu_alias_info_file(char *name) } =20 /* - * Process all the sysfs attributes located under the directory - * specified in 'dir' parameter. + * Reading the pmu event aliases definition, which should be located at: + * /sys/bus/event_source/devices//events as sysfs group attributes. */ -static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd) +static int pmu_aliases_parse(struct perf_pmu *pmu) { + char path[PATH_MAX]; struct dirent *evt_ent; DIR *event_dir; - int fd; + size_t len; + int fd, dir_fd; =20 - event_dir =3D fdopendir(dirfd); - if (!event_dir) + len =3D perf_pmu__event_source_devices_scnprintf(path, sizeof(path)); + if (!len) + return 0; + scnprintf(path + len, sizeof(path) - len, "%s/events", pmu->name); + + dir_fd =3D open(path, O_DIRECTORY); + if (dir_fd =3D=3D -1) { + pmu->sysfs_aliases_loaded =3D true; + return 0; + } + + event_dir =3D fdopendir(dir_fd); + if (!event_dir){ + close (dir_fd); return -EINVAL; + } =20 while ((evt_ent =3D readdir(event_dir))) { char *name =3D evt_ent->d_name; @@ -637,7 +659,7 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int = dirfd) if (pmu_alias_info_file(name)) continue; =20 - fd =3D openat(dirfd, name, O_RDONLY); + fd =3D openat(dir_fd, name, O_RDONLY); if (fd =3D=3D -1) { pr_debug("Cannot open %s\n", name); continue; @@ -655,25 +677,8 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int= dirfd) } =20 closedir(event_dir); - return 0; -} - -/* - * Reading the pmu event aliases definition, which should be located at: - * /sys/bus/event_source/devices//events as sysfs group attributes. - */ -static int pmu_aliases(struct perf_pmu *pmu, int dirfd, const char *name) -{ - int fd; - - fd =3D perf_pmu__pathname_fd(dirfd, name, "events", O_DIRECTORY); - if (fd < 0) - return 0; - - /* it'll close the fd */ - if (pmu_aliases_parse(pmu, fd)) - return -1; - + close (dir_fd); + pmu->sysfs_aliases_loaded =3D true; return 0; } =20 @@ -1017,13 +1022,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *= pmus, int dirfd, const char free(pmu); return NULL; } - /* - * Check the aliases first to avoid unnecessary work. - */ - if (pmu_aliases(pmu, dirfd, name)) { - free(pmu); - return NULL; - } pmu->is_core =3D is_pmu_core(name); pmu->cpus =3D pmu_cpumask(dirfd, name, pmu->is_core); =20 @@ -1438,7 +1436,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct p= erf_pmu *pmu, return NULL; } =20 - alias =3D perf_pmu__find_alias(pmu, name); + alias =3D perf_pmu__find_alias(pmu, name, /*load=3D*/ true); if (alias || pmu->cpu_aliases_added) return alias; =20 @@ -1447,7 +1445,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct p= erf_pmu *pmu, pmu_events_table__find_event(pmu->events_table, pmu, name, pmu_add_cpu_aliases_map_callback, pmu) =3D=3D 0) { - alias =3D perf_pmu__find_alias(pmu, name); + alias =3D perf_pmu__find_alias(pmu, name, /*load=3D*/ false); } return alias; } @@ -1620,7 +1618,7 @@ bool perf_pmu__auto_merge_stats(const struct perf_pmu= *pmu) =20 bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name) { - if (perf_pmu__find_alias(pmu, name) !=3D NULL) + if (perf_pmu__find_alias(pmu, name, /*load=3D*/ true) !=3D NULL) return true; if (pmu->cpu_aliases_added || !pmu->events_table) return false; @@ -1629,7 +1627,12 @@ bool perf_pmu__have_event(struct perf_pmu *pmu, cons= t char *name) =20 size_t perf_pmu__num_events(struct perf_pmu *pmu) { - size_t nr =3D pmu->sysfs_aliases; + size_t nr; + + if (!pmu->sysfs_aliases_loaded) + pmu_aliases_parse(pmu); + + nr =3D pmu->sysfs_aliases; =20 if (pmu->cpu_aliases_added) nr +=3D pmu->loaded_json_aliases; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 288d2908382a..bae0de3ed7a5 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -122,6 +122,8 @@ struct perf_pmu { uint32_t sysfs_aliases; /** @sysfs_aliases: Number of json event aliases loaded. */ uint32_t loaded_json_aliases; + /** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */ + bool sysfs_aliases_loaded; /** * @cpu_aliases_added: Have all json events table entries for the PMU * been added? --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:50 2025 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 DEE34C27C40 for ; Thu, 24 Aug 2023 04:15:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240269AbjHXEPX (ORCPT ); Thu, 24 Aug 2023 00:15:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240131AbjHXEOg (ORCPT ); Thu, 24 Aug 2023 00:14:36 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66E1B1721 for ; Wed, 23 Aug 2023 21:14:29 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id d9443c01a7336-1bf60f85d78so69713415ad.3 for ; Wed, 23 Aug 2023 21:14:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850468; x=1693455268; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=7+7xUX+eQzSie7iWr2Aj1jLiysTzidRjiqSjjI4y5Nk=; b=uU1EeSRyWsOnWw8WEo2g3bS2sR9n78nACyt4JfvClGGDbCVGCoCvCZsQqpt+AZ2CTq YJEBNspR5QYXGNXUpidC8y0uaV+h7RkN0R7zg1zvA68LMQEI9jZNhJIz+AIWj7xTqKZY sGd4skfuyBLEAIwqroRuh3zqwCrbNAN3HOL5zEa2N+N32q+VSOPHHDCFR9w9zPx6b4EM gDIjcYujmVBTUEpsWKx9sWxNG3D7VVdjyVjG0gMmuKOJz2uoOYL7PcyRLEr6mZ+k9AZu pvuGWtNZ4aB2ftmOL3awDgXXaWf+LlBLNLKgjQE+swgMFHKB0Hqui0F3ABcQ3LGfGS7j AR2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850468; x=1693455268; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7+7xUX+eQzSie7iWr2Aj1jLiysTzidRjiqSjjI4y5Nk=; b=dLmoTIXKJncX2KzsxeCOxa3CJOTA2SS0j7+IMcxDLwlI9Oqnu8hWAVro1O3Kfqi9J7 ebuh9zheQ0rQkJl02xRpYWU77KGLr9jXLb3Dq5JzJuHU8Y6Xn6hc1G8Vn8VBtTBw7XQd 4zWC8Zjs+l9yvMqvk1hdBASn6eUWE3poGOqf32ZYE8TR+3ArduNa4i6eE1z1FCWPgFg4 PEqwaoJvWXD3gDcUF/E7lF9pz6g9uS8FNY4Cs1oYbolVB7p9LIpKDwSPzOwj9+LSW4D9 PpPIo/oyeC45C8l5TZuMojQaESkpquh6PJu5KFERCnOUkLhKPHaUHUGR7pXd1d9q9Qvr dO+A== X-Gm-Message-State: AOJu0Ywk/6PPkAyFxYzU9tM2EN1iE1N8nXxp53+mdYXpgyoD4sQjx9/l piLq2vmjhDi/mOA3Q7d8r11EVrJnGC7L X-Google-Smtp-Source: AGHT+IGUdFfyT2rsPjoGhQ7i1sFxV31nUqycJqtfiepKpwR//LF7/kpDZWU4+yRSyscZ09VLHA9H44SdCBhF X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a17:902:fb05:b0:1b8:a593:7568 with SMTP id le5-20020a170902fb0500b001b8a5937568mr5165739plb.8.1692850468304; Wed, 23 Aug 2023 21:14:28 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:29 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-18-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 17/18] perf jevents: Sort strings in the big C string to reduce faults From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org 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 strings within the big C string based on whether they were for a metric and then by when they were added. This helps group related strings and reduce minor faults by approximately 10 in 1740, about 0.57%. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/jevents.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 01335a452e70..e5bce57f5688 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -113,13 +113,24 @@ class BigCString: strings: Set[str] big_string: Sequence[str] offsets: Dict[str, int] + insert_number: int + insert_point: Dict[str, int] + metrics: Set[str] =20 def __init__(self): self.strings =3D set() + self.insert_number =3D 0; + self.insert_point =3D {} + self.metrics =3D set() =20 - def add(self, s: str) -> None: + def add(self, s: str, metric: bool) -> None: """Called to add to the big string.""" - self.strings.add(s) + if s not in self.strings: + self.strings.add(s) + self.insert_point[s] =3D self.insert_number + self.insert_number +=3D 1 + if metric: + self.metrics.add(s) =20 def compute(self) -> None: """Called once all strings are added to compute the string and offsets= .""" @@ -160,8 +171,11 @@ class BigCString: self.big_string =3D [] self.offsets =3D {} =20 + def string_cmp_key(s: str) -> Tuple[bool, int, str]: + return (s in self.metrics, self.insert_point[s], s) + # Emit all strings that aren't folded in a sorted manner. - for s in sorted(self.strings): + for s in sorted(self.strings, key=3Dstring_cmp_key): if s not in folded_strings: self.offsets[s] =3D big_string_offset self.big_string.append(f'/* offset=3D{big_string_offset} */ "') @@ -574,19 +588,20 @@ def preprocess_one_file(parents: Sequence[str], item:= os.DirEntry) -> None: assert len(mgroup) > 1, parents description =3D f"{metricgroup_descriptions[mgroup]}\\000" mgroup =3D f"{mgroup}\\000" - _bcs.add(mgroup) - _bcs.add(description) + _bcs.add(mgroup, metric=3DTrue) + _bcs.add(description, metric=3DTrue) _metricgroups[mgroup] =3D description return =20 topic =3D get_topic(item.name) for event in read_json_events(item.path, topic): pmu_name =3D f"{event.pmu}\\000" - _bcs.add(pmu_name) if event.name: - _bcs.add(event.build_c_string(metric=3DFalse)) + _bcs.add(pmu_name, metric=3DFalse) + _bcs.add(event.build_c_string(metric=3DFalse), metric=3DFalse) if event.metric_name: - _bcs.add(event.build_c_string(metric=3DTrue)) + _bcs.add(pmu_name, metric=3DTrue) + _bcs.add(event.build_c_string(metric=3DTrue), metric=3DTrue) =20 def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None: """Process a JSON file during the main walk.""" --=20 2.42.0.rc1.204.g551eb34607-goog From nobody Tue Dec 16 19:54:50 2025 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 04630C71153 for ; Thu, 24 Aug 2023 04:15:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240125AbjHXEPc (ORCPT ); Thu, 24 Aug 2023 00:15:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240195AbjHXEOk (ORCPT ); Thu, 24 Aug 2023 00:14:40 -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 C5C7D173F for ; Wed, 23 Aug 2023 21:14:31 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id 98e67ed59e1d1-26f9107479bso3050629a91.1 for ; Wed, 23 Aug 2023 21:14:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692850471; x=1693455271; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=TvLE3Spqr0cSOEv2xXiI7FCQdeqKmdObep26XyHFaEA=; b=0vO41xS+LjkPKHDjpVXscNfFqCSMB7ITBrNVNeAk4Paz3gQXB5fvmRpMFfRSHETaP2 aWU5eGIqYfFxKw+xRhKJowSWPm4if1XXtvaK8jHr3Gl2D0gCNqpCyRlphUWMW4iADo1T u7xoBk9UE9lhEz+7eAVJA1J3k8gyH0RBLnGFbPdHrsWFlfdSW1atQLY2nUSwXYTL6FsI 5cMZ65p7NE8Og8x8tBSXL5p8EoNthY/nwicaGIYjkFKWquqYC8FdAyc6wiGsTvUP8NDo 99j0fBniQII3hw9CiE9JObznBCYs2OstumIbMBXTR7I+QJFLl6ixvJ76b6bYEs0R4Kk0 XNnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692850471; x=1693455271; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=TvLE3Spqr0cSOEv2xXiI7FCQdeqKmdObep26XyHFaEA=; b=ID42gAwngfGZMWDwXo5symXjD62rbZX0f9XDkKAjd+qtuwTtotCRVkb9OMcypln7+D gd97m61Xu5y4YlRCeT5XNdcFXCrUNkNuY2ReC1e0wkfVDPojlfnpDNdlDuc6C+RTCfxp 2UhrETSCNIZjl2vzNe8fvpWOWVhyoTZQk1avp0kHsmWed2RuvTypNKIGmp3Sw2graxc7 JFffZqtd0Eub4m7oXFphUtREVgD1UEx7Jy/V2pqtHhH+ulEk+nAfM2yaC8XJVl2/Vh2B b2pkfPItcuJFo0WCGftjv/BBt2khuau2DIC0dUU0iAyRf8VbRaFsrFHwGH9R1Fi67sKv locw== X-Gm-Message-State: AOJu0YyhneRRy6hCiYqasKhxezUTcbEBOFes+QIB363xys/gytuk/7qs KlPeDgs6vM/L1cxywO/kh/+a8a3TcyC9 X-Google-Smtp-Source: AGHT+IGPxDqYXAjpEC8kRChbVf9bd4e24xHLGbDbs7LLn6nrJmUfFHbxUsGqfUXPUGgYxtzWEGqbel03lsJ6 X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:fbb9:d9e7:7405:2651]) (user=irogers job=sendgmr) by 2002:a17:90a:d80c:b0:26c:fab1:9e23 with SMTP id a12-20020a17090ad80c00b0026cfab19e23mr3745874pjv.0.1692850471230; Wed, 23 Aug 2023 21:14:31 -0700 (PDT) Date: Wed, 23 Aug 2023 21:13:30 -0700 In-Reply-To: <20230824041330.266337-1-irogers@google.com> Message-Id: <20230824041330.266337-19-irogers@google.com> Mime-Version: 1.0 References: <20230824041330.266337-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Subject: [PATCH v2 18/18] perf jevents: Don't append Unit to desc From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , James Clark , Kan Liang , John Garry , Kajol Jain , Jing Zhang , Ravi Bangoria , Rob Herring , Gaosheng Cui , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Unit with the PMU name is appended to desc in jevents.py, but on hybrid platforms it causes the desc to differ from the regular non-hybrid system with a PMU of 'cpu'. Having differing descs means the events don't deduplicate. To make the perf list output not differ, append the Unit on again in the perf list printing code. On x86 reduces the binary size by 409,600 bytes or about 4%. Signed-off-by: Ian Rogers --- tools/perf/builtin-list.c | 13 ++++++++++++- tools/perf/pmu-events/jevents.py | 7 ------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 7fec2cca759f..d8b9f606e734 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -145,9 +145,20 @@ static void default_print_event(void *ps, const char *= pmu_name, const char *topi putchar('\n'); =20 if (desc && print_state->desc) { + char *desc_with_unit =3D NULL; + int desc_len =3D -1; + + if (pmu_name && strcmp(pmu_name, "cpu")) { + desc_len =3D strlen(desc); + desc_len =3D asprintf(&desc_with_unit, + desc[desc_len - 1] !=3D '.' + ? "%s. Unit: %s" : "%s Unit: %s", + desc, pmu_name); + } printf("%*s", 8, "["); - wordwrap(desc, 8, pager_get_columns(), 0); + wordwrap(desc_len > 0 ? desc_with_unit : desc, 8, pager_get_columns(), 0= ); printf("]\n"); + free(desc_with_unit); } long_desc =3D long_desc ?: desc; if (long_desc && print_state->long_desc) { diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index e5bce57f5688..712f80d7d071 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -357,13 +357,6 @@ class JsonEvent: self.desc +=3D extra_desc if self.long_desc and extra_desc: self.long_desc +=3D extra_desc - if self.pmu and self.pmu !=3D 'cpu': - if not self.desc: - self.desc =3D 'Unit: ' + self.pmu - else: - if not self.desc.endswith('. '): - self.desc +=3D '. ' - self.desc +=3D 'Unit: ' + self.pmu if arch_std: if arch_std.lower() in _arch_std_events: event =3D _arch_std_events[arch_std.lower()].event --=20 2.42.0.rc1.204.g551eb34607-goog