From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (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 D61012FD88C for ; Thu, 10 Jul 2025 20:37:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179832; cv=none; b=i1hY8NxMPk5g3BLr1r9Hh1qsc6jXYEBTCVPwqVg4WFWM22bg3gB+EGMCemzljwUy9ZZ9heERZ32FMdZcyoRDYVNRkloqBYc557+V2GhS/qG3QfyJsq9SQpXFLenM846BARjp0FZEwAzzx9yGkU3KU5GCId9lwyIPoul/bmt1mqA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179832; c=relaxed/simple; bh=wU3wz0df7C5ZQeeQLCPpt5hn2poNUqfyMGtKBgXp6Co=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=L5LbfssYJbj/SLOoiM59RWoZPg77ANJN+1Icg8VIw70FmlzOAX9W6iZ4EC9sp0w4yE03kBd+qgNAhZX/4DxVrzn6NdtfdWDaL2rdmED/Xbax7+HZvQAhtnjrqT+Oz2FpFY+F+x2Uq+YJ8n3023TX1i+Iw2bgxlHMEPpSicznTlM= 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=4SydLV5g; arc=none smtp.client-ip=209.85.215.202 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="4SydLV5g" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b3ba7659210so1042957a12.2 for ; Thu, 10 Jul 2025 13:37:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179829; x=1752784629; 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=wHY0GCNF2IapelErUdXSA7miepGcy18/bQ3SNGrcpTA=; b=4SydLV5graj2CCqrsundVLQymUQdsEKhmvXc41y1lt6g+roF3O7Bgxfkp4RShp+EDt PUHLch0imOvS25bc2FWNGmPq2tQfCnLEg2p6/rydqCa1zMfCrQbAaw+ZUy5AtRFWcm9U YXBI0VVJXDXqOxPhDxWMQBKNIY0zqU9RxeUqUdSNlF6SFEUx4CLXzysdhBncQcyeDpgx 8/qatjZONPx83ln/7lTKH6QZdWTSB0Cq4wiM+jrFahHOLlUtgPTYuG0drUg9S8U1QRjz GKCL3w49HHPYyuhvoRy37XcjbcHwCHuISg8TKaoWRjH4ioxqiw2lKYMFn/0yRFuHyc84 PkFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179829; x=1752784629; 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=wHY0GCNF2IapelErUdXSA7miepGcy18/bQ3SNGrcpTA=; b=UnBLnwVCkwiww3+rPBr+Mxl7Y58HuPacmw/LB1+2klOWdQqDfaalfv1nSYY0t9HG3v ZFn+z8QgaFPUa0VHUMW7rfudd7+vuglmuGbNaUdOv9u/pBc/CORtAdMKHDy5ZVR/ovmb 2xgEH8Je4fQS0cwlkRXvTN9J8a09xFZ6GKaMk6U1Mj8APAbCNQdsVZ446xjBfQ1HlFmB EyOocckK0wFhetw7VF//GKQkkgoyXAFxw8k89Tm+ZVgPoZeezUQNTHVoTjh5n+ci76+1 OrYh3r0L48ygxYW0TB6prJCBqKLYJtYjJ3UwO7molpq5Vr/2FUP173M7iJdY4ATOuJil 9q0w== X-Forwarded-Encrypted: i=1; AJvYcCU993CGajjLZ1Sra05ccYnyQ9RAX8hbnXAqLZfmTD96E3Im5B3gZHZwz6fSz1hkHwH5yez4DdyoLmMLN6k=@vger.kernel.org X-Gm-Message-State: AOJu0YxHGe1+AEk2PfPg+/Q5fIK9vs4Xa/TrioZ9g9RMZ2suxVTwHW8D y62G8lmNQBu+F+4Yn2uopFQE2D+ju2ayLEUck4rtYQaKRXqjMN0vm3Eg90k5syGFXK9OK0a7s9L uhDsIyuPRRw== X-Google-Smtp-Source: AGHT+IGx3GnfskaT85UhO6ZjCMDc8hu7BZ3VjOpbmh01XBwKwU46uYfCRLYPuwXRHZ/aGyYlFIrdU2ySbEoE X-Received: from plhi11.prod.google.com ([2002:a17:903:2ecb:b0:220:eaab:51c4]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:ec81:b0:231:c9bb:60fd with SMTP id d9443c01a7336-23dee26e24bmr6177865ad.33.1752179829291; Thu, 10 Jul 2025 13:37:09 -0700 (PDT) Date: Thu, 10 Jul 2025 13:36:45 -0700 In-Reply-To: <20250710203656.1963075-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: <20250710203656.1963075-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710203656.1963075-4-irogers@google.com> Subject: [PATCH v5 03/14] 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 , "Masami Hiramatsu (Google)" , Collin Funk , Howard Chu , Weilin Wang , Andi Kleen , "Dr. David Alan Gilbert" , Thomas Richter , Tiezhu Yang , Gautam Menghani , Thomas Falcon , Chun-Tse Shao , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org 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 12bc01c843b2..4959e7a990e4 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -88,6 +88,7 @@ perf-util-y += pmu-bison.o perf-util-y += drm_pmu.o perf-util-y += hwmon_pmu.o perf-util-y += tool_pmu.o +perf-util-y += tp_pmu.o perf-util-y += svghelper.o perf-util-y += trace-event-info.o perf-util-y += trace-event-scripting.o diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 3896a04d90af..5a1d19b4e5cd 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -59,6 +59,7 @@ #include "drm_pmu.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" @@ -571,24 +572,6 @@ struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig) return NULL; } -static int trace_event__id(const char *sys, const char *name) -{ - char *tp_dir = 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 = filename__read_int(path, &id); - if (err) - return err; - - return id; -} - /* * Returns pointer with encoded error via interface. */ @@ -622,7 +605,7 @@ struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool event_attr_init(&attr); if (format) { - id = trace_event__id(sys, name); + id = tp_pmu__id(sys, name); if (id < 0) { err = id; goto out_free; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 1ae481c9802b..f19541ca5268 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 #define MAX_NAME_LEN 100 @@ -558,105 +558,82 @@ static int add_tracepoint(struct parse_events_state *parse_state, return 0; } -static int add_tracepoint_multi_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) -{ - char *evt_path; - struct io_dirent64 *evt_ent; - struct io_dir evt_dir; - int ret = 0, found = 0; - - evt_path = 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; +}; - while (!ret && (evt_ent = 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 = state; + int ret; - if (!strglobmatch(evt_ent->d_name, evt_name)) - continue; + if (!strglobmatch(evt_name, args->evt_glob)) + return 0; - found++; + args->found++; + ret = add_tracepoint(args->parse_state, args->list, sys_name, evt_name, + args->err, args->head_config, args->loc); - ret = add_tracepoint(parse_state, list, sys_name, evt_ent->d_name, - err, head_config, loc); - } + return ret; +} - if (!found) { - tracepoint_error(err, ENOENT, sys_name, evt_name, loc->first_column); - ret = -1; +static int add_tracepoint_multi_event(struct add_tracepoint_multi_args *args, const char *sys_name) +{ + if (strpbrk(args->evt_glob, "*?") == 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); } - put_events_file(evt_path); - close(evt_dir.dirfd); - return ret; + return tp_pmu__for_each_tp_event(sys_name, args, add_tracepoint_multi_event_cb); } -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 = state; + + if (!strglobmatch(sys_name, args->sys_glob)) + return 0; + + return add_tracepoint_multi_event(args, sys_name); } 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 = 0; - char *events_dir_path = get_tracing_file("events"); + struct add_tracepoint_multi_args args = { + .parse_state = parse_state, + .list = list, + .sys_glob = sys_glob, + .evt_glob = evt_glob, + .err = err, + .head_config = head_config, + .loc = loc, + .found = 0, + }; + int ret; - if (!events_dir_path) { - tracepoint_error(err, errno, sys_name, evt_name, loc->first_column); - return -1; + if (strpbrk(sys_glob, "*?") == NULL) { + /* Not a glob. */ + ret = add_tracepoint_multi_event(&args, sys_glob); + } else { + ret = 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 == 0) { + tracepoint_error(err, ENOENT, sys_glob, evt_glob, loc->first_column); + return -ENOENT; } - - while (!ret && (events_ent = 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 = add_tracepoint_event(parse_state, list, events_ent->d_name, - evt_name, err, head_config, loc); - } - close(events_dir.dirfd); return ret; } @@ -1348,12 +1325,8 @@ int parse_events_add_tracepoint(struct parse_events_state *parse_state, return -EINVAL; } - 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); } static int __parse_events_add_numeric(struct parse_events_state *parse_state, 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 = 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 = 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_callback cb) +{ + char *evt_path; + struct io_dirent64 *evt_ent; + struct io_dir evt_dir; + int ret = 0; + + evt_path = 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 = -errno; + put_events_file(evt_path); + return ret; + } + put_events_file(evt_path); + + while (!ret && (evt_ent = 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 = 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 = 0; + char *events_dir_path = 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 = -errno; + put_events_file(events_dir_path); + return ret; + } + put_events_file(events_dir_path); + + while (!ret && (events_ent = 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 = 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_callback cb); +int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb); + +#endif /* __TP_PMU_H */ -- 2.50.0.727.gbf7dc18ff4-goog