From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (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 6BE4E252917 for ; Fri, 25 Jul 2025 18:52:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469534; cv=none; b=C7j+F2jI47l/Vm3wlGfyvao7TpiycUoayh0ThfC5YYjAQLuZFPS7HPrhEej8ujKPMpFCMI6eKGHz9eFbt7Kpj6XlT23Li5VapymN6QMemMCTT43KU8VfUmyI27ygojHudrg10WaUInw/wOd79+kdZ/Bm6lK2OTB8MAMItOaUuok= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469534; c=relaxed/simple; bh=x1oDUvRWtnxx2zf7jV9K/bE1vHUJygLj2ln3EI9Q0Jk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rdRYt3M0OPjo188cFRNSFDx/g0EPCCrEvxfYnmIx/kTS7gLABCtWfAcBAH8X3beh7pDEyk+td5m63EL/2u+uvJFBfGRvHwDDVg8YuYulrtTkGkvtTwBZOHKsn75+ncWuaZIjcEmGu5mthYLP4bbiSiLofslzZvMyl0K/q1CPRao= 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=nVL9MYlq; arc=none smtp.client-ip=209.85.214.201 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="nVL9MYlq" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2354ba59eb6so38066035ad.1 for ; Fri, 25 Jul 2025 11:52:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469533; x=1754074333; 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=vKrQy9jWlpHmx2H86IY6nleA9kDjYzDczHYTDNV4vRQ=; b=nVL9MYlqJi6xorZInpp/tVYZkEHHvIC76bgnoDOPbtliEGHUsvYONkGsSDPZRrkz0f KqaknYEku+9pTBlLYffzBmnLhwVdOICpWIUQ03wtDz02m4b0ywwaRHOzwHnkXLV7FlLI 7CP1rOcH3qBkIko9NkR4kvVC31XZI9JP6eW19LhRI+Rcq3z6Ddz0wDHzEh3tw1LuUXrg jF0mRQdpFR7htzlpYMqWsUWEiUwYLPQjOr+i7dK1BLnTqfQIIp8YjN0T+VpT8h9HMq9X H4fxNytp0mRq8rTS+t406fAsxrsiNhm6SA6eaNntxq+mQEQj/WZBjW1/Zm4npQ9Nqo8G zWiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469533; x=1754074333; 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=vKrQy9jWlpHmx2H86IY6nleA9kDjYzDczHYTDNV4vRQ=; b=ErfUmNxdcS6Gk3RqRMrxT0msURdgJF5KvMM5DbOnccSItraYoeuPqdAwYWk0dcVZG2 eZxPan41bN2TUJL/L+qtoiqtv7Vn+nkRTo50K8U5RrP+rHFK9vMejb3Q5e/XqaOBRXr1 ABj/oWpFHahNqYt8+gXKvYfS0Io1aad7I2reM3AxrDbG+sjnZLkzGb2ac8rLFODbajv6 SEmW/W5YUrrI4p1htqDXoz9Jjr78nbA9R8hWAucHZVC6mpUR6CWKLsJhNeGfIeQAbooD Id9qN4/cmkvm6gQpzw/pgF3BR6DLh6fPQwZCsUisRs739eFTj0kpz+VDgJmZ7KCWsM7+ nYXg== X-Forwarded-Encrypted: i=1; AJvYcCWMY9GGpxdbErDDQQvoVZPKvNpxH0fNQIHhXzVDcGnII5CkL7heQTtIHqEZEsf7OJW+G/C8H7A955qWcs8=@vger.kernel.org X-Gm-Message-State: AOJu0YyxaMvZ0X2fE5V6PQEebIXbvWo5ieo4K5ILoh7ROVeAJU72PESp PClGDIIUlxFyM60XsOAiALnwSz0xvrkfZY9nDGTdB/HpoLbUSRrvbj0qwl2CVvHdNlXmA5pAQAs jyrw2UE0K5Q== X-Google-Smtp-Source: AGHT+IGQ0CPUNqlhaiW8IDbXCE7+NjYhca9/C2ns6zlxUx4mQY8Djx0wiDfuNEGDwS2LlHAe8uJR+5CuVj6w X-Received: from pjbsl3.prod.google.com ([2002:a17:90b:2e03:b0:312:1e70:e233]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:292:b0:234:f182:a754 with SMTP id d9443c01a7336-23fb3118d1dmr47509925ad.47.1753469532754; Fri, 25 Jul 2025 11:52:12 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:47 -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-2-irogers@google.com> Subject: [PATCH v9 01/16] perf python: Add more exceptions on error paths 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" Returning NULL will cause the python interpreter to fail but not report an error. If none wants to be returned then Py_None needs returning. Set the error for the cases returning NULL so that more meaningful interpreter behavior is had. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 2f28f71325a8..3affde0ad15a 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -475,13 +475,19 @@ static PyObject *pyrf_event__new(const union perf_eve= nt *event) if ((event->header.type < PERF_RECORD_MMAP || event->header.type > PERF_RECORD_SAMPLE) && !(event->header.type =3D=3D PERF_RECORD_SWITCH || - event->header.type =3D=3D PERF_RECORD_SWITCH_CPU_WIDE)) + event->header.type =3D=3D PERF_RECORD_SWITCH_CPU_WIDE)) { + PyErr_Format(PyExc_TypeError, "Unexpected header type %u", + event->header.type); return NULL; + } =20 // FIXME this better be dynamic or we need to parse everything // before calling perf_mmap__consume(), including tracepoint fields. - if (sizeof(pevent->event) < event->header.size) + if (sizeof(pevent->event) < event->header.size) { + PyErr_Format(PyExc_TypeError, "Unexpected event size: %zd < %u", + sizeof(pevent->event), event->header.size); return NULL; + } =20 ptype =3D pyrf_event__type[event->header.type]; pevent =3D PyObject_New(struct pyrf_event, ptype); @@ -1199,8 +1205,10 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyr= f_evlist *pevlist, return NULL; =20 md =3D get_md(evlist, cpu); - if (!md) + if (!md) { + PyErr_Format(PyExc_TypeError, "Unknown CPU '%d'", cpu); return NULL; + } =20 if (perf_mmap__read_init(&md->core) < 0) goto end; --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 B99F92566D2 for ; Fri, 25 Jul 2025 18:52:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469538; cv=none; b=QOYCGPHA2i9C5iT65CWIhDNgnH127RIQFj1ThgN+4p212GybHYVIvaVXjBe+Jg7o+UsDZP5i7Al6mSCk5IfwbqUTJAlA+x6jkjcXMd9/QnKBfs2k0M+Yn4HWmeZz5TIXfffGQN6TwolQOu8oUg7XUwwdqXmiZy0TJHWjBf30/go= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469538; c=relaxed/simple; bh=qGhK+bCU+oqZ7TaylGjJ/L81OhilulFo9wucjd3AQcw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=CJIfnRrFlXZhPzR6gx3FOuN2GnrgpF+phiic8osYkw2uOk64Gu48O+QYRjOnNfNsUUWWK/ej5Ss+mkEwWnDdpSdpnc36QCloC3mkHht2sfv6X2T+YsVSTAPXJUY510lAJqhG2C0OsLTB3CTtECs7CBPezQX035l7m6nCv0cZXjQ= 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=hvqtBk2E; arc=none smtp.client-ip=209.85.216.73 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="hvqtBk2E" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-313ff01d2a6so2569241a91.3 for ; Fri, 25 Jul 2025 11:52:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469535; x=1754074335; 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=QpMbVTHnQDGKfF/113O6SImK4aKjF5UHh+pWnaRDwvA=; b=hvqtBk2EqNIuprZYz15dwdDTg99pVfdwiRFop0ULoSbS0hWdqA5VN0gwQK+cPRIR13 fEajF0KEKQXJUBl2QXdTpKE+7PRwfEZ0En3r2bBuRjjA7p1nd9EpmPVRE4M7/8yKE488 VG1RAJVgGgbfTcFkxN5yqdZtuZFOnSIIrumAqwgHthbluq/2cgEVEY4c2I58voexBwvw 3TsoHGV1QpqsDQ4Rovul+ZUtHwP/KHawKBENLGj5MZt5Y8eDpXWAX0kjgZ73WozwWILZ PSfAmrZP86luxtAkLWalFl16vpL96hSLhXwUcbKeBSiBEhnGQUR5RlaKFgDBYP/kPick 3Sew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469535; x=1754074335; 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=QpMbVTHnQDGKfF/113O6SImK4aKjF5UHh+pWnaRDwvA=; b=g3qKT4fkgI8ycJy0Qo13ngwRzvpu+JMzmLsClQKQY69FmfMvz3dduHqQUieVIX6lp0 9a9SeaUpq3aI4WnE/xSeXUdLrcALy/7JRtaPPiw8i34PLVdAe4dWn1EFkXmZGTP8aSj7 86Mnrdkmm14f0UEMGD0RyZMXDMvU8wxcWUn7+tbifvL06l9pl0nrXtCX0TX/h9soJz5c Vz97tCgGfdiP0ruJ0o6YT65iL7P3QZfDRQzl4N/VUmKB8BeL9iTCEnnJQB/2BQwOwLPe lZnJJRtMjrMeiOT9WkFCsDzuUltpRLoTYNdfyQ39BhDEi3Xf+WEMoGx04Ebr5blfwa7E ZdQg== X-Forwarded-Encrypted: i=1; AJvYcCUIHcRqRvHxl4l1Ee/EY8MmRB7CnXM0vSkVB8sMXd2bZOgtGajX3Xaq/5heXu64pZ+tDz8QXSFTNfqjgIM=@vger.kernel.org X-Gm-Message-State: AOJu0YxqAkVCXJYYcbq4YMfpWy/Mk9jz6mNRIHJ23JcOxV/PuY8zh/QU gMsoEa3EFQjTj34VRy/XNDVsuy3GGiQf3y21xRbO+xZTYUZgejZDYzqZqErSRkV9UOgtTOVbUkk /I0B+rhOj5A== X-Google-Smtp-Source: AGHT+IEdzhcIbEroGgh+B6l9nBfHtZc7ov/JDmXYAsjFh2LJbSIj/kBI2drP599e0Ps3bnFFkF4tonbTS8pm X-Received: from pjxx11.prod.google.com ([2002:a17:90b:58cb:b0:314:29b4:453]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3946:b0:313:283e:e87c with SMTP id 98e67ed59e1d1-31e77841b33mr4275005a91.3.1753469534981; Fri, 25 Jul 2025 11:52:14 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:48 -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-3-irogers@google.com> Subject: [PATCH v9 02/16] perf jevents: Add common software event json 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 json for software events so that in perf list the events can have a description. Common json exists for the tool PMU but it has no sysfs equivalent. Modify the map_for_pmu code to return the common map (rather than an architecture specific one) when a PMU with a common name is being looked for, this allows the events to be found. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- .../arch/common/common/software.json | 92 ++++++ tools/perf/pmu-events/empty-pmu-events.c | 266 +++++++++++------- tools/perf/pmu-events/jevents.py | 15 +- 3 files changed, 264 insertions(+), 109 deletions(-) create mode 100644 tools/perf/pmu-events/arch/common/common/software.json diff --git a/tools/perf/pmu-events/arch/common/common/software.json b/tools= /perf/pmu-events/arch/common/common/software.json new file mode 100644 index 000000000000..f2551f1107fd --- /dev/null +++ b/tools/perf/pmu-events/arch/common/common/software.json @@ -0,0 +1,92 @@ +[ + { + "Unit": "software", + "EventName": "cpu-clock", + "BriefDescription": "Per-CPU high-resolution timer based event", + "ConfigCode": "0" + }, + { + "Unit": "software", + "EventName": "task-clock", + "BriefDescription": "Per-task high-resolution timer based event", + "ConfigCode": "1" + }, + { + "Unit": "software", + "EventName": "faults", + "BriefDescription": "Number of page faults [This event is an alias of = page-faults]", + "ConfigCode": "2" + }, + { + "Unit": "software", + "EventName": "page-faults", + "BriefDescription": "Number of page faults [This event is an alias of = faults]", + "ConfigCode": "2" + }, + { + "Unit": "software", + "EventName": "context-switches", + "BriefDescription": "Number of context switches [This event is an alia= s of cs]", + "ConfigCode": "3" + }, + { + "Unit": "software", + "EventName": "cs", + "BriefDescription": "Number of context switches [This event is an alia= s of context-switches]", + "ConfigCode": "3" + }, + { + "Unit": "software", + "EventName": "cpu-migrations", + "BriefDescription": "Number of times a process has migrated to a new C= PU [This event is an alias of migrations]", + "ConfigCode": "4" + }, + { + "Unit": "software", + "EventName": "migrations", + "BriefDescription": "Number of times a process has migrated to a new C= PU [This event is an alias of cpu-migrations]", + "ConfigCode": "4" + }, + { + "Unit": "software", + "EventName": "minor-faults", + "BriefDescription": "Number of minor page faults. Minor faults don't r= equire I/O to handle", + "ConfigCode": "5" + }, + { + "Unit": "software", + "EventName": "major-faults", + "BriefDescription": "Number of major page faults. Major faults require= I/O to handle", + "ConfigCode": "6" + }, + { + "Unit": "software", + "EventName": "alignment-faults", + "BriefDescription": "Number of kernel handled memory alignment faults", + "ConfigCode": "7" + }, + { + "Unit": "software", + "EventName": "emulation-faults", + "BriefDescription": "Number of kernel handled unimplemented instructio= n faults handled through emulation", + "ConfigCode": "8" + }, + { + "Unit": "software", + "EventName": "dummy", + "BriefDescription": "A placeholder event that doesn't count anything", + "ConfigCode": "9" + }, + { + "Unit": "software", + "EventName": "bpf-output", + "BriefDescription": "An event used by BPF programs to write to the per= f ring buffer", + "ConfigCode": "10" + }, + { + "Unit": "software", + "EventName": "cgroup-switches", + "BriefDescription": "Number of context switches to a task in a differe= nt cgroup", + "ConfigCode": "11" + } +] diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index a4569a74db07..041c598b16d8 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -19,109 +19,147 @@ struct pmu_table_entry { }; =20 static const char *const big_c_string =3D -/* offset=3D0 */ "tool\000" -/* offset=3D5 */ "duration_time\000tool\000Wall clock interval time in nan= oseconds\000config=3D1\000\00000\000\000\000\000\000" -/* offset=3D81 */ "user_time\000tool\000User (non-kernel) time in nanoseco= nds\000config=3D2\000\00000\000\000\000\000\000" -/* offset=3D151 */ "system_time\000tool\000System/kernel time in nanosecon= ds\000config=3D3\000\00000\000\000\000\000\000" -/* offset=3D219 */ "has_pmem\000tool\0001 if persistent memory installed o= therwise 0\000config=3D4\000\00000\000\000\000\000\000" -/* offset=3D295 */ "num_cores\000tool\000Number of cores. A core consists = of 1 or more thread, with each thread being associated with a logical Linux= CPU\000config=3D5\000\00000\000\000\000\000\000" -/* offset=3D440 */ "num_cpus\000tool\000Number of logical Linux CPUs. Ther= e may be multiple such CPUs on a core\000config=3D6\000\00000\000\000\000\0= 00\000" -/* offset=3D543 */ "num_cpus_online\000tool\000Number of online logical Li= nux CPUs. There may be multiple such CPUs on a core\000config=3D7\000\00000= \000\000\000\000\000" -/* offset=3D660 */ "num_dies\000tool\000Number of dies. Each die has 1 or = more cores\000config=3D8\000\00000\000\000\000\000\000" -/* offset=3D736 */ "num_packages\000tool\000Number of packages. Each packa= ge has 1 or more die\000config=3D9\000\00000\000\000\000\000\000" -/* offset=3D822 */ "slots\000tool\000Number of functional units that in pa= rallel can execute parts of an instruction\000config=3D0xa\000\00000\000\00= 0\000\000\000" -/* offset=3D932 */ "smt_on\000tool\0001 if simultaneous multithreading (ak= a hyperthreading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\0= 00\000\000" -/* offset=3D1039 */ "system_tsc_freq\000tool\000The amount a Time Stamp Co= unter (TSC) increases per second\000config=3D0xc\000\00000\000\000\000\000\= 000" -/* offset=3D1138 */ "default_core\000" -/* offset=3D1151 */ "bp_l1_btb_correct\000branch\000L1 BTB Correction\000e= vent=3D0x8a\000\00000\000\000\000\000\000" -/* offset=3D1213 */ "bp_l2_btb_correct\000branch\000L2 BTB Correction\000e= vent=3D0x8b\000\00000\000\000\000\000\000" -/* offset=3D1275 */ "l3_cache_rd\000cache\000L3 cache access, read\000even= t=3D0x40\000\00000\000\000\000\000Attributable Level 3 cache access, read\0= 00" -/* offset=3D1373 */ "segment_reg_loads.any\000other\000Number of segment r= egister loads\000event=3D6,period=3D200000,umask=3D0x80\000\00000\000\000\0= 00\000\000" -/* offset=3D1475 */ "dispatch_blocked.any\000other\000Memory cluster signa= ls to block micro-op dispatch for any reason\000event=3D9,period=3D200000,u= mask=3D0x20\000\00000\000\000\000\000\000" -/* offset=3D1608 */ "eist_trans\000other\000Number of Enhanced Intel Speed= Step(R) Technology (EIST) transitions\000event=3D0x3a,period=3D200000\000\0= 0000\000\000\000\000\000" -/* offset=3D1726 */ "hisi_sccl,ddrc\000" -/* offset=3D1741 */ "uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write co= mmands\000event=3D2\000\00000\000\000\000\000\000" -/* offset=3D1811 */ "uncore_cbox\000" -/* offset=3D1823 */ "unc_cbo_xsnp_response.miss_eviction\000uncore\000A cr= oss-core snoop resulted from L3 Eviction which misses in some processor cor= e\000event=3D0x22,umask=3D0x81\000\00000\000\000\000\000\000" -/* offset=3D1977 */ "event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0= xe0\000\00000\000\000\000\000\000" -/* offset=3D2031 */ "event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event= =3D0xc0\000\00000\000\000\000\000\000" -/* offset=3D2089 */ "hisi_sccl,l3c\000" -/* offset=3D2103 */ "uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read = hits\000event=3D7\000\00000\000\000\000\000\000" -/* offset=3D2171 */ "uncore_imc_free_running\000" -/* offset=3D2195 */ "uncore_imc_free_running.cache_miss\000uncore\000Total= cache misses\000event=3D0x12\000\00000\000\000\000\000\000" -/* offset=3D2275 */ "uncore_imc\000" -/* offset=3D2286 */ "uncore_imc.cache_hits\000uncore\000Total cache hits\0= 00event=3D0x34\000\00000\000\000\000\000\000" -/* offset=3D2351 */ "uncore_sys_ddr_pmu\000" -/* offset=3D2370 */ "sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycle= s event\000event=3D0x2b\000v8\00000\000\000\000\000\000" -/* offset=3D2446 */ "uncore_sys_ccn_pmu\000" -/* offset=3D2465 */ "sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles = event\000config=3D0x2c\0000x01\00000\000\000\000\000\000" -/* offset=3D2542 */ "uncore_sys_cmn_pmu\000" -/* offset=3D2561 */ "sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total = cache misses in first lookup result (high priority)\000eventid=3D1,type=3D5= \000(434|436|43c|43a).*\00000\000\000\000\000\000" -/* offset=3D2704 */ "CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000" -/* offset=3D2726 */ "IPC\000group1\000inst_retired.any / cpu_clk_unhalted.= thread\000\000\000\000\000\000\000\00000" -/* offset=3D2789 */ "Frontend_Bound_SMT\000\000idq_uops_not_delivered.core= / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_act= ive / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000" -/* offset=3D2955 */ "dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_re= tired.any\000\000\000\000\000\000\000\00000" -/* offset=3D3019 */ "icache_miss_cycles\000\000l1i\\-loads\\-misses / inst= _retired.any\000\000\000\000\000\000\000\00000" -/* offset=3D3086 */ "cache_miss_cycles\000group1\000dcache_miss_cpi + icac= he_miss_cycles\000\000\000\000\000\000\000\00000" -/* offset=3D3157 */ "DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit= + l2_rqsts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000" -/* offset=3D3251 */ "DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_dat= a_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_mi= ss\000\000\000\000\000\000\000\00000" -/* offset=3D3385 */ "DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_A= ll_Miss\000\000\000\000\000\000\000\00000" -/* offset=3D3449 */ "DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCa= che_L2_All)\000\000\000\000\000\000\000\00000" -/* offset=3D3517 */ "DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, D= Cache_L2_All)\000\000\000\000\000\000\000\00000" -/* offset=3D3587 */ "M1\000\000ipc + M2\000\000\000\000\000\000\000\00000" -/* offset=3D3609 */ "M2\000\000ipc + M1\000\000\000\000\000\000\000\00000" -/* offset=3D3631 */ "M3\000\0001 / M3\000\000\000\000\000\000\000\00000" -/* offset=3D3651 */ "L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 /= duration_time\000\000\000\000\000\000\000\00000" +/* offset=3D0 */ "software\000" +/* offset=3D9 */ "cpu-clock\000software\000Per-CPU high-resolution timer b= ased event\000config=3D0\000\00000\000\000\000\000\000" +/* offset=3D87 */ "task-clock\000software\000Per-task high-resolution time= r based event\000config=3D1\000\00000\000\000\000\000\000" +/* offset=3D167 */ "faults\000software\000Number of page faults [This even= t is an alias of page-faults]\000config=3D2\000\00000\000\000\000\000\000" +/* offset=3D262 */ "page-faults\000software\000Number of page faults [This= event is an alias of faults]\000config=3D2\000\00000\000\000\000\000\000" +/* offset=3D357 */ "context-switches\000software\000Number of context swit= ches [This event is an alias of cs]\000config=3D3\000\00000\000\000\000\000= \000" +/* offset=3D458 */ "cs\000software\000Number of context switches [This eve= nt is an alias of context-switches]\000config=3D3\000\00000\000\000\000\000= \000" +/* offset=3D559 */ "cpu-migrations\000software\000Number of times a proces= s has migrated to a new CPU [This event is an alias of migrations]\000confi= g=3D4\000\00000\000\000\000\000\000" +/* offset=3D691 */ "migrations\000software\000Number of times a process ha= s migrated to a new CPU [This event is an alias of cpu-migrations]\000confi= g=3D4\000\00000\000\000\000\000\000" +/* offset=3D823 */ "minor-faults\000software\000Number of minor page fault= s. Minor faults don't require I/O to handle\000config=3D5\000\00000\000\000= \000\000\000" +/* offset=3D932 */ "major-faults\000software\000Number of major page fault= s. Major faults require I/O to handle\000config=3D6\000\00000\000\000\000\0= 00\000" +/* offset=3D1035 */ "alignment-faults\000software\000Number of kernel hand= led memory alignment faults\000config=3D7\000\00000\000\000\000\000\000" +/* offset=3D1127 */ "emulation-faults\000software\000Number of kernel hand= led unimplemented instruction faults handled through emulation\000config=3D= 8\000\00000\000\000\000\000\000" +/* offset=3D1254 */ "dummy\000software\000A placeholder event that doesn't= count anything\000config=3D9\000\00000\000\000\000\000\000" +/* offset=3D1334 */ "bpf-output\000software\000An event used by BPF progra= ms to write to the perf ring buffer\000config=3D0xa\000\00000\000\000\000\0= 00\000" +/* offset=3D1436 */ "cgroup-switches\000software\000Number of context swit= ches to a task in a different cgroup\000config=3D0xb\000\00000\000\000\000\= 000\000" +/* offset=3D1539 */ "tool\000" +/* offset=3D1544 */ "duration_time\000tool\000Wall clock interval time in = nanoseconds\000config=3D1\000\00000\000\000\000\000\000" +/* offset=3D1620 */ "user_time\000tool\000User (non-kernel) time in nanose= conds\000config=3D2\000\00000\000\000\000\000\000" +/* offset=3D1690 */ "system_time\000tool\000System/kernel time in nanoseco= nds\000config=3D3\000\00000\000\000\000\000\000" +/* offset=3D1758 */ "has_pmem\000tool\0001 if persistent memory installed = otherwise 0\000config=3D4\000\00000\000\000\000\000\000" +/* offset=3D1834 */ "num_cores\000tool\000Number of cores. A core consists= of 1 or more thread, with each thread being associated with a logical Linu= x CPU\000config=3D5\000\00000\000\000\000\000\000" +/* offset=3D1979 */ "num_cpus\000tool\000Number of logical Linux CPUs. The= re may be multiple such CPUs on a core\000config=3D6\000\00000\000\000\000\= 000\000" +/* offset=3D2082 */ "num_cpus_online\000tool\000Number of online logical L= inux CPUs. There may be multiple such CPUs on a core\000config=3D7\000\0000= 0\000\000\000\000\000" +/* offset=3D2199 */ "num_dies\000tool\000Number of dies. Each die has 1 or= more cores\000config=3D8\000\00000\000\000\000\000\000" +/* offset=3D2275 */ "num_packages\000tool\000Number of packages. Each pack= age has 1 or more die\000config=3D9\000\00000\000\000\000\000\000" +/* offset=3D2361 */ "slots\000tool\000Number of functional units that in p= arallel can execute parts of an instruction\000config=3D0xa\000\00000\000\0= 00\000\000\000" +/* offset=3D2471 */ "smt_on\000tool\0001 if simultaneous multithreading (a= ka hyperthreading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\= 000\000\000" +/* offset=3D2578 */ "system_tsc_freq\000tool\000The amount a Time Stamp Co= unter (TSC) increases per second\000config=3D0xc\000\00000\000\000\000\000\= 000" +/* offset=3D2677 */ "default_core\000" +/* offset=3D2690 */ "bp_l1_btb_correct\000branch\000L1 BTB Correction\000e= vent=3D0x8a\000\00000\000\000\000\000\000" +/* offset=3D2752 */ "bp_l2_btb_correct\000branch\000L2 BTB Correction\000e= vent=3D0x8b\000\00000\000\000\000\000\000" +/* offset=3D2814 */ "l3_cache_rd\000cache\000L3 cache access, read\000even= t=3D0x40\000\00000\000\000\000\000Attributable Level 3 cache access, read\0= 00" +/* offset=3D2912 */ "segment_reg_loads.any\000other\000Number of segment r= egister loads\000event=3D6,period=3D200000,umask=3D0x80\000\00000\000\000\0= 00\000\000" +/* offset=3D3014 */ "dispatch_blocked.any\000other\000Memory cluster signa= ls to block micro-op dispatch for any reason\000event=3D9,period=3D200000,u= mask=3D0x20\000\00000\000\000\000\000\000" +/* offset=3D3147 */ "eist_trans\000other\000Number of Enhanced Intel Speed= Step(R) Technology (EIST) transitions\000event=3D0x3a,period=3D200000\000\0= 0000\000\000\000\000\000" +/* offset=3D3265 */ "hisi_sccl,ddrc\000" +/* offset=3D3280 */ "uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write co= mmands\000event=3D2\000\00000\000\000\000\000\000" +/* offset=3D3350 */ "uncore_cbox\000" +/* offset=3D3362 */ "unc_cbo_xsnp_response.miss_eviction\000uncore\000A cr= oss-core snoop resulted from L3 Eviction which misses in some processor cor= e\000event=3D0x22,umask=3D0x81\000\00000\000\000\000\000\000" +/* offset=3D3516 */ "event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0= xe0\000\00000\000\000\000\000\000" +/* offset=3D3570 */ "event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event= =3D0xc0\000\00000\000\000\000\000\000" +/* offset=3D3628 */ "hisi_sccl,l3c\000" +/* offset=3D3642 */ "uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read = hits\000event=3D7\000\00000\000\000\000\000\000" +/* offset=3D3710 */ "uncore_imc_free_running\000" +/* offset=3D3734 */ "uncore_imc_free_running.cache_miss\000uncore\000Total= cache misses\000event=3D0x12\000\00000\000\000\000\000\000" +/* offset=3D3814 */ "uncore_imc\000" +/* offset=3D3825 */ "uncore_imc.cache_hits\000uncore\000Total cache hits\0= 00event=3D0x34\000\00000\000\000\000\000\000" +/* offset=3D3890 */ "uncore_sys_ddr_pmu\000" +/* offset=3D3909 */ "sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycle= s event\000event=3D0x2b\000v8\00000\000\000\000\000\000" +/* offset=3D3985 */ "uncore_sys_ccn_pmu\000" +/* offset=3D4004 */ "sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles = event\000config=3D0x2c\0000x01\00000\000\000\000\000\000" +/* offset=3D4081 */ "uncore_sys_cmn_pmu\000" +/* offset=3D4100 */ "sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total = cache misses in first lookup result (high priority)\000eventid=3D1,type=3D5= \000(434|436|43c|43a).*\00000\000\000\000\000\000" +/* offset=3D4243 */ "CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000" +/* offset=3D4265 */ "IPC\000group1\000inst_retired.any / cpu_clk_unhalted.= thread\000\000\000\000\000\000\000\00000" +/* offset=3D4328 */ "Frontend_Bound_SMT\000\000idq_uops_not_delivered.core= / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_act= ive / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000" +/* offset=3D4494 */ "dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_re= tired.any\000\000\000\000\000\000\000\00000" +/* offset=3D4558 */ "icache_miss_cycles\000\000l1i\\-loads\\-misses / inst= _retired.any\000\000\000\000\000\000\000\00000" +/* offset=3D4625 */ "cache_miss_cycles\000group1\000dcache_miss_cpi + icac= he_miss_cycles\000\000\000\000\000\000\000\00000" +/* offset=3D4696 */ "DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit= + l2_rqsts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000" +/* offset=3D4790 */ "DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_dat= a_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_mi= ss\000\000\000\000\000\000\000\00000" +/* offset=3D4924 */ "DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_A= ll_Miss\000\000\000\000\000\000\000\00000" +/* offset=3D4988 */ "DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCa= che_L2_All)\000\000\000\000\000\000\000\00000" +/* offset=3D5056 */ "DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, D= Cache_L2_All)\000\000\000\000\000\000\000\00000" +/* offset=3D5126 */ "M1\000\000ipc + M2\000\000\000\000\000\000\000\00000" +/* offset=3D5148 */ "M2\000\000ipc + M1\000\000\000\000\000\000\000\00000" +/* offset=3D5170 */ "M3\000\0001 / M3\000\000\000\000\000\000\000\00000" +/* offset=3D5190 */ "L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 /= duration_time\000\000\000\000\000\000\000\00000" ; =20 +static const struct compact_pmu_event pmu_events__common_software[] =3D { +{ 1035 }, /* alignment-faults\000software\000Number of kernel handled memo= ry alignment faults\000config=3D7\000\00000\000\000\000\000\000 */ +{ 1334 }, /* bpf-output\000software\000An event used by BPF programs to wr= ite to the perf ring buffer\000config=3D0xa\000\00000\000\000\000\000\000 */ +{ 1436 }, /* cgroup-switches\000software\000Number of context switches to = a task in a different cgroup\000config=3D0xb\000\00000\000\000\000\000\000 = */ +{ 357 }, /* context-switches\000software\000Number of context switches [Th= is event is an alias of cs]\000config=3D3\000\00000\000\000\000\000\000 */ +{ 9 }, /* cpu-clock\000software\000Per-CPU high-resolution timer based eve= nt\000config=3D0\000\00000\000\000\000\000\000 */ +{ 559 }, /* cpu-migrations\000software\000Number of times a process has mi= grated to a new CPU [This event is an alias of migrations]\000config=3D4\00= 0\00000\000\000\000\000\000 */ +{ 458 }, /* cs\000software\000Number of context switches [This event is an= alias of context-switches]\000config=3D3\000\00000\000\000\000\000\000 */ +{ 1254 }, /* dummy\000software\000A placeholder event that doesn't count a= nything\000config=3D9\000\00000\000\000\000\000\000 */ +{ 1127 }, /* emulation-faults\000software\000Number of kernel handled unim= plemented instruction faults handled through emulation\000config=3D8\000\00= 000\000\000\000\000\000 */ +{ 167 }, /* faults\000software\000Number of page faults [This event is an = alias of page-faults]\000config=3D2\000\00000\000\000\000\000\000 */ +{ 932 }, /* major-faults\000software\000Number of major page faults. Major= faults require I/O to handle\000config=3D6\000\00000\000\000\000\000\000 */ +{ 691 }, /* migrations\000software\000Number of times a process has migrat= ed to a new CPU [This event is an alias of cpu-migrations]\000config=3D4\00= 0\00000\000\000\000\000\000 */ +{ 823 }, /* minor-faults\000software\000Number of minor page faults. Minor= faults don't require I/O to handle\000config=3D5\000\00000\000\000\000\000= \000 */ +{ 262 }, /* page-faults\000software\000Number of page faults [This event i= s an alias of faults]\000config=3D2\000\00000\000\000\000\000\000 */ +{ 87 }, /* task-clock\000software\000Per-task high-resolution timer based = event\000config=3D1\000\00000\000\000\000\000\000 */ +}; static const struct compact_pmu_event pmu_events__common_tool[] =3D { -{ 5 }, /* duration_time\000tool\000Wall clock interval time in nanoseconds= \000config=3D1\000\00000\000\000\000\000\000 */ -{ 219 }, /* has_pmem\000tool\0001 if persistent memory installed otherwise= 0\000config=3D4\000\00000\000\000\000\000\000 */ -{ 295 }, /* num_cores\000tool\000Number of cores. A core consists of 1 or = more thread, with each thread being associated with a logical Linux CPU\000= config=3D5\000\00000\000\000\000\000\000 */ -{ 440 }, /* num_cpus\000tool\000Number of logical Linux CPUs. There may be= multiple such CPUs on a core\000config=3D6\000\00000\000\000\000\000\000 */ -{ 543 }, /* num_cpus_online\000tool\000Number of online logical Linux CPUs= . There may be multiple such CPUs on a core\000config=3D7\000\00000\000\000= \000\000\000 */ -{ 660 }, /* num_dies\000tool\000Number of dies. Each die has 1 or more cor= es\000config=3D8\000\00000\000\000\000\000\000 */ -{ 736 }, /* num_packages\000tool\000Number of packages. Each package has 1= or more die\000config=3D9\000\00000\000\000\000\000\000 */ -{ 822 }, /* slots\000tool\000Number of functional units that in parallel c= an execute parts of an instruction\000config=3D0xa\000\00000\000\000\000\00= 0\000 */ -{ 932 }, /* smt_on\000tool\0001 if simultaneous multithreading (aka hypert= hreading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\000\000\0= 00 */ -{ 151 }, /* system_time\000tool\000System/kernel time in nanoseconds\000co= nfig=3D3\000\00000\000\000\000\000\000 */ -{ 1039 }, /* system_tsc_freq\000tool\000The amount a Time Stamp Counter (T= SC) increases per second\000config=3D0xc\000\00000\000\000\000\000\000 */ -{ 81 }, /* user_time\000tool\000User (non-kernel) time in nanoseconds\000c= onfig=3D2\000\00000\000\000\000\000\000 */ +{ 1544 }, /* duration_time\000tool\000Wall clock interval time in nanoseco= nds\000config=3D1\000\00000\000\000\000\000\000 */ +{ 1758 }, /* has_pmem\000tool\0001 if persistent memory installed otherwis= e 0\000config=3D4\000\00000\000\000\000\000\000 */ +{ 1834 }, /* num_cores\000tool\000Number of cores. A core consists of 1 or= more thread, with each thread being associated with a logical Linux CPU\00= 0config=3D5\000\00000\000\000\000\000\000 */ +{ 1979 }, /* num_cpus\000tool\000Number of logical Linux CPUs. There may b= e multiple such CPUs on a core\000config=3D6\000\00000\000\000\000\000\000 = */ +{ 2082 }, /* num_cpus_online\000tool\000Number of online logical Linux CPU= s. There may be multiple such CPUs on a core\000config=3D7\000\00000\000\00= 0\000\000\000 */ +{ 2199 }, /* num_dies\000tool\000Number of dies. Each die has 1 or more co= res\000config=3D8\000\00000\000\000\000\000\000 */ +{ 2275 }, /* num_packages\000tool\000Number of packages. Each package has = 1 or more die\000config=3D9\000\00000\000\000\000\000\000 */ +{ 2361 }, /* slots\000tool\000Number of functional units that in parallel = can execute parts of an instruction\000config=3D0xa\000\00000\000\000\000\0= 00\000 */ +{ 2471 }, /* smt_on\000tool\0001 if simultaneous multithreading (aka hyper= threading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\000\000\= 000 */ +{ 1690 }, /* system_time\000tool\000System/kernel time in nanoseconds\000c= onfig=3D3\000\00000\000\000\000\000\000 */ +{ 2578 }, /* system_tsc_freq\000tool\000The amount a Time Stamp Counter (T= SC) increases per second\000config=3D0xc\000\00000\000\000\000\000\000 */ +{ 1620 }, /* user_time\000tool\000User (non-kernel) time in nanoseconds\00= 0config=3D2\000\00000\000\000\000\000\000 */ =20 }; =20 const struct pmu_table_entry pmu_events__common[] =3D { +{ + .entries =3D pmu_events__common_software, + .num_entries =3D ARRAY_SIZE(pmu_events__common_software), + .pmu_name =3D { 0 /* software\000 */ }, +}, { .entries =3D pmu_events__common_tool, .num_entries =3D ARRAY_SIZE(pmu_events__common_tool), - .pmu_name =3D { 0 /* tool\000 */ }, + .pmu_name =3D { 1539 /* tool\000 */ }, }, }; =20 static const struct compact_pmu_event pmu_events__test_soc_cpu_default_cor= e[] =3D { -{ 1151 }, /* bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=3D0= x8a\000\00000\000\000\000\000\000 */ -{ 1213 }, /* bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=3D0= x8b\000\00000\000\000\000\000\000 */ -{ 1475 }, /* dispatch_blocked.any\000other\000Memory cluster signals to bl= ock micro-op dispatch for any reason\000event=3D9,period=3D200000,umask=3D0= x20\000\00000\000\000\000\000\000 */ -{ 1608 }, /* eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) = Technology (EIST) transitions\000event=3D0x3a,period=3D200000\000\00000\000= \000\000\000\000 */ -{ 1275 }, /* l3_cache_rd\000cache\000L3 cache access, read\000event=3D0x40= \000\00000\000\000\000\000Attributable Level 3 cache access, read\000 */ -{ 1373 }, /* segment_reg_loads.any\000other\000Number of segment register = loads\000event=3D6,period=3D200000,umask=3D0x80\000\00000\000\000\000\000\0= 00 */ +{ 2690 }, /* bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=3D0= x8a\000\00000\000\000\000\000\000 */ +{ 2752 }, /* bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=3D0= x8b\000\00000\000\000\000\000\000 */ +{ 3014 }, /* dispatch_blocked.any\000other\000Memory cluster signals to bl= ock micro-op dispatch for any reason\000event=3D9,period=3D200000,umask=3D0= x20\000\00000\000\000\000\000\000 */ +{ 3147 }, /* eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) = Technology (EIST) transitions\000event=3D0x3a,period=3D200000\000\00000\000= \000\000\000\000 */ +{ 2814 }, /* l3_cache_rd\000cache\000L3 cache access, read\000event=3D0x40= \000\00000\000\000\000\000Attributable Level 3 cache access, read\000 */ +{ 2912 }, /* segment_reg_loads.any\000other\000Number of segment register = loads\000event=3D6,period=3D200000,umask=3D0x80\000\00000\000\000\000\000\0= 00 */ }; static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_d= drc[] =3D { -{ 1741 }, /* uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\0= 00event=3D2\000\00000\000\000\000\000\000 */ +{ 3280 }, /* uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\0= 00event=3D2\000\00000\000\000\000\000\000 */ }; static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_l= 3c[] =3D { -{ 2103 }, /* uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000= event=3D7\000\00000\000\000\000\000\000 */ +{ 3642 }, /* uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000= event=3D7\000\00000\000\000\000\000\000 */ }; static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_cbox= [] =3D { -{ 1977 }, /* event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0xe0\000\= 00000\000\000\000\000\000 */ -{ 2031 }, /* event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=3D0xc0\= 000\00000\000\000\000\000\000 */ -{ 1823 }, /* unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core= snoop resulted from L3 Eviction which misses in some processor core\000eve= nt=3D0x22,umask=3D0x81\000\00000\000\000\000\000\000 */ +{ 3516 }, /* event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0xe0\000\= 00000\000\000\000\000\000 */ +{ 3570 }, /* event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=3D0xc0\= 000\00000\000\000\000\000\000 */ +{ 3362 }, /* unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core= snoop resulted from L3 Eviction which misses in some processor core\000eve= nt=3D0x22,umask=3D0x81\000\00000\000\000\000\000\000 */ }; static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc[= ] =3D { -{ 2286 }, /* uncore_imc.cache_hits\000uncore\000Total cache hits\000event= =3D0x34\000\00000\000\000\000\000\000 */ +{ 3825 }, /* uncore_imc.cache_hits\000uncore\000Total cache hits\000event= =3D0x34\000\00000\000\000\000\000\000 */ }; static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc_= free_running[] =3D { -{ 2195 }, /* uncore_imc_free_running.cache_miss\000uncore\000Total cache m= isses\000event=3D0x12\000\00000\000\000\000\000\000 */ +{ 3734 }, /* uncore_imc_free_running.cache_miss\000uncore\000Total cache m= isses\000event=3D0x12\000\00000\000\000\000\000\000 */ =20 }; =20 @@ -129,51 +167,51 @@ const struct pmu_table_entry pmu_events__test_soc_cpu= [] =3D { { .entries =3D pmu_events__test_soc_cpu_default_core, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_cpu_default_core), - .pmu_name =3D { 1138 /* default_core\000 */ }, + .pmu_name =3D { 2677 /* default_core\000 */ }, }, { .entries =3D pmu_events__test_soc_cpu_hisi_sccl_ddrc, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_ddrc), - .pmu_name =3D { 1726 /* hisi_sccl,ddrc\000 */ }, + .pmu_name =3D { 3265 /* hisi_sccl,ddrc\000 */ }, }, { .entries =3D pmu_events__test_soc_cpu_hisi_sccl_l3c, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_l3c), - .pmu_name =3D { 2089 /* hisi_sccl,l3c\000 */ }, + .pmu_name =3D { 3628 /* hisi_sccl,l3c\000 */ }, }, { .entries =3D pmu_events__test_soc_cpu_uncore_cbox, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_cbox), - .pmu_name =3D { 1811 /* uncore_cbox\000 */ }, + .pmu_name =3D { 3350 /* uncore_cbox\000 */ }, }, { .entries =3D pmu_events__test_soc_cpu_uncore_imc, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc), - .pmu_name =3D { 2275 /* uncore_imc\000 */ }, + .pmu_name =3D { 3814 /* uncore_imc\000 */ }, }, { .entries =3D pmu_events__test_soc_cpu_uncore_imc_free_running, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc_free_= running), - .pmu_name =3D { 2171 /* uncore_imc_free_running\000 */ }, + .pmu_name =3D { 3710 /* uncore_imc_free_running\000 */ }, }, }; =20 static const struct compact_pmu_event pmu_metrics__test_soc_cpu_default_co= re[] =3D { -{ 2704 }, /* CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000 */ -{ 3385 }, /* DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\= 000\000\000\000\000\000\000\00000 */ -{ 3157 }, /* DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit + l2_rq= sts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000 */ -{ 3251 }, /* DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l= 2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\0= 00\000\000\000\000\000\00000 */ -{ 3449 }, /* DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_A= ll)\000\000\000\000\000\000\000\00000 */ -{ 3517 }, /* DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2= _All)\000\000\000\000\000\000\000\00000 */ -{ 2789 }, /* Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * = (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cp= u_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000 */ -{ 2726 }, /* IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\0= 00\000\000\000\000\000\000\00000 */ -{ 3651 }, /* L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duratio= n_time\000\000\000\000\000\000\000\00000 */ -{ 3587 }, /* M1\000\000ipc + M2\000\000\000\000\000\000\000\00000 */ -{ 3609 }, /* M2\000\000ipc + M1\000\000\000\000\000\000\000\00000 */ -{ 3631 }, /* M3\000\0001 / M3\000\000\000\000\000\000\000\00000 */ -{ 3086 }, /* cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_= cycles\000\000\000\000\000\000\000\00000 */ -{ 2955 }, /* dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.an= y\000\000\000\000\000\000\000\00000 */ -{ 3019 }, /* icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired= .any\000\000\000\000\000\000\000\00000 */ +{ 4243 }, /* CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000 */ +{ 4924 }, /* DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\= 000\000\000\000\000\000\000\00000 */ +{ 4696 }, /* DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit + l2_rq= sts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000 */ +{ 4790 }, /* DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l= 2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\0= 00\000\000\000\000\000\00000 */ +{ 4988 }, /* DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_A= ll)\000\000\000\000\000\000\000\00000 */ +{ 5056 }, /* DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2= _All)\000\000\000\000\000\000\000\00000 */ +{ 4328 }, /* Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * = (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cp= u_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000 */ +{ 4265 }, /* IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\0= 00\000\000\000\000\000\000\00000 */ +{ 5190 }, /* L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duratio= n_time\000\000\000\000\000\000\000\00000 */ +{ 5126 }, /* M1\000\000ipc + M2\000\000\000\000\000\000\000\00000 */ +{ 5148 }, /* M2\000\000ipc + M1\000\000\000\000\000\000\000\00000 */ +{ 5170 }, /* M3\000\0001 / M3\000\000\000\000\000\000\000\00000 */ +{ 4625 }, /* cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_= cycles\000\000\000\000\000\000\000\00000 */ +{ 4494 }, /* dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.an= y\000\000\000\000\000\000\000\00000 */ +{ 4558 }, /* icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired= .any\000\000\000\000\000\000\000\00000 */ =20 }; =20 @@ -181,18 +219,18 @@ const struct pmu_table_entry pmu_metrics__test_soc_cp= u[] =3D { { .entries =3D pmu_metrics__test_soc_cpu_default_core, .num_entries =3D ARRAY_SIZE(pmu_metrics__test_soc_cpu_default_core), - .pmu_name =3D { 1138 /* default_core\000 */ }, + .pmu_name =3D { 2677 /* default_core\000 */ }, }, }; =20 static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_= ccn_pmu[] =3D { -{ 2465 }, /* sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\00= 0config=3D0x2c\0000x01\00000\000\000\000\000\000 */ +{ 4004 }, /* sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\00= 0config=3D0x2c\0000x01\00000\000\000\000\000\000 */ }; static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_= cmn_pmu[] =3D { -{ 2561 }, /* sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache mi= sses in first lookup result (high priority)\000eventid=3D1,type=3D5\000(434= |436|43c|43a).*\00000\000\000\000\000\000 */ +{ 4100 }, /* sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache mi= sses in first lookup result (high priority)\000eventid=3D1,type=3D5\000(434= |436|43c|43a).*\00000\000\000\000\000\000 */ }; static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_= ddr_pmu[] =3D { -{ 2370 }, /* sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\= 000event=3D0x2b\000v8\00000\000\000\000\000\000 */ +{ 3909 }, /* sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\= 000event=3D0x2b\000v8\00000\000\000\000\000\000 */ =20 }; =20 @@ -200,17 +238,17 @@ const struct pmu_table_entry pmu_events__test_soc_sys= [] =3D { { .entries =3D pmu_events__test_soc_sys_uncore_sys_ccn_pmu, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ccn_p= mu), - .pmu_name =3D { 2446 /* uncore_sys_ccn_pmu\000 */ }, + .pmu_name =3D { 3985 /* uncore_sys_ccn_pmu\000 */ }, }, { .entries =3D pmu_events__test_soc_sys_uncore_sys_cmn_pmu, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_cmn_p= mu), - .pmu_name =3D { 2542 /* uncore_sys_cmn_pmu\000 */ }, + .pmu_name =3D { 4081 /* uncore_sys_cmn_pmu\000 */ }, }, { .entries =3D pmu_events__test_soc_sys_uncore_sys_ddr_pmu, .num_entries =3D ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ddr_p= mu), - .pmu_name =3D { 2351 /* uncore_sys_ddr_pmu\000 */ }, + .pmu_name =3D { 3890 /* uncore_sys_ddr_pmu\000 */ }, }, }; =20 @@ -632,8 +670,20 @@ static const struct pmu_events_map *map_for_pmu(struct= perf_pmu *pmu) { struct perf_cpu cpu =3D {-1}; =20 - if (pmu) + if (pmu) { + for (size_t i =3D 0; i < ARRAY_SIZE(pmu_events__common); i= ++) { + const char *pmu_name =3D &big_c_string[pmu_events_= _common[i].pmu_name.offset]; + + if (!strcmp(pmu_name, pmu->name)) { + const struct pmu_events_map *map =3D &pmu_= events_map[0]; + + while (strcmp("common", map->arch)) + map++; + return map; + } + } cpu =3D perf_cpu_map__min(pmu->cpus); + } return map_for_cpu(cpu); } =20 diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index e821155151ec..60e13a1a7d7a 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -295,6 +295,7 @@ class JsonEvent: 'cpu_atom': 'cpu_atom', 'ali_drw': 'ali_drw', 'arm_cmn': 'arm_cmn', + 'software': 'software', 'tool': 'tool', } return table[unit] if unit in table else f'uncore_{unit.lower()}' @@ -1158,8 +1159,20 @@ static const struct pmu_events_map *map_for_pmu(stru= ct perf_pmu *pmu) { struct perf_cpu cpu =3D {-1}; =20 - if (pmu) + if (pmu) { + for (size_t i =3D 0; i < ARRAY_SIZE(pmu_events__common); i= ++) { + const char *pmu_name =3D &big_c_string[pmu_events_= _common[i].pmu_name.offset]; + + if (!strcmp(pmu_name, pmu->name)) { + const struct pmu_events_map *map =3D &pmu_= events_map[0]; + + while (strcmp("common", map->arch)) + map++; + return map; + } + } cpu =3D perf_cpu_map__min(pmu->cpus); + } return map_for_cpu(cpu); } =20 --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 E60A92561B6 for ; Fri, 25 Jul 2025 18:52:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469540; cv=none; b=PszNRY3HXMtPCILhL4/Ua21wEp1LTvqf7bcwfQouhsHYslbx7Ag+Mc9JUQ6CY9doHnlEWcWUlaj3d8/8TSBLyNIuNd34KX9+s3y0V50TVDvxNbOhTTTKJPo45YgiNQQD15JVyW6TrYkAPKJr9HxRsd8cmohxFR/0E9ZwLFWTyeM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469540; c=relaxed/simple; bh=I8JtreWD5YP3mpdmcZspDQ6px466qFWW6RarayLjrKg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=eQjxO8Dcaxe/OUFFPhAGhPIJZ0CE5Ii99xfbVj3HnKv0p/t12G5zZl386rOq61CpFJGZ5LrgSC6bvi/zWaT5tCG1ILZlKvb/UWCjwD84GKcX0czkPqi9xQZKIERGA+uXTVb2UIZZRFrE5IO8JEGvkXIMkUKUhWW5+irliGuIdoo= 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=zOFZEWRF; arc=none smtp.client-ip=209.85.216.73 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="zOFZEWRF" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-3132c1942a1so3668799a91.2 for ; Fri, 25 Jul 2025 11:52:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469537; x=1754074337; 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=arcs1it3/qjLvlLfDt5UHiN3JHMiv9fKKd32k8nFb5I=; b=zOFZEWRFXZfpD9ry+KFRc/c7zHFaebFnC5aWtUw0IHN+ID12SoJuRW0HTnYvHW3p1u AJEY7v5xOcsW/BAxBmgXMzBEjgYt0RqFCty9UIaoXyleyTsHunAFnNw5nYhpDSWRv87S 1d3TLlUxHm2IaofGvP+dkmXLqxs+QpCIXhvQrIdfA9ixKSbaLSJtIqW1HDfQ8yLwW4Xv YPEPib4i8sZ23IRf/M10/clCvXEGTNF9gPsOgAPngNGVvV7a9fSTUt6/wqtsaLC3JZ/t pO3/v+iVh2xTxhZHYorLQmMdRHRKaCKA/lIUjfTUICgMmgIZW0TtEHEjVAGbPI7eepIo 6ZLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469537; x=1754074337; 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=arcs1it3/qjLvlLfDt5UHiN3JHMiv9fKKd32k8nFb5I=; b=G5PA0/PcIyRKvCVogLEfLWJTN9xwsWI0JYbbOqVmowNFirQXtWQoRHFejC+6oJtxv3 3WAHiBBiRi67ckmGM6KlohNTNxczf/xjav8Rmg6zJoYMzPPPFTmrjr84RtnWU2T6Bouk nMdM5iaR8tHQw/7b1G6L/9VGt8IhfnsE/ufDsmIcLAwMXXUCCcC4NDgtjsOMkGQtOgGw UfCjq0tO6kXFnglHW2IFrSSyFMWXFw1kP5v9sAlb2SKCycg+YpUDGa3wgLpFRuVIg1DC /FaF6ZnUmNzzqsKHiwVWnH5pVTwqsfpPnwXbOjM2cKMSfxN2cmphoG7K05UiDtX/8GeO MkDA== X-Forwarded-Encrypted: i=1; AJvYcCUxKbyJ7XZjittcPe1EPqHRMStTnO4kg4d0Icrnkug1/v+KdEAT1ROTZWvGqgUwVbVC8QfyAjfWEj0df7c=@vger.kernel.org X-Gm-Message-State: AOJu0YwulCIe6DxgYihcexqxfxO7Q/zlDdu9OeTsOHiBW1Synun8Mro2 oV1rLA5l/kUvYzzpC+KSYlEhijFuBMAWDVvxXllbZwAo+yL9uBc2m9QcFQDTlB0V/wIOilTsqkR 8k7h3AmJb3g== X-Google-Smtp-Source: AGHT+IFtc7AY0LTRMUt9w3418AqAMSJFNr9EuXh+pmofl53OfQ5b2Ts2jruYKqWFXd5yD45VFektiHu3hAst X-Received: from pjyr5.prod.google.com ([2002:a17:90a:e185:b0:31c:2fe4:33be]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:134e:b0:31c:23f2:d2ae with SMTP id 98e67ed59e1d1-31e77a59e53mr4006584a91.15.1753469537254; Fri, 25 Jul 2025 11:52:17 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:49 -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-4-irogers@google.com> Subject: [PATCH v9 03/16] perf parse-events: Remove non-json software events 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" Remove the hard coded encodings from parse-events. This has the consequence that software events are matched using the sysfs/json priority, will be case insensitive and will be wildcarded across PMUs. As there were software and hardware types in the parsing code, the removal means software vs hardware logic can be removed and hardware assumed. Now the perf json provides detailed descriptions of software events, remove the previous listing support that didn't contain event descriptions. When globbing is required for the "sw" option in perf list, use string PMU globbing as was done previously for the tool PMU. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/builtin-list.c | 19 ++++++------- tools/perf/util/parse-events.c | 51 ---------------------------------- tools/perf/util/parse-events.h | 1 - tools/perf/util/parse-events.l | 38 +++++++++---------------- tools/perf/util/parse-events.y | 29 ++++++++----------- tools/perf/util/print-events.c | 2 -- 6 files changed, 33 insertions(+), 107 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index e9b595d75df2..674bb0afbf93 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -623,16 +623,17 @@ int cmd_list(int argc, const char **argv) else if (strcmp(argv[i], "sw") =3D=3D 0 || strcmp(argv[i], "software") =3D=3D 0) { char *old_pmu_glob =3D default_ps.pmu_glob; + static const char * const sw_globs[] =3D { "software", "tool" }; =20 - print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX); - default_ps.pmu_glob =3D strdup("tool"); - if (!default_ps.pmu_glob) { - ret =3D -1; - goto out; + for (size_t j =3D 0; j < ARRAY_SIZE(sw_globs); j++) { + default_ps.pmu_glob =3D strdup(sw_globs[j]); + if (!default_ps.pmu_glob) { + ret =3D -1; + goto out; + } + perf_pmus__print_pmu_events(&print_cb, ps); + zfree(&default_ps.pmu_glob); } - perf_pmus__print_pmu_events(&print_cb, ps); - zfree(&default_ps.pmu_glob); default_ps.pmu_glob =3D old_pmu_glob; } else if (strcmp(argv[i], "cache") =3D=3D 0 || strcmp(argv[i], "hwcache") =3D=3D 0) @@ -679,8 +680,6 @@ int cmd_list(int argc, const char **argv) default_ps.event_glob =3D s; print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX); - print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX); print_hwcache_events(&print_cb, ps); perf_pmus__print_pmu_events(&print_cb, ps); print_tracepoint_events(&print_cb, ps); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index a59ae5ca0f89..1ae481c9802b 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -84,57 +84,6 @@ const struct event_symbol event_symbols_hw[PERF_COUNT_HW= _MAX] =3D { }, }; =20 -const struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] =3D { - [PERF_COUNT_SW_CPU_CLOCK] =3D { - .symbol =3D "cpu-clock", - .alias =3D "", - }, - [PERF_COUNT_SW_TASK_CLOCK] =3D { - .symbol =3D "task-clock", - .alias =3D "", - }, - [PERF_COUNT_SW_PAGE_FAULTS] =3D { - .symbol =3D "page-faults", - .alias =3D "faults", - }, - [PERF_COUNT_SW_CONTEXT_SWITCHES] =3D { - .symbol =3D "context-switches", - .alias =3D "cs", - }, - [PERF_COUNT_SW_CPU_MIGRATIONS] =3D { - .symbol =3D "cpu-migrations", - .alias =3D "migrations", - }, - [PERF_COUNT_SW_PAGE_FAULTS_MIN] =3D { - .symbol =3D "minor-faults", - .alias =3D "", - }, - [PERF_COUNT_SW_PAGE_FAULTS_MAJ] =3D { - .symbol =3D "major-faults", - .alias =3D "", - }, - [PERF_COUNT_SW_ALIGNMENT_FAULTS] =3D { - .symbol =3D "alignment-faults", - .alias =3D "", - }, - [PERF_COUNT_SW_EMULATION_FAULTS] =3D { - .symbol =3D "emulation-faults", - .alias =3D "", - }, - [PERF_COUNT_SW_DUMMY] =3D { - .symbol =3D "dummy", - .alias =3D "", - }, - [PERF_COUNT_SW_BPF_OUTPUT] =3D { - .symbol =3D "bpf-output", - .alias =3D "", - }, - [PERF_COUNT_SW_CGROUP_SWITCHES] =3D { - .symbol =3D "cgroup-switches", - .alias =3D "", - }, -}; - static const char *const event_types[] =3D { [PERF_TYPE_HARDWARE] =3D "hardware", [PERF_TYPE_SOFTWARE] =3D "software", diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index b47bf2810112..62dc7202e3ba 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -264,7 +264,6 @@ struct event_symbol { const char *alias; }; extern const struct event_symbol event_symbols_hw[]; -extern const struct event_symbol event_symbols_sw[]; =20 char *parse_events_formats_error_string(char *additional_terms); =20 diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 4af7b9c1f44d..2034590eb789 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -117,12 +117,12 @@ do { \ yyless(0); \ } while (0) =20 -static int sym(yyscan_t scanner, int type, int config) +static int sym(yyscan_t scanner, int config) { YYSTYPE *yylval =3D parse_events_get_lval(scanner); =20 - yylval->num =3D (type << 16) + config; - return type =3D=3D PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW; + yylval->num =3D config; + return PE_VALUE_SYM_HW; } =20 static int term(yyscan_t scanner, enum parse_events__term_type type) @@ -391,28 +391,16 @@ r0x{num_raw_hex} { return str(yyscanner, PE_RAW); } <> { BEGIN(INITIAL); } } =20 -cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUN= T_HW_CPU_CYCLES); } -stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_= TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } -stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TY= PE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } -instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW= _INSTRUCTIONS); } -cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT= _HW_CACHE_REFERENCES); } -cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW= _CACHE_MISSES); } -branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE,= PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } -branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_H= W_BRANCH_MISSES); } -bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_B= US_CYCLES); } -ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_R= EF_CPU_CYCLES); } -cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CP= U_CLOCK); } -task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_T= ASK_CLOCK); } -page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COU= NT_SW_PAGE_FAULTS); } -minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW= _PAGE_FAULTS_MIN); } -major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW= _PAGE_FAULTS_MAJ); } -context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_CO= UNT_SW_CONTEXT_SWITCHES); } -cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PE= RF_COUNT_SW_CPU_MIGRATIONS); } -alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT= _SW_ALIGNMENT_FAULTS); } -emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT= _SW_EMULATION_FAULTS); } -dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY= ); } -bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_B= PF_OUTPUT); } -cgroup-switches { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT= _SW_CGROUP_SWITCHES); } +cpu-cycles|cycles { return sym(yyscanner, PERF_COUNT_HW_CPU_CYCLES); } +stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_= COUNT_HW_STALLED_CYCLES_FRONTEND); } +stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_CO= UNT_HW_STALLED_CYCLES_BACKEND); } +instructions { return sym(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); } +cache-references { return sym(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES= ); } +cache-misses { return sym(yyscanner, PERF_COUNT_HW_CACHE_MISSES); } +branch-instructions|branches { return sym(yyscanner, PERF_COUNT_HW_BRANC= H_INSTRUCTIONS); } +branch-misses { return sym(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); } +bus-cycles { return sym(yyscanner, PERF_COUNT_HW_BUS_CYCLES); } +ref-cycles { return sym(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); } =20 {lc_type} { return str(yyscanner, PE_LEGACY_CACHE); } {lc_type}-{lc_op_result} { return str(yyscanner, PE_LEGACY_CACHE); } diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index f888cbb076d6..a2361c0040d7 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -55,7 +55,7 @@ static void free_list_evsel(struct list_head* list_evsel) %} =20 %token PE_START_EVENTS PE_START_TERMS -%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_TERM +%token PE_VALUE PE_VALUE_SYM_HW PE_TERM %token PE_EVENT_NAME %token PE_RAW PE_NAME %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH @@ -66,10 +66,8 @@ static void free_list_evsel(struct list_head* list_evsel) %token PE_TERM_HW %type PE_VALUE %type PE_VALUE_SYM_HW -%type PE_VALUE_SYM_SW %type PE_MODIFIER_EVENT %type PE_TERM -%type value_sym %type PE_RAW %type PE_NAME %type PE_LEGACY_CACHE @@ -306,24 +304,19 @@ PE_NAME sep_dc $$ =3D list; } =20 -value_sym: -PE_VALUE_SYM_HW -| -PE_VALUE_SYM_SW - event_legacy_symbol: -value_sym '/' event_config '/' +PE_VALUE_SYM_HW '/' event_config '/' { struct list_head *list; - int type =3D $1 >> 16; - int config =3D $1 & 255; int err; - bool wildcard =3D (type =3D=3D PERF_TYPE_HARDWARE || type =3D=3D PERF_TYP= E_HW_CACHE); =20 list =3D alloc_list(); if (!list) YYNOMEM; - err =3D parse_events_add_numeric(_parse_state, list, type, config, $3, wi= ldcard); + err =3D parse_events_add_numeric(_parse_state, list, + PERF_TYPE_HARDWARE, $1, + $3, + /*wildcard=3D*/true); parse_events_terms__delete($3); if (err) { free_list_evsel(list); @@ -332,18 +325,18 @@ value_sym '/' event_config '/' $$ =3D list; } | -value_sym sep_slash_slash_dc +PE_VALUE_SYM_HW sep_slash_slash_dc { struct list_head *list; - int type =3D $1 >> 16; - int config =3D $1 & 255; - bool wildcard =3D (type =3D=3D PERF_TYPE_HARDWARE || type =3D=3D PERF_TYP= E_HW_CACHE); int err; =20 list =3D alloc_list(); if (!list) YYNOMEM; - err =3D parse_events_add_numeric(_parse_state, list, type, config, /*head= _config=3D*/NULL, wildcard); + err =3D parse_events_add_numeric(_parse_state, list, + PERF_TYPE_HARDWARE, $1, + /*head_config=3D*/NULL, + /*wildcard=3D*/true); if (err) PE_ABORT(err); $$ =3D list; diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index e233bacaa641..c1a8708b55ab 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -521,8 +521,6 @@ void print_events(const struct print_callbacks *print_c= b, void *print_state) { print_symbol_events(print_cb, print_state, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX); - print_symbol_events(print_cb, print_state, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX); =20 print_hwcache_events(print_cb, print_state); =20 --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 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 1DF94257422 for ; Fri, 25 Jul 2025 18:52:19 +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=1753469542; cv=none; b=ECpfqMtOy1uj+AG9LuC7es1iqe0y9Z2mqD82L29MrjeleopoClYLEbqMt/+gbxLrNS4Z4J57jtp+REgGVLeyIRwifbFJfui17OQlGa8aV7WicCl6qWmZZjrURgIeNmoTAmO+dbcZRr05/jryTojTXqGkYfZlaRMlwMz/GQXXChQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469542; c=relaxed/simple; bh=hoj5eUkToMm6uZObGB5cFwAWBnzXumOBYBWCaw68h+c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EBb3pJJHkmanonwQdg6FT9JH7pNQIk+hZ7yj25/VBV+AWFDCHkMPsFGNcQk9MDsxXb9Rm+eZ6c1ogIfZf/qhvhH8be5elT9/DX9AXDZy0UCNv6tyMsJKAADWrwljW0eEuPu1O2hQouCXOT/lnyT/poFommeO4pS4sQPvNrhlGn8= 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=w7G4qGDQ; 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="w7G4qGDQ" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b31f4a9f67cso3081802a12.1 for ; Fri, 25 Jul 2025 11:52:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469539; x=1754074339; 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=08PPgDE5OdsZ+d+jF5WfUFB9opxwrXI8ASW2+zMZdDM=; b=w7G4qGDQOGb0E0xmBXG6FSzWC2Ij9XtQABmOmRS2psJ8AQ7U1XINvba1DopRlL09TW y7Le+3Q1ecz5bsxhTfcHJXTXcjmjmlz2H05vvebI3NC1dcKm8hr3wJ4VcIE2a51FE67I ClNwXdd36RQDz5Zu5BZ4eGzEiBcqhbdl1rjLWL51ufykCaXf9oR2xRuOhYhYXfDfXMeF rCSGcwUO5ueKgPblC4i/L04d6RkxjNhXpyAF4tzp34UUW880Qyjxmc2V/oK+4wtvyL3F UTJrJVE5FSVyQPpqr5mjelnldALI4DrDN9yrjTeTsYJFEiRytOG/uIUv7dnEPfzNqR74 74zA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469539; x=1754074339; 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=08PPgDE5OdsZ+d+jF5WfUFB9opxwrXI8ASW2+zMZdDM=; b=YUcqETVJx7VG+hqH7GOpcRoAxZfM52GZ+dBYUPOvWZFBEByw4hVlTv8vC31Jr1mJv4 yuw9f/AgVckuuKcAeCiPCyKeViIJJbHLADvd4fPLfKYkc+r3/aOR1/JJ7r31n3vY7pe6 9l10Ucagh/4MvYMZ3bJ4n5cLamIRCRLFpyTO39DjoXQN6QBiaf9QZq3umhie+GKs91NC Acda3bn/oznTsSwZu9QyZZ9b9xwhu/nQFxc8Nr/y5W2eiYXY+ALN7JrDjNfW/RIU7j3p aT1dJZ2oq/rUv4K5jWgwHlFoeZDCfuL7FQzioPMNSOY8LVfz1601eVNuVhi1abmDDtbq NwRw== X-Forwarded-Encrypted: i=1; AJvYcCUch72jpmGpLskwk7c5E/HccqXbfNYhvVyvd2zMoCa+7LAOumz29V44xep9tfc/zOiSCHXnXFjCSRTuYI4=@vger.kernel.org X-Gm-Message-State: AOJu0Yy8AGqaN838MGghgtfi/qMKnsPB1O9KKBVWcJzynCslmv0u4yK1 2E6aUghXeEueIoaXn2Qejvtm3yeTvocUzS61h1aRN3CJhz0elGNy3iWIuWr36Sl2XBztxxqGLYQ iC/lWRBHpWA== X-Google-Smtp-Source: AGHT+IF2Zpaq0tMC8GDyA1CH3m0xqebFcW5hrIFObdmyrzVQD++xikkbvUz0uGcNDnBgQXHETYu2ygnIXRcg X-Received: from plbmm6.prod.google.com ([2002:a17:903:a06:b0:236:9738:9180]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:e5c4:b0:235:f3e6:467f with SMTP id d9443c01a7336-23fb309c031mr48015075ad.2.1753469539357; Fri, 25 Jul 2025 11:52:19 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:50 -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-5-irogers@google.com> Subject: [PATCH v9 04/16] 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 Cc: Arnaldo Carvalho de Melo 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 Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- 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 +=3D pmu-bison.o perf-util-y +=3D drm_pmu.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 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; } =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. */ @@ -622,7 +605,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 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 =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..42bd967a4530 --- /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.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 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 Reviewed-by: Howard Chu --- 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 From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (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 290D9259C93 for ; Fri, 25 Jul 2025 18:52:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469545; cv=none; b=tyjI92V1BkLHIKcEau7uMWyDMxVCJK4gjUasTKUjtpjwpS/hiiUOr+yYRL6Xx0z5Mxiaob5R/qVQVGaHPnZpBZn20VzS3sxeGW1jJLjyX1+p+6rLoCtwD1oHSd62T78DCxpRicOEgeYgReuxPJxJVKaNOic2YS8r5gQnkKd7wNA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469545; c=relaxed/simple; bh=ppHlmYUuAHv5DYS9QXKLT4UzrfJvaJA2xgfk+czayuQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ghj6Sy6fRTLq6rpiB2NfGrr26FDeDIdbBXiFinUY3Zpicd80wydMDpnaTd710ynjB6/52IZL3Wk7uO+N8Q3PzRRKf/RKv/5O8EH0+LJzZNEr0XYH3laeo+cAtRY0nC+H1N9F0wm6TgDuCwiady2pnszHWn0217HbjaHlJaRsnFo= 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=pw0GqT70; arc=none smtp.client-ip=209.85.214.201 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="pw0GqT70" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-235c897d378so25868245ad.1 for ; Fri, 25 Jul 2025 11:52:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469543; x=1754074343; 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=sA4i8xTnlF3/CS6H5DH4dmVmv5iGDQy59prS9DyuVBA=; b=pw0GqT70A2PF0RKFSY/2LVPyWsnECzRW15SEiv4hMIa3lF8Eko0a7sh/jL27LG7x/a RK4wXn06wm4i79YuTkIxL2vqKD/6BBoKSsUoIhy95HgDHR2/mxGCT7hS6dvnByRbFu4x xygNum52K6eTuKpgiGoL677zFJTqGsvoENrsHau7TG9OxaZN3XJlHsYw6wBQ61Tp0qxo fMW8RJQ4yjfwLR5mCYhcK5Ld6jtvvjnUwVhNChPj74Rb6za+3vYdGOdvJeJ9ENVJz2xK Fy7vNOyf0MY6kMtAslV9l8Eh+b7x0Ws9SYomp6qdJDwm/rNvqCBrJtBr2G7qjdIuuNc5 QMgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469543; x=1754074343; 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=sA4i8xTnlF3/CS6H5DH4dmVmv5iGDQy59prS9DyuVBA=; b=UayHko56LFKwVQb/i2/dNwqdIjSgP98y/Azmdkawf3Vq7Sodofzp7/Bpg/f5knY399 2/qGxhn54J3vlc8Rzp6i7DsVdTdjKJcZYnKxHNSyCe4V6V3ciDnqD1L5xhGFOz6Zet91 lKjyk9J0cgPd212DTELGpYtSCg2OYCjH0BT6B2PiyTDK63yoiLcZegqdU/XwtnsvHk2b 4CKL/U1eySbU8ZtNaPht6aUiFNJgZNIN5vEog7oMDJG9N9LAO1NUr8eEJIMGukMnjOMo 9sjVhSA+2PbCPyHuhiNk2ROJFdsbxiuOvkqcoXrY/Hlncks1/cXsLRQaLIgST64KxKPq VJow== X-Forwarded-Encrypted: i=1; AJvYcCWf8fHpktBnyct/weQHrfWLpgFhxn4yzBKfY8VhfNrZ4n+/nnZ/oVdbaZuIRB7isKAycCQiIno2MtxwSpQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yza9zfDgIZruD02Sx2cQH8sF0XubR387HHUzNAxGdOEM3pR4MUW ILmXuOWNJ1VToNIh8UImET1UZUt6PNxWqAc/CuPn1KxN8SSP4CFVTcuG0qjsuCRv1AwLe7/HjKu 0NxtruW79YQ== X-Google-Smtp-Source: AGHT+IGxhjvl84CTxgxdyhbo7AiTP5Ij1s6m1VkfrUtHM05lXZm2mLtVuYJ1Uk6vIYaIOoYroNcmyvoytsRe X-Received: from pllt10.prod.google.com ([2002:a17:902:dcca:b0:234:952b:35a2]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:198d:b0:235:eb8d:7fff with SMTP id d9443c01a7336-23fb30be09fmr42077855ad.28.1753469543350; Fri, 25 Jul 2025 11:52:23 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:52 -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-7-irogers@google.com> Subject: [PATCH v9 06/16] perf list: Remove tracepoint printing code 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" Now that the tp_pmu can iterate and describe events remove the custom tracepoint printing logic, this avoids perf list showing the tracepoint events twice. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/builtin-list.c | 29 ++++++++--- tools/perf/util/print-events.c | 93 ---------------------------------- tools/perf/util/print-events.h | 2 - 3 files changed, 23 insertions(+), 101 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 674bb0afbf93..3a4061d02f6c 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -614,9 +614,18 @@ int cmd_list(int argc, const char **argv) for (i =3D 0; i < argc; ++i) { char *sep, *s; =20 - if (strcmp(argv[i], "tracepoint") =3D=3D 0) - print_tracepoint_events(&print_cb, ps); - else if (strcmp(argv[i], "hw") =3D=3D 0 || + if (strcmp(argv[i], "tracepoint") =3D=3D 0) { + char *old_pmu_glob =3D default_ps.pmu_glob; + + default_ps.pmu_glob =3D strdup("tracepoint"); + if (!default_ps.pmu_glob) { + ret =3D -1; + goto out; + } + perf_pmus__print_pmu_events(&print_cb, ps); + zfree(&default_ps.pmu_glob); + default_ps.pmu_glob =3D old_pmu_glob; + } else if (strcmp(argv[i], "hw") =3D=3D 0 || strcmp(argv[i], "hardware") =3D=3D 0) print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX); @@ -658,6 +667,7 @@ int cmd_list(int argc, const char **argv) #endif else if ((sep =3D strchr(argv[i], ':')) !=3D NULL) { char *old_pmu_glob =3D default_ps.pmu_glob; + char *old_event_glob =3D default_ps.event_glob; =20 default_ps.event_glob =3D strdup(argv[i]); if (!default_ps.event_glob) { @@ -665,13 +675,21 @@ int cmd_list(int argc, const char **argv) goto out; } =20 - print_tracepoint_events(&print_cb, ps); + default_ps.pmu_glob =3D strdup("tracepoint"); + if (!default_ps.pmu_glob) { + zfree(&default_ps.event_glob); + ret =3D -1; + goto out; + } + perf_pmus__print_pmu_events(&print_cb, ps); + zfree(&default_ps.pmu_glob); + default_ps.pmu_glob =3D old_pmu_glob; print_sdt_events(&print_cb, ps); default_ps.metrics =3D true; default_ps.metricgroups =3D true; metricgroup__print(&print_cb, ps); zfree(&default_ps.event_glob); - default_ps.pmu_glob =3D old_pmu_glob; + default_ps.event_glob =3D old_event_glob; } else { if (asprintf(&s, "*%s*", argv[i]) < 0) { printf("Critical: Not enough memory! Trying to continue...\n"); @@ -682,7 +700,6 @@ int cmd_list(int argc, const char **argv) event_symbols_hw, PERF_COUNT_HW_MAX); print_hwcache_events(&print_cb, ps); perf_pmus__print_pmu_events(&print_cb, ps); - print_tracepoint_events(&print_cb, ps); print_sdt_events(&print_cb, ps); default_ps.metrics =3D true; default_ps.metricgroups =3D true; diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index c1a8708b55ab..3a5e5e7bae13 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -44,97 +44,6 @@ static const char * const event_type_descriptors[] =3D { "Hardware breakpoint", }; =20 -/* - * Print the events from /tracing/events - */ -void print_tracepoint_events(const struct print_callbacks *print_cb __mayb= e_unused, void *print_state __maybe_unused) -{ - char *events_path =3D get_tracing_file("events"); - int events_fd =3D open(events_path, O_PATH); - struct dirent **sys_namelist =3D NULL; - int sys_items; - - if (events_fd < 0) { - pr_err("Error: failed to open tracing events directory\n"); - pr_err("%s: %s\n", events_path, strerror(errno)); - return; - } - put_tracing_file(events_path); - - sys_items =3D tracing_events__scandir_alphasort(&sys_namelist); - - for (int i =3D 0; i < sys_items; i++) { - struct dirent *sys_dirent =3D sys_namelist[i]; - struct dirent **evt_namelist =3D NULL; - int dir_fd; - int evt_items; - - if (sys_dirent->d_type !=3D DT_DIR || - !strcmp(sys_dirent->d_name, ".") || - !strcmp(sys_dirent->d_name, "..")) - goto next_sys; - - dir_fd =3D openat(events_fd, sys_dirent->d_name, O_PATH); - if (dir_fd < 0) - goto next_sys; - - evt_items =3D scandirat(events_fd, sys_dirent->d_name, &evt_namelist, NU= LL, alphasort); - for (int j =3D 0; j < evt_items; j++) { - /* - * Buffer sized at twice the max filename length + 1 - * separator + 1 \0 terminator. - */ - char buf[NAME_MAX * 2 + 2]; - /* 16 possible hex digits and 22 other characters and \0. */ - char encoding[16 + 22]; - struct dirent *evt_dirent =3D evt_namelist[j]; - struct io id; - __u64 config; - - if (evt_dirent->d_type !=3D DT_DIR || - !strcmp(evt_dirent->d_name, ".") || - !strcmp(evt_dirent->d_name, "..")) - goto next_evt; - - snprintf(buf, sizeof(buf), "%s/id", evt_dirent->d_name); - io__init(&id, openat(dir_fd, buf, O_RDONLY), buf, sizeof(buf)); - - if (id.fd < 0) - goto next_evt; - - if (io__get_dec(&id, &config) < 0) { - close(id.fd); - goto next_evt; - } - close(id.fd); - - snprintf(buf, sizeof(buf), "%s:%s", - sys_dirent->d_name, evt_dirent->d_name); - snprintf(encoding, sizeof(encoding), "tracepoint/config=3D0x%llx/", con= fig); - print_cb->print_event(print_state, - /*topic=3D*/NULL, - /*pmu_name=3D*/NULL, /* really "tracepoint" */ - /*event_name=3D*/buf, - /*event_alias=3D*/NULL, - /*scale_unit=3D*/NULL, - /*deprecated=3D*/false, - "Tracepoint event", - /*desc=3D*/NULL, - /*long_desc=3D*/NULL, - encoding); -next_evt: - free(evt_namelist[j]); - } - close(dir_fd); - free(evt_namelist); -next_sys: - free(sys_namelist[i]); - } - - free(sys_namelist); - close(events_fd); -} - void print_sdt_events(const struct print_callbacks *print_cb, void *print_= state) { struct strlist *bidlist, *sdtlist; @@ -552,8 +461,6 @@ void print_events(const struct print_callbacks *print_c= b, void *print_state) /*long_desc=3D*/NULL, /*encoding_desc=3D*/NULL); =20 - print_tracepoint_events(print_cb, print_state); - print_sdt_events(print_cb, print_state); =20 metricgroup__print(print_cb, print_state); diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h index 48682e2d166d..4d95b8257e23 100644 --- a/tools/perf/util/print-events.h +++ b/tools/perf/util/print-events.h @@ -37,8 +37,6 @@ void print_sdt_events(const struct print_callbacks *print= _cb, void *print_state) void print_symbol_events(const struct print_callbacks *print_cb, void *pri= nt_state, unsigned int type, const struct event_symbol *syms, unsigned int max); - -void print_tracepoint_events(const struct print_callbacks *print_cb, void = *print_state); void metricgroup__print(const struct print_callbacks *print_cb, void *prin= t_state); bool is_event_supported(u8 type, u64 config); =20 --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 3100E25A337 for ; Fri, 25 Jul 2025 18:52:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469547; cv=none; b=ISwPyDPu30cRp+jKt2FmaODk3xQ3rAouY7sAjfHaaZOrLbMwJDYtrskkD+2y5NynVLjPLeL0WgPzEUsOJGenZgqxKInfLHwTjNXblRxWqwq7feRbJumm+qbmUJvBPfmBHvmX0Zw9aAlxsgw/TZ4qh3N7CH6TspMCwHFg6ArLNrc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469547; c=relaxed/simple; bh=fmOf67mYy2YF9nljA/l/8CF2En/7uvdEKGswm7M5KtQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=H3PcVYHtHCJhnpp/aJpgC0ZNxegJnoP8gM1CiHRlEgou065Kku9L0UGjhdTBvfQ6CR+95DFmP4ujAp39ERlFHp+nbuSELVtndwzwXhL564WokAsiWDvpSfNIawb/57VKaFTcI311z9SztdRwuDAB1PusaoOB+p6i8bWhVUus3kg= 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=jGRdTxdC; arc=none smtp.client-ip=209.85.216.73 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="jGRdTxdC" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-313d346dc8dso3920517a91.1 for ; Fri, 25 Jul 2025 11:52:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469545; x=1754074345; 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=ajPd5cDSeZah077hQm/GVBCOuGQaq5LX5cjERb/YlTs=; b=jGRdTxdCqIjtaY434YO3TUwSKS/ozAC1ZtsdULQIIG+XtSZjOQbTG9XZwYirn7p5A9 qHfZn20KEwI2tWe1N0rehsaFRV1A0PyTFgFFzYC/5zUGUbSsSUBkb5ZXGSaxUucaj0D2 3zrWATypq6vjo2zGNRgwU67yKt1CTx+S6o8XxXuXdl36BiosvdPvVaHBk6rp4tBD4te8 M7he7qsEvit22/Z+hJtJb/MU67UsjRiwBdxgQVkf2CrwYMChCklsJU3d97pGfT1Z1uA1 5ySPocgLMAbP0qeGZVvIBWMe7xhceC/cx9iDVlkf9slunaO4GFxoIqQn0DCLaOaZOhQh FTCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469545; x=1754074345; 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=ajPd5cDSeZah077hQm/GVBCOuGQaq5LX5cjERb/YlTs=; b=CfqthYGbdMI0BjmgiOiK1iSEwuPSImG6okhtExxYDIqf/oYDVYj0khf/57Zjtjr9eD V+g6UDwA7/vdG8BnYoJnBlNK06qk0+m7x2UR6RQdsPoVibWoLayeK9hYicwhJ39PUAxt WVqDYTXY/DUkFq1zNs7+4SINiS8Lr8zHet5jvPMKIb58JQNAvXnSBmIvL8MeQ7v9Jla/ 63GRvDEDtH2bK1w16//IeHSeaOARN/X9VE4PX0Z4jNY1kGCrcQtdXkSNYddau4Z9tWAM SJDMRYYTjn4NVMI2ENLCOdIVncBx7PjPdCFR4p1hAWiAlLYK8H9ZhRSYdAPvq+UKNc9R Embg== X-Forwarded-Encrypted: i=1; AJvYcCWeofSaornZ92RCRExw6FkJWjqUUYtJj3Ym0O7aG7s1crJa2jpGFX5iKlo/oyV9qg7lV7yuq+v7MsTmL0I=@vger.kernel.org X-Gm-Message-State: AOJu0YynV3ybMK5eAvNnYTViajmBwWcLTLSIYOleU3faUcdWK3Wc1DVu w5plDeARirIXQi9tHZn+fzDyUgsWnkYf+A7ZpjeQRokBCdQbshBTX0RU8FyLe8D7jy4YOlSLQUO pveiTIij8xQ== X-Google-Smtp-Source: AGHT+IHSnBl04YbUkk+eLAxdnDYSwz2p9wJx1N/PAq3VqpzbJJCK6yudLgzRX+KTk7h5Fyp80StCly+JU5eq X-Received: from pjqq12.prod.google.com ([2002:a17:90b:584c:b0:2ff:6132:8710]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3bc4:b0:308:7270:d6ea with SMTP id 98e67ed59e1d1-31e77a2483fmr4188367a91.30.1753469545549; Fri, 25 Jul 2025 11:52:25 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:53 -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-8-irogers@google.com> Subject: [PATCH v9 07/16] perf list: Skip ABI PMUs when printing pmu values 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" Avoid printing tracepoint, legacy and software events when listing for the pmu option. Add the PMU type to the print_event callbacks to ease detection. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/builtin-list.c | 17 +++++++++++++---- tools/perf/util/pfm.c | 2 ++ tools/perf/util/pmus.c | 2 ++ tools/perf/util/print-events.c | 5 +++++ tools/perf/util/print-events.h | 2 +- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 3a4061d02f6c..caf42276bd0f 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -58,6 +58,8 @@ struct print_state { bool metrics; /** @metricgroups: Controls printing of metric and metric groups. */ bool metricgroups; + /** @exclude_abi: Exclude PMUs with types less than PERF_TYPE_MAX except = PERF_TYPE_RAW. */ + bool exclude_abi; /** @last_topic: The last printed event topic. */ char *last_topic; /** @last_metricgroups: The last printed metric group. */ @@ -113,7 +115,8 @@ static void wordwrap(FILE *fp, const char *s, int start= , int max, int corr) } } =20 -static void default_print_event(void *ps, const char *topic, const char *p= mu_name, +static void default_print_event(void *ps, const char *topic, + const char *pmu_name, u32 pmu_type, const char *event_name, const char *event_alias, const char *scale_unit __maybe_unused, bool deprecated, const char *event_type_desc, @@ -130,6 +133,9 @@ static void default_print_event(void *ps, const char *t= opic, const char *pmu_nam if (print_state->pmu_glob && pmu_name && !strglobmatch(pmu_name, print_st= ate->pmu_glob)) return; =20 + if (print_state->exclude_abi && pmu_type < PERF_TYPE_MAX && pmu_type !=3D= PERF_TYPE_RAW) + return; + if (print_state->event_glob && (!event_name || !strglobmatch(event_name, print_state->event_glob)) && (!event_alias || !strglobmatch(event_alias, print_state->event_glob))= && @@ -354,7 +360,8 @@ static void fix_escape_fprintf(FILE *fp, struct strbuf = *buf, const char *fmt, .. fputs(buf->buf, fp); } =20 -static void json_print_event(void *ps, const char *topic, const char *pmu_= name, +static void json_print_event(void *ps, const char *topic, + const char *pmu_name, u32 pmu_type __maybe_unused, const char *event_name, const char *event_alias, const char *scale_unit, bool deprecated, const char *event_type_desc, @@ -647,9 +654,11 @@ int cmd_list(int argc, const char **argv) } else if (strcmp(argv[i], "cache") =3D=3D 0 || strcmp(argv[i], "hwcache") =3D=3D 0) print_hwcache_events(&print_cb, ps); - else if (strcmp(argv[i], "pmu") =3D=3D 0) + else if (strcmp(argv[i], "pmu") =3D=3D 0) { + default_ps.exclude_abi =3D true; perf_pmus__print_pmu_events(&print_cb, ps); - else if (strcmp(argv[i], "sdt") =3D=3D 0) + default_ps.exclude_abi =3D false; + } else if (strcmp(argv[i], "sdt") =3D=3D 0) print_sdt_events(&print_cb, ps); else if (strcmp(argv[i], "metric") =3D=3D 0 || strcmp(argv[i], "metrics"= ) =3D=3D 0) { default_ps.metricgroups =3D false; diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c index 0dacc133ed39..15fc3898ec83 100644 --- a/tools/perf/util/pfm.c +++ b/tools/perf/util/pfm.c @@ -234,6 +234,7 @@ print_libpfm_event(const struct print_callbacks *print_= cb, void *print_state, =20 if (is_libpfm_event_supported(name, cpus, threads)) { print_cb->print_event(print_state, topic, pinfo->name, + /*pmu_type=3D*/PERF_TYPE_RAW, name, info->equiv, /*scale_unit=3D*/NULL, /*deprecated=3D*/NULL, "PFM event", @@ -269,6 +270,7 @@ print_libpfm_event(const struct print_callbacks *print_= cb, void *print_state, print_cb->print_event(print_state, topic, pinfo->name, + /*pmu_type=3D*/PERF_TYPE_RAW, name, /*alias=3D*/NULL, /*scale_unit=3D*/NULL, /*deprecated=3D*/NULL, "PFM event", diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c index 409b909cfa02..004f5f0c621f 100644 --- a/tools/perf/util/pmus.c +++ b/tools/perf/util/pmus.c @@ -645,6 +645,7 @@ void perf_pmus__print_pmu_events(const struct print_cal= lbacks *print_cb, void *p print_cb->print_event(print_state, aliases[j].topic, aliases[j].pmu_name, + aliases[j].pmu->type, aliases[j].name, aliases[j].alias, aliases[j].scale_unit, @@ -749,6 +750,7 @@ void perf_pmus__print_raw_pmu_events(const struct print= _callbacks *print_cb, voi print_cb->print_event(print_state, /*topic=3D*/NULL, /*pmu_name=3D*/NULL, + pmu->type, format_args.short_string.buf, /*event_alias=3D*/NULL, /*scale_unit=3D*/NULL, diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index 3a5e5e7bae13..4153124a9948 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -121,6 +121,7 @@ void print_sdt_events(const struct print_callbacks *pri= nt_cb, void *print_state) print_cb->print_event(print_state, /*topic=3D*/NULL, /*pmu_name=3D*/NULL, + PERF_TYPE_TRACEPOINT, evt_name ?: sdt_name->s, /*event_alias=3D*/NULL, /*deprecated=3D*/false, @@ -222,6 +223,7 @@ int print_hwcache_events(const struct print_callbacks *= print_cb, void *print_sta print_cb->print_event(print_state, "cache", pmu->name, + pmu->type, name, alias_name, /*scale_unit=3D*/NULL, @@ -278,6 +280,7 @@ void print_symbol_events(const struct print_callbacks *= print_cb, void *print_sta print_cb->print_event(print_state, /*topic=3D*/NULL, /*pmu_name=3D*/NULL, + type, nd->s, alias, /*scale_unit=3D*/NULL, @@ -438,6 +441,7 @@ void print_events(const struct print_callbacks *print_c= b, void *print_state) print_cb->print_event(print_state, /*topic=3D*/NULL, /*pmu_name=3D*/NULL, + PERF_TYPE_RAW, "rNNN", /*event_alias=3D*/NULL, /*scale_unit=3D*/NULL, @@ -452,6 +456,7 @@ void print_events(const struct print_callbacks *print_c= b, void *print_state) print_cb->print_event(print_state, /*topic=3D*/NULL, /*pmu_name=3D*/NULL, + PERF_TYPE_BREAKPOINT, "mem:[/len][:access]", /*scale_unit=3D*/NULL, /*event_alias=3D*/NULL, diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h index 4d95b8257e23..d6ba384f0c66 100644 --- a/tools/perf/util/print-events.h +++ b/tools/perf/util/print-events.h @@ -12,7 +12,7 @@ struct print_callbacks { void (*print_start)(void *print_state); void (*print_end)(void *print_state); void (*print_event)(void *print_state, const char *topic, - const char *pmu_name, + const char *pmu_name, u32 pmu_type, const char *event_name, const char *event_alias, const char *scale_unit, bool deprecated, const char *event_type_desc, --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 4FA1F25B2E1 for ; Fri, 25 Jul 2025 18:52:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469549; cv=none; b=bKMKNm6+TJEB/0FFMS4oR/NYe6dc6DNNiD3E3SXbhM8jo7yWOL52wxLmCi8GbFaiX/KWSD2gJ7IqAIrRXGEvj6RYTAvS341b36q8eNcZRxxXRpxEMb5uaJQG6Y8m6gYkUYd+RN03zXCNLgCmKak6Vc9eGlmmJq0SdFLMG1zrI8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469549; c=relaxed/simple; bh=HqDk6X1/DfCGPk0Gp0ehRv47DcS+8QrSdxSSMXn33lQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=r/VceZCO6g3i4w1GqmyPtcGm0BgPusQAoj2pBmJpYEfzMQOIKiCQFwcPU0dG2vZlGQLMp3P4cV6AWeVkNafPGOxb6kg0mOI0nzFehhMoOLro18jatrVxgTdVKKzGdCx8lgyqTOCwCM6wPWVnyqgwo51bMLzZoqh5Py4fUHdlabI= 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=nOZTinoG; arc=none smtp.client-ip=209.85.216.73 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="nOZTinoG" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-31e3d563a53so3390450a91.3 for ; Fri, 25 Jul 2025 11:52:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469547; x=1754074347; 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=dmEgoww/7meU+yLm8fgYCDKtHPDOME4Ul+s+jjhRtlQ=; b=nOZTinoGR+RKl2yLPkY9+bpYb5ySJNGOKiwJBXuS/YTApdz3ksDCXXrB2J26mgyCD7 pzXmZjnf/avAdWzuc8AyLsc70uuKJ+JHU8UnMjD5XwMsBdxs+s7PXLHzuEClHGN/MqiZ BQUZUpG1HPgkZ4ozF3AP3QsXx1RlTQE7Vqo4EyCgJhHEUXN6/CCXYROegmst/czlIqye bEeyp4ZWf+tnMOxw+uDPVpvk8I5c56bF5z2Peu2/xmx0ds6x0QlxYR1mXxH/tXTTKZz+ ilTU7goMXNQilhaJPzTNfCAJwQfZa753kadbXfsB45YNqMZmZ8FOxRo/JKxOzciYIKCe 9Z7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469547; x=1754074347; 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=dmEgoww/7meU+yLm8fgYCDKtHPDOME4Ul+s+jjhRtlQ=; b=Zo+yZL01tE2XSU+WJyo7cQKIrVCCGwDg3kCI5C8ydiiy9Z/cKOKJzkIloXi9c2FEce 74EGRpeRLDvnnK25L7/PPdbVPyyFNWwt1xkCL67zX6tMd5N4w/Mo4ccIYwjHrZ9AFZ96 qVn99T57wEhhNt+De2UNo+Hh/EVhbxVHo0OrOLWXMQXkipyHWF4o5Pb5/0f3eYpySCjB dBOtEVZxU4fVzRJ88Jjfzh171CUe96L0XyKxUdlqVYJqdosVB6IMWjQksqvLVbc4K1Xw /yGILQQbQJsn76ct+wgVJAfUYdvvreme39jnSxg1KcI0om9+6H7AtO97CtUwKPGfdD/p v9XA== X-Forwarded-Encrypted: i=1; AJvYcCX1pG1ZmmB6T8qIr1Q+NP52WbZz8Zj7bnL7jC/PC/n61DjCrXyWlPo224MHfZIHQrLFWQxgkThOjBcct5Q=@vger.kernel.org X-Gm-Message-State: AOJu0YzUuCgiwDEjT1Cg8k8QD1D8LsPxk3JO1RQMws5d3uwiYdg2Udz4 gP/Jam7wZO6vAGeEFvY21Ey8RtJvA5tMG2EsfSbJu9yQWDXry0PwVfz/NXqTzDD7fxK1DJ3plNW yjL4FR8Gc4w== X-Google-Smtp-Source: AGHT+IGUqLRV5Yb6+qeKqxFNA0h+T/6ceXq86GJKGP9IFI8x/riCJDryd+TO6TzmpDgCqJ/6dINlzlxLO4nS X-Received: from pjbqd6.prod.google.com ([2002:a17:90b:3cc6:b0:31c:32f8:3f88]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:5244:b0:311:9e59:7aba with SMTP id 98e67ed59e1d1-31e77871248mr4447359a91.2.1753469547424; Fri, 25 Jul 2025 11:52:27 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:54 -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-9-irogers@google.com> Subject: [PATCH v9 08/16] perf python: Improve the tracepoint function if no libtraceevent 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" The tracepoint function just returns the tracepoint id, this doesn't require libtraceevent which is only used for parsing the event format data. Implement the function using the id function in tp_pmu. No current code in perf is using this, the previous code migrated to perf.parse_events, but it feels good to have less ifdef HAVE_LIBTRACEEVENT. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 3affde0ad15a..9c9972d77d1e 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -18,6 +18,7 @@ #include "record.h" #include "strbuf.h" #include "thread_map.h" +#include "tp_pmu.h" #include "trace-event.h" #include "metricgroup.h" #include "mmap.h" @@ -1544,10 +1545,6 @@ static const struct perf_constant perf__constants[] = =3D { static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs) { -#ifndef HAVE_LIBTRACEEVENT - return NULL; -#else - struct tep_event *tp_format; static char *kwlist[] =3D { "sys", "name", NULL }; char *sys =3D NULL; char *name =3D NULL; @@ -1556,12 +1553,7 @@ static PyObject *pyrf__tracepoint(struct pyrf_evsel = *pevsel, &sys, &name)) return NULL; =20 - tp_format =3D trace_event__tp_format(sys, name); - if (IS_ERR(tp_format)) - return PyLong_FromLong(-1); - - return PyLong_FromLong(tp_format->id); -#endif // HAVE_LIBTRACEEVENT + return PyLong_FromLong(tp_pmu__id(sys, name)); } =20 static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel) --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 6639E25CC4B for ; Fri, 25 Jul 2025 18:52:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469552; cv=none; b=HXkP69vyJByf46fEW5i2iiSxd8JRWRbdpqwsAXEsEN+2FqvgOUItz0zqSK3brUczMJ04illhczT7t+EM73Jf5T8e7+0xd0lhdWOZh5wyMPtMnrPuqm1/4a8e/xhR4wd+CoQrTTpd7c7P8YLH3X6TmXPUVTiBt8CbwJ4H7yakYns= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469552; c=relaxed/simple; bh=WH5p4e07F4j/C2grpvaVClwmENW7p3AYQnbpEGMwEwM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=E9XxPUWYrSToHlqgCIpz9k27kV0zyMYS/nGmDIdWNYdQAHT0O3ZatA0jDaFJJ5sSeHU78VQFdaLB6JtAeRlHDzp1O4U66yoHToFldzQ2+kL6+psArFoy5jQN1aw9ZPsShBOBVLaK9vj5soOgVp82tLuZQJv7ba18oOCB3m388gs= 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=kFb+O97a; arc=none smtp.client-ip=209.85.214.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="kFb+O97a" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-234906c5e29so29890935ad.0 for ; Fri, 25 Jul 2025 11:52:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469551; x=1754074351; 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=36jzqX45ozM1W5UExySfyBKC/IdxpLPD3I1cgg1xnIc=; b=kFb+O97auJ/9pL8k5QPw/srQGAtbwsxq/css43HRrV6tIBjb8lY49DoSimTmQREnjy s4tFhlRR143DPqOSO1atouWCl4b1ZGf0CxQPrRXWsbqWEcIKBX5SQJ4ZpYfyjRJmWbLy RmYm7NhJG1PSzDxRCJGM3AoRhE/NRDUXSFBe+6x+bEVXuxT7TAZiIVgdQosl23EnfOys kDW4DnZyJRbBURo1qj2NI3WhLUteG93MX36wKZgrh+u6Hvk/wZ58jZa+nnk6Pzmc/g1e M22cBnka4FqcNUPiJxD4zOCUpl2IRQNJ+UxlpmeofX3L64YVdzK0FC6dw+98lyxtRhpJ EwRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469551; x=1754074351; 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=36jzqX45ozM1W5UExySfyBKC/IdxpLPD3I1cgg1xnIc=; b=ggBqve1yWs06Rm64lTHg20aw7a1HX1Ld0R+ON1jx+5qUD80536kBtyUjFvRExuiKa+ ayJM18zsDN525VR1QFv+bi2QecrQzJ9Uv32yjUfd/KG2RQ9hreuH+rGcvmXl89HBwofP lsmt46ljbWL0tkfdzHQbjaX2ZCLSqkqU6P86sQTdD51fXf1wvzBxixJMq9VWLcs1ICfN 4vK9J6boiixg7VlWGMQAdAvJKxAn4V3TdmHOxhLou6UO2qa9Bz1j6vWe4DDKSD/0ylJD hcBfuK34rgsKQsxIukHW2ytyz7mwlKqoab/uf/v9XFWS9MYprBTmeeKiULaZSc+c1t5W CG2A== X-Forwarded-Encrypted: i=1; AJvYcCUaqUloGXSDLl944hsxt8yMWeFRlC6ZtK2W2eLXJXPvsj8kBMuBTtvRhq2zV9WjaXPwmdA97GOWPMJNDVc=@vger.kernel.org X-Gm-Message-State: AOJu0Yw1jEVh4P5hXOIkoZrvlnt5LkdVEt5stR6pouz2IXQSgVbDZNxI gnQxDef7TYQeWzpJ1t/iT/HOHuqY9Ujxb/hk6a/9jJWHoaAtjGOvro2hHYGvVyde+Fuk/mMOlhU uEzse1PMGrQ== X-Google-Smtp-Source: AGHT+IFGweU6cmOkhYOD4Op5Ao3pioLcfS1ktxTpDhwRZ4rXL+7ZFxYMYEvTsxGoi+V91kmvV7lJYLdPbbVi X-Received: from plbmq11.prod.google.com ([2002:a17:902:fd4b:b0:23f:b1ee:3457]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1111:b0:234:d7b2:2ac3 with SMTP id d9443c01a7336-23fb3029b76mr43134105ad.20.1753469550702; Fri, 25 Jul 2025 11:52:30 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:55 -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-10-irogers@google.com> Subject: [PATCH v9 09/16] perf python: Add basic PMU abstraction and pmus sequence 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 an ability to iterate over PMUs and a basic PMU type then can just show the PMU's name. An example usage: ``` $ python Python 3.12.9 (main, Feb 5 2025, 01:31:18) [GCC 14.2.0] on linux >>> import perf >>> list(perf.pmus()) [pmu(cpu), pmu(breakpoint), pmu(cstate_core), pmu(cstate_pkg), pmu(hwmon_acpitz), pmu(hwmon_ac), pmu(hwmon_bat0), pmu(hwmon_coretemp), pmu(hwmon_iwlwifi_1), pmu(hwmon_nvme), pmu(hwmon_thinkpad), pmu(hwmon_ucsi_source_psy_usbc000_0), pmu(hwmon_ucsi_source_psy_usbc000_0), pmu(i915), pmu(intel_bts), pmu(intel_pt), pmu(kprobe), pmu(msr), pmu(power), pmu(software), pmu(tool), pmu(tracepoint), pmu(uncore_arb), pmu(uncore_cbox_0), pmu(uncore_cbox_1), pmu(uncore_cbox_2), pmu(uncore_cbox_3), pmu(uncore_cbox_4), pmu(uncore_cbox_5), pmu(uncore_cbox_6), pmu(uncore_cbox_7), pmu(uncore_clock), pmu(uncore_imc_free_running_0), pmu(uncore_imc_free_running_1), pmu(uprobe)] ``` Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 140 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 9c9972d77d1e..ddcb5d40ff14 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -639,6 +639,138 @@ static int pyrf_thread_map__setup_types(void) return PyType_Ready(&pyrf_thread_map__type); } =20 +/** + * A python wrapper for perf_pmus that are globally owned by the pmus.c co= de. + */ +struct pyrf_pmu { + PyObject_HEAD + + struct perf_pmu *pmu; +}; + +static void pyrf_pmu__delete(struct pyrf_pmu *ppmu) +{ + Py_TYPE(ppmu)->tp_free((PyObject *)ppmu); +} + +static PyObject *pyrf_pmu__name(PyObject *self) +{ + struct pyrf_pmu *ppmu =3D (void *)self; + + return PyUnicode_FromString(ppmu->pmu->name); +} + +static PyObject *pyrf_pmu__repr(PyObject *self) +{ + struct pyrf_pmu *ppmu =3D (void *)self; + + return PyUnicode_FromFormat("pmu(%s)", ppmu->pmu->name); +} + +static const char pyrf_pmu__doc[] =3D PyDoc_STR("perf Performance Monitori= ng Unit (PMU) object."); + +static PyMethodDef pyrf_pmu__methods[] =3D { + { + .ml_name =3D "name", + .ml_meth =3D (PyCFunction)pyrf_pmu__name, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR("Name of the PMU including suffixes.") + }, + { .ml_name =3D NULL, } +}; + +/** The python type for a perf.pmu. */ +static PyTypeObject pyrf_pmu__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.pmu", + .tp_basicsize =3D sizeof(struct pyrf_pmu), + .tp_dealloc =3D (destructor)pyrf_pmu__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D pyrf_pmu__doc, + .tp_methods =3D pyrf_pmu__methods, + .tp_str =3D pyrf_pmu__name, + .tp_repr =3D pyrf_pmu__repr, +}; + +static int pyrf_pmu__setup_types(void) +{ + pyrf_pmu__type.tp_new =3D PyType_GenericNew; + return PyType_Ready(&pyrf_pmu__type); +} + + +/** A python iterator for pmus that has no equivalent in the C code. */ +struct pyrf_pmu_iterator { + PyObject_HEAD + struct perf_pmu *pmu; +}; + +static void pyrf_pmu_iterator__dealloc(struct pyrf_pmu_iterator *self) +{ + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject *pyrf_pmu_iterator__new(PyTypeObject *type, PyObject *args= __maybe_unused, + PyObject *kwds __maybe_unused) +{ + struct pyrf_pmu_iterator *itr =3D (void *)type->tp_alloc(type, 0); + + if (itr !=3D NULL) + itr->pmu =3D perf_pmus__scan(/*pmu=3D*/NULL); + + return (PyObject *) itr; +} + +static PyObject *pyrf_pmu_iterator__iter(PyObject *self) +{ + Py_INCREF(self); + return self; +} + +static PyObject *pyrf_pmu_iterator__iternext(PyObject *self) +{ + struct pyrf_pmu_iterator *itr =3D (void *)self; + struct pyrf_pmu *ppmu; + + if (itr->pmu =3D=3D NULL) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + // Create object to return. + ppmu =3D PyObject_New(struct pyrf_pmu, &pyrf_pmu__type); + if (ppmu) { + ppmu->pmu =3D itr->pmu; + // Advance iterator. + itr->pmu =3D perf_pmus__scan(itr->pmu); + } + return (PyObject *)ppmu; +} + +/** The python type for the PMU iterator. */ +static PyTypeObject pyrf_pmu_iterator__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "pmus.iterator", + .tp_doc =3D "Iterator for the pmus string sequence.", + .tp_basicsize =3D sizeof(struct pyrf_pmu_iterator), + .tp_itemsize =3D 0, + .tp_flags =3D Py_TPFLAGS_DEFAULT, + .tp_new =3D pyrf_pmu_iterator__new, + .tp_dealloc =3D (destructor) pyrf_pmu_iterator__dealloc, + .tp_iter =3D pyrf_pmu_iterator__iter, + .tp_iternext =3D pyrf_pmu_iterator__iternext, +}; + +static int pyrf_pmu_iterator__setup_types(void) +{ + return PyType_Ready(&pyrf_pmu_iterator__type); +} + +static PyObject *pyrf__pmus(PyObject *self, PyObject *args) +{ + // Calling the class creates an instance of the iterator. + return PyObject_CallObject((PyObject *) &pyrf_pmu_iterator__type, /*args= =3D*/NULL); +} + struct pyrf_counts_values { PyObject_HEAD =20 @@ -1691,6 +1823,12 @@ static PyMethodDef perf__methods[] =3D { .ml_flags =3D METH_VARARGS, .ml_doc =3D PyDoc_STR("Parse a string of events and return an evlist.") }, + { + .ml_name =3D "pmus", + .ml_meth =3D (PyCFunction) pyrf__pmus, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR("Returns a sequence of pmus.") + }, { .ml_name =3D NULL, } }; =20 @@ -1718,6 +1856,8 @@ PyMODINIT_FUNC PyInit_perf(void) pyrf_evsel__setup_types() < 0 || pyrf_thread_map__setup_types() < 0 || pyrf_cpu_map__setup_types() < 0 || + pyrf_pmu_iterator__setup_types() < 0 || + pyrf_pmu__setup_types() < 0 || pyrf_counts_values__setup_types() < 0) return module; =20 --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 7A4532561DD for ; Fri, 25 Jul 2025 18:52:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469554; cv=none; b=P+7Ms0Mwdyh8w1e+yBl7Ix7hocLE/tgRuwhdcxMFrYOQNXy7ST1qgVn8pJZqKTabi37dPiqbV46dRcKgsnXhPqDWErdh+E6bU10dDefiUPwCQIXlcAzbFbUCVyIZjTHmCxY/obKYrIK7Qlm/gTb71DGeHK0qOdV/r8sanlVs1EU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469554; c=relaxed/simple; bh=TEdXz7pmjX/VVGqT+6IAkD79lk9qzvOAigwv0QCzm1o=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NL9g4MpnJboSX9rGFKOryNDd5XBf9M35BmLbhQtz5quu6VLmoMJ2kpJMEvpp6crQ/zdxYgQ6crSlgGuB38b93hLg3WSoXbUo/oBnEqMD2YUrJsHww+ndfWKuKOLR7AEPR3sgRAJ3IF2RIRix8uWtOIH/ebDLl/MbNVl6rPoi7VI= 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=Qu9kUaJs; arc=none smtp.client-ip=209.85.214.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="Qu9kUaJs" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-235e1d66fa6so24218365ad.0 for ; Fri, 25 Jul 2025 11:52:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469553; x=1754074353; 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=TZYsIecRZJDshqzI/wllN5UafWVm9WY9utPZhWIM3pU=; b=Qu9kUaJsBJeWUOTV5bWNr5VbcmP6Ycn6NrwumOSlsVe+uvL/fXrNpyhJYHULLnjfU5 5oGK54v4uco6VtUemBs1O/Ss/Al8/KGiSRin0PQQCsMrsIwa+R8iqVYH/QJZxv/Ipw+4 5apP46w2AlwsdybxYioR+wf96cQzskRN6/pswPvBVe5S95H8uizTKFySDsOlRDT9q6pQ rxpOCcBNSv2kPVTkiWRNG3XXtjlJoCTGPKfKbEN3iLGcPXYaUy0U9q4RqfkYzOVFvTvx RjzcNos5avK0DQe35cWn5ozNvckNBgjQezbB6WjcZswPIzmys5lUeXyYnLf/P2n6KbEY 2Hmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469553; x=1754074353; 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=TZYsIecRZJDshqzI/wllN5UafWVm9WY9utPZhWIM3pU=; b=ovrRgiATcyi22PdOPGNVQP2r9XNYxU6OfgAY9p7dS8GzicEwe64BXEp1rijHpKB+cO 5M/2CtrRq6FPIbdzfzus1x9ITX78kBiZsNl9uidxokmv7B7O6rJJctxuAMnnNCOI87Cz BMsDbzuf/LeSVo+ETARPpZvpp1phM9qyPlab3joLbt6a0cDbEfabltc6BdvceNlVQsf1 BCiccxwM/VlCTB7SomwAS4nNuswe1E7PybWt8qYQwvkRqdPwetwkUeHBsq/hrI9dZD1x BoBeKf94Abg1emu2C+YwkHuUEqGdkAAQDUOLkxsourc9eZjQ4xCSEtj8txd8Z7WqJVvl I1WA== X-Forwarded-Encrypted: i=1; AJvYcCV7VShdUDQeKaKAvI2MINlkZm5jp0eG1Stu+JtAgb59ePtgL6Q36YIVObpW1jg/AbIFAgaJw98HYTGRDO4=@vger.kernel.org X-Gm-Message-State: AOJu0YwgGGnjbs5XV7dWQzo+bbOJFDROOZTctLZRPFe+lN6Fth+huaKj zN3sjalpyPvCca23Mgl2eiCbbIAJamWtCNRK8916iQE5zqlFsbf59lUAQK082qlOyozxtWVQ4y8 IgGL9kzjZ/g== X-Google-Smtp-Source: AGHT+IEKlvLcagcimf+HHBXj8vgIqOb3k6bzDPBVgZTJwDjKILapovy/9ACfNqmyU4bwCI8eL7s4Eb7Jv9V+ X-Received: from plpj7.prod.google.com ([2002:a17:903:3d87:b0:23d:dd69:dd07]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1b4c:b0:235:e76c:4353 with SMTP id d9443c01a7336-23fb31b01a6mr51649805ad.51.1753469552764; Fri, 25 Jul 2025 11:52:32 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:56 -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-11-irogers@google.com> Subject: [PATCH v9 10/16] perf python: Add function returning dictionary of all events on a PMU 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" Allow all events on a PMU to be gathered, similar to how perf list gathers event information. An example usage: ``` $ python Python 3.12.9 (main, Feb 5 2025, 01:31:18) [GCC 14.2.0] on linux >>> import perf >>> for pmu in perf.pmus(): ... print(pmu.events()) ... [{'name': 'mem_load_retired.l3_hit', 'desc': 'Retired load instructions... ``` Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index ddcb5d40ff14..d49b4401ab7e 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -660,6 +660,71 @@ static PyObject *pyrf_pmu__name(PyObject *self) return PyUnicode_FromString(ppmu->pmu->name); } =20 +static bool add_to_dict(PyObject *dict, const char *key, const char *value) +{ + PyObject *pkey, *pvalue; + bool ret; + + if (value =3D=3D NULL) + return true; + + pkey =3D PyUnicode_FromString(key); + pvalue =3D PyUnicode_FromString(value); + + ret =3D pkey && pvalue && PyDict_SetItem(dict, pkey, pvalue) =3D=3D 0; + Py_XDECREF(pkey); + Py_XDECREF(pvalue); + return ret; +} + +static int pyrf_pmu__events_cb(void *state, struct pmu_event_info *info) +{ + PyObject *py_list =3D state; + PyObject *dict =3D PyDict_New(); + + if (!dict) + return -ENOMEM; + + if (!add_to_dict(dict, "name", info->name) || + !add_to_dict(dict, "alias", info->alias) || + !add_to_dict(dict, "scale_unit", info->scale_unit) || + !add_to_dict(dict, "desc", info->desc) || + !add_to_dict(dict, "long_desc", info->long_desc) || + !add_to_dict(dict, "encoding_desc", info->encoding_desc) || + !add_to_dict(dict, "topic", info->topic) || + !add_to_dict(dict, "event_type_desc", info->event_type_desc) || + !add_to_dict(dict, "str", info->str) || + !add_to_dict(dict, "deprecated", info->deprecated ? "deprecated" : NU= LL) || + PyList_Append(py_list, dict) !=3D 0) { + Py_DECREF(dict); + return -ENOMEM; + } + Py_DECREF(dict); + return 0; +} + +static PyObject *pyrf_pmu__events(PyObject *self) +{ + struct pyrf_pmu *ppmu =3D (void *)self; + PyObject *py_list =3D PyList_New(0); + int ret; + + if (!py_list) + return NULL; + + ret =3D perf_pmu__for_each_event(ppmu->pmu, + /*skip_duplicate_pmus=3D*/false, + py_list, + pyrf_pmu__events_cb); + if (ret) { + Py_DECREF(py_list); + errno =3D -ret; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return py_list; +} + static PyObject *pyrf_pmu__repr(PyObject *self) { struct pyrf_pmu *ppmu =3D (void *)self; @@ -670,6 +735,12 @@ static PyObject *pyrf_pmu__repr(PyObject *self) static const char pyrf_pmu__doc[] =3D PyDoc_STR("perf Performance Monitori= ng Unit (PMU) object."); =20 static PyMethodDef pyrf_pmu__methods[] =3D { + { + .ml_name =3D "events", + .ml_meth =3D (PyCFunction)pyrf_pmu__events, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR("Name of the PMU including suffixes.") + }, { .ml_name =3D "name", .ml_meth =3D (PyCFunction)pyrf_pmu__name, --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 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 8BF4125E824 for ; Fri, 25 Jul 2025 18:52:37 +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=1753469559; cv=none; b=SheCTa91ZG7ZE8eqt7viR7a8wNmCX+BTpqWWEISppK5UV/Pxr6kzEQPaDHRCiInNom8pC68che2Rqa3sFujDI+jhoXq5YpjE+6/FpTsENVSLZSVDRCKgX47RIRhn8crjqzh4RbASfqBXFhl/HMfoUirhHi60B8ocdDEkNIAdlFA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469559; c=relaxed/simple; bh=Wt/9cTNDU/X+BUkTG5LHANb6WRxyH4YmYctT9qjNB7g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RTbkcY8XeYvAU73dn0kZd5EHgmLp2zumsRTP5Tme520djq4Q1AAsMk/u+fezbFC7R6sZ9yUi56S9rASdBizwvAbn4ya3e3V0FUcl+avectpDhYl/5ewigxYXXRTbw9STWZDLQe54c00GDq/zp38720f4IxKAT1l0n3J55Ks8pHU= 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=OxWOELGb; 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="OxWOELGb" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-31215090074so3743320a91.0 for ; Fri, 25 Jul 2025 11:52:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469557; x=1754074357; 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=yxboK8So5w98iikHW02ASAwQMmoQRUJcv67Gb920jew=; b=OxWOELGbGu0FTG2ZmoeYGh3CFOwawKIN8PbMefs51cFoFMpAoqydu8qTLd9SFTLpJH /rXlmq1u54tD4uqFZXHcU/t9X4ie4oWoCpZBnpVS4mSr0nbvWmdV7QKWQSLSZxetzSqo YJstVWK5DnXH0KiP2J5F2YrwYP5+2FyHrzDtyoezrp8yCfFWpzGAqN7CW/BN1j+4TCXt 10kq8Di/45GH7k6VszgCg+c0wnziWqMQaE8BSKQTruO+27ijK1lBZnP1Ts+qIssS3kD1 91AnTiVkBMZe0R0XHYjogVrskngGlWzy1ABxZq7vLGWmPwWqziB+Ww00CYR6ruLMlDDu ysaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469557; x=1754074357; 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=yxboK8So5w98iikHW02ASAwQMmoQRUJcv67Gb920jew=; b=c/XnyVfZd17vyG6bMpn7iPvfdG46/f3CLO2v5Uq201DDf2JJFWRLaZok25hafgN7R+ 787u2quOvb+vwDesnTev86f6UkfLQaf7pcRBTWaIobp8FNxxw0kCuFQYk3bPWoMzFh+O k948YGQbsxUOyp64KgFEryV9wY2RMXYTEvJ9JZrhBeHWOIcey8uYatcF8xSzSBbsGEKd 2Tj4RmMeQk4FIDRhv+mt5k4RdotdpPjQKDrUEajxSKzELKHTj4A/ynl90NxoCC/S1uxF Ekav6WpP2AAUGaGxK17Wb4JYOZ+adaWznWvv2BFvyhpbJGF1OgRgDaoLuLEDSAF82xts RhWw== X-Forwarded-Encrypted: i=1; AJvYcCWtjtTb8b81/tP4NoBki1tui1w8jVz7VPLO3b3g1o0/FTkQ+hYF4XD87FCam8hWxGF9TewERcPj2e+8NRA=@vger.kernel.org X-Gm-Message-State: AOJu0YxkCco/7WgipbOxRZnr1oa62RSSEx1ZpKqNa3l8LLfakxIQJrt5 EZ0J6lZ3IRtarkGMvq2vhB7NHphzWGQ+EA/D9jqieLPyYzhd+hFi5/RTX5/xVXQ0tWJNI1qb2WY I/h2TnfrP5w== X-Google-Smtp-Source: AGHT+IHeNEQikPR78JhyZAQjE4y/+H3MytvNsjlj54GnhV7Te07RqS70kzg+IsPKYhINhp5JyTcYKDCBmfyd X-Received: from pjbos7.prod.google.com ([2002:a17:90b:1cc7:b0:312:15b:e5d1]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1e08:b0:311:ea13:2e70 with SMTP id 98e67ed59e1d1-31e77a3e9f7mr4543830a91.14.1753469556992; Fri, 25 Jul 2025 11:52:36 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:57 -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-12-irogers@google.com> Subject: [PATCH v9 11/16] perf ilist: Add new python ilist command 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" The perf ilist command is a textual app [1] similar to perf list. In the top-left pane a tree of PMUs is displayed. Selecting a PMU expands the events within it. Selecting an event displays the `perf list` style event information in the top-right pane. When an event is selected it is opened and the counters on each CPU the event is for are periodically read. The bottom of the screen contains a scrollable set of sparklines showing the events in total and on each CPU. Scrolling below the sparklines shows the same data as raw counts. The sparklines are small graphs where the height of the bar is in relation to maximum of the other counts in the graph. By default the counts are read with an interval of 0.1 seconds (10 times per second). A -I/--interval command line option allows the interval to be changed. The oldest read counts are dropped when the counts fill the line causing the sparkline to move from right to left. A search box can be pulled up with the 's' key. 'n' and 'p' iterate through the search results. As some PMUs have hundreds of events a 'c' key will collapse the events in the current PMU to make navigating the PMUs easier. [1] https://textual.textualize.io/ Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/python/ilist.py | 385 +++++++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100755 tools/perf/python/ilist.py diff --git a/tools/perf/python/ilist.py b/tools/perf/python/ilist.py new file mode 100755 index 000000000000..22c70a8b31f3 --- /dev/null +++ b/tools/perf/python/ilist.py @@ -0,0 +1,385 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +"""Interactive perf list.""" + +import argparse +from typing import Any, Dict, Optional, Tuple +import perf +from textual import on +from textual.app import App, ComposeResult +from textual.binding import Binding +from textual.containers import Horizontal, HorizontalGroup, Vertical, Vert= icalScroll +from textual.command import SearchIcon +from textual.screen import ModalScreen +from textual.widgets import Button, Footer, Header, Input, Label, Sparklin= e, Static, Tree +from textual.widgets.tree import TreeNode + + +class ErrorScreen(ModalScreen[bool]): + """Pop up dialog for errors.""" + + CSS =3D """ + ErrorScreen { + align: center middle; + } + """ + + def __init__(self, error: str): + self.error =3D error + super().__init__() + + def compose(self) -> ComposeResult: + yield Button(f"Error: {self.error}", variant=3D"primary", id=3D"er= ror") + + def on_button_pressed(self, event: Button.Pressed) -> None: + self.dismiss(True) + + +class SearchScreen(ModalScreen[str]): + """Pop up dialog for search.""" + + CSS =3D """ + SearchScreen Horizontal { + align: center middle; + margin-top: 1; + } + SearchScreen Input { + width: 1fr; + } + """ + + def compose(self) -> ComposeResult: + yield Horizontal(SearchIcon(), Input(placeholder=3D"Event name")) + + def on_input_submitted(self, event: Input.Submitted) -> None: + """Handle the user pressing Enter in the input field.""" + self.dismiss(event.value) + + +class Counter(HorizontalGroup): + """Two labels for a CPU and its counter value.""" + + CSS =3D """ + Label { + gutter: 1; + } + """ + + def __init__(self, cpu: int) -> None: + self.cpu =3D cpu + super().__init__() + + def compose(self) -> ComposeResult: + label =3D f"cpu{self.cpu}" if self.cpu >=3D 0 else "total" + yield Label(label + " ") + yield Label("0", id=3Df"counter_{label}") + + +class CounterSparkline(HorizontalGroup): + """A Sparkline for a performance counter.""" + + def __init__(self, cpu: int) -> None: + self.cpu =3D cpu + super().__init__() + + def compose(self) -> ComposeResult: + label =3D f"cpu{self.cpu}" if self.cpu >=3D 0 else "total" + yield Label(label) + yield Sparkline([], summary_function=3Dmax, id=3Df"sparkline_{labe= l}") + + +class IListApp(App): + TITLE =3D "Interactive Perf List" + + BINDINGS =3D [ + Binding(key=3D"s", action=3D"search", description=3D"Search", + tooltip=3D"Search events and PMUs"), + Binding(key=3D"n", action=3D"next", description=3D"Next", + tooltip=3D"Next search result or item"), + Binding(key=3D"p", action=3D"prev", description=3D"Previous", + tooltip=3D"Previous search result or item"), + Binding(key=3D"c", action=3D"collapse", description=3D"Collapse", + tooltip=3D"Collapse the current PMU"), + Binding(key=3D"^q", action=3D"quit", description=3D"Quit", + tooltip=3D"Quit the app"), + ] + + CSS =3D """ + /* Make the 'total' sparkline a different color. */ + #sparkline_total > .sparkline--min-color { + color: $accent; + } + #sparkline_total > .sparkline--max-color { + color: $accent 30%; + } + /* + * Make the active_search initially not displayed with the text in + * the middle of the line. + */ + #active_search { + display: none; + width: 100%; + text-align: center; + } + """ + + def __init__(self, interval: float) -> None: + self.interval =3D interval + self.evlist =3D None + self.search_results: list[TreeNode[str]] =3D [] + self.cur_search_result: TreeNode[str] | None =3D None + super().__init__() + + def expand_and_select(self, node: TreeNode[Any]) -> None: + """Expand select a node in the tree.""" + if node.parent: + node.parent.expand() + if node.parent.parent: + node.parent.parent.expand() + node.expand() + node.tree.select_node(node) + node.tree.scroll_to_node(node) + + def set_searched_tree_node(self, previous: bool) -> None: + """Set the cur_search_result node to either the next or previous."= "" + l =3D len(self.search_results) + + if l < 1: + tree: Tree[str] =3D self.query_one("#pmus", Tree) + if previous: + tree.action_cursor_up() + else: + tree.action_cursor_down() + return + + if self.cur_search_result: + idx =3D self.search_results.index(self.cur_search_result) + if previous: + idx =3D idx - 1 if idx > 0 else l - 1 + else: + idx =3D idx + 1 if idx < l - 1 else 0 + else: + idx =3D l - 1 if previous else 0 + + node =3D self.search_results[idx] + if node =3D=3D self.cur_search_result: + return + + self.cur_search_result =3D node + self.expand_and_select(node) + + def action_search(self) -> None: + """Search was chosen.""" + def set_initial_focus(event: str | None) -> None: + """Sets the focus after the SearchScreen is dismissed.""" + + search_label =3D self.query_one("#active_search", Label) + search_label.display =3D True if event else False + if not event: + return + event =3D event.lower() + search_label.update(f'Searching for events matching "{event}"') + + tree: Tree[str] =3D self.query_one("#pmus", Tree) + + def find_search_results(event: str, node: TreeNode[str], + cursor_seen: bool =3D False, + match_after_cursor: Optional[TreeNode[= str]] =3D None + ) -> Tuple[bool, Optional[TreeNode[str= ]]]: + """Find nodes that match the search remembering the one af= ter the cursor.""" + if not cursor_seen and node =3D=3D tree.cursor_node: + cursor_seen =3D True + if node.data and event in node.data: + if cursor_seen and not match_after_cursor: + match_after_cursor =3D node + self.search_results.append(node) + + if node.children: + for child in node.children: + (cursor_seen, match_after_cursor) =3D \ + find_search_results(event, child, cursor_seen,= match_after_cursor) + return (cursor_seen, match_after_cursor) + + self.search_results.clear() + (_, self.cur_search_result) =3D find_search_results(event, tre= e.root) + if len(self.search_results) < 1: + self.push_screen(ErrorScreen(f"Failed to find pmu/event {e= vent}")) + search_label.display =3D False + elif self.cur_search_result: + self.expand_and_select(self.cur_search_result) + else: + self.set_searched_tree_node(previous=3DFalse) + + self.push_screen(SearchScreen(), set_initial_focus) + + def action_next(self) -> None: + """Next was chosen.""" + self.set_searched_tree_node(previous=3DFalse) + + def action_prev(self) -> None: + """Previous was chosen.""" + self.set_searched_tree_node(previous=3DTrue) + + def action_collapse(self) -> None: + """Collapse the potentially large number of events under a PMU.""" + tree: Tree[str] =3D self.query_one("#pmus", Tree) + node =3D tree.cursor_node + if node and node.parent and node.parent.parent: + node.parent.collapse_all() + node.tree.scroll_to_node(node.parent) + + def update_counts(self) -> None: + """Called every interval to update counts.""" + if not self.evlist: + return + + def update_count(cpu: int, count: int): + # Update the raw count display. + counter: Label =3D self.query(f"#counter_cpu{cpu}" if cpu >=3D= 0 else "#counter_total") + if not counter: + return + counter =3D counter.first(Label) + counter.update(str(count)) + + # Update the sparkline. + line: Sparkline =3D self.query(f"#sparkline_cpu{cpu}" if cpu >= =3D 0 else "#sparkline_total") + if not line: + return + line =3D line.first(Sparkline) + # If there are more events than the width, remove the front ev= ent. + if len(line.data) > line.size.width: + line.data.pop(0) + line.data.append(count) + line.mutate_reactive(Sparkline.data) + + # Update the total and each CPU counts, assume there's just 1 evse= l. + total =3D 0 + self.evlist.disable() + for evsel in self.evlist: + for cpu in evsel.cpus(): + aggr =3D 0 + for thread in evsel.threads(): + counts =3D evsel.read(cpu, thread) + aggr +=3D counts.val + update_count(cpu, aggr) + total +=3D aggr + update_count(-1, total) + self.evlist.enable() + + def on_mount(self) -> None: + """When App starts set up periodic event updating.""" + self.update_counts() + self.set_interval(self.interval, self.update_counts) + + def set_pmu_and_event(self, pmu: str, event: str) -> None: + """Updates the event/description and starts the counters.""" + # Remove previous event information. + if self.evlist: + self.evlist.disable() + self.evlist.close() + lines =3D self.query(CounterSparkline) + for line in lines: + line.remove() + lines =3D self.query(Counter) + for line in lines: + line.remove() + + def pmu_event_description(pmu: str, event: str) -> str: + """Find and format event description for {pmu}/{event}/.""" + def get_info(info: Dict[str, str], key: str): + return (info[key] + "\n") if key in info else "" + + for p in perf.pmus(): + if p.name() !=3D pmu: + continue + for info in p.events(): + if "name" not in info or info["name"] !=3D event: + continue + + desc =3D get_info(info, "topic") + desc +=3D get_info(info, "event_type_desc") + desc +=3D get_info(info, "desc") + desc +=3D get_info(info, "long_desc") + desc +=3D get_info(info, "encoding_desc") + return desc + return "description" + + # Parse event, update event text and description. + full_name =3D event if event.startswith(pmu) or ':' in event else = f"{pmu}/{event}/" + self.query_one("#event_name", Label).update(full_name) + self.query_one("#event_description", Static).update(pmu_event_desc= ription(pmu, event)) + + # Open the event. + try: + self.evlist =3D perf.parse_events(full_name) + if self.evlist: + self.evlist.open() + self.evlist.enable() + except: + self.evlist =3D None + + if not self.evlist: + self.push_screen(ErrorScreen(f"Failed to open {full_name}")) + return + + # Add spark lines for all the CPUs. Note, must be done after + # open so that the evlist CPUs have been computed by propagate + # maps. + lines =3D self.query_one("#lines") + line =3D CounterSparkline(cpu=3D-1) + lines.mount(line) + for cpu in self.evlist.all_cpus(): + line =3D CounterSparkline(cpu) + lines.mount(line) + line =3D Counter(cpu=3D-1) + lines.mount(line) + for cpu in self.evlist.all_cpus(): + line =3D Counter(cpu) + lines.mount(line) + + def compose(self) -> ComposeResult: + """Draws the app.""" + def pmu_event_tree() -> Tree: + """Create tree of PMUs with events under.""" + tree: Tree[str] =3D Tree("PMUs", id=3D"pmus") + tree.root.expand() + for pmu in perf.pmus(): + pmu_name =3D pmu.name().lower() + pmu_node =3D tree.root.add(pmu_name, data=3Dpmu_name) + try: + for event in sorted(pmu.events(), key=3Dlambda x: x["n= ame"]): + if "name" in event: + e =3D event["name"].lower() + if "alias" in event: + pmu_node.add_leaf(f'{e} ({event["alias"]})= ', data=3De) + else: + pmu_node.add_leaf(e, data=3De) + except: + # Reading events may fail with EPERM, ignore. + pass + return tree + + yield Header(id=3D"header") + yield Horizontal(Vertical(pmu_event_tree(), id=3D"events"), + Vertical(Label("event name", id=3D"event_name"), + Static("description", markup=3DFalse, id= =3D"event_description"), + )) + yield Label(id=3D"active_search") + yield VerticalScroll(id=3D"lines") + yield Footer(id=3D"footer") + + @on(Tree.NodeSelected) + def on_tree_node_selected(self, event: Tree.NodeSelected[str]) -> None: + """Called when a tree node is selected, selecting the event.""" + if event.node.parent and event.node.parent.parent: + assert event.node.parent.data is not None + assert event.node.data is not None + self.set_pmu_and_event(event.node.parent.data, event.node.data) + + +if __name__ =3D=3D "__main__": + ap =3D argparse.ArgumentParser() + ap.add_argument('-I', '--interval', help=3D"Counter update interval in= seconds", default=3D0.1) + args =3D ap.parse_args() + app =3D IListApp(float(args.interval)) + app.run() --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.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 A3EAF25F784 for ; Fri, 25 Jul 2025 18:52:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469561; cv=none; b=akkn+a6/+LlpgQLluakcCBfKPEYMzOXY+FC6WvC6kQJweL7eWTiyPkgdVjoAseVg39VFSkVOelHmPc+24W61oNU46Qz3XEhMGqESS3/PFjYamI6zEUa/lVxuzX0sDXQYreR6yqAzaJ03vuTl1hSRVtZYzdNPJRaaQJC1XdGt6pk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469561; c=relaxed/simple; bh=urNi6uKfuUdrgMauV+q1itJC+RILuVmptr/ZTH1CPrU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BHpdls3Nk37pIk2mMSk6IO3c9CxF8LYBvVqRbgqo2kT+gO0h0hfODRMMRmMQl+sXV5rqp6Jv+oG7y6bX3aN9GyBGLvR8NFYG2gOVTbl340qjuJOUc6Wy5h4y6TyaD/1l8C6gdQT+sbTOsY+hWYg6pUgF5oRvkaaeg1esRV+f8z8= 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=PkScFAVZ; arc=none smtp.client-ip=209.85.210.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="PkScFAVZ" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-764072aca31so293566b3a.2 for ; Fri, 25 Jul 2025 11:52:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469559; x=1754074359; 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=xBcNlwUCnqg9fhgYcfot94+T/+Sz9Lr9MsJzZ/Y12YM=; b=PkScFAVZh9D1QgG25EEbFdtkly5pNGTGrepx3XtJh+Qor+O9ixMGI7AF4uOj440sME pfKlErqWi93FRHVT2ean6D+br2b1LzpduC6B5vBZgPz2Q+2pL9x0ZL/ZHxFWN9oHL03s 3SFKfX/ofr/V2I0XDsb4nlS749MgB2ESsHWTxMfFA9H7TJT0EoYVf0mOemjXnEYb4pVb LzTsxGw2BXQpuL2BwdhFoY8bKFEONDx6i5dYxMwwkIbShSB2QwtHrMOVrGuk3TZgiiyA Xvx5dx4NPtGjsBIFqX2oxnZdG3A9DIEioQ8SYytnt+R07aMo103S6GBfIUYiGBpCTgCz IjEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469559; x=1754074359; 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=xBcNlwUCnqg9fhgYcfot94+T/+Sz9Lr9MsJzZ/Y12YM=; b=JaulA1Bv0wyhge0rb9YXoEdaspcNPPJtJg1WZaEf5dhJJKApIjVDBFuZU5G1g+r+dx x2MHm+1SLrNqkmE5XToJOTN9jdpsSpjg65hjDmhO7LWjRt0nOBILroLuqgrHvje5J487 oWEtXpgcSnmY419bt/ue4/nRFeV46cZQUNeIZLFhGYsUrvVsYpBeK7Js2jL3UrAxZ4Gg ZvQ1nfqqnAJPzIc3PTREXwDODbPduKZZN7PRJp+GttAuApIQngUBQAivt5MV2UwCTSbY jq2ttCY9DaAkX/jWdl39r6NRoKBJxCC1Pq04IWy6ke/zUTm39pzcX/1hI9M8F2puVgFz azLg== X-Forwarded-Encrypted: i=1; AJvYcCUyFE7lNLWmsk3z+FB5ZYhC+BSrcrdzfjyragZdIYNgbeDfg1x9MXERhKYIFkuasK9h/BbXvuPjPCeS/Kg=@vger.kernel.org X-Gm-Message-State: AOJu0YzOS/ccHxLIu4wlReNGhOQhTWf51eJfmILCMp1X8egvq+xLc5ea XAsYQPL/vvnPdQxBabYIy5EuN7LBsgY8Fq9aQZsXqTnvY4zmHr+M/TShqWurhCp0I74e3KUkkzM uTGjt/hEBaA== X-Google-Smtp-Source: AGHT+IGLwU48Bo03CMDE5Nn0cKVvwMcb6DGuseQmlXPkUAqSEsedl1UI3nxQXn3OhvXtOUY3PTsPpvHROwjl X-Received: from pfbmb21.prod.google.com ([2002:a05:6a00:7615:b0:748:e276:8454]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:139f:b0:742:da7c:3f30 with SMTP id d2e1a72fcca58-763377f0704mr4831879b3a.19.1753469558989; Fri, 25 Jul 2025 11:52:38 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:58 -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-13-irogers@google.com> Subject: [PATCH v9 12/16] perf python: Add parse_metrics function 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 parse_metrics function that takes a string of metrics and/or metric groups and returns the evlist containing the events and metrics. For example: ``` >>> import perf >>> perf.parse_metrics("TopdownL1") evlist([cpu/TOPDOWN.SLOTS/,cpu/topdown-retiring/,cpu/topdown-fe-bound/, cpu/topdown-be-bound/,cpu/topdown-bad-spec/,cpu/INT_MISC.CLEARS_COUNT/, cpu/INT_MISC.UOP_DROPPING/]) ``` Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index d49b4401ab7e..3a58080bab24 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1881,6 +1881,40 @@ static PyObject *pyrf__parse_events(PyObject *self, = PyObject *args) return result; } =20 +static PyObject *pyrf__parse_metrics(PyObject *self, PyObject *args) +{ + const char *input; + struct evlist evlist =3D {}; + PyObject *result; + PyObject *pcpus =3D NULL, *pthreads =3D NULL; + struct perf_cpu_map *cpus; + struct perf_thread_map *threads; + int ret; + + if (!PyArg_ParseTuple(args, "s|OO", &input, &pcpus, &pthreads)) + return NULL; + + threads =3D pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NU= LL; + cpus =3D pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL; + + evlist__init(&evlist, cpus, threads); + ret =3D metricgroup__parse_groups(&evlist, /*pmu=3D*/"all", input, + /*metric_no_group=3D*/ false, + /*metric_no_merge=3D*/ false, + /*metric_no_threshold=3D*/ true, + /*user_requested_cpu_list=3D*/ NULL, + /*system_wide=3D*/true, + /*hardware_aware_grouping=3D*/ false); + if (ret) { + errno =3D -ret; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + result =3D pyrf_evlist__from_evlist(&evlist); + evlist__exit(&evlist); + return result; +} + static PyMethodDef perf__methods[] =3D { { .ml_name =3D "tracepoint", @@ -1894,6 +1928,13 @@ static PyMethodDef perf__methods[] =3D { .ml_flags =3D METH_VARARGS, .ml_doc =3D PyDoc_STR("Parse a string of events and return an evlist.") }, + { + .ml_name =3D "parse_metrics", + .ml_meth =3D (PyCFunction) pyrf__parse_metrics, + .ml_flags =3D METH_VARARGS, + .ml_doc =3D PyDoc_STR( + "Parse a string of metics or metric groups and return an evlist.") + }, { .ml_name =3D "pmus", .ml_meth =3D (PyCFunction) pyrf__pmus, --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 EB0B725FA13 for ; Fri, 25 Jul 2025 18:52:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469564; cv=none; b=MZ27uU4O1rlpB4kTO4sK+2IQgLjV5u+New8KY5L+B5TJ6NS6S7XeXhm8pkWpdjjEi3KhjfVe9TfO3aU/lHIo9G6gC1bPOmFIvKZnwmeDERQtuRfZ/nW9LbE8HzkQ13mdgZKMx1INH39MuJTMA56/jkzfHVvNAIQitB8OZe6PEcw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469564; c=relaxed/simple; bh=sw0V4tcRM8nzystS/ROnWaYm14K4bPEjZplUBiHrm0g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mzItV27DTuoLwKaCaORgn21mgpAKcCX4H+1vI6Uhp27VEpN0Qr3IoqYo3u4L5L52GXgEqm/si3hEFPBMhbbk9TRQAWEtTKvYU3rEU2Hm/4qcznbtFuXJ6s9cJaz3BxuFLdI5AcHU7apq52iY+yexPAe1+7Ni2TuZZebuvaKH250= 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=eF1EMMLg; arc=none smtp.client-ip=209.85.214.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="eF1EMMLg" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2356ce55d33so39322665ad.0 for ; Fri, 25 Jul 2025 11:52:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469561; x=1754074361; 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=n8OCFhwd2lpx54kVyZvp/cazm5hu5rf3uGrxE8ojG60=; b=eF1EMMLgbiLvmarRKF4rscuH4xTaEwN2p6TGd9yjMjTAYe0sa9bpBkhwQmipU51jdV 4rsTfKK6hiM0fMiuzuJCoeE42pEODIF2fotoukdUpVxJqAp4yRhXeSlZyuXghT+QS0ok ER3XGN95aaWwQifmaR8ycqEq4EEW1hi/n1BXY66f/Tf+SmTtEs8tI7Y9DHBr6HTLr+Zs QPm0XdBOqo90kOLAWv+W+m/D0ymWsIjZ3tokmlhGv/WFlS5rhG+58cwNLYEAWpkht9Fi CumGp6ClwdVSqJwyHGpyfzNaBR2PCFnFGbT8cYwJ1FJfcEHq1TbYjHXMmXWPFwZpRsoV dOpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469561; x=1754074361; 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=n8OCFhwd2lpx54kVyZvp/cazm5hu5rf3uGrxE8ojG60=; b=FtBJz4+/p0zHpytpecnOfzduMGmztcUxL5Vh3pF5RBlKBBi8UvCSosPS1u4BrL/Duu TeJ+Q3VsBZFT10pSn7rDY+iUXpMES3OizKGpEtyGP5az+utwnJAL50pqWmARZ1q3bFJP UEyJ/K+y5enE6yuEVk+Ql2IKqqHr6LHNQAJJrGIUBKUa2ekG7Oin1JcoqLWB+zVPvJCc bCpQUp86J5NMGTJeDC+VBtBHAquj54KtK6iUdq5oqnDXRN7IXQ3ir8W+OD86/Xh2p/7E VGt9tdI1YTVsJBXOH3oQoWC3mYuqwxpNzWHgdT5Obem4u2QjRC19H3UD5yYGzoPCvAUc keCA== X-Forwarded-Encrypted: i=1; AJvYcCXbVvVY/r1JMn/7ODD98/2nyBSD1Bfbm967b/+KMNi5M0zw+LHcX2FhPzgFZj9bKWi0AwS+Clh3Sn8JD/I=@vger.kernel.org X-Gm-Message-State: AOJu0YyCEGJ249KOmoy7FLui5LEdZXW1zKA63MB6VFp3pW4j7V1np1yv UDUA7yGIgssDWQPEYDKlYPAEBO3YwnBQyCCfQnbAfQX6A01A2zoFQN+KI90FCvyxFEPGSHz9NR6 sHzk+NO5u/A== X-Google-Smtp-Source: AGHT+IF2ZIMzOsjNBNx9unpLBTRWdC7TZPOx60ZBUCd1CXeGH6I+54LnIHrGuSFf5hW0ofiA4wyBjbLySQ4T X-Received: from plbkt8.prod.google.com ([2002:a17:903:888:b0:23d:d2e9:8861]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:240f:b0:236:8df9:ab38 with SMTP id d9443c01a7336-23fb31456fbmr51818505ad.34.1753469561246; Fri, 25 Jul 2025 11:52:41 -0700 (PDT) Date: Fri, 25 Jul 2025 11:51:59 -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-14-irogers@google.com> Subject: [PATCH v9 13/16] perf python: Add evlist metrics function 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" The function returns a list of the names of metrics within the evlist. For example: ``` >>> import perf >>> perf.parse_metrics("TopdownL1").metrics() ['tma_bad_speculation', 'tma_frontend_bound', 'tma_backend_bound', 'tma_ret= iring'] ``` Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 3a58080bab24..ccfa1ac4ad4b 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1293,6 +1293,33 @@ static PyObject *pyrf_evlist__all_cpus(struct pyrf_e= vlist *pevlist) return (PyObject *)pcpu_map; } =20 +static PyObject *pyrf_evlist__metrics(struct pyrf_evlist *pevlist) +{ + PyObject *list =3D PyList_New(/*len=3D*/0); + struct rb_node *node; + + if (!list) + return NULL; + + for (node =3D rb_first_cached(&pevlist->evlist.metric_events.entries); no= de; + node =3D rb_next(node)) { + struct metric_event *me =3D container_of(node, struct metric_event, nd); + struct list_head *pos; + + list_for_each(pos, &me->head) { + struct metric_expr *expr =3D container_of(pos, struct metric_expr, nd); + PyObject *str =3D PyUnicode_FromString(expr->metric_name); + + if (!str || PyList_Append(list, str) !=3D 0) { + Py_DECREF(list); + return NULL; + } + Py_DECREF(str); + } + } + return list; +} + static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { @@ -1521,6 +1548,12 @@ static PyMethodDef pyrf_evlist__methods[] =3D { .ml_flags =3D METH_NOARGS, .ml_doc =3D PyDoc_STR("CPU map union of all evsel CPU maps.") }, + { + .ml_name =3D "metrics", + .ml_meth =3D (PyCFunction)pyrf_evlist__metrics, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR("List of metric names within the evlist.") + }, { .ml_name =3D "mmap", .ml_meth =3D (PyCFunction)pyrf_evlist__mmap, --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 F10A225F997 for ; Fri, 25 Jul 2025 18:52:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469565; cv=none; b=U9Rt90gf0ITlwL7auxE85mwhJYH6YAbdTQYEQX1JmQse5qGlO9SkFWgD4ANR5ZsK58BJiC8MkqikLMN7j3PtNYpAa+G/Kdd5Cj7Ec+7iw2xQ7PLmEVNd3jvW/JuSa9Wc1wiCkuFbvHRaYoKm23iHhQb1OP/wqY8TnmE+WtzwzZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469565; c=relaxed/simple; bh=QNymXMsh0+PDwJgBEIf87BOhNAAwdyMjmuDCswOESpQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ukTLqT4vqEWq/MJA+nI5sb24iCZgyoUwczK5/Ejsy3+tNO3M/0mxKbSg2SzllPqgWN4RDy6PYNOq2bKIBzfyBrSxvToHlTrAYZyjWht3SBhl3RmBaELbiujaBkXnKKB6poEEFmppx3/XN6SnWjHd1mBqS0LGV2bhsr1FKB+GZY4= 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=rK2w7CHB; arc=none smtp.client-ip=209.85.214.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="rK2w7CHB" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2354ba59eb6so38072345ad.1 for ; Fri, 25 Jul 2025 11:52:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469563; x=1754074363; 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=eIGuclGiABh3QC0DEVnjdGmWupx/QA5phZrLpy71AEk=; b=rK2w7CHBc4mLbXjEwd84LikxU5TZzq5BD0cVY1NWQ1lEH4uZLmqawGLPd2hTVS1AS8 GAO7jOCnG0OE/SlFGpsh7KdKloqH4p24DuLacmZ5l/m5MzH/jgiEy14wwM5AC7+h2SBr rBzLBq9HbioPgWmd7GOmOYEBJ8nAA/1oAO6GlSzdShofipsVZ06duu54Gy+RM9ovecgX C2v2DKjP4LGCQCbLEsdtipSTDfar5nltUDdaIwnjJUisY0Q+HOCEGYkC0TzZUGzVCUsH YO1xHvea8iypx5DgGg9xHux6wu3f56AB6uyi+2lg+lHYa/aFFqrPawy6BTqjlndtm46y PzOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469563; x=1754074363; 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=eIGuclGiABh3QC0DEVnjdGmWupx/QA5phZrLpy71AEk=; b=Fk57O8GuI/2BIQ0LRwCM3o9GsAP+potpVG5mfrzG2o77N5/kfwief7kigRZ0Le09Y2 7ZF1qpazGzYMe575zOCwRNvR0arMQbNbj4Tsr3SjFjEkY5eXfAXvy0Gu8GuTeDwfjddc Q5bqS3D6KFlj+wAUYWtuZfhuRSv72WaOWW1YQHa1yjZQLKqobe66wXhp4GvGN4rGj0qA HH1ZWt4gRtbJIgJQUNXnK+7yt52f7m9hJwDPpm0QN6hLTJ09q1HtXptYLA5dQz460FMY 1uYYDD2wywkKYNr60thN+FESW8lI/MMlTTcjYU22+04j+YBWnLGfQKdSOo8SYd1fV9se ZURA== X-Forwarded-Encrypted: i=1; AJvYcCUfZNkQDt2azU/CbUpIWjEc0nAtAtQvlHbnZnXBInCbHqqJFpNTZ5zVgTOljKLRN9yz4xbkY/A+k/by3Tg=@vger.kernel.org X-Gm-Message-State: AOJu0YzPmmfwVkUBPJGXpqiBKXggL3H11+21iYKCWCmtIB6boGi9hoov FGuX/v88M29L8C+igzMo5Sj2brv3Nsh4YBz39z1QxDNstqjO3q7x3XjkPSuAwFb/MKiUyaEdE7L TGCpqFBlzLA== X-Google-Smtp-Source: AGHT+IHs6tlNj+93w5GJ6/PacV7fKa7xzryQVfnW20CZNa7JKwjGoSHXoYrDrxU6vRx2aNJFJLb3d0AbBEfS X-Received: from plor11.prod.google.com ([2002:a17:902:8bcb:b0:220:ca3c:96bc]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:e541:b0:23f:8bcc:e4f3 with SMTP id d9443c01a7336-23fb30ab8bbmr49052845ad.32.1753469563354; Fri, 25 Jul 2025 11:52:43 -0700 (PDT) Date: Fri, 25 Jul 2025 11:52:00 -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-15-irogers@google.com> Subject: [PATCH v9 14/16] perf python: Add evlist compute_metric 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 a compute_metric function that computes a metric double value for a given evlist, metric name, CPU and thread. For example: ``` >>> import perf >>> x =3D perf.parse_metrics("TopdownL1") >>> x.open() >>> x.enable() >>> x.disable() >>> x.metrics() ['tma_bad_speculation', 'tma_frontend_bound', 'tma_backend_bound', 'tma_ret= iring'] >>> x.compute_metric('tma_bad_speculation', 0, -1) 0.08605342847131037 ``` Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 125 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index ccfa1ac4ad4b..bee7c8a69bad 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -14,6 +14,7 @@ #include "evlist.h" #include "evsel.h" #include "event.h" +#include "expr.h" #include "print_binary.h" #include "record.h" #include "strbuf.h" @@ -1320,6 +1321,124 @@ static PyObject *pyrf_evlist__metrics(struct pyrf_e= vlist *pevlist) return list; } =20 +static int prepare_metric(const struct metric_expr *mexp, + const struct evsel *evsel, + struct expr_parse_ctx *pctx, + int cpu_idx, int thread_idx) +{ + struct evsel * const *metric_events =3D mexp->metric_events; + struct metric_ref *metric_refs =3D mexp->metric_refs; + + for (int i =3D 0; metric_events[i]; i++) { + char *n =3D strdup(evsel__metric_id(metric_events[i])); + double val, ena, run; + int source_count =3D evsel__source_count(metric_events[i]); + int ret; + struct perf_counts_values *old_count, *new_count; + + if (!n) + return -ENOMEM; + + if (source_count =3D=3D 0) + source_count =3D 1; + + ret =3D evsel__ensure_counts(metric_events[i]); + if (ret) + return ret; + + /* Set up pointers to the old and newly read counter values. */ + old_count =3D perf_counts(metric_events[i]->prev_raw_counts, cpu_idx, th= read_idx); + new_count =3D perf_counts(metric_events[i]->counts, cpu_idx, thread_idx); + /* Update the value in metric_events[i]->counts. */ + evsel__read_counter(metric_events[i], cpu_idx, thread_idx); + + val =3D new_count->val - old_count->val; + ena =3D new_count->ena - old_count->ena; + run =3D new_count->run - old_count->run; + + if (ena !=3D run && run !=3D 0) + val =3D val * ena / run; + ret =3D expr__add_id_val_source_count(pctx, n, val, source_count); + if (ret) + return ret; + } + + for (int i =3D 0; metric_refs && metric_refs[i].metric_name; i++) { + int ret =3D expr__add_ref(pctx, &metric_refs[i]); + + if (ret) + return ret; + } + + return 0; +} + +static PyObject *pyrf_evlist__compute_metric(struct pyrf_evlist *pevlist, + PyObject *args, PyObject *kwargs) +{ + int ret, cpu =3D 0, cpu_idx, thread =3D 0, thread_idx; + const char *metric; + struct rb_node *node; + struct metric_expr *mexp =3D NULL; + struct expr_parse_ctx *pctx; + double result =3D 0; + + if (!PyArg_ParseTuple(args, "sii", &metric, &cpu, &thread)) + return NULL; + + for (node =3D rb_first_cached(&pevlist->evlist.metric_events.entries); + mexp =3D=3D NULL && node; + node =3D rb_next(node)) { + struct metric_event *me =3D container_of(node, struct metric_event, nd); + struct list_head *pos; + + list_for_each(pos, &me->head) { + struct metric_expr *e =3D container_of(pos, struct metric_expr, nd); + + if (strcmp(e->metric_name, metric)) + continue; + + if (e->metric_events[0] =3D=3D NULL) + continue; + + cpu_idx =3D perf_cpu_map__idx(e->metric_events[0]->core.cpus, + (struct perf_cpu){.cpu =3D cpu}); + if (cpu_idx < 0) + continue; + + thread_idx =3D perf_thread_map__idx(e->metric_events[0]->core.threads, + thread); + if (thread_idx < 0) + continue; + + mexp =3D e; + break; + } + } + if (!mexp) { + PyErr_Format(PyExc_TypeError, "Unknown metric '%s' for CPU '%d' and thre= ad '%d'", + metric, cpu, thread); + return NULL; + } + + pctx =3D expr__ctx_new(); + if (!pctx) + return PyErr_NoMemory(); + + ret =3D prepare_metric(mexp, mexp->metric_events[0], pctx, cpu_idx, threa= d_idx); + if (ret) { + expr__ctx_free(pctx); + errno =3D -ret; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (expr__parse(&result, pctx, mexp->metric_expr)) + result =3D 0.0; + + expr__ctx_free(pctx); + return PyFloat_FromDouble(result); +} + static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { @@ -1554,6 +1673,12 @@ static PyMethodDef pyrf_evlist__methods[] =3D { .ml_flags =3D METH_NOARGS, .ml_doc =3D PyDoc_STR("List of metric names within the evlist.") }, + { + .ml_name =3D "compute_metric", + .ml_meth =3D (PyCFunction)pyrf_evlist__compute_metric, + .ml_flags =3D METH_VARARGS | METH_KEYWORDS, + .ml_doc =3D PyDoc_STR("compute metric for given name, cpu and thread") + }, { .ml_name =3D "mmap", .ml_meth =3D (PyCFunction)pyrf_evlist__mmap, --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (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 2181C2620D2 for ; Fri, 25 Jul 2025 18:52:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469567; cv=none; b=i9VMTkDgHoLV7skx8/hI3B9i8A0COPXfYZcNaFtGoV7qtcc3Ij8j7NFw6CTXS0BBOdeNhureDLLPub7D2lJjxc7iQ8CGgNzmA7CZyDTMdLHu9jM+BUZ+nmpXgOpafStws7dBlYvwEWO83Iw5Q49LObp3dsD9i95IpABe7qSqJoU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469567; c=relaxed/simple; bh=nwIPXmddXA1zM4816Vbz6lPdTIjBK/CaMTkmHr5EAk4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kyM+cwrFqyqxuYEarrBVADC+belEpMDsJ5YO1SOXW+XW+Q+8klWKQU40J5JsoJzKoIhwfLmNhwfJAo5FzhIEVY8v3ylmIqqCyhjceFqts7AhN+SidhfJTm2rGMbFvq0Mzg9LiWEovklLjf3xlZqDfoht1i7uaDJ/wC0HYqd6AFA= 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=EcYnRGsZ; arc=none smtp.client-ip=209.85.210.201 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="EcYnRGsZ" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-764072aca31so293748b3a.2 for ; Fri, 25 Jul 2025 11:52:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469565; x=1754074365; 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=zTJ3W0ByLpHZ9CXRNmMdi9xgwMpplNAcPbcEQMrdjtY=; b=EcYnRGsZsq2lKyJxQPjsvJip36Z044qPci8sDCSiCI89eg5blL3KvxfeFI9gQt0Bo1 dQ5RaxwsDh3ol7zkNxx5RhyQ8VHPpVAuvS8BBhkv7k2gTdauOFuDVqf2+uU7UzbJ7Tnb PtS6Jpd9mWqUcOMSE87dmjojgKaIGtGwUZZsilDHRvjnUqbhwA/O/DPIvRDWW9v5XPGC NzhCcjM57n3NMHVOB4vGK/3A5w6L0K1aLq9r+yU/DMe5ui8HrxrSYQ4AuS+AYbekFG5l oiOR2G39q2aMAkWu1IgvT+Wi2yakWhBSsc/l1WxKxRFE+E8YJE6xEI6eNhtznRpiKMhw L8Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469565; x=1754074365; 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=zTJ3W0ByLpHZ9CXRNmMdi9xgwMpplNAcPbcEQMrdjtY=; b=aSDz1AVUE835XaYthtXxyMSLbCNHVIFTIj96EU+sS5qFTzUhjKcq3Ofio3I4i3koeJ /SpFt3EF9hclBQocd3lS2ZcX+8tgFiKSR4+8Ltzp6YK+Jt5BNGogYzY77kIdrjhdzHHw EJ4WSve36Ir/y6EcBkVwe1uas9F1mzyOb712bWX4BhagWIfzHiBZw6vN/1lsr3rueWld hqd94e/KKoCI1eIpZuteW5xxKwYTgmNMLGpy33yf+EYUM5vM1BII3De9k9GTcZ0QoNkO LSRaXEInXJbwEeLokGylTN66B4GsgTLrmvhN+efATxj1xNvYAHFgMlzq8jsJVyL4LD56 heCw== X-Forwarded-Encrypted: i=1; AJvYcCVggXZzweXv0HKjGp3DPsYlCHriOlVZ36OhIK45hxMIIYqOtTmj6uokERRFRcT6zVCfQwEH/tO3hlO9fkc=@vger.kernel.org X-Gm-Message-State: AOJu0Ywm5oLtCgE63C2u2sloYghb/4HpZrcm8Y2vX8ff6Ub9ac6CkJio kA8mokwyQEdQ64CLeyGOeYY4gdJ7GGJ+VqNEskAvSWK9gHnv3yTeGyAePli8Z9izYXqUrN2e2Fu 5dzhuQ/pH5w== X-Google-Smtp-Source: AGHT+IFxSOul8ScKq/4q+dfu++ZwKGFNHTMTnkU9owlfUOg4oAViLuM+aVMlEXBYML2I8AovmEy1y4dJRHm9 X-Received: from pfbei31.prod.google.com ([2002:a05:6a00:80df:b0:746:22b3:4c0d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:970c:b0:215:ead1:b867 with SMTP id adf61e73a8af0-23d700d3688mr4110328637.14.1753469565477; Fri, 25 Jul 2025 11:52:45 -0700 (PDT) Date: Fri, 25 Jul 2025 11:52:01 -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-16-irogers@google.com> Subject: [PATCH v9 15/16] perf python: Add metrics function 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" The metrics function returns a list dictionaries describing metrics as strings mapping to strings, except for metric groups that are a string mapping to a list of strings. For example: ``` >>> import perf >>> perf.metrics()[0] {'MetricGroup': ['Power'], 'MetricName': 'C10_Pkg_Residency', 'PMU': 'default_core', 'MetricExpr': 'cstate_pkg@c10\\-residency@ / TSC', 'ScaleUnit': '100%', 'BriefDescription': 'C10 residency percent per packag= e'} ``` Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/util/python.c | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index bee7c8a69bad..aaed7745df22 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -2073,7 +2073,93 @@ static PyObject *pyrf__parse_metrics(PyObject *self,= PyObject *args) return result; } =20 +static PyObject *pyrf__metrics_groups(const struct pmu_metric *pm) +{ + PyObject *groups =3D PyList_New(/*len=3D*/0); + const char *mg =3D pm->metric_group; + + if (!groups) + return NULL; + + while (mg) { + PyObject *val =3D NULL; + const char *sep =3D strchr(mg, ';'); + size_t len =3D sep ? (size_t)(sep - mg) : strlen(mg); + + if (len > 0) { + val =3D PyUnicode_FromStringAndSize(mg, len); + if (val) + PyList_Append(groups, val); + + Py_XDECREF(val); + } + mg =3D sep ? sep + 1 : NULL; + } + return groups; +} + +static int pyrf__metrics_cb(const struct pmu_metric *pm, + const struct pmu_metrics_table *table __maybe_unused, + void *vdata) +{ + PyObject *py_list =3D vdata; + PyObject *dict =3D PyDict_New(); + PyObject *key =3D dict ? PyUnicode_FromString("MetricGroup") : NULL; + PyObject *value =3D key ? pyrf__metrics_groups(pm) : NULL; + + if (!value || PyDict_SetItem(dict, key, value) !=3D 0) { + Py_XDECREF(key); + Py_XDECREF(value); + Py_XDECREF(dict); + return -ENOMEM; + } + + if (!add_to_dict(dict, "MetricName", pm->metric_name) || + !add_to_dict(dict, "PMU", pm->pmu) || + !add_to_dict(dict, "MetricExpr", pm->metric_expr) || + !add_to_dict(dict, "MetricThreshold", pm->metric_threshold) || + !add_to_dict(dict, "ScaleUnit", pm->unit) || + !add_to_dict(dict, "Compat", pm->compat) || + !add_to_dict(dict, "BriefDescription", pm->desc) || + !add_to_dict(dict, "PublicDescription", pm->long_desc) || + PyList_Append(py_list, dict) !=3D 0) { + Py_DECREF(dict); + return -ENOMEM; + } + Py_DECREF(dict); + return 0; +} + +static PyObject *pyrf__metrics(PyObject *self, PyObject *args) +{ + const struct pmu_metrics_table *table =3D pmu_metrics_table__find(); + PyObject *list =3D PyList_New(/*len=3D*/0); + int ret; + + if (!list) + return NULL; + + ret =3D pmu_metrics_table__for_each_metric(table, pyrf__metrics_cb, list); + if (!ret) + ret =3D pmu_for_each_sys_metric(pyrf__metrics_cb, list); + + if (ret) { + Py_DECREF(list); + errno =3D -ret; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return list; +} + static PyMethodDef perf__methods[] =3D { + { + .ml_name =3D "metrics", + .ml_meth =3D (PyCFunction) pyrf__metrics, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR( + "Returns a list of metrics represented as string values in dictionaries= .") + }, { .ml_name =3D "tracepoint", .ml_meth =3D (PyCFunction) pyrf__tracepoint, --=20 2.50.1.552.g942d659e1b-goog From nobody Mon Oct 6 01:29:05 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 45B0A260585 for ; Fri, 25 Jul 2025 18:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469570; cv=none; b=j1KnIhkjrQizeAB+wSYWq/ZUVyRzXCSU3H7tL+JMU1ELp5ZdFnFCBNsMlDl+LmmwA3YetJSL9/ONVB60zivvrWqU/Jq1nSxey8FD+yWi+007Of90Cfciog2MUpYedZzHqtmsHEKgTNvKFaW7BtK0XHSiR1ERlrqfEv8wOHvGTYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753469570; c=relaxed/simple; bh=Vfi2altf/yDSdlyxjJ/gdPgkRGPQaIiQsz/byk+X8qk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LsFPpiJ/shJL1uTrnhXFsZrBe00YmPquPTJOXVtQeaY9hfE00uo7GsTjrYpNtvOoUzVI6vdRsN9MB+w4dIqTaQsNfluvr95NsHv4xan15TlLQJb36V0QY8KmtPvcQ4/yPtJ6I0qFfsbBlCVN+XrsMZxO4uY5fGHGUYPa7debZo0= 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=aT8rkSkU; arc=none smtp.client-ip=209.85.216.73 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="aT8rkSkU" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-313ff01d2a6so2569558a91.3 for ; Fri, 25 Jul 2025 11:52:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1753469568; x=1754074368; 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=5biP+aspbDb1VTaF1TY+yJXr6205zuAsUMKrYZmAMzM=; b=aT8rkSkUaBfuvi6cJuauhCwXiVjH2+DZzIeNMLMPdmXtsVyu+cirQKU/p5Z3TOSGm/ GLfbi/QQCAP8F3qqDho0bh5+XIQ6KBvA9Rc3BJDYhnZxI3GhmeSKbOtMnvTAYTYlmBGU MJQH3Gq2ohsIZ0XunbqrqHeQ4I/EnBKOxdxu+s/kUr1ozxhYHQGZMMr9xfS4GspC8phn 3VtB9i2KaltOddKCLdplsvxduUsrPgpgMBSNz4hbh/RTEtVc7OgqS0IWw208E/zMA4Cq VqWLXPRp+X34vix1voQtjC1ldGNK9g8yErPaJHpEO6o00MQirmIqvejwOUBsPX3U0iZ3 nZ5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753469568; x=1754074368; 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=5biP+aspbDb1VTaF1TY+yJXr6205zuAsUMKrYZmAMzM=; b=NSh5OBUjdl/eZXdVRw3f8K8+xUwHz0o5ALAJDzjeqY9RGfTpQI0BtJl2shj3s2SSsD 0Lvjp0Zd1o7mLeZBsqrr8GPZj7daPkNylnTyz6PWFMKtWV6LRVGUINGrxgN2O/TGQgC/ FfDf4LDsP2wJLKFWF8VdSlUfno3lF9krnsTkKI/nUcKdaO5RL0ptGu0WDdOJkxAAaKqg zvkIMsN89WBzk2BDDviVRe7OVc5DjMoD71tSpzc2O8ar1SY6OcI5UGxc6qANKpF8BZnm EJfFpGHTVXLJLFwWatijKAOmyGble5ItYGs3Kxk8g4HEpGjAktP9Swog3ndR/v15A3Mp HDkg== X-Forwarded-Encrypted: i=1; AJvYcCVxZOiIK7NdBeMEu2zuBgsy/dkLGB6Gx49fTVMV77jhndm421N5m2p6ALUzaKMRhK/TtTlwn7lrPQSYeWQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3HVZiVRMqXU4V9YZtV2o/IFGl+ayJJxYOn7XykOwBvlQieEYO 9DXj+yDaBWOK4n2mXB93piO5Zlv26T4PkhV5gxzMQ8TzmvlW3IrksTdkBUcfAPFDMPL1SNO+kiB 67rD4FrD0fw== X-Google-Smtp-Source: AGHT+IEdZlb1KwL/9nTv2K4WuCsVoChQ7cTl1rbJNJMbN8SA+4qeiR+FTBeB3JzPeyDrdcuXTwpxtGk2aEsh X-Received: from pjbsl11.prod.google.com ([2002:a17:90b:2e0b:b0:313:245:8921]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:38d1:b0:311:c596:5c6f with SMTP id 98e67ed59e1d1-31e778f788fmr5013986a91.17.1753469567665; Fri, 25 Jul 2025 11:52:47 -0700 (PDT) Date: Fri, 25 Jul 2025 11:52:02 -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-17-irogers@google.com> Subject: [PATCH v9 16/16] perf ilist: Add support for metrics 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" Change tree nodes to having a value of either Metric or PmuEvent, these values have the ability to match searches, be parsed to create evlists and to give a value per CPU and per thread to display. Use perf.metrics to generate a tree of metrics. Most metrics are placed under their metric group, if the metric group name ends with '_group' then the metric group is placed next to the associated metric. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Reviewed-by: Howard Chu --- tools/perf/python/ilist.py | 226 +++++++++++++++++++++++++++---------- 1 file changed, 168 insertions(+), 58 deletions(-) diff --git a/tools/perf/python/ilist.py b/tools/perf/python/ilist.py index 22c70a8b31f3..9d6465c60df3 100755 --- a/tools/perf/python/ilist.py +++ b/tools/perf/python/ilist.py @@ -2,19 +2,121 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) """Interactive perf list.""" =20 +from abc import ABC, abstractmethod import argparse +from dataclasses import dataclass +import math from typing import Any, Dict, Optional, Tuple import perf from textual import on from textual.app import App, ComposeResult from textual.binding import Binding from textual.containers import Horizontal, HorizontalGroup, Vertical, Vert= icalScroll +from textual.css.query import NoMatches from textual.command import SearchIcon from textual.screen import ModalScreen from textual.widgets import Button, Footer, Header, Input, Label, Sparklin= e, Static, Tree from textual.widgets.tree import TreeNode =20 =20 +def get_info(info: Dict[str, str], key: str): + return (info[key] + "\n") if key in info else "" + + +class TreeValue(ABC): + """Abstraction for the data of value in the tree.""" + + @abstractmethod + def name(self) -> str: + pass + + @abstractmethod + def description(self) -> str: + pass + + @abstractmethod + def matches(self, query: str) -> bool: + pass + + @abstractmethod + def parse(self) -> perf.evlist: + pass + + @abstractmethod + def value(self, evlist: perf.evlist, evsel: perf.evsel, cpu: int, thre= ad: int) -> float: + pass + + +@dataclass +class Metric(TreeValue): + """A metric in the tree.""" + metric_name: str + + def name(self) -> str: + return self.metric_name + + def description(self) -> str: + """Find and format metric description.""" + for metric in perf.metrics(): + if metric["MetricName"] !=3D self.metric_name: + continue + desc =3D get_info(metric, "BriefDescription") + desc +=3D get_info(metric, "PublicDescription") + desc +=3D get_info(metric, "MetricExpr") + desc +=3D get_info(metric, "MetricThreshold") + return desc + return "description" + + def matches(self, query: str) -> bool: + return query in self.metric_name + + def parse(self) -> perf.evlist: + return perf.parse_metrics(self.metric_name) + + def value(self, evlist: perf.evlist, evsel: perf.evsel, cpu: int, thre= ad: int) -> float: + val =3D evlist.compute_metric(self.metric_name, cpu, thread) + return 0 if math.isnan(val) else val + + +@dataclass +class PmuEvent(TreeValue): + """A PMU and event within the tree.""" + pmu: str + event: str + + def name(self) -> str: + if self.event.startswith(self.pmu) or ':' in self.event: + return self.event + else: + return f"{self.pmu}/{self.event}/" + + def description(self) -> str: + """Find and format event description for {pmu}/{event}/.""" + for p in perf.pmus(): + if p.name() !=3D self.pmu: + continue + for info in p.events(): + if "name" not in info or info["name"] !=3D self.event: + continue + + desc =3D get_info(info, "topic") + desc +=3D get_info(info, "event_type_desc") + desc +=3D get_info(info, "desc") + desc +=3D get_info(info, "long_desc") + desc +=3D get_info(info, "encoding_desc") + return desc + return "description" + + def matches(self, query: str) -> bool: + return query in self.pmu or query in self.event + + def parse(self) -> perf.evlist: + return perf.parse_events(self.name()) + + def value(self, evlist: perf.evlist, evsel: perf.evsel, cpu: int, thre= ad: int) -> float: + return evsel.read(cpu, thread).val + + class ErrorScreen(ModalScreen[bool]): """Pop up dialog for errors.""" =20 @@ -126,8 +228,9 @@ class IListApp(App): def __init__(self, interval: float) -> None: self.interval =3D interval self.evlist =3D None - self.search_results: list[TreeNode[str]] =3D [] - self.cur_search_result: TreeNode[str] | None =3D None + self.selected: Optional[TreeValue] =3D None + self.search_results: list[TreeNode[TreeValue]] =3D [] + self.cur_search_result: TreeNode[TreeValue] | None =3D None super().__init__() =20 def expand_and_select(self, node: TreeNode[Any]) -> None: @@ -145,7 +248,7 @@ class IListApp(App): l =3D len(self.search_results) =20 if l < 1: - tree: Tree[str] =3D self.query_one("#pmus", Tree) + tree: Tree[TreeValue] =3D self.query_one("#root", Tree) if previous: tree.action_cursor_up() else: @@ -180,7 +283,7 @@ class IListApp(App): event =3D event.lower() search_label.update(f'Searching for events matching "{event}"') =20 - tree: Tree[str] =3D self.query_one("#pmus", Tree) + tree: Tree[str] =3D self.query_one("#root", Tree) =20 def find_search_results(event: str, node: TreeNode[str], cursor_seen: bool =3D False, @@ -189,7 +292,7 @@ class IListApp(App): """Find nodes that match the search remembering the one af= ter the cursor.""" if not cursor_seen and node =3D=3D tree.cursor_node: cursor_seen =3D True - if node.data and event in node.data: + if node.data and node.data.matches(event): if cursor_seen and not match_after_cursor: match_after_cursor =3D node self.search_results.append(node) @@ -203,7 +306,7 @@ class IListApp(App): self.search_results.clear() (_, self.cur_search_result) =3D find_search_results(event, tre= e.root) if len(self.search_results) < 1: - self.push_screen(ErrorScreen(f"Failed to find pmu/event {e= vent}")) + self.push_screen(ErrorScreen(f"Failed to find pmu/event or= metric {event}")) search_label.display =3D False elif self.cur_search_result: self.expand_and_select(self.cur_search_result) @@ -221,16 +324,16 @@ class IListApp(App): self.set_searched_tree_node(previous=3DTrue) =20 def action_collapse(self) -> None: - """Collapse the potentially large number of events under a PMU.""" - tree: Tree[str] =3D self.query_one("#pmus", Tree) + """Collapse the part of the tree currently on.""" + tree: Tree[str] =3D self.query_one("#root", Tree) node =3D tree.cursor_node - if node and node.parent and node.parent.parent: + if node and node.parent: node.parent.collapse_all() node.tree.scroll_to_node(node.parent) =20 def update_counts(self) -> None: """Called every interval to update counts.""" - if not self.evlist: + if not self.selected or not self.evlist: return =20 def update_count(cpu: int, count: int): @@ -259,8 +362,7 @@ class IListApp(App): for cpu in evsel.cpus(): aggr =3D 0 for thread in evsel.threads(): - counts =3D evsel.read(cpu, thread) - aggr +=3D counts.val + aggr +=3D self.selected.value(self.evlist, evsel, cpu,= thread) update_count(cpu, aggr) total +=3D aggr update_count(-1, total) @@ -271,47 +373,37 @@ class IListApp(App): self.update_counts() self.set_interval(self.interval, self.update_counts) =20 - def set_pmu_and_event(self, pmu: str, event: str) -> None: + def set_selected(self, value: TreeValue) -> None: """Updates the event/description and starts the counters.""" + try: + label_name =3D self.query_one("#event_name", Label) + event_description =3D self.query_one("#event_description", Sta= tic) + lines =3D self.query_one("#lines") + except NoMatches: + # A race with rendering, ignore the update as we can't + # mount the assumed output widgets. + return + + self.selected =3D value + # Remove previous event information. if self.evlist: self.evlist.disable() self.evlist.close() - lines =3D self.query(CounterSparkline) - for line in lines: - line.remove() - lines =3D self.query(Counter) - for line in lines: + old_lines =3D self.query(CounterSparkline) + for line in old_lines: line.remove() + old_counters =3D self.query(Counter) + for counter in old_counters: + counter.remove() =20 - def pmu_event_description(pmu: str, event: str) -> str: - """Find and format event description for {pmu}/{event}/.""" - def get_info(info: Dict[str, str], key: str): - return (info[key] + "\n") if key in info else "" - - for p in perf.pmus(): - if p.name() !=3D pmu: - continue - for info in p.events(): - if "name" not in info or info["name"] !=3D event: - continue - - desc =3D get_info(info, "topic") - desc +=3D get_info(info, "event_type_desc") - desc +=3D get_info(info, "desc") - desc +=3D get_info(info, "long_desc") - desc +=3D get_info(info, "encoding_desc") - return desc - return "description" - - # Parse event, update event text and description. - full_name =3D event if event.startswith(pmu) or ':' in event else = f"{pmu}/{event}/" - self.query_one("#event_name", Label).update(full_name) - self.query_one("#event_description", Static).update(pmu_event_desc= ription(pmu, event)) + # Update event/metric text and description. + label_name.update(value.name()) + event_description.update(value.description()) =20 # Open the event. try: - self.evlist =3D perf.parse_events(full_name) + self.evlist =3D value.parse() if self.evlist: self.evlist.open() self.evlist.enable() @@ -319,13 +411,12 @@ class IListApp(App): self.evlist =3D None =20 if not self.evlist: - self.push_screen(ErrorScreen(f"Failed to open {full_name}")) + self.push_screen(ErrorScreen(f"Failed to open {value.name()}")) return =20 # Add spark lines for all the CPUs. Note, must be done after # open so that the evlist CPUs have been computed by propagate # maps. - lines =3D self.query_one("#lines") line =3D CounterSparkline(cpu=3D-1) lines.mount(line) for cpu in self.evlist.all_cpus(): @@ -339,28 +430,49 @@ class IListApp(App): =20 def compose(self) -> ComposeResult: """Draws the app.""" - def pmu_event_tree() -> Tree: - """Create tree of PMUs with events under.""" - tree: Tree[str] =3D Tree("PMUs", id=3D"pmus") - tree.root.expand() + def metric_event_tree() -> Tree: + """Create tree of PMUs and metricgroups with events or metrics= under.""" + tree: Tree[TreeValue] =3D Tree("Root", id=3D"root") + pmus =3D tree.root.add("PMUs") for pmu in perf.pmus(): pmu_name =3D pmu.name().lower() - pmu_node =3D tree.root.add(pmu_name, data=3Dpmu_name) + pmu_node =3D pmus.add(pmu_name) try: for event in sorted(pmu.events(), key=3Dlambda x: x["n= ame"]): if "name" in event: e =3D event["name"].lower() if "alias" in event: - pmu_node.add_leaf(f'{e} ({event["alias"]})= ', data=3De) + pmu_node.add_leaf(f'{e} ({event["alias"]})= ', + data=3DPmuEvent(pmu_name= , e)) else: - pmu_node.add_leaf(e, data=3De) + pmu_node.add_leaf(e, data=3DPmuEvent(pmu_n= ame, e)) except: # Reading events may fail with EPERM, ignore. pass + metrics =3D tree.root.add("Metrics") + groups =3D set() + for metric in perf.metrics(): + groups.update(metric["MetricGroup"]) + + def add_metrics_to_tree(node: TreeNode[TreeValue], parent: str= ): + for metric in sorted(perf.metrics(), key=3Dlambda x: x["Me= tricName"]): + if parent in metric["MetricGroup"]: + name =3D metric["MetricName"] + node.add_leaf(name, data=3DMetric(name)) + child_group_name =3D f'{name}_group' + if child_group_name in groups: + add_metrics_to_tree(node.add(child_group_name)= , child_group_name) + + for group in sorted(groups): + if group.endswith('_group'): + continue + add_metrics_to_tree(metrics.add(group), group) + + tree.root.expand() return tree =20 yield Header(id=3D"header") - yield Horizontal(Vertical(pmu_event_tree(), id=3D"events"), + yield Horizontal(Vertical(metric_event_tree(), id=3D"events"), Vertical(Label("event name", id=3D"event_name"), Static("description", markup=3DFalse, id= =3D"event_description"), )) @@ -369,12 +481,10 @@ class IListApp(App): yield Footer(id=3D"footer") =20 @on(Tree.NodeSelected) - def on_tree_node_selected(self, event: Tree.NodeSelected[str]) -> None: + def on_tree_node_selected(self, event: Tree.NodeSelected[TreeValue]) -= > None: """Called when a tree node is selected, selecting the event.""" - if event.node.parent and event.node.parent.parent: - assert event.node.parent.data is not None - assert event.node.data is not None - self.set_pmu_and_event(event.node.parent.data, event.node.data) + if event.node.data: + self.set_selected(event.node.data) =20 =20 if __name__ =3D=3D "__main__": --=20 2.50.1.552.g942d659e1b-goog