From nobody Mon Oct 6 03:13:59 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 2DC93257AC2 for ; Fri, 25 Jul 2025 18:52:21 +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=1753469545; cv=none; b=phy1jCjqH781fipr2Z0EH2gqbcrqjYu/a9KpbgvBVIWnYiLlKT9cjXpj3tVJzJPQp7wjL8CK54wqAeiEYMncUEjBuaEaXi3D+t7VaAgr9TLlgUb8cjVBzYRtNBSWJAY2ApKA6HkApDyCnAY5byQ+R1nFhSpsJmuLmhIk6ZdL+l0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469545; c=relaxed/simple; bh=0fW5uKhoqUMu6t/2+fOCxERGXZX+hkR8WxQ95mw2OFI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hpViY0j0qeqWRuqlK83R8k7QweSiNUcnM1ycRywhY8qaxZrert8CDlg5PHYlcPUgGQPpubOoERK9nRCWmAHySEYZZHND+jEGzY4+31wfouXigrmladhen8wvkK94+cSV2RZ6LIBVm7JgQzuZgGCKbM7CstsdK7D4vSLQ3/JQLCE= 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=0hkIKyJu; 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="0hkIKyJu" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-3121cffd7e8so2094699a91.0 for ; Fri, 25 Jul 2025 11:52:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469541; x=1754074341; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=iY4LHvEGR54Ap9oyuafzbxQtWKQpZaO9JTXpL1G/L5Y=; b=0hkIKyJuHSJSkweIZn8FaaBJw+/9ImK6yNoBHMuqGq/1pGCqc9WzYFza8ptJGwa68+ cUYHWBTozXcEE8CScPswMkgXuibQNlschS7vBXQkoEQZPfD2f+FXZBxhQfQS9e3c+yW7 m1PT3YTvAKnH7v/0YSezAi+ughKXnZwtu8iqA9noC+OpUyr7TqJALeQf4GhVdfCHDJD7 OjdO6aYrowwCMNykKXBtnL/AewMTA248dh2s9OqVVH92NYe7WFZTHGwwSez2J2sjvYco 6WqjVV2ACge5S6CBXOkuqazNOZbnKpUUX9aGm5U11tUNYspBSwnzUwrLYUQ3Gp/v26wJ N74Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469541; x=1754074341; h=cc: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=iY4LHvEGR54Ap9oyuafzbxQtWKQpZaO9JTXpL1G/L5Y=; b=OIf1K28wXZdjsORBmRL+zI+elIcso+XIPlGNsOmIVNNTNSq4ZbrPLo06Lfi68LFhBW h22amaHoUcYWWGG4LmwlAkiDLPHgm/cuKXnPzMDKWKuUNjzpQexRtYNqVgISlQRZdGvA QE8ehDT6WHnlobh6KwlZebhd+dNijkVkHaBm+ZsFcApRYzm/+jJrMr4rPOW7+hUX0+pN nx+V8luvDrD5wa9W6/aQOs9x5MPrNAaGIcXp5SFNRBSJpfsclt/Glof6kIHMX3PFY7Le ueic2Ww9Qt77pbWa51Ihwxka8Dy/KnJZruqQlxuVD+29Ji/IIGPp0flx7Qt+RiAMvFUO eP6A== X-Forwarded-Encrypted: i=1; AJvYcCX9oNn1idqKRssWBXpV29Ryh5Le7K86BiqXc0cv71/Ln/V7dXn5SJwCW6thSK+P8giyoXh2KomCuXMapqo=@vger.kernel.org X-Gm-Message-State: AOJu0YzBzILEvQKpjMWVdb5OXjb+IDDSGgjgCNVb0oCWxBRgscTs6Zcq i+sgBeyK9ttp2PuSfnTzCvkl3L1yaXJq2ntlzYSNkzHz3HGxvZZfVq3zJxZikSCZHCr7a+ZrCve 6ROGbLXDPHA== X-Google-Smtp-Source: AGHT+IFTbpi7Qo/ciLALO0Gyufr7lG9u28hr2ETmyaA2R8YBtZ0mm7hNkzV+Dxa5kLDsJMnRCI07qseDccgq X-Received: from pjqz1.prod.google.com ([2002:a17:90a:b101:b0:31e:74cb:7677]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:134e:b0:311:9c9a:58ca with SMTP id 98e67ed59e1d1-31e7788a6aemr4681561a91.8.1753469541405; Fri, 25 Jul 2025 11:52:21 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:51 -0700 In-Reply-To: <20250725185202.68671-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: <20250725185202.68671-1-irogers@google.com> X-Mailer: git-send-email 2.50.1.552.g942d659e1b-goog Message-ID: <20250725185202.68671-6-irogers@google.com> Subject: [PATCH v9 05/16] perf tp_pmu: Add event APIs 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 Cc: Arnaldo Carvalho de Melo Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add event APIs for the tracepoint PMU allowing things like perf list to function using it. For perf list add the tracepoint format in the long description (shown with -v). Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 7 +++ tools/perf/util/tp_pmu.c | 115 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/tp_pmu.h | 7 +++ 3 files changed, 129 insertions(+) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f3da6e27bfcb..5a291f1380ed 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -24,6 +24,7 @@ #include "hwmon_pmu.h" #include "pmus.h" #include "tool_pmu.h" +#include "tp_pmu.h" #include #include #include "parse-events.h" @@ -1983,6 +1984,8 @@ bool perf_pmu__have_event(struct perf_pmu *pmu, const= char *name) return false; if (perf_pmu__is_tool(pmu) && tool_pmu__skip_event(name)) return false; + if (perf_pmu__is_tracepoint(pmu)) + return tp_pmu__have_event(pmu, name); if (perf_pmu__is_hwmon(pmu)) return hwmon_pmu__have_event(pmu, name); if (perf_pmu__is_drm(pmu)) @@ -1998,6 +2001,8 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu) { size_t nr; =20 + if (perf_pmu__is_tracepoint(pmu)) + return tp_pmu__num_events(pmu); if (perf_pmu__is_hwmon(pmu)) return hwmon_pmu__num_events(pmu); if (perf_pmu__is_drm(pmu)) @@ -2068,6 +2073,8 @@ int perf_pmu__for_each_event(struct perf_pmu *pmu, bo= ol skip_duplicate_pmus, struct hashmap_entry *entry; size_t bkt; =20 + if (perf_pmu__is_tracepoint(pmu)) + return tp_pmu__for_each_event(pmu, state, cb); if (perf_pmu__is_hwmon(pmu)) return hwmon_pmu__for_each_event(pmu, state, cb); if (perf_pmu__is_drm(pmu)) diff --git a/tools/perf/util/tp_pmu.c b/tools/perf/util/tp_pmu.c index 42bd967a4530..e7534a973247 100644 --- a/tools/perf/util/tp_pmu.c +++ b/tools/perf/util/tp_pmu.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) #include "tp_pmu.h" +#include "pmus.h" #include #include #include @@ -93,3 +94,117 @@ int tp_pmu__for_each_tp_sys(void *state, tp_sys_callbac= k cb) close(events_dir.dirfd); return ret; } + +bool perf_pmu__is_tracepoint(const struct perf_pmu *pmu) +{ + return pmu->type =3D=3D PERF_TYPE_TRACEPOINT; +} + +struct for_each_event_args { + void *state; + pmu_event_callback cb; + const struct perf_pmu *pmu; +}; + +static int for_each_event_cb(void *state, const char *sys_name, const char= *evt_name) +{ + struct for_each_event_args *args =3D state; + char name[2 * FILENAME_MAX + 2]; + /* 16 possible hex digits and 22 other characters and \0. */ + char encoding[16 + 22]; + char *format =3D NULL; + size_t format_size; + struct pmu_event_info info =3D { + .pmu =3D args->pmu, + .pmu_name =3D args->pmu->name, + .event_type_desc =3D "Tracepoint event", + }; + char *tp_dir =3D get_events_file(sys_name); + char path[PATH_MAX]; + int id, err; + + if (!tp_dir) + return -1; + + scnprintf(path, sizeof(path), "%s/%s/id", tp_dir, evt_name); + err =3D filename__read_int(path, &id); + if (err =3D=3D 0) { + snprintf(encoding, sizeof(encoding), "tracepoint/config=3D0x%x/", id); + info.encoding_desc =3D encoding; + } + + scnprintf(path, sizeof(path), "%s/%s/format", tp_dir, evt_name); + put_events_file(tp_dir); + err =3D filename__read_str(path, &format, &format_size); + if (err =3D=3D 0) { + info.long_desc =3D format; + for (size_t i =3D 0 ; i < format_size; i++) { + /* Swap tabs to spaces due to some rendering issues. */ + if (format[i] =3D=3D '\t') + format[i] =3D ' '; + } + } + snprintf(name, sizeof(name), "%s:%s", sys_name, evt_name); + info.name =3D name; + err =3D args->cb(args->state, &info); + free(format); + return err; +} + +static int for_each_event_sys_cb(void *state, const char *sys_name) +{ + return tp_pmu__for_each_tp_event(sys_name, state, for_each_event_cb); +} + +int tp_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_ca= llback cb) +{ + struct for_each_event_args args =3D { + .state =3D state, + .cb =3D cb, + .pmu =3D pmu, + }; + + return tp_pmu__for_each_tp_sys(&args, for_each_event_sys_cb); +} + +static int num_events_cb(void *state, const char *sys_name __maybe_unused, + const char *evt_name __maybe_unused) +{ + size_t *count =3D state; + + (*count)++; + return 0; +} + +static int num_events_sys_cb(void *state, const char *sys_name) +{ + return tp_pmu__for_each_tp_event(sys_name, state, num_events_cb); +} + +size_t tp_pmu__num_events(struct perf_pmu *pmu __maybe_unused) +{ + size_t count =3D 0; + + tp_pmu__for_each_tp_sys(&count, num_events_sys_cb); + return count; +} + +bool tp_pmu__have_event(struct perf_pmu *pmu __maybe_unused, const char *n= ame) +{ + char *dup_name, *colon; + int id; + + colon =3D strchr(name, ':'); + if (colon =3D=3D NULL) + return false; + + dup_name =3D strdup(name); + if (!dup_name) + return false; + + colon =3D dup_name + (colon - name); + *colon =3D '\0'; + id =3D tp_pmu__id(dup_name, colon + 1); + free(dup_name); + return id >=3D 0; +} diff --git a/tools/perf/util/tp_pmu.h b/tools/perf/util/tp_pmu.h index 49537303bd73..30456bd6943d 100644 --- a/tools/perf/util/tp_pmu.h +++ b/tools/perf/util/tp_pmu.h @@ -2,6 +2,8 @@ #ifndef __TP_PMU_H #define __TP_PMU_H =20 +#include "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); =20 @@ -9,4 +11,9 @@ 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); =20 +bool perf_pmu__is_tracepoint(const struct perf_pmu *pmu); +int tp_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_ca= llback cb); +size_t tp_pmu__num_events(struct perf_pmu *pmu); +bool tp_pmu__have_event(struct perf_pmu *pmu, const char *name); + #endif /* __TP_PMU_H */ --=20 2.50.1.552.g942d659e1b-goog