From nobody Fri Oct 10 08:24:27 2025 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C20C31FAC4D for ; Mon, 16 Jun 2025 05:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750050954; cv=none; b=oTaiVj/sAd+UH4B+RvfZnybMk8FJzc3L/XA6J7kaIvgaUwIX/f1odQO7Q+gX5I7PPtqMbfZg6hQ379DJaA3QWGWt+MMcmpOrLwk7blOz6xnfV06CCKRFZkfm6JbOENMgWRim3TB/HbLd31UWyFEGusfpmlKCTMLDKgKEzkQ8ovw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750050954; c=relaxed/simple; bh=1MWPyFOi1/GoUcsqXK25Y3904s3Kehm3Fw9Fh/2O+gk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=qxD8x3t5+OjC/KH9bFvT6+p7BBJL5vivjP1tfOa7zFF5S5RImPG8FM9JEQhMRVl0jCJXi6WvoURxS4VT4NDm/9v4qjF9U9yqad3l13NQfAqVEW7llWniSPaGmgcvOU+bFsSDVNfJvjS+0M4oED+fKntirh8MYxMJQHBYcQSg2Ec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=MFd3wGQ9; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="MFd3wGQ9" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-31202bbaafaso3759420a91.1 for ; Sun, 15 Jun 2025 22:15:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1750050951; x=1750655751; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=kFCa6TUdPFwTF6/gzbUNjOw6rOCDbrBUWir2XCQ0ybg=; b=MFd3wGQ9xpx2da8hkV59hDirg70EAcAa5KfQK8SxAEdibbKldWVIKpb+ZCWRznQdUH kqrU6TNGRzyPJUOGWPiMHw8dkq+yHQ2uxBDdF7v/RY5Ne+jTau9y0hUYVv0a9QhGXJCP H3NXXwWHS6Uqzr8jURuQDDeXQBbFnrgOONySC3j6KLj0KlqecKUWO8hdVlnHSnNxsbN5 uZrnycGF89k1M9MlcIjUPPYN0IbGbCIBe4j8Av0NRDkmMpuFMSLt0GdLC9VXmjv+7Iue J+97iMjXfjrmOEFZZAn7rE32DTNXOQoAu3oyIaeDE/KhQzLK8aHWO98miWxWzt18bADF TNKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750050951; x=1750655751; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kFCa6TUdPFwTF6/gzbUNjOw6rOCDbrBUWir2XCQ0ybg=; b=DzWMiNKAySiHATBAMHZVrLeTG0TicMNE2eBtNKR5aDU7ghOAugyZeyDVCvS7CPLi+a DvshIQ3A1qoaeNh4vZavjlgergZjZrKvi1Vfd8Mn56ysYI7Om7f6sEBmW4E1eTXDmLNM bPYe1pUjZEl3/SOMVCWg+LKd84R1OqzZCJJWIa+428FIJ0hk12ILL5CWp2PD77g7tr53 GFEjwh0rn/Ea7mmSdqcy0FJB2Guee1hBsAwhn3pcJ9p8aovBmhBv7A/+mEE89v0QEDAy hyjPBqnuFhWJFKA491PNQx9g2u/jhQ5AidOZCv86p7cIIj4qDI5DkN8kBJOv1ze3wlWz lZww== X-Forwarded-Encrypted: i=1; AJvYcCXuaf/4kWyXVS3KSgcp7/p/BFIQPIq7muUCXy+9pFzHVVOT7JcSgWoTxCxkwUhy/hxjife/mvQUQoVvWqs=@vger.kernel.org X-Gm-Message-State: AOJu0YwBCRxpJIjGin4eO7wqjbq46tbkCPs39LnsV4GQVHQeZtHipA/o iQ/6q6Yp+eWoPBXUHLK8kgg2icV1YlE9T0aXdIbCgjjeuq/TGq+gA7QZMR4TzcYwCc7c2R2SDGc 0TQPOVE8AzQ== X-Google-Smtp-Source: AGHT+IGUzYJwQxex/N/iBG/6ouOxN4qo6le4GQrouZ8qDvOGw8Tzly7xESr6M5dyHrZbKuG3KzpWWhFuLiwz X-Received: from pjtu3.prod.google.com ([2002:a17:90a:c883:b0:312:e914:4548]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1a87:b0:311:abba:53c0 with SMTP id 98e67ed59e1d1-313f1c03004mr12655127a91.9.1750050950842; Sun, 15 Jun 2025 22:15:50 -0700 (PDT) Date: Sun, 15 Jun 2025 22:14:57 -0700 In-Reply-To: <20250616051500.1047173-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250616051500.1047173-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.rc2.696.g1fc2a0284f-goog Message-ID: <20250616051500.1047173-13-irogers@google.com> Subject: [PATCH v3 12/15] perf tp_pmu: Factor existing tracepoint logic to new file From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , James Clark , Xu Yang , John Garry , "Masami Hiramatsu (Google)" , Howard Chu , Weilin Wang , Thomas Richter , Andi Kleen , Tiezhu Yang , Gautam Menghani , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Start the creation of a tracepoint PMU abstraction. Tracepoint events don't follow the regular sysfs perf conventions. Eventually the new PMU abstraction will bridge the gap so tracepoint events look more like regular perf ones. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/evsel.c | 21 +---- tools/perf/util/parse-events.c | 147 ++++++++++++++------------------- tools/perf/util/tp_pmu.c | 95 +++++++++++++++++++++ tools/perf/util/tp_pmu.h | 12 +++ 5 files changed, 170 insertions(+), 106 deletions(-) create mode 100644 tools/perf/util/tp_pmu.c create mode 100644 tools/perf/util/tp_pmu.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 7910d908c814..a06ff82f9dd7 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -86,6 +86,7 @@ perf-util-y +=3D pmu-flex.o perf-util-y +=3D pmu-bison.o perf-util-y +=3D hwmon_pmu.o perf-util-y +=3D tool_pmu.o +perf-util-y +=3D tp_pmu.o perf-util-y +=3D svghelper.o perf-util-y +=3D trace-event-info.o perf-util-y +=3D trace-event-scripting.o diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d55482f094bf..beab9710fbf5 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -58,6 +58,7 @@ #include "pmus.h" #include "hwmon_pmu.h" #include "tool_pmu.h" +#include "tp_pmu.h" #include "rlimit.h" #include "../perf-sys.h" #include "util/parse-branch-options.h" @@ -570,24 +571,6 @@ struct evsel *evsel__clone(struct evsel *dest, struct = evsel *orig) return NULL; } =20 -static int trace_event__id(const char *sys, const char *name) -{ - char *tp_dir =3D get_events_file(sys); - char path[PATH_MAX]; - int id, err; - - if (!tp_dir) - return -1; - - scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name); - put_events_file(tp_dir); - err =3D filename__read_int(path, &id); - if (err) - return err; - - return id; -} - /* * Returns pointer with encoded error via interface. */ @@ -621,7 +604,7 @@ struct evsel *evsel__newtp_idx(const char *sys, const c= har *name, int idx, bool event_attr_init(&attr); =20 if (format) { - id =3D trace_event__id(sys, name); + id =3D tp_pmu__id(sys, name); if (id < 0) { err =3D id; goto out_free; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 4dbae59dccb3..b3f56236fd60 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -17,13 +17,12 @@ #include "string2.h" #include "strbuf.h" #include "debug.h" -#include -#include #include #include #include #include "pmu.h" #include "pmus.h" +#include "tp_pmu.h" #include "asm/bug.h" #include "ui/ui.h" #include "util/parse-branch-options.h" @@ -33,6 +32,7 @@ #include "util/stat.h" #include "util/util.h" #include "tracepoint.h" +#include =20 #define MAX_NAME_LEN 100 =20 @@ -558,105 +558,82 @@ static int add_tracepoint(struct parse_events_state = *parse_state, return 0; } =20 -static int add_tracepoint_multi_event(struct parse_events_state *parse_sta= te, - struct list_head *list, - const char *sys_name, const char *evt_name, - struct parse_events_error *err, - struct parse_events_terms *head_config, YYLTYPE *loc) -{ - char *evt_path; - struct io_dirent64 *evt_ent; - struct io_dir evt_dir; - int ret =3D 0, found =3D 0; - - evt_path =3D get_events_file(sys_name); - if (!evt_path) { - tracepoint_error(err, errno, sys_name, evt_name, loc->first_column); - return -1; - } - io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY)= ); - if (evt_dir.dirfd < 0) { - put_events_file(evt_path); - tracepoint_error(err, errno, sys_name, evt_name, loc->first_column); - return -1; - } +struct add_tracepoint_multi_args { + struct parse_events_state *parse_state; + struct list_head *list; + const char *sys_glob; + const char *evt_glob; + struct parse_events_error *err; + struct parse_events_terms *head_config; + YYLTYPE *loc; + int found; +}; =20 - while (!ret && (evt_ent =3D io_dir__readdir(&evt_dir))) { - if (!strcmp(evt_ent->d_name, ".") - || !strcmp(evt_ent->d_name, "..") - || !strcmp(evt_ent->d_name, "enable") - || !strcmp(evt_ent->d_name, "filter")) - continue; +static int add_tracepoint_multi_event_cb(void *state, const char *sys_name= , const char *evt_name) +{ + struct add_tracepoint_multi_args *args =3D state; + int ret; =20 - if (!strglobmatch(evt_ent->d_name, evt_name)) - continue; + if (!strglobmatch(evt_name, args->evt_glob)) + return 0; =20 - found++; + args->found++; + ret =3D add_tracepoint(args->parse_state, args->list, sys_name, evt_name, + args->err, args->head_config, args->loc); =20 - ret =3D add_tracepoint(parse_state, list, sys_name, evt_ent->d_name, - err, head_config, loc); - } + return ret; +} =20 - if (!found) { - tracepoint_error(err, ENOENT, sys_name, evt_name, loc->first_column); - ret =3D -1; +static int add_tracepoint_multi_event(struct add_tracepoint_multi_args *ar= gs, const char *sys_name) +{ + if (strpbrk(args->evt_glob, "*?") =3D=3D NULL) { + /* Not a glob. */ + args->found++; + return add_tracepoint(args->parse_state, args->list, sys_name, args->evt= _glob, + args->err, args->head_config, args->loc); } =20 - put_events_file(evt_path); - close(evt_dir.dirfd); - return ret; + return tp_pmu__for_each_tp_event(sys_name, args, add_tracepoint_multi_eve= nt_cb); } =20 -static int add_tracepoint_event(struct parse_events_state *parse_state, - struct list_head *list, - const char *sys_name, const char *evt_name, - struct parse_events_error *err, - struct parse_events_terms *head_config, YYLTYPE *loc) +static int add_tracepoint_multi_sys_cb(void *state, const char *sys_name) { - return strpbrk(evt_name, "*?") ? - add_tracepoint_multi_event(parse_state, list, sys_name, evt_name, - err, head_config, loc) : - add_tracepoint(parse_state, list, sys_name, evt_name, - err, head_config, loc); + struct add_tracepoint_multi_args *args =3D state; + + if (!strglobmatch(sys_name, args->sys_glob)) + return 0; + + return add_tracepoint_multi_event(args, sys_name); } =20 static int add_tracepoint_multi_sys(struct parse_events_state *parse_state, struct list_head *list, - const char *sys_name, const char *evt_name, + const char *sys_glob, const char *evt_glob, struct parse_events_error *err, struct parse_events_terms *head_config, YYLTYPE *loc) { - struct io_dirent64 *events_ent; - struct io_dir events_dir; - int ret =3D 0; - char *events_dir_path =3D get_tracing_file("events"); + struct add_tracepoint_multi_args args =3D { + .parse_state =3D parse_state, + .list =3D list, + .sys_glob =3D sys_glob, + .evt_glob =3D evt_glob, + .err =3D err, + .head_config =3D head_config, + .loc =3D loc, + .found =3D 0, + }; + int ret; =20 - if (!events_dir_path) { - tracepoint_error(err, errno, sys_name, evt_name, loc->first_column); - return -1; + if (strpbrk(sys_glob, "*?") =3D=3D NULL) { + /* Not a glob. */ + ret =3D add_tracepoint_multi_event(&args, sys_glob); + } else { + ret =3D tp_pmu__for_each_tp_sys(&args, add_tracepoint_multi_sys_cb); } - io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY |= O_RDONLY)); - put_events_file(events_dir_path); - if (events_dir.dirfd < 0) { - tracepoint_error(err, errno, sys_name, evt_name, loc->first_column); - return -1; + if (args.found =3D=3D 0) { + tracepoint_error(err, ENOENT, sys_glob, evt_glob, loc->first_column); + return -ENOENT; } - - while (!ret && (events_ent =3D io_dir__readdir(&events_dir))) { - if (!strcmp(events_ent->d_name, ".") - || !strcmp(events_ent->d_name, "..") - || !strcmp(events_ent->d_name, "enable") - || !strcmp(events_ent->d_name, "header_event") - || !strcmp(events_ent->d_name, "header_page")) - continue; - - if (!strglobmatch(events_ent->d_name, sys_name)) - continue; - - ret =3D add_tracepoint_event(parse_state, list, events_ent->d_name, - evt_name, err, head_config, loc); - } - close(events_dir.dirfd); return ret; } =20 @@ -1348,12 +1325,8 @@ int parse_events_add_tracepoint(struct parse_events_= state *parse_state, return -EINVAL; } =20 - if (strpbrk(sys, "*?")) - return add_tracepoint_multi_sys(parse_state, list, sys, event, - err, head_config, loc); - else - return add_tracepoint_event(parse_state, list, sys, event, - err, head_config, loc); + return add_tracepoint_multi_sys(parse_state, list, sys, event, + err, head_config, loc); } =20 static int __parse_events_add_numeric(struct parse_events_state *parse_sta= te, diff --git a/tools/perf/util/tp_pmu.c b/tools/perf/util/tp_pmu.c new file mode 100644 index 000000000000..fd83164f8763 --- /dev/null +++ b/tools/perf/util/tp_pmu.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +#include "tp_pmu.h" +#include +#include +#include +#include +#include +#include + +int tp_pmu__id(const char *sys, const char *name) +{ + char *tp_dir =3D get_events_file(sys); + char path[PATH_MAX]; + int id, err; + + if (!tp_dir) + return -1; + + scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name); + put_events_file(tp_dir); + err =3D filename__read_int(path, &id); + if (err) + return err; + + return id; +} + + +int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callb= ack cb) +{ + char *evt_path; + struct io_dirent64 *evt_ent; + struct io_dir evt_dir; + int ret =3D 0; + + evt_path =3D get_events_file(sys); + if (!evt_path) + return -errno; + + io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY)= ); + if (evt_dir.dirfd < 0) { + ret =3D -errno; + put_events_file(evt_path); + return ret; + } + put_events_file(evt_path); + + while (!ret && (evt_ent =3D io_dir__readdir(&evt_dir))) { + if (!strcmp(evt_ent->d_name, ".") + || !strcmp(evt_ent->d_name, "..") + || !strcmp(evt_ent->d_name, "enable") + || !strcmp(evt_ent->d_name, "filter")) + continue; + + ret =3D cb(state, sys, evt_ent->d_name); + if (ret) + break; + } + close(evt_dir.dirfd); + return ret; +} + +int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb) +{ + struct io_dirent64 *events_ent; + struct io_dir events_dir; + int ret =3D 0; + char *events_dir_path =3D get_tracing_file("events"); + + if (!events_dir_path) + return -errno; + + io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY |= O_RDONLY)); + if (events_dir.dirfd < 0) { + ret =3D -errno; + put_events_file(events_dir_path); + return ret; + } + put_events_file(events_dir_path); + + while (!ret && (events_ent =3D io_dir__readdir(&events_dir))) { + if (!strcmp(events_ent->d_name, ".") + || !strcmp(events_ent->d_name, "..") + || !strcmp(events_ent->d_name, "enable") + || !strcmp(events_ent->d_name, "header_event") + || !strcmp(events_ent->d_name, "header_page")) + continue; + + ret =3D cb(state, events_ent->d_name); + if (ret) + break; + } + close(events_dir.dirfd); + return ret; +} diff --git a/tools/perf/util/tp_pmu.h b/tools/perf/util/tp_pmu.h new file mode 100644 index 000000000000..49537303bd73 --- /dev/null +++ b/tools/perf/util/tp_pmu.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +#ifndef __TP_PMU_H +#define __TP_PMU_H + +typedef int (*tp_sys_callback)(void *state, const char *sys_name); +typedef int (*tp_event_callback)(void *state, const char *sys_name, const = char *evt_name); + +int tp_pmu__id(const char *sys, const char *name); +int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callb= ack cb); +int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb); + +#endif /* __TP_PMU_H */ --=20 2.50.0.rc2.696.g1fc2a0284f-goog