From nobody Tue Oct 7 09:55:04 2025 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.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 43E452FD87F for ; Thu, 10 Jul 2025 20:25:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179111; cv=none; b=K9NdZ6RAzo4+x+v9fTx1Gy5Zi3tc69Pbz3JJvwFHoRAZA3jJICkCI+9xD/Yv3J4kPI2o1DRaQFmhSwW9lwG/S/7k+MEVYhRYybadcnJrkI3pFYbEL8mHkUpBQTsmjFOyuX0qfFVsT3bOsAF1mM6iTBumvqU0uif75xvpCjLtD2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179111; c=relaxed/simple; bh=OBUnSNyWg9w1qVJi5lsWp0gnwPU6CVGbBfnB2vqpaFI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=mJ2jpOj+Rmg9uPriz9GZF0iwT8obYvZw9FPmecyoRUXFFvFiFI24RgaLieq1BOWDVoeu5T2tCx4gBC6V49JJgafCd1IYGJP2BHJUO2p/8VmzSA1XhWr42pw4F1o50aVmXP9Cutaq7teDZZmFoSLL+f7JRq8l5QplGbA2sS+xRN8= 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=fCIjr5lH; arc=none smtp.client-ip=209.85.215.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="fCIjr5lH" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b2c36951518so1436372a12.2 for ; Thu, 10 Jul 2025 13:25:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179108; x=1752783908; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=NRGNNr/giRHcF/RZj7awN1PXfLHMVDY5ladq/SDyrWA=; b=fCIjr5lHVWsUXIJXa9WzxRDOOWHtr/2b+FYuWhs1jCAv6JWRemnLB8OdC8OmKRzbTs qDH1VeheH4SIkVgcxUhjbZx10dXyNBaA6oRfpwoKiM/rGEDAH5GcrY2K1FF5lrxo7hTW Ojf/JYApXYVuyhOW5Ep0ryTgz6L3F6MQvCjmcB3hrFsKwNb6eXatTRpE4ZcRJD3ywA2A WWVVJt9eOH6rDmVlTXbo9r6MponIgHvob1dYkBmhSVlh3MTx3Q05L8QNAWWimyqa6xHp kIq0NW1Na39ewdcykNrnnGHM5BUarmLCv9EbWTn7zk6V7Zfs6XpTuyddeV00cMlqnk1w 32Aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179108; x=1752783908; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NRGNNr/giRHcF/RZj7awN1PXfLHMVDY5ladq/SDyrWA=; b=JIM+B0iyYk3hXGxY11FvukvBsKzafzzGEzB84KIboFepvqleQgOmMXSRgcfVDLouXR a8ntHgCO91824PvakKfElZy/X4DiTvXWgYNVOKgSuQsY3SUVtnD47IuWGenw96pErW6Y mI+MF++UfUphGLm3t1CjxikoyuuZqs7X+jlLzn9Tt2c4FHejs/GZUpse+OpRAzhr/KAl TusbCrcAsIkvNkwp/rY0Rp4YJO2uhoOALPZ85DJEz7AUwM5Ixna8s5oOm3vaGeR6cLEJ KWxn1AV+YSy6b6Ry263+dX7WsELAA37lI4IS2VWsIrUElkv/yjI9YHpygWWfv6IGjdA1 1MvQ== X-Forwarded-Encrypted: i=1; AJvYcCV5uTV4n7z3xrOosZQ7+XepaAqLbx1cwjK/vdWpC4KD+jGJ9Hg5TXOMuphhqF7mfBN24hb4saswGCQt/qo=@vger.kernel.org X-Gm-Message-State: AOJu0YzXjXkn4aJDD5MYi1WqT7LNj631u4orGs7LglVPJhDkdFfCwGnZ Ha1AsoozBU4Ud9ggK8BxwQYO5kb+6tpgp53YQOKcIDBQuyp2YP5koQGMAWdwcwaMcGwKW6PHgCs 4vO8/mORY3g== X-Google-Smtp-Source: AGHT+IH72NrD7CNe+09hGlYHy69c4whBgY9uNs2471nAV52gepH25V4fw/mcpBmjSWWmNaYEVhO7BZuHXQIy X-Received: from pfbna38.prod.google.com ([2002:a05:6a00:3e26:b0:746:1bf8:e16]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7f8e:b0:1f5:79c4:5da6 with SMTP id adf61e73a8af0-2311dc59daemr1026203637.5.1752179108537; Thu, 10 Jul 2025 13:25:08 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:39 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-2-irogers@google.com> Subject: [PATCH v5 01/14] 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 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 --- .../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..3af2f565a601 --- /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": "Task based 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..7d179d703ab1 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\000Task based high-resolution ti= mer based event\000config=3D1\000\00000\000\000\000\000\000" +/* offset=3D169 */ "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=3D264 */ "page-faults\000software\000Number of page faults [This= event is an alias of faults]\000config=3D2\000\00000\000\000\000\000\000" +/* offset=3D359 */ "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=3D460 */ "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=3D561 */ "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=3D693 */ "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=3D825 */ "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=3D934 */ "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=3D1037 */ "alignment-faults\000software\000Number of kernel hand= led memory alignment faults\000config=3D7\000\00000\000\000\000\000\000" +/* offset=3D1129 */ "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=3D1256 */ "dummy\000software\000A placeholder event that doesn't= count anything\000config=3D9\000\00000\000\000\000\000\000" +/* offset=3D1336 */ "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=3D1438 */ "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=3D1541 */ "tool\000" +/* offset=3D1546 */ "duration_time\000tool\000Wall clock interval time in = nanoseconds\000config=3D1\000\00000\000\000\000\000\000" +/* offset=3D1622 */ "user_time\000tool\000User (non-kernel) time in nanose= conds\000config=3D2\000\00000\000\000\000\000\000" +/* offset=3D1692 */ "system_time\000tool\000System/kernel time in nanoseco= nds\000config=3D3\000\00000\000\000\000\000\000" +/* offset=3D1760 */ "has_pmem\000tool\0001 if persistent memory installed = otherwise 0\000config=3D4\000\00000\000\000\000\000\000" +/* offset=3D1836 */ "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=3D1981 */ "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=3D2084 */ "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=3D2201 */ "num_dies\000tool\000Number of dies. Each die has 1 or= more cores\000config=3D8\000\00000\000\000\000\000\000" +/* offset=3D2277 */ "num_packages\000tool\000Number of packages. Each pack= age has 1 or more die\000config=3D9\000\00000\000\000\000\000\000" +/* offset=3D2363 */ "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=3D2473 */ "smt_on\000tool\0001 if simultaneous multithreading (a= ka hyperthreading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\= 000\000\000" +/* offset=3D2580 */ "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=3D2679 */ "default_core\000" +/* offset=3D2692 */ "bp_l1_btb_correct\000branch\000L1 BTB Correction\000e= vent=3D0x8a\000\00000\000\000\000\000\000" +/* offset=3D2754 */ "bp_l2_btb_correct\000branch\000L2 BTB Correction\000e= vent=3D0x8b\000\00000\000\000\000\000\000" +/* offset=3D2816 */ "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=3D2914 */ "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=3D3016 */ "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=3D3149 */ "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=3D3267 */ "hisi_sccl,ddrc\000" +/* offset=3D3282 */ "uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write co= mmands\000event=3D2\000\00000\000\000\000\000\000" +/* offset=3D3352 */ "uncore_cbox\000" +/* offset=3D3364 */ "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=3D3518 */ "event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0= xe0\000\00000\000\000\000\000\000" +/* offset=3D3572 */ "event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event= =3D0xc0\000\00000\000\000\000\000\000" +/* offset=3D3630 */ "hisi_sccl,l3c\000" +/* offset=3D3644 */ "uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read = hits\000event=3D7\000\00000\000\000\000\000\000" +/* offset=3D3712 */ "uncore_imc_free_running\000" +/* offset=3D3736 */ "uncore_imc_free_running.cache_miss\000uncore\000Total= cache misses\000event=3D0x12\000\00000\000\000\000\000\000" +/* offset=3D3816 */ "uncore_imc\000" +/* offset=3D3827 */ "uncore_imc.cache_hits\000uncore\000Total cache hits\0= 00event=3D0x34\000\00000\000\000\000\000\000" +/* offset=3D3892 */ "uncore_sys_ddr_pmu\000" +/* offset=3D3911 */ "sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycle= s event\000event=3D0x2b\000v8\00000\000\000\000\000\000" +/* offset=3D3987 */ "uncore_sys_ccn_pmu\000" +/* offset=3D4006 */ "sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles = event\000config=3D0x2c\0000x01\00000\000\000\000\000\000" +/* offset=3D4083 */ "uncore_sys_cmn_pmu\000" +/* offset=3D4102 */ "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=3D4245 */ "CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000" +/* offset=3D4267 */ "IPC\000group1\000inst_retired.any / cpu_clk_unhalted.= thread\000\000\000\000\000\000\000\00000" +/* offset=3D4330 */ "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=3D4496 */ "dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_re= tired.any\000\000\000\000\000\000\000\00000" +/* offset=3D4560 */ "icache_miss_cycles\000\000l1i\\-loads\\-misses / inst= _retired.any\000\000\000\000\000\000\000\00000" +/* offset=3D4627 */ "cache_miss_cycles\000group1\000dcache_miss_cpi + icac= he_miss_cycles\000\000\000\000\000\000\000\00000" +/* offset=3D4698 */ "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=3D4792 */ "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=3D4926 */ "DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_A= ll_Miss\000\000\000\000\000\000\000\00000" +/* offset=3D4990 */ "DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCa= che_L2_All)\000\000\000\000\000\000\000\00000" +/* offset=3D5058 */ "DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, D= Cache_L2_All)\000\000\000\000\000\000\000\00000" +/* offset=3D5128 */ "M1\000\000ipc + M2\000\000\000\000\000\000\000\00000" +/* offset=3D5150 */ "M2\000\000ipc + M1\000\000\000\000\000\000\000\00000" +/* offset=3D5172 */ "M3\000\0001 / M3\000\000\000\000\000\000\000\00000" +/* offset=3D5192 */ "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 { +{ 1037 }, /* alignment-faults\000software\000Number of kernel handled memo= ry alignment faults\000config=3D7\000\00000\000\000\000\000\000 */ +{ 1336 }, /* 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 */ +{ 1438 }, /* cgroup-switches\000software\000Number of context switches to = a task in a different cgroup\000config=3D0xb\000\00000\000\000\000\000\000 = */ +{ 359 }, /* 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 */ +{ 561 }, /* 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 */ +{ 460 }, /* cs\000software\000Number of context switches [This event is an= alias of context-switches]\000config=3D3\000\00000\000\000\000\000\000 */ +{ 1256 }, /* dummy\000software\000A placeholder event that doesn't count a= nything\000config=3D9\000\00000\000\000\000\000\000 */ +{ 1129 }, /* emulation-faults\000software\000Number of kernel handled unim= plemented instruction faults handled through emulation\000config=3D8\000\00= 000\000\000\000\000\000 */ +{ 169 }, /* faults\000software\000Number of page faults [This event is an = alias of page-faults]\000config=3D2\000\00000\000\000\000\000\000 */ +{ 934 }, /* major-faults\000software\000Number of major page faults. Major= faults require I/O to handle\000config=3D6\000\00000\000\000\000\000\000 */ +{ 693 }, /* 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 */ +{ 825 }, /* 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 */ +{ 264 }, /* 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\000Task based high-resolution timer base= d 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 */ +{ 1546 }, /* duration_time\000tool\000Wall clock interval time in nanoseco= nds\000config=3D1\000\00000\000\000\000\000\000 */ +{ 1760 }, /* has_pmem\000tool\0001 if persistent memory installed otherwis= e 0\000config=3D4\000\00000\000\000\000\000\000 */ +{ 1836 }, /* 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 */ +{ 1981 }, /* 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 = */ +{ 2084 }, /* 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 */ +{ 2201 }, /* num_dies\000tool\000Number of dies. Each die has 1 or more co= res\000config=3D8\000\00000\000\000\000\000\000 */ +{ 2277 }, /* num_packages\000tool\000Number of packages. Each package has = 1 or more die\000config=3D9\000\00000\000\000\000\000\000 */ +{ 2363 }, /* 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 */ +{ 2473 }, /* smt_on\000tool\0001 if simultaneous multithreading (aka hyper= threading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\000\000\= 000 */ +{ 1692 }, /* system_time\000tool\000System/kernel time in nanoseconds\000c= onfig=3D3\000\00000\000\000\000\000\000 */ +{ 2580 }, /* system_tsc_freq\000tool\000The amount a Time Stamp Counter (T= SC) increases per second\000config=3D0xc\000\00000\000\000\000\000\000 */ +{ 1622 }, /* 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 { 1541 /* 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 */ +{ 2692 }, /* bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=3D0= x8a\000\00000\000\000\000\000\000 */ +{ 2754 }, /* bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=3D0= x8b\000\00000\000\000\000\000\000 */ +{ 3016 }, /* 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 */ +{ 3149 }, /* eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) = Technology (EIST) transitions\000event=3D0x3a,period=3D200000\000\00000\000= \000\000\000\000 */ +{ 2816 }, /* l3_cache_rd\000cache\000L3 cache access, read\000event=3D0x40= \000\00000\000\000\000\000Attributable Level 3 cache access, read\000 */ +{ 2914 }, /* 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 */ +{ 3282 }, /* 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 */ +{ 3644 }, /* 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 */ +{ 3518 }, /* event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0xe0\000\= 00000\000\000\000\000\000 */ +{ 3572 }, /* event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=3D0xc0\= 000\00000\000\000\000\000\000 */ +{ 3364 }, /* 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 */ +{ 3827 }, /* 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 */ +{ 3736 }, /* 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 { 2679 /* 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 { 3267 /* 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 { 3630 /* 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 { 3352 /* 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 { 3816 /* 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 { 3712 /* 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 */ +{ 4245 }, /* CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000 */ +{ 4926 }, /* DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\= 000\000\000\000\000\000\000\00000 */ +{ 4698 }, /* 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 */ +{ 4792 }, /* 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 */ +{ 4990 }, /* DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_A= ll)\000\000\000\000\000\000\000\00000 */ +{ 5058 }, /* DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2= _All)\000\000\000\000\000\000\000\00000 */ +{ 4330 }, /* 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 */ +{ 4267 }, /* IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\0= 00\000\000\000\000\000\000\00000 */ +{ 5192 }, /* L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duratio= n_time\000\000\000\000\000\000\000\00000 */ +{ 5128 }, /* M1\000\000ipc + M2\000\000\000\000\000\000\000\00000 */ +{ 5150 }, /* M2\000\000ipc + M1\000\000\000\000\000\000\000\00000 */ +{ 5172 }, /* M3\000\0001 / M3\000\000\000\000\000\000\000\00000 */ +{ 4627 }, /* cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_= cycles\000\000\000\000\000\000\000\00000 */ +{ 4496 }, /* dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.an= y\000\000\000\000\000\000\000\00000 */ +{ 4560 }, /* 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 { 2679 /* 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 */ +{ 4006 }, /* 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 */ +{ 4102 }, /* 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 */ +{ 3911 }, /* 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 { 3987 /* 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 { 4083 /* 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 { 3892 /* 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=3D0; 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..76c1e7b0bc22 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=3D0; 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 590E82FE305 for ; Thu, 10 Jul 2025 20:25:11 +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=1752179112; cv=none; b=Jl1xorh5JO3rq1YuwTBoQMhCW5N+ka6uSwzzpIjSkTMoi6u4hCHkUdDG2CDsNnfWoP94egjgHV7ROdTKu7sDfJsi0wrCbplGrIJFxjKhzf9EV4baf7WP0DxqfScl5KZ0AqciW98eiN8PH0C4ENxu4gN/DL5lhq10ArfmNkGGQ1E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179112; c=relaxed/simple; bh=djgGA+2uKhtnV1MR7VzStD3Qsfg+MK7coxDPgG/6gFk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=CcdlmG7SeXqQ5j5zlDjwRbed2JCa0etLQrzZ3x2DLjeRpfXJqgIoeb+Fsr4DWyI7ihp/05STJc3gagK3dQlG56nkp9Qhd1VQvOLrdIqRuxKoXrgMcjkKQRg+qgzh4RIYroPRxo06nm7TqauWJXwCUARroodRDepsI042CT30t24= 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=WoVl9grk; 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="WoVl9grk" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-23632fd6248so13983665ad.3 for ; Thu, 10 Jul 2025 13:25:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179111; x=1752783911; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=U89VxtBTYyWaxU+pAq4vLFW77vwlkptU1zKa/exvlE4=; b=WoVl9grkGT4vsdmDGhr2ZYfvk9/iLb/upnbP+/pWAsv0mxPIbkafcGRNdydFbte4aM /u61edyM+MQVXLSULN74j0rrZ/1AK6GzwvWyVN3E07S1hsiRlX6P83Ca+wjUlz4Ml+4X lKaizwsUTloi5y4BKd48WjEMWCC6o7YI0W2IScAjMhTf5U1qeoGkI16wQMxdwoGsWwjI lPgtJJ2YJUWcGOOVmAfv2S9MPqNzubjOoRBFAby7Rytktbo0mys+1UEfJ0KoSPpb2Xu8 Mdc/FO10M+Om1N8X7N4LWUpeSdtbbQHY9FtfuIirpvkzNRf8mJVLe7eyR57J5tcfdxLn 9hAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179111; x=1752783911; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=U89VxtBTYyWaxU+pAq4vLFW77vwlkptU1zKa/exvlE4=; b=ChkCVds8HdKX4Bw0RljW1+tW4KNemF8QCt53i1WUGGdtkwK47pe8tL97+hkPFeeUnh 7HoaF16aCm0AOMCHyfTulh6gohkmaOwHWj15dwDg4a1iza3i0Yp4z79eWkUT7dE1dRRz XFhm0RCroVPJlOd98++6+41ryUW+Fo+s5depilEx/VPbuILP5Z+pVKDpNLI4/4gzTjPR 1rRzYOwdNnROd5QY44sdkXHSIjmiSo/E/yEsgykzUOK7VML+bn85Zkw23IGnE1/ZI/C8 h7ZJQZc2XFh+YBxG+8KtVPUKTaNLLituV9Fa5d6Ef67KnMrN/oJiEdIMhDSZBIoLO0rI XbQA== X-Forwarded-Encrypted: i=1; AJvYcCUicbZb3y5iyCAOQ1Cw7jbbgl6feMtdAONG5FXMiVf3EjA36WJfw4KjO4RbmwRtonXWX8VV/ykLUGy/vYE=@vger.kernel.org X-Gm-Message-State: AOJu0YyV8pBiU8QxmJID/a/J55PL8boAA2xHYHiHULbxndLnSXK0AXzx CXoQoGMw6iwxemwHMymm7BE3IX4uOGgVe3tavUSJQo33rfV5EKHuECwG5ucpOMcDfjATB2lpsUz IaTS/wl4nPg== X-Google-Smtp-Source: AGHT+IFe7QXbh0bjW2GZ6NdukfdwdxAvamifW7/SPsDgRmd2RqZ4JidMl/2TN77wK/xm2ej22Sj0UjJyBQkN X-Received: from pjtd14.prod.google.com ([2002:a17:90b:4e:b0:314:2a3f:89c5]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:f7cf:b0:235:2403:77c7 with SMTP id d9443c01a7336-23dee0c6bd3mr5402795ad.37.1752179110706; Thu, 10 Jul 2025 13:25:10 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:40 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-3-irogers@google.com> Subject: [PATCH v5 01/14] 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 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 --- 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 ad2437d132f3..0124db5ab3d1 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -628,6 +628,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 @@ -1663,6 +1795,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 @@ -1690,6 +1828,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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 68C8B2FE31B for ; Thu, 10 Jul 2025 20:25:13 +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=1752179115; cv=none; b=Q8P7lcGgpKRucu5dX1AbJuzFiPkZhIDj5q/kpRGGok2cYnM5gJPKn29VW/CIGep17t39myOW5tcAHSvCynBVGAmPGEgGmzAks8Cl0GZmI4QM4056qfxtYBhb11Qy88MHnTxrE07o+WdKqo7ZmkjbH5zFTkR1tcaO6NxnwzwFKxg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179115; c=relaxed/simple; bh=hQokINY7w1ShrrgZa7yZzzTcBe2DFkxckj5lH340Cec=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=D86w2zd8Me8rZhwjXQmkzsTTvxjFW67h8ZHhkDh6hSAWopbHpY26Y8SK0pw/lQY6pbBBUVfFHSjtyQ0o/YsqLflFA2hyHz6JK7YFgIHoovqNx/JdMoaF847GI+DHCDhIlzvLl0IkTFebLnEKOldGSTprVh7dDiK8JyNwuTsjO2g= 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=ChEH8W6F; 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="ChEH8W6F" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-235e1d70d67so13753705ad.0 for ; Thu, 10 Jul 2025 13:25:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179113; x=1752783913; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=rlDQWnF9PwaPlaf+aejcqkoEmXJ/40GLuFVvGJ4bgdI=; b=ChEH8W6Fc0ju2KxMjc0c4U+g2BYcEJxHXmPLBSRiJvktSBYeXFAE48KWEB5YYSAsZ3 0PWrv/qY+C2oJpnA1ugilLKuZXDydTcM/W2R04XirRcSWyboGAtdQMJu1+rJy+638xUo lHubgtLGMIzQDRfx80Ul0gaSiZNKo9Zs/9MD8+sYpqlhMYmbx7j9vhmyi1ZeEr8w7/IX jVydECmthpw5q8sxETbxvSWhISmSWAz02y1iakoLas+qogVnuzizODfHxL266YO2Uonw U4ud1IQwfTOBey4Vf+g6R5BfeZEpfaV9K1gzdRTgQnEI8sPk/SGqqJGy2KnuPbfs63aY UdOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179113; x=1752783913; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rlDQWnF9PwaPlaf+aejcqkoEmXJ/40GLuFVvGJ4bgdI=; b=QT1r2QMm9kIOXy6PPzCNq/4Wdi1iRUFV0pb3sjVKN9ThuXOBX6cabbCZr5QbdpFLmO YoLBn6qoLs9TIb99BildNm1wJvO6QL9fiYAJXT44pp5GLSxw1a3gNM44JoTzla+uUqrA Flb6olirCD/6qpYeFJtea0gz8xd3gSOjL0vOpKAYXQC/atxtPdLzEZyN+w4ss0Jfd2iY NtKvY5XoRIt1+9U5lS7Vb/ZSWt5uBAFIJNhqpm28yKdkbGeSXuogxGVoOcK1iIASZlwN nikJP2WU+PusWZWV9j59xIsViih1wn7DrL7e6PFpZ5HavKKTvdPVa7kXXwOja869xIAH tZHQ== X-Forwarded-Encrypted: i=1; AJvYcCUX66ztsu1lfn0JuPHR6uqvQrb62KyBHWgoJz2y2Sk5xszwWyC1GCJEc9magoWt7fwyiWLykBlLKSQQuJk=@vger.kernel.org X-Gm-Message-State: AOJu0Yz60x5pCAI7nFR++ztM/NprTEGA1Z6dfx66bibdEsYxR4+AsmDj iiuRYkCsiW6mrlB4tmJA8qeqMokyKtA+zskzm4iv2WjNooi/aHUKLI7PpDJagLvUnIN6U2PoyB6 ROT29F5yp3g== X-Google-Smtp-Source: AGHT+IFxUxSNM9Jj7Qp3AW0G45CbXW47A0jHPPnikNBTDcMjlnzGv0sTGlhLljKBXZPHk/0SpsCc362vCmM+ X-Received: from plpf5.prod.google.com ([2002:a17:903:3c45:b0:236:9ead:1ac4]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:f682:b0:234:8eeb:d834 with SMTP id d9443c01a7336-23dee1e8154mr6811065ad.16.1752179112746; Thu, 10 Jul 2025 13:25:12 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:41 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-4-irogers@google.com> Subject: [PATCH v5 02/14] 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 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 --- 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 8DE1B2FE33B for ; Thu, 10 Jul 2025 20:25: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=1752179117; cv=none; b=AnGu+G3WTfkA4Zd3zS5zYbZbsuEa5F0FLwd80EgVUmMUtsnnRzBVT/IF4wsym14XHwdsfuF3Zd2/zEGFRG+xAaoLHkOkKWJOEtvxhIrekLdtfIvkJIoEKZq0bN/piG//REydYW0gvLypkyLuttQqddD2f6z3vW4gY15vNQcBQVM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179117; c=relaxed/simple; bh=WFS1g6kYY+XgrAAa5iSXxbIVXwge/aB1XoG8Q1Q1zEI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=cGycKKTGvMurUyW9zyxBw/oYOK61qXyievisrt8QnX2Ohs1cK5o0sMU0gBOrdhVHZHVtKEMzgWD98uYavC3UIBK+mWxQXkJ8Cde2J61RD7rDSTIZ9172QzfHs2Mh54qvndKl9KVvubJdANwESLD623Z+kwQ0sw65G/RwWRT2AWs= 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=fb9W3gVI; 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="fb9W3gVI" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-3132c1942a1so2143608a91.2 for ; Thu, 10 Jul 2025 13:25:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179115; x=1752783915; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=nLmmHKES778Ih0J3i1L0ZkfJuaKP4hpTsElytjjdQfs=; b=fb9W3gVIVOr+pacZm50pzm1Ccihhu5zduZDNsNPM1W224DFEDdRphXktJvHGLHvq5h B6h3T/OahgTIrAo+6WYJPv4H2b1o7253YdY+jMiOx8MQMcMNNE/FIMOZ1K2PcW7ZEtN4 en73YykXG+8n4DfrcWbvXM1cbxr9C6OPTXGGnxrwXfOCZvw0GBpTO9rMS08/DQ4Rm8Ef gxDQSHQa+lG2MisoN8a8jAJExIr+8AxKLPZ2c2XjEgMJ7JZRHbSLK9hxd+MPoB/yG/ny aoe1MeUdLBDa3xeqKzVbpSwdQziYysZH9XDa2xTxjVhMGkK5fI9Yj4FArdcTtQaor89c lekQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179115; x=1752783915; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nLmmHKES778Ih0J3i1L0ZkfJuaKP4hpTsElytjjdQfs=; b=JTUILEkZxbY3DuL3xof+H/76it/CbmJeGNjt/vqGXwWkxCvfbjoR43MvfPIclz0Idj NjpJdGvc6c8VslIuTGhrHjHBTBnLu7oOSwcbug8e8I2NdKWLsdXucWm/vDFEy8ySz/nA tSuVNKTDTyTAgfBHREDNNTxsuX3vPYTsnFNoR0oK7oilKl3p6Aqtk1u7ZtjN4CztDH0G KXkEjxrHIqbhtc+OfFsTNk1JhGdq96+1onOwarp1cvb8EDwv9W3r847mHI8LH/sio8Tw sJkqrgetFlyTpAMIcwUHGnHsh/SaR0aHiCLxtv78naqX+vs6rvzwC6EESqQNq9dK9utq 8e1g== X-Forwarded-Encrypted: i=1; AJvYcCW8Iq+F3pPnrCSLGtDs2uVfPG1OwCUs1iTA3VJ1gft0cMUD9xqYZyiUsRum2gBhXzgNaeECE2aJy/6Q4Ok=@vger.kernel.org X-Gm-Message-State: AOJu0YyNyVMQdEX0zlAB5PbMTrQK6Zv103P4j1OIFteJW+GV/kbkaYt8 stEPnowsnYSQtsrKYrIS+0D+0D9Jw5EXy6X2ZeaQC7yzdL9UKuewAiMz7zy+rYdr5Fk6i3WRtNn UBXYk79pPIw== X-Google-Smtp-Source: AGHT+IHzBHYcOb0ZjZYgjdQfhaAwhHVz+PNWGSCKUC+dRMctJvIIfCbhj3frakOoN6CUI8TBd5c/GQZjKiSs X-Received: from pjbcz11.prod.google.com ([2002:a17:90a:d44b:b0:2fc:2c9c:880]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:48cf:b0:31c:260e:55e9 with SMTP id 98e67ed59e1d1-31c4f591cebmr13217a91.24.1752179114802; Thu, 10 Jul 2025 13:25:14 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:42 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-5-irogers@google.com> Subject: [PATCH v5 02/14] 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 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 --- tools/perf/util/python.c | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 0124db5ab3d1..728ed27986b5 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -649,6 +649,67 @@ 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); + + if (!py_list) + return NULL; + + if (perf_pmu__for_each_event(ppmu->pmu, + /*skip_duplicate_pmus=3D*/false, + py_list, + pyrf_pmu__events_cb) !=3D 0) { + Py_DECREF(py_list); + return NULL; + } + return py_list; +} + static PyObject *pyrf_pmu__repr(PyObject *self) { struct pyrf_pmu *ppmu =3D (void *)self; @@ -659,6 +720,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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 A43742FE39A for ; Thu, 10 Jul 2025 20:25: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=1752179121; cv=none; b=uQgiQNz5NjB18oz7DSMs/g1oais0JnHQYLhGtQcsJiakQ0J8E8C0wabR73JqbwSoiwd+J2F5oFvvuR/kJWqUG+vEXvRyFOJexDMN31K7sEpEidQhey3L40CAGFzy4GcWDQWErZEP9eNSUEcqalPrMYEdTDMGT2m4Xw7FVTJ3fVE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179121; c=relaxed/simple; bh=wU3wz0df7C5ZQeeQLCPpt5hn2poNUqfyMGtKBgXp6Co=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=Nweng3pMPG6Lh8i9gCA/f61DbHHkUbAbq3qhsRJzhwq1IjZ8AZtetd4O8s2N6V81ncayxIEqPwShuT8C3gDHwqAe5UgRlhBKT5tSZzPff89W3i3cxxFmsz/ZUB1SX//feRExo59b4T8S4siAWtc46S34LUipbnECtPkZw14C+3M= 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=xh8DW+zg; 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="xh8DW+zg" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b2fa1a84566so1105040a12.1 for ; Thu, 10 Jul 2025 13:25:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179119; x=1752783919; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=wHY0GCNF2IapelErUdXSA7miepGcy18/bQ3SNGrcpTA=; b=xh8DW+zgEYEN0nPNkORhPoWVcgvlvr7frKybNG9o+87KvW/n0Q/QSJnz79f+YE/bRU hIwWLlU9SE7ZttHqUlQ6C9EwMSMLhhBI+FMxMG1vey51APubpZgPoFU5EaP7RCU5ozVL VUC/4Ip0/KEwCJEj+a/Fys8vKvxUn3rlfe6bDdPJDPNyvnuZRM7DR625O20zM8meKEBZ 5qGPPo9tQyX42JirXKwzC04bOpPn9j5xiCsm7ZUHL1sBzjDj2FIjoyBk7qkrHbWng2B0 V87RxP2MWLo9pzCHQ3GzmqZn2HoGzkNp2Wo9NvdqdVA+js98+7mt6Z5xOHaf9gECdsGX BLfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179119; x=1752783919; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wHY0GCNF2IapelErUdXSA7miepGcy18/bQ3SNGrcpTA=; b=W+UPD00p2xSvp+9DoL1DhwJXm9qFmnONTArgmPuOcazVRmmoRVdOur6HmF8hK6pF13 sQLGyhhHhMuyAvEphNqy+gJ3gScSVV44hSv6G4Idf1mAiw4bkWUrdrNdECCzxl5/60oW SFE11DbohvhrOcP/fndNnbcPlEInyldeSnv+BMzqVoHZQQ/DZ/LgWtC+no6yfGO8XjVD Ib2WK7DDh/1Wo7XLRxn76qMaOnlQSYYyvRW4d7uVdficvCHXgMUzd/oGb87+opnUf5DW 05FtJ5rCgRG+gCPfR0AvAw/Uw84cvXqIXrxX7x7WF20tpaV+gr7D4S8bP3JPH6eyGK8f LJPQ== X-Forwarded-Encrypted: i=1; AJvYcCVgOWQkxQlSB5w3UJ69lM2Qo/b5LvI2LDmOYaauM+QwjbWhgh1o6OMqm5odiKSo160sJJSH3oAzA4auqEg=@vger.kernel.org X-Gm-Message-State: AOJu0Yzi8FpUKCVSftXhnj4NfFFIcss8ep4RBBZ2uRocxmPZasFrsVSF 4f1EODsx1URMP//oV9m0/kfCCdh07f1g/PAuJYqbsoMzZZ2Y6CUgp9RXav7bp3TIxWaLU0y5gTp 6DJefVQcfBQ== X-Google-Smtp-Source: AGHT+IH1+N2Fz8QAthrPB6jc2BNeovKwa2VMncn9mr0p+avAlqLigVNIfuBAU2Ctr6dRe6qgFA2IK+SUIvmj X-Received: from pjbpl3.prod.google.com ([2002:a17:90b:2683:b0:311:462d:cb60]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4b49:b0:313:15fe:4c13 with SMTP id 98e67ed59e1d1-31c4ccf40d2mr1127066a91.27.1752179118963; Thu, 10 Jul 2025 13:25:18 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:44 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-7-irogers@google.com> Subject: [PATCH v5 03/14] perf tp_pmu: Factor existing tracepoint logic to new file From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , James Clark , Xu Yang , "Masami Hiramatsu (Google)" , Collin Funk , Howard Chu , Weilin Wang , Andi Kleen , "Dr. David Alan Gilbert" , Thomas Richter , Tiezhu Yang , Gautam Menghani , Thomas Falcon , Chun-Tse Shao , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Start the creation of a tracepoint PMU abstraction. Tracepoint events don't follow the regular sysfs perf conventions. Eventually the new PMU abstraction will bridge the gap so tracepoint events look more like regular perf ones. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/evsel.c | 21 +---- tools/perf/util/parse-events.c | 147 ++++++++++++++------------------- tools/perf/util/tp_pmu.c | 95 +++++++++++++++++++++ tools/perf/util/tp_pmu.h | 12 +++ 5 files changed, 170 insertions(+), 106 deletions(-) create mode 100644 tools/perf/util/tp_pmu.c create mode 100644 tools/perf/util/tp_pmu.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 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..fd83164f8763 --- /dev/null +++ b/tools/perf/util/tp_pmu.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +#include "tp_pmu.h" +#include +#include +#include +#include +#include +#include + +int tp_pmu__id(const char *sys, const char *name) +{ + char *tp_dir =3D get_events_file(sys); + char path[PATH_MAX]; + int id, err; + + if (!tp_dir) + return -1; + + scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name); + put_events_file(tp_dir); + err =3D filename__read_int(path, &id); + if (err) + return err; + + return id; +} + + +int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callb= ack cb) +{ + char *evt_path; + struct io_dirent64 *evt_ent; + struct io_dir evt_dir; + int ret =3D 0; + + evt_path =3D get_events_file(sys); + if (!evt_path) + return -errno; + + io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY)= ); + if (evt_dir.dirfd < 0) { + ret =3D -errno; + put_events_file(evt_path); + return ret; + } + put_events_file(evt_path); + + while (!ret && (evt_ent =3D io_dir__readdir(&evt_dir))) { + if (!strcmp(evt_ent->d_name, ".") + || !strcmp(evt_ent->d_name, "..") + || !strcmp(evt_ent->d_name, "enable") + || !strcmp(evt_ent->d_name, "filter")) + continue; + + ret =3D cb(state, sys, evt_ent->d_name); + if (ret) + break; + } + close(evt_dir.dirfd); + return ret; +} + +int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb) +{ + struct io_dirent64 *events_ent; + struct io_dir events_dir; + int ret =3D 0; + char *events_dir_path =3D get_tracing_file("events"); + + if (!events_dir_path) + return -errno; + + io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY |= O_RDONLY)); + if (events_dir.dirfd < 0) { + ret =3D -errno; + put_events_file(events_dir_path); + return ret; + } + put_events_file(events_dir_path); + + while (!ret && (events_ent =3D io_dir__readdir(&events_dir))) { + if (!strcmp(events_ent->d_name, ".") + || !strcmp(events_ent->d_name, "..") + || !strcmp(events_ent->d_name, "enable") + || !strcmp(events_ent->d_name, "header_event") + || !strcmp(events_ent->d_name, "header_page")) + continue; + + ret =3D cb(state, events_ent->d_name); + if (ret) + break; + } + close(events_dir.dirfd); + return ret; +} diff --git a/tools/perf/util/tp_pmu.h b/tools/perf/util/tp_pmu.h new file mode 100644 index 000000000000..49537303bd73 --- /dev/null +++ b/tools/perf/util/tp_pmu.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +#ifndef __TP_PMU_H +#define __TP_PMU_H + +typedef int (*tp_sys_callback)(void *state, const char *sys_name); +typedef int (*tp_event_callback)(void *state, const char *sys_name, const = char *evt_name); + +int tp_pmu__id(const char *sys, const char *name); +int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callb= ack cb); +int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb); + +#endif /* __TP_PMU_H */ --=20 2.50.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 3B29E2FE305 for ; Thu, 10 Jul 2025 20:25:17 +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=1752179120; cv=none; b=XwB80D1v9x5BHZrRBKcmUuvACyCuk1wH/N11YRE+xESZ4Lb/oYxLI/818qDhhrDqzbuILXWHEC3R8IsqY6X3RMdHHdMxKu1yDUMl/i1aVLLXy2tdqdBnTtsxDhzZzDxhb3HUEp30Ga3VX21ZxGQI+uNHY3F/GA0wFYh4sp4/muM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179120; c=relaxed/simple; bh=OBUnSNyWg9w1qVJi5lsWp0gnwPU6CVGbBfnB2vqpaFI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=Mz+InCFSZxczOIyxBbAPtwLL4L65EPkLh8YRRXxeKcoTYaZ6NuUsQNWlPDZYGYjmSbMtMpxQhJXmm821a3ozpzrhzBaf2VaYNB4nGfgfT78nlTnyRDlhOO3G7t9FWT+9jDz7z5rVGTgRLqPtvcUKAfKttGeBMNj81tziMofDRYY= 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=eprKsvVr; 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="eprKsvVr" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b31ca4b6a8eso1010757a12.1 for ; Thu, 10 Jul 2025 13:25:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179117; x=1752783917; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=NRGNNr/giRHcF/RZj7awN1PXfLHMVDY5ladq/SDyrWA=; b=eprKsvVrk2KvTb1YVmUXKzqM2RIWTSVkYNTKkprvTvfaLFQaINyMfHAyb2rE9JFlDq Aw/7WIvBwGx70YYJJPQyu/VV+rua4ngZG/FZ1EBYAj1/MZMNbxkxPgT4j+KHZ6ulosxf NJGk4Sm1f22PD1IDO9hUTz1uzsedfAsF+jO8Hoq04mU478/K6R4h3G9xtAQnzHidnGfy KCdhx0TWahFNgINTDcKAR+fCbDtCQIvKO0GOxestj+sH31MF+xpjisJl6+SLwCWENsrz tYEIKQ4MPVgghnjHNQwfcbH8bmPXdTrTZgJK9/hu7qXh4FmE6cEtuO0lvHaX0rm7D7wh CAjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179117; x=1752783917; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NRGNNr/giRHcF/RZj7awN1PXfLHMVDY5ladq/SDyrWA=; b=XXINvcsLokLuUpOKVi0jxmCTcIrNVlsg+VcrkZPV5DG76yQ2dDnFr5qOSCdVfxvru6 ZhcEOlnNxxqWJCYeAXQysCMnWVifszD83Wt+jq780tsoXaZvb0tQYDSf/nzBwuKlQX0A Mb9ckM9EpN/2FrXz4LArqW3u1LKpOS1LKms+q33zXcZ5zjtXGaB1RK5Rw9ISdKYy4MTK CB/eOkW3Q8qWUQPzjT5n0vDzwSKTbJovCrSnWgEm8lhBPxn9gyD8Pri+vu0mllQvYQsf lfGmaT3QPs+Y7RLZVHZQ9LnPCts2vknUAkUm7oRivwjJC26FB9qCo0JgC++sIm7W51Ar wmFg== X-Forwarded-Encrypted: i=1; AJvYcCUbXsvdKHeI6lMGE/WFdsXKXnRrYhspWjGUJ23xj5RxthNYdiGjL1rIXbhXCT1JjY1S6bQZynA0bHWWKIw=@vger.kernel.org X-Gm-Message-State: AOJu0YycUckFG73FagQPWYeEWXIyEKLX2JmWOtm3s28Ig/sofTl8WIIv vZ6UqmKP6iojDVeKgZBGjOT/avMqCIVMV7myochqIbM3kWBZ9l+DH5DisQFe3Jk8PazqfSF0CUx DOdQtxMJiKw== X-Google-Smtp-Source: AGHT+IFTB+Mw655D5/YXaTte7/g08GUxiYaQnn7irFLXO4KM4Mzv5srO89Qsr6IjLluQuOnezniuM763mJzB X-Received: from pjbnd12.prod.google.com ([2002:a17:90b:4ccc:b0:311:c20d:676d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:17d1:b0:311:b5ac:6f6b with SMTP id 98e67ed59e1d1-31c4ccbbec2mr1185914a91.9.1752179116734; Thu, 10 Jul 2025 13:25:16 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:43 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-6-irogers@google.com> Subject: [PATCH v5 03/14] 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 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 --- .../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..3af2f565a601 --- /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": "Task based 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..7d179d703ab1 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\000Task based high-resolution ti= mer based event\000config=3D1\000\00000\000\000\000\000\000" +/* offset=3D169 */ "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=3D264 */ "page-faults\000software\000Number of page faults [This= event is an alias of faults]\000config=3D2\000\00000\000\000\000\000\000" +/* offset=3D359 */ "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=3D460 */ "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=3D561 */ "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=3D693 */ "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=3D825 */ "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=3D934 */ "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=3D1037 */ "alignment-faults\000software\000Number of kernel hand= led memory alignment faults\000config=3D7\000\00000\000\000\000\000\000" +/* offset=3D1129 */ "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=3D1256 */ "dummy\000software\000A placeholder event that doesn't= count anything\000config=3D9\000\00000\000\000\000\000\000" +/* offset=3D1336 */ "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=3D1438 */ "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=3D1541 */ "tool\000" +/* offset=3D1546 */ "duration_time\000tool\000Wall clock interval time in = nanoseconds\000config=3D1\000\00000\000\000\000\000\000" +/* offset=3D1622 */ "user_time\000tool\000User (non-kernel) time in nanose= conds\000config=3D2\000\00000\000\000\000\000\000" +/* offset=3D1692 */ "system_time\000tool\000System/kernel time in nanoseco= nds\000config=3D3\000\00000\000\000\000\000\000" +/* offset=3D1760 */ "has_pmem\000tool\0001 if persistent memory installed = otherwise 0\000config=3D4\000\00000\000\000\000\000\000" +/* offset=3D1836 */ "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=3D1981 */ "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=3D2084 */ "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=3D2201 */ "num_dies\000tool\000Number of dies. Each die has 1 or= more cores\000config=3D8\000\00000\000\000\000\000\000" +/* offset=3D2277 */ "num_packages\000tool\000Number of packages. Each pack= age has 1 or more die\000config=3D9\000\00000\000\000\000\000\000" +/* offset=3D2363 */ "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=3D2473 */ "smt_on\000tool\0001 if simultaneous multithreading (a= ka hyperthreading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\= 000\000\000" +/* offset=3D2580 */ "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=3D2679 */ "default_core\000" +/* offset=3D2692 */ "bp_l1_btb_correct\000branch\000L1 BTB Correction\000e= vent=3D0x8a\000\00000\000\000\000\000\000" +/* offset=3D2754 */ "bp_l2_btb_correct\000branch\000L2 BTB Correction\000e= vent=3D0x8b\000\00000\000\000\000\000\000" +/* offset=3D2816 */ "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=3D2914 */ "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=3D3016 */ "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=3D3149 */ "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=3D3267 */ "hisi_sccl,ddrc\000" +/* offset=3D3282 */ "uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write co= mmands\000event=3D2\000\00000\000\000\000\000\000" +/* offset=3D3352 */ "uncore_cbox\000" +/* offset=3D3364 */ "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=3D3518 */ "event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0= xe0\000\00000\000\000\000\000\000" +/* offset=3D3572 */ "event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event= =3D0xc0\000\00000\000\000\000\000\000" +/* offset=3D3630 */ "hisi_sccl,l3c\000" +/* offset=3D3644 */ "uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read = hits\000event=3D7\000\00000\000\000\000\000\000" +/* offset=3D3712 */ "uncore_imc_free_running\000" +/* offset=3D3736 */ "uncore_imc_free_running.cache_miss\000uncore\000Total= cache misses\000event=3D0x12\000\00000\000\000\000\000\000" +/* offset=3D3816 */ "uncore_imc\000" +/* offset=3D3827 */ "uncore_imc.cache_hits\000uncore\000Total cache hits\0= 00event=3D0x34\000\00000\000\000\000\000\000" +/* offset=3D3892 */ "uncore_sys_ddr_pmu\000" +/* offset=3D3911 */ "sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycle= s event\000event=3D0x2b\000v8\00000\000\000\000\000\000" +/* offset=3D3987 */ "uncore_sys_ccn_pmu\000" +/* offset=3D4006 */ "sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles = event\000config=3D0x2c\0000x01\00000\000\000\000\000\000" +/* offset=3D4083 */ "uncore_sys_cmn_pmu\000" +/* offset=3D4102 */ "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=3D4245 */ "CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000" +/* offset=3D4267 */ "IPC\000group1\000inst_retired.any / cpu_clk_unhalted.= thread\000\000\000\000\000\000\000\00000" +/* offset=3D4330 */ "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=3D4496 */ "dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_re= tired.any\000\000\000\000\000\000\000\00000" +/* offset=3D4560 */ "icache_miss_cycles\000\000l1i\\-loads\\-misses / inst= _retired.any\000\000\000\000\000\000\000\00000" +/* offset=3D4627 */ "cache_miss_cycles\000group1\000dcache_miss_cpi + icac= he_miss_cycles\000\000\000\000\000\000\000\00000" +/* offset=3D4698 */ "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=3D4792 */ "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=3D4926 */ "DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_A= ll_Miss\000\000\000\000\000\000\000\00000" +/* offset=3D4990 */ "DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCa= che_L2_All)\000\000\000\000\000\000\000\00000" +/* offset=3D5058 */ "DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, D= Cache_L2_All)\000\000\000\000\000\000\000\00000" +/* offset=3D5128 */ "M1\000\000ipc + M2\000\000\000\000\000\000\000\00000" +/* offset=3D5150 */ "M2\000\000ipc + M1\000\000\000\000\000\000\000\00000" +/* offset=3D5172 */ "M3\000\0001 / M3\000\000\000\000\000\000\000\00000" +/* offset=3D5192 */ "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 { +{ 1037 }, /* alignment-faults\000software\000Number of kernel handled memo= ry alignment faults\000config=3D7\000\00000\000\000\000\000\000 */ +{ 1336 }, /* 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 */ +{ 1438 }, /* cgroup-switches\000software\000Number of context switches to = a task in a different cgroup\000config=3D0xb\000\00000\000\000\000\000\000 = */ +{ 359 }, /* 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 */ +{ 561 }, /* 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 */ +{ 460 }, /* cs\000software\000Number of context switches [This event is an= alias of context-switches]\000config=3D3\000\00000\000\000\000\000\000 */ +{ 1256 }, /* dummy\000software\000A placeholder event that doesn't count a= nything\000config=3D9\000\00000\000\000\000\000\000 */ +{ 1129 }, /* emulation-faults\000software\000Number of kernel handled unim= plemented instruction faults handled through emulation\000config=3D8\000\00= 000\000\000\000\000\000 */ +{ 169 }, /* faults\000software\000Number of page faults [This event is an = alias of page-faults]\000config=3D2\000\00000\000\000\000\000\000 */ +{ 934 }, /* major-faults\000software\000Number of major page faults. Major= faults require I/O to handle\000config=3D6\000\00000\000\000\000\000\000 */ +{ 693 }, /* 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 */ +{ 825 }, /* 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 */ +{ 264 }, /* 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\000Task based high-resolution timer base= d 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 */ +{ 1546 }, /* duration_time\000tool\000Wall clock interval time in nanoseco= nds\000config=3D1\000\00000\000\000\000\000\000 */ +{ 1760 }, /* has_pmem\000tool\0001 if persistent memory installed otherwis= e 0\000config=3D4\000\00000\000\000\000\000\000 */ +{ 1836 }, /* 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 */ +{ 1981 }, /* 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 = */ +{ 2084 }, /* 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 */ +{ 2201 }, /* num_dies\000tool\000Number of dies. Each die has 1 or more co= res\000config=3D8\000\00000\000\000\000\000\000 */ +{ 2277 }, /* num_packages\000tool\000Number of packages. Each package has = 1 or more die\000config=3D9\000\00000\000\000\000\000\000 */ +{ 2363 }, /* 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 */ +{ 2473 }, /* smt_on\000tool\0001 if simultaneous multithreading (aka hyper= threading) is enable otherwise 0\000config=3D0xb\000\00000\000\000\000\000\= 000 */ +{ 1692 }, /* system_time\000tool\000System/kernel time in nanoseconds\000c= onfig=3D3\000\00000\000\000\000\000\000 */ +{ 2580 }, /* system_tsc_freq\000tool\000The amount a Time Stamp Counter (T= SC) increases per second\000config=3D0xc\000\00000\000\000\000\000\000 */ +{ 1622 }, /* 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 { 1541 /* 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 */ +{ 2692 }, /* bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=3D0= x8a\000\00000\000\000\000\000\000 */ +{ 2754 }, /* bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=3D0= x8b\000\00000\000\000\000\000\000 */ +{ 3016 }, /* 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 */ +{ 3149 }, /* eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) = Technology (EIST) transitions\000event=3D0x3a,period=3D200000\000\00000\000= \000\000\000\000 */ +{ 2816 }, /* l3_cache_rd\000cache\000L3 cache access, read\000event=3D0x40= \000\00000\000\000\000\000Attributable Level 3 cache access, read\000 */ +{ 2914 }, /* 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 */ +{ 3282 }, /* 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 */ +{ 3644 }, /* 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 */ +{ 3518 }, /* event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=3D0xe0\000\= 00000\000\000\000\000\000 */ +{ 3572 }, /* event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=3D0xc0\= 000\00000\000\000\000\000\000 */ +{ 3364 }, /* 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 */ +{ 3827 }, /* 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 */ +{ 3736 }, /* 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 { 2679 /* 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 { 3267 /* 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 { 3630 /* 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 { 3352 /* 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 { 3816 /* 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 { 3712 /* 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 */ +{ 4245 }, /* CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000 */ +{ 4926 }, /* DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\= 000\000\000\000\000\000\000\00000 */ +{ 4698 }, /* 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 */ +{ 4792 }, /* 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 */ +{ 4990 }, /* DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_A= ll)\000\000\000\000\000\000\000\00000 */ +{ 5058 }, /* DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2= _All)\000\000\000\000\000\000\000\00000 */ +{ 4330 }, /* 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 */ +{ 4267 }, /* IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\0= 00\000\000\000\000\000\000\00000 */ +{ 5192 }, /* L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duratio= n_time\000\000\000\000\000\000\000\00000 */ +{ 5128 }, /* M1\000\000ipc + M2\000\000\000\000\000\000\000\00000 */ +{ 5150 }, /* M2\000\000ipc + M1\000\000\000\000\000\000\000\00000 */ +{ 5172 }, /* M3\000\0001 / M3\000\000\000\000\000\000\000\00000 */ +{ 4627 }, /* cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_= cycles\000\000\000\000\000\000\000\00000 */ +{ 4496 }, /* dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.an= y\000\000\000\000\000\000\000\00000 */ +{ 4560 }, /* 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 { 2679 /* 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 */ +{ 4006 }, /* 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 */ +{ 4102 }, /* 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 */ +{ 3911 }, /* 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 { 3987 /* 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 { 4083 /* 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 { 3892 /* 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=3D0; 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..76c1e7b0bc22 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=3D0; 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 D86082FEE2D for ; Thu, 10 Jul 2025 20:25:23 +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=1752179125; cv=none; b=IuZCKHYKMOhgwmVYE8SfviSGvx4v+HuMG/Br035xt7qRawwL0XwhcFzA5gisZlIf24YnuULijFfgXyfFExirNjZM9eNBmxLOBaLIJknix8PfkTeOWal+g9Tho1Vi5azVI8J7YaZuEr21o4N27mtzpUDEeXfCiZdoM+6L3olPXzo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179125; c=relaxed/simple; bh=RZ/4wZ7BLS3RqD09YBHOjY7W3qZV5Jmx+MPGWahCs1s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=j/2TPbeCysMlSgH/y9n5/Q5ktKYEGLChm1HszSkWl1C0WhyBBgTCaEH4QeVDP4nLnpIH6OYpqe2NiFPM2PZMtuNbVwqtRBLKQFhv0fKMdjKgKCNHRFXdEbuMUPnxiF0O4Tin6CXCvNJ1sxm5548ApBkoSBsG1fpj7KACuh5IUFc= 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=GcTzggQ0; 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="GcTzggQ0" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2356ce55d33so20416995ad.0 for ; Thu, 10 Jul 2025 13:25:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179123; x=1752783923; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=O5/KtDdH9KZtizmnT+G+DMzo0YjRxsCsauFrBz7enXg=; b=GcTzggQ0faPfxZxG5oTO5sH8MQSiL1jSsUQ3BeCi4CG/fGdanT+Dv3loYPXpvrgMCY oXNf+upGID5XiLe1Hg91HRJAf4vSCzHUYBPdM9dGDZMKo9XcSamqdKWp5FPp7gReRpdD ZzWNMRY8oap4Rje7S5jH+gRXl3bK9mlWMNAjPivCGgYzKHtnKIiIainZ3cPUMl/Z7efK V5ZhTAx9X2VBxRfd20RpZCj9cZ2CA86yX/n0fGBlEHAQxi6jpYsr2nNjjbRsFuRYXE0j WrJ/JgQGkcm2rLhpqdWtMUxqD1DX+0RSmCo1wwJ0FZD+52335Id7ArJOFIjieyfDfqA3 QL3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179123; x=1752783923; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=O5/KtDdH9KZtizmnT+G+DMzo0YjRxsCsauFrBz7enXg=; b=XRYPojA0mg/pTKcR7tkSvZJfBK8NwnC/uU5E+X+OyvMtjzxXdh1Hq+D9QiH2lXXzyw 3iN0Y2yQPaY9FOG+XkX44ZDMseNv9K8JOQBqyeD3a4m6truv3QZD4B1TbJLNTmuf5lDh dvEF2ZkZXJv4bRXQ5yKlf2/tUO1QKgcOg0U5W5tAdd6Q36rwCJR3zWJgqe0CZGZz+Hh9 X3kC1ukX32lcSTvKpwUTkkeTy18jHRGbnfehd210EkJWzCwVzZ9/djgS38E9B7R+Yb8M d6HNer9hB3eEqZuVJoH5dh89Lu4+r08c+MjCzRmaVICnzF7R0L7lOAkwzge+sKfzTTm3 anMQ== X-Forwarded-Encrypted: i=1; AJvYcCXU4iSisgRyJ92HUmwaJIPqnN5qglx9pEty1Ut6ZtK822BxReFhGE+oz76XjvOJCab75jOzq0Q5pPZc5c4=@vger.kernel.org X-Gm-Message-State: AOJu0Yx6fI6DbhP/Tq1fzbACTNd4X4ukU+WPn9th1GMMpK35kEGks6cy jZ5EdHCS/BJjCiLidkXcaMT8vhLpGeCY35oqs7b+sCF0PRal6rhq0R7+hUgZg92c81y/5DLu3el A5ieZzoUASA== X-Google-Smtp-Source: AGHT+IHaGeLOfBryMahOJzggF1DCw2HHiX14ouqhiqra3X86Gdz2fJYf6KlkbMisD9vqw5fj1CKc1+r0GrsO X-Received: from plbkf11.prod.google.com ([2002:a17:903:5cb:b0:234:4c97:1e84]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1247:b0:236:8db5:7e50 with SMTP id d9443c01a7336-23dede2d0e8mr7155075ad.9.1752179123264; Thu, 10 Jul 2025 13:25:23 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:46 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-9-irogers@google.com> Subject: [PATCH v5 04/14] 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 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 --- tools/perf/util/pmu.c | 7 +++ tools/perf/util/tp_pmu.c | 114 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/tp_pmu.h | 7 +++ 3 files changed, 128 insertions(+) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index b09b2ea2407a..dc05233e8232 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 fd83164f8763..9d68a1da17f6 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,116 @@ 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; + + if (strchr(name, ':') =3D=3D NULL) + return false; + + dup_name =3D strdup(name); + if (!dup_name) + return false; + + colon =3D strchr(dup_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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 922662FEE16 for ; Thu, 10 Jul 2025 20:25:21 +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=1752179123; cv=none; b=poaBOBmejZUYTnn0gjK32/KZ8ZontyPJGjYz4M973YEWZlDm0TQRvYPzR8dB4VYjqIIzALgxPO91bLkidLIxC1Y3tg2nDSKxajz7KScuJ/2k8Q2I0LMS0d2xRwUGNAJFQzBy0GA/w6cUx7NOszi6vfjq5Ma3bOFlD7RiYRC7yK8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179123; c=relaxed/simple; bh=hQokINY7w1ShrrgZa7yZzzTcBe2DFkxckj5lH340Cec=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=Cotev8ggaL6b3vlRuk3ZgRo+2heP7kYBrSs9OQcDx7LKzF5vGHaua2/oXkd/6s8xx6cfnJBshXH0Vh/OaTA2FlFWxg69Q+1qFBi8J4EqsaX82eRSldG5Mlk2x9V1rpI8y2kiAgnNcBPqJEP9q2EopiGgRd4viWTIQUAQgdE6sLo= 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=FoWnq0Sr; 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="FoWnq0Sr" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-74ea7007866so1216971b3a.2 for ; Thu, 10 Jul 2025 13:25:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179121; x=1752783921; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=rlDQWnF9PwaPlaf+aejcqkoEmXJ/40GLuFVvGJ4bgdI=; b=FoWnq0SrdvLvNcjILzWQj8yT7oQ8drjNaxYxw3EOrldHJSbZJLh3lCESvW4pMjQwTF nyIWjSCdoS0aMyUOnm66DklEWhUS9tjp/0Temzor/9GNXArKr+0C87msuiw6AMqDFRmS RNZZ23O8ySCivYRc79UlMDpq1mtwOtIbGPKpQTVqKA9y0MtOPU12BeVpt/DVNx/HdPKy iJlk0Yr+xQRilAsKelIlVUw7d+uGCZHHRIZd+AWFVuZ/lKE3CkX2HhGmO7SeFwJGeQem 71CmBAibV0Y1FCcCQtBQigsUSx0FJJ+0pK0Kg5Lh0RHxI6DCTv/vG2QSdofmsFaCYLMI 22eQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179121; x=1752783921; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rlDQWnF9PwaPlaf+aejcqkoEmXJ/40GLuFVvGJ4bgdI=; b=St7i7noyjGXK5kIccInqMmh5Ix1wsEGMvUoyr7wRibscOTBBt2WH1ILF/otI2D2mF8 aVziFW+Ddt4jnIO3KdJ26gGL7ZR0BMQaQl2nnspLWBVRyIvMnqJOqJ4lQC75Rml4QcRu iTOzlva67yyp0q5ysrl6PW7gUNhiATs8G5tDGn4GsyZz+gIT2tkJWmOiSDZo/F5YmRHb S5hQer2zmHFqjzmjETemvEHJPDfu4QWlYwnJmomcoeQL/Qsg6vgmzFLqmtshb4E0nlsJ DHM7RYeYDKgOkE6d9jTRYGl8AgKoAfH+IRQy6De0KXu6kRSfnXWNUEsTsihazw1bf9S+ +gWg== X-Forwarded-Encrypted: i=1; AJvYcCUw68XG659k7H1xDLy18w+/fLIMw3oeksl9eAqrGky360X0S6rSGfjw+aU2QNbRH6A7crlnRmu3xjGhfCs=@vger.kernel.org X-Gm-Message-State: AOJu0YykaPbVJWh396YsYrtw2axxLmySTkXS0fOjhqwMUvNY0ToMP4p7 mqYkZG5Af0jZxRs9FJGqCeYPNdOCY3f1qNE8W8ISEcsl6EqeyaONKxvSWppPKEqcek3NK1eyp0C jSh4Ioz1jBA== X-Google-Smtp-Source: AGHT+IHMNy4Q31LboP85gsIwJrQxvGvECYOb108Sx40mXXMNclwZHgSsymAeOz/+xa2Eq1FVzyYYakfN0g7O X-Received: from pge13.prod.google.com ([2002:a05:6a02:2d0d:b0:b2f:64d0:993e]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:104:b0:230:e29c:5752 with SMTP id adf61e73a8af0-23136e6e1f6mr716269637.30.1752179121054; Thu, 10 Jul 2025 13:25:21 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:45 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-8-irogers@google.com> Subject: [PATCH v5 04/14] 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 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 --- 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 24CA12FD896 for ; Thu, 10 Jul 2025 20:25:26 +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=1752179128; cv=none; b=RYwmZTBQAE3XWG2FU07wPOz1cf3WDFrRQ1EeVD9Ds7L8IFdevmWMN5eZNQYoFA8pqO9MexVK7Cd1t3sTZyLxQiIrFfnpNluBZwqPgXcYNCrWAkDv/JIrk6mu6YerjS4CWOyDO0IiL02YHexUOtzhQZCZm/2oQ1hCLfPDOdVLGEQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179128; c=relaxed/simple; bh=Le7QYk5ewKhVR0KfjzP7e5zYRhwCNT3h9zVSLbbTSyE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=hGan6PXCfVidWJELfhP2PzH5QfT5konquMiaXphCVuHBUyl47vNzGfHi4+Ktm5BGZvC+UIfR1tYnDPmcrLO/CleCeA4PZuhcZX8fcQj9jHBH2TocvpNBjRg19fFUNsjCKzljxXG/P6e7o4JpoPDvsifFAqBMxsCuPv39el/TSQM= 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=Sk1KbLvz; 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="Sk1KbLvz" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-313f702d37fso1501717a91.3 for ; Thu, 10 Jul 2025 13:25:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179125; x=1752783925; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=uF/yydA2LLHLkSIXR9wu8iMwdqKiKLaNFSdET/2T+tA=; b=Sk1KbLvzg+RAGZ1fFP7P77EMaL4oA7pOmsCqeml1DLTstLtfNBF7GsCMeJiWmI+vxO yeM4VKXGODgGybSShjSW/Jfb9NuzYhh6Fmsivap+FxfjCDM041j/muzydLyH2FbM5Dci JNDP6QlO4e3Qvf42PywSqebEVeW9WCSRPTVXHWC+O96aDOlB/BZWmR8Hxzsi1Mmr9eXt a+UDLrpHmU+rxkgq2Y0nFJaeEYf3cPQJ7+MN0coTge2hzoFZmYoJXcMeYZpZv43FQoxi HnPWu8zkSY1b1nGCCMxp1tb+6TluNqxlpwtpLpkk1CaSVTyokM7EnukHtI8d3WcWC98G UOtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179125; x=1752783925; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=uF/yydA2LLHLkSIXR9wu8iMwdqKiKLaNFSdET/2T+tA=; b=ckdYm3ZuYhimny4xf3sFGTbWLxO/JTsQD/wrXzmXS1zrAmOLhfUhVw58TU6vNfXb9d BjO+bcCRBqeSDdZ2aYpggzfr115X9FSBnIc6vTWk2nf+lIdpqcLsva8NFNLxm2zxBlVU G7kZACOLUerj7/uRcNEiDUd5CutotpDb2Yz660HIO/v8ok6S0ZWYuOHElvwe22FPDYrl yH+T6xjSct7EkuVDR2Y15cgTuknno+rt/4NO6xEht+offE1xy7tj7Fbu3IwuB8z4HQi1 KCjwg24nEPi+0RdPRwwH4o8QrB5Qmp4UJ0xrs/n3ra7fLDlekYuUd67dR4oN7dl9lpXQ Q35g== X-Forwarded-Encrypted: i=1; AJvYcCWyx6V7VxhEU9L9dJiJzr48wN7L4zpr4ZUCGUNRJqynMRLJjy0vNboghoU6AQxIITTpJQxWbJuWUPpbBZY=@vger.kernel.org X-Gm-Message-State: AOJu0YxGfoKUhtvssby8rQ8abDazDDOqmmnegC7PaeLc9qsknolckN+N i9d+6YtS43xq0a9htDVhaR1wv07sxWTOIp7HKNVVxPuUQm/w4axrtpLWrYydd/g1yjJGIkrlobW YSagA6efsBg== X-Google-Smtp-Source: AGHT+IFJ8yApjcqN7/YeHi9YiY641kBixEgXYptH5zLcYkpDEZhMi54pBKqOxXm7L1CZTb0KhSUcq0uJ3beh X-Received: from pjbsh12.prod.google.com ([2002:a17:90b:524c:b0:311:eb65:e269]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:554f:b0:311:e305:4e97 with SMTP id 98e67ed59e1d1-31c4f512c31mr25508a91.19.1752179125360; Thu, 10 Jul 2025 13:25:25 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:47 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-10-irogers@google.com> Subject: [PATCH v5 05/14] 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 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 --- 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 2025 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 56C19301130 for ; Thu, 10 Jul 2025 20:25:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179130; cv=none; b=OAhU7ksAvGnYVT8Gt+SQoW7riFXkRPnOfMBa4yNPYTe89x1lysSdJiU/hF+hGg1Yuu19igFPPUbmNXWPriw+AK4YV/eF8VAOXvL/z3QZygG4yjD6bIyLDUiMOw+f3SzY4Io7VtYzj7+1etRh3e89b4djChwArLMmHe2YeUcr2p8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179130; c=relaxed/simple; bh=wU3wz0df7C5ZQeeQLCPpt5hn2poNUqfyMGtKBgXp6Co=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=Xdq+rTZkRGowgpLupfZu/Y0rrLikmQre6JG5fgymgqApb87zMSYMHLbheDai7Ts//o8nhRxETpkpw2N0DA7WKriAW7CQhD+q0xvf+8NQWQb6yvWlFdy0OPJKwS0O3JEYLaVG4D3tXryTmLbBWbvEGntrfaSbqfGeE60YwO/vTIg= 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=FszkQUxd; arc=none smtp.client-ip=209.85.128.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="FszkQUxd" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-714052e5103so19573517b3.3 for ; Thu, 10 Jul 2025 13:25:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179127; x=1752783927; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=wHY0GCNF2IapelErUdXSA7miepGcy18/bQ3SNGrcpTA=; b=FszkQUxdMpK5G85NwRTJUrZBMiscHQHHIr5RwHWGLn8XV1xqatdHAm/thaOo4nK3Cd U4+rbULW1JgYuMKhePH0t1iqekXv95IEoSiwhqW9V7Djnl0W52ocEMEfIU5Oo/kwaB3M A1ublUI4zXbfH8LZPEZV/rxqOub7szNZJgYg2mkeEXivTubtRcb8UDzJfZ4zcpfGoIOm qD3yQbC5KrCAv+MhFAW5u4ul7RfKDyQoyXaIb/ku/50XJDO3eLe/LN8EhwWyYmM0OmgK MV8zMWuUJOnLt20Cj3rhfAdEHVhujGoVXqFutUklwY8b0AFWJV0q0LjcIxi+1o+GuG8E NYLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179127; x=1752783927; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wHY0GCNF2IapelErUdXSA7miepGcy18/bQ3SNGrcpTA=; b=YTDouDOx/61pEL13CU0PGZfzLPQPnMUCb+1bHdqY1k87gG0/P3vYxBkgn9RwtoH4hv JiuJiKIZFr2JHW1JS2IXEcLO8BjlbTVhtbuT9egtsfoiUkESjXGBqETVXms7bbxmdaL/ TiZTzfSu4cLliSIMk0j/M2BQx1CsiZ5x9sgxYJ753JiS6XaEBgewyK8cmhod602lprtS fquWRHjsAnwdjHLyvhWdUydNt6HcsBEUU15/RGggcMgm2MWCJ7ZWeq2RGKRIVNe1Wgz1 4yVZ+6UBCTFDRF6a1PWUPJ6UPpwyjpmBlOYjsgnm4CZ6RzG1HWnNJR9ZXxIapzYZJhmS 6o+A== X-Forwarded-Encrypted: i=1; AJvYcCUsfSfaaqfNRKfxkyEHaWGb3KGPwaACMi3bHdnsq9OUCozHmuZUPqMcndLPLEtVGpH4MzKarE3tfNWC14I=@vger.kernel.org X-Gm-Message-State: AOJu0YxNcIQnQct/vF1Coxnx8O2J39ORLwjiG0eNpq/uXu1Q3NxC8k2M +x9DP8ngnCLrQ+aINXe/h39E2NnpnBlhtMWaWlKAhHTj4ppBaHBgkbXNj96uRttQclkcIC4wnGk M3sgLfLUpmw== X-Google-Smtp-Source: AGHT+IGb2BJac+5qg4XikqMA8FuZCTlrFU1BJFSjgWOTzYqT0etTmCdIYJcZMy8MTkjUQCGNQrootFw9KlBx X-Received: from ywbif1.prod.google.com ([2002:a05:690c:6901:b0:70e:7555:a3b0]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:690c:6ac9:b0:70e:18c0:dabd with SMTP id 00721157ae682-717d592a597mr18290397b3.0.1752179127352; Thu, 10 Jul 2025 13:25:27 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:48 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-11-irogers@google.com> Subject: [PATCH v5 05/14] perf tp_pmu: Factor existing tracepoint logic to new file From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , James Clark , Xu Yang , "Masami Hiramatsu (Google)" , Collin Funk , Howard Chu , Weilin Wang , Andi Kleen , "Dr. David Alan Gilbert" , Thomas Richter , Tiezhu Yang , Gautam Menghani , Thomas Falcon , Chun-Tse Shao , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Start the creation of a tracepoint PMU abstraction. Tracepoint events don't follow the regular sysfs perf conventions. Eventually the new PMU abstraction will bridge the gap so tracepoint events look more like regular perf ones. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/evsel.c | 21 +---- tools/perf/util/parse-events.c | 147 ++++++++++++++------------------- tools/perf/util/tp_pmu.c | 95 +++++++++++++++++++++ tools/perf/util/tp_pmu.h | 12 +++ 5 files changed, 170 insertions(+), 106 deletions(-) create mode 100644 tools/perf/util/tp_pmu.c create mode 100644 tools/perf/util/tp_pmu.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 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..fd83164f8763 --- /dev/null +++ b/tools/perf/util/tp_pmu.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +#include "tp_pmu.h" +#include +#include +#include +#include +#include +#include + +int tp_pmu__id(const char *sys, const char *name) +{ + char *tp_dir =3D get_events_file(sys); + char path[PATH_MAX]; + int id, err; + + if (!tp_dir) + return -1; + + scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name); + put_events_file(tp_dir); + err =3D filename__read_int(path, &id); + if (err) + return err; + + return id; +} + + +int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callb= ack cb) +{ + char *evt_path; + struct io_dirent64 *evt_ent; + struct io_dir evt_dir; + int ret =3D 0; + + evt_path =3D get_events_file(sys); + if (!evt_path) + return -errno; + + io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY)= ); + if (evt_dir.dirfd < 0) { + ret =3D -errno; + put_events_file(evt_path); + return ret; + } + put_events_file(evt_path); + + while (!ret && (evt_ent =3D io_dir__readdir(&evt_dir))) { + if (!strcmp(evt_ent->d_name, ".") + || !strcmp(evt_ent->d_name, "..") + || !strcmp(evt_ent->d_name, "enable") + || !strcmp(evt_ent->d_name, "filter")) + continue; + + ret =3D cb(state, sys, evt_ent->d_name); + if (ret) + break; + } + close(evt_dir.dirfd); + return ret; +} + +int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb) +{ + struct io_dirent64 *events_ent; + struct io_dir events_dir; + int ret =3D 0; + char *events_dir_path =3D get_tracing_file("events"); + + if (!events_dir_path) + return -errno; + + io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY |= O_RDONLY)); + if (events_dir.dirfd < 0) { + ret =3D -errno; + put_events_file(events_dir_path); + return ret; + } + put_events_file(events_dir_path); + + while (!ret && (events_ent =3D io_dir__readdir(&events_dir))) { + if (!strcmp(events_ent->d_name, ".") + || !strcmp(events_ent->d_name, "..") + || !strcmp(events_ent->d_name, "enable") + || !strcmp(events_ent->d_name, "header_event") + || !strcmp(events_ent->d_name, "header_page")) + continue; + + ret =3D cb(state, events_ent->d_name); + if (ret) + break; + } + close(events_dir.dirfd); + return ret; +} diff --git a/tools/perf/util/tp_pmu.h b/tools/perf/util/tp_pmu.h new file mode 100644 index 000000000000..49537303bd73 --- /dev/null +++ b/tools/perf/util/tp_pmu.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +#ifndef __TP_PMU_H +#define __TP_PMU_H + +typedef int (*tp_sys_callback)(void *state, const char *sys_name); +typedef int (*tp_event_callback)(void *state, const char *sys_name, const = char *evt_name); + +int tp_pmu__id(const char *sys, const char *name); +int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callb= ack cb); +int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb); + +#endif /* __TP_PMU_H */ --=20 2.50.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 2025 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 676C3302042 for ; Thu, 10 Jul 2025 20:25:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179132; cv=none; b=HRqfnomidJFjP8lIryqDmQChTSQeo2EbmhIAtjg+KjtXcr0e7JWL9y+BAZdByWVbkhiG002Mg7pFQhSbmcemLqF9+oVqiIKhZa+4l2rSM/GaVddij+Vx0FjpSXaB259wYKrZXfunBGRKNFh1WUglcn6t4hANkgjonE1P9MK2ErI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179132; c=relaxed/simple; bh=QBQ6rMMGrCCqcqpv0nGcMrSiGZpXq85vCuSs2bWMZ9U=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=UmD6lJ20pe7RJYa0PB6GAcbXNrZ2LkwRPxYT55YtstDLruxj3KEIh+neOEgTvEcQVXrRDPsUcGom8DVJUEkVypCnNNw/linauUCTC8c//IXhGWl6ROp4xJyGG55rVAshheUVi9a+Vc9ihfQxaDz6YgHGTBUBaxgdQkX4xNYugCg= 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=bwkzkSvm; arc=none smtp.client-ip=209.85.128.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="bwkzkSvm" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-70e5e6ab756so21576147b3.2 for ; Thu, 10 Jul 2025 13:25:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179129; x=1752783929; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=EP30FVHzqvLXJ2GVgWwMYde05oJPsW/Vmscvz9g3I8Q=; b=bwkzkSvmjkkV77hafhZoC7tVH/JZ1jcCF7DN0Cwg1aCEePZoQOzX8fY3id+2IzmH5+ yx5JahU8ZRhH8mqhkP/sNBJLGlCrc5Rp7n/ZzoRXtEWbXL0q1/sNWD8nCZeFZJXWq41C N1nnLIyTVCexID8cdgIr5GbrEYFvob8bJ1dUgOZTNH7I3SvpYvrVgyOCcLfJALyJmuFB 6jnwoWjhmUr3rF7X8+QYFRiGjUZ83mmruxo5lJ+OfDARNKw6JLRjKrxHyfd7RNiDin0l AAz9EbwWVAJg3SGMV+p44Fq3j/8Ggf7Fa/1yaVxpdFgGHRjoAk8ynT0QYZDZRsdAi1fI rQsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179129; x=1752783929; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EP30FVHzqvLXJ2GVgWwMYde05oJPsW/Vmscvz9g3I8Q=; b=pjVF3nzrKO3vgf/JBKhpIzrKIZzD39hpOAmVC0sDbYlDn7mxHfKseCgJt8sX3KRHpv EIwIPEGJ/gwpHNNqzSLkg6FCFTTNTxyJqzgn/i8ZnJnKt8p2ud2SUzNm8rJlaA2dH/th 0kXiLMrQlnxyC99fYjbrVFbcqCp6QCa2zkZgIG4qaFZy74rMkw9zR/qRa2cNy4sbfvD1 WrvC9OGOVgaK0faZxfkkYN8IVKdxpIMAmp0CuDh3qj52lAos23f8ZQc2J5I/8vWJOn98 RrTDo1SCuVEu7btCfVvi9Q6MunTqLVlTECp9CCXjcADHliJpsRcIw1sRgYtZOtPabBZa n19A== X-Forwarded-Encrypted: i=1; AJvYcCX7whvjJzA0dhnvFQ91a4N4rbtPVzXzsLDoA0NzaQjspoxKAUiHQhK6TfvoyoczZfEyDvEUoWw0VLFm6ew=@vger.kernel.org X-Gm-Message-State: AOJu0YwIYW8u9BG2gV0NC+SFVCdsAJUMaORum6qdcQlWRz71WrzHaq0C 7i9oe9iGF9ifDd6v9WeVHhDAYqFuFfG5aA99zdFK5N4orlTEmIC/UvOboqQJyYxutLoRNfzkxJa V6fPUfgP7Iw== X-Google-Smtp-Source: AGHT+IGyWXApOWFFD+BaJZCZ3c34cfQFe2HNL9LUvFQjVQmBoq/zqmmdE2XiTyrxAqEzCnnsNUxwJElA5PFP X-Received: from ybck5.prod.google.com ([2002:a25:6f05:0:b0:e87:b3ed:db62]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:690c:6e06:b0:70c:90af:154 with SMTP id 00721157ae682-717d5dac9d1mr19242217b3.20.1752179129568; Thu, 10 Jul 2025 13:25:29 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:49 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-12-irogers@google.com> Subject: [PATCH v5 06/14] 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 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 --- tools/perf/builtin-list.c | 17 +++++++++++++---- tools/perf/util/pmus.c | 2 ++ tools/perf/util/print-events.c | 5 +++++ tools/perf/util/print-events.h | 2 +- 4 files changed, 21 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/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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 2025 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 B6368302073 for ; Thu, 10 Jul 2025 20:25:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179134; cv=none; b=Xfid36uWdbx8csAmu1KaHzcMZ7dyNWm9RZBi0QfgjuQopmMvan/zLoMu+nElXDY1F4uPtFSZU9BDZS3Fue1844aGykAMDUWX2NKxA+thNyPhqteInn6fCHeT+XvKUDCmwHAZXVYjew1QQ9rc5KpBO7mEr+TuW7adl0rN9LMuco8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179134; c=relaxed/simple; bh=RZ/4wZ7BLS3RqD09YBHOjY7W3qZV5Jmx+MPGWahCs1s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=GgSib84Nlffy1aO+Uo7UKDlXdz5pAKUvxxRhY0sJd1DN6aGPbA5S7b2MIsuAZjZTx4PrS1txoAew6UlgYPNMidBrfr0tXkjYUOmZK+pazZzarxLEUy7cPTZfl05NyycZrgH6OrH4B9eQC+axj+gFj2ZRxacB7E6b4pJAjgQB+pw= 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=DdA/HFgA; arc=none smtp.client-ip=209.85.219.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="DdA/HFgA" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e897280c7c5so1617582276.2 for ; Thu, 10 Jul 2025 13:25:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179132; x=1752783932; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=O5/KtDdH9KZtizmnT+G+DMzo0YjRxsCsauFrBz7enXg=; b=DdA/HFgALucO5v9XfEn5W/AotUcvetaI930eZFRNQfucQABGNhgZJvPUM1Mx0/kbA+ N7AT3har+gpBpYgLjB1DUpBfqACVvmzzB5ZK/ZHki+TPqlZQSprY7HqZqgPQKe49YBFy ZAGCeCVIRS0FjPXom1pcxKflFMl6C8kfz+rTmsrjFyvxfm9jx308/24L52RqG/VnQRw7 ahaQBEGdv95bq+FABva85zz/yfXJj2FrLuiFnKDJFHrC5EpbTlZ/LAH2Lw7p9jhcmzU3 Mk0N8E+HrpTwr63UAfLQmTwbybBn/8tlkhtvD8YDcE04B0DVAV3ARwBCEAOXogQtCsx9 z2Yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179132; x=1752783932; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=O5/KtDdH9KZtizmnT+G+DMzo0YjRxsCsauFrBz7enXg=; b=GHOPA3SxPNXrEhABEEQDEdkVSDXpqtzNWsz7FytL+8Bl6v+Gpkf6igvTG058T4G0Sc lT4JQOFwSMZHDWP7vbk+Jphoto5lYiL0ojw03DMBrvLpunj/RusDlpI1fR1jSs0ChLw3 a07rXSax7TGTgtCx5U1Oi4gbVD74gahc/RtCFXBoNwmDundSkcgZGsHfXVwI344CypeE UTuh0pV6komBq7mERCHwLqkYaB/MDz8XEeyrtQgr86GPTV6sfSykeOKy1FpF3RU+qmMN QupATdm+cKxhzrNvVsZ0gkCbw+iINy/ql37NSSl3wfZabExonLcPjMNcQZ/GcfEQ0Pl/ 1EBw== X-Forwarded-Encrypted: i=1; AJvYcCUvCJR6Y26DXyYG6ctnx1nZhicnR/th6VrJBTVWlVKV1jQnXBUsh0Nf3dP3dcLpR+r1LsnyJ4973d/niac=@vger.kernel.org X-Gm-Message-State: AOJu0YwhXcSGuAifVJg4Z1DuVLo0e7QxH/pT7JvlYwmwLabTloVUnqH9 96dPaNdFsPrSMGP1ML0nkwnecalqsCctW+ebDNi1YE/PRFARwa+cAUWeQGKeZcY9nP2qUBAqjQB ypfO4HTNU8A== X-Google-Smtp-Source: AGHT+IFPsZZ8Pon5iQTQbkiz4BNJHmhslcTEiUQkXFnr5TtGnAPI9A1k4XuAhqIb8pts4UKYB3Sie/SqdYmN X-Received: from ybey20.prod.google.com ([2002:a25:dc14:0:b0:e82:3db1:f91b]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6902:1b11:b0:e89:9aea:fdd8 with SMTP id 3f1490d57ef6-e8b85b5fe96mr530131276.31.1752179131630; Thu, 10 Jul 2025 13:25:31 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:50 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-13-irogers@google.com> Subject: [PATCH v5 06/14] 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 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 --- tools/perf/util/pmu.c | 7 +++ tools/perf/util/tp_pmu.c | 114 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/tp_pmu.h | 7 +++ 3 files changed, 128 insertions(+) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index b09b2ea2407a..dc05233e8232 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 fd83164f8763..9d68a1da17f6 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,116 @@ 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; + + if (strchr(name, ':') =3D=3D NULL) + return false; + + dup_name =3D strdup(name); + if (!dup_name) + return false; + + colon =3D strchr(dup_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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 803B630207A for ; Thu, 10 Jul 2025 20:25:34 +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=1752179137; cv=none; b=fz09atseTMl54qfFDw4m5kIxGQs8I0D3BrwAyG0DiZep9Qer8DNtx2fzTyeHJT+0XoqzEd5oB1FXQ+kfODdTy9ukj/n/IkLuy4xZj/VBTidQL9hfspP3nu5D5ba0udEwtrSZTC0BwK7aPD9/su8wVfUsXwklg5j4mc18N1zy9d8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179137; c=relaxed/simple; bh=Le7QYk5ewKhVR0KfjzP7e5zYRhwCNT3h9zVSLbbTSyE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=UundQ/mIVURQjxFTsOOycFPwqtgytQWvwXNgwwEYFPLY/+yzzAOmfJWzjdC/uultxuEoRnXI755AMgE13hyRr5JcqhSV/w383WlohTqBUkV0Am3YkkB1wf4sCu/SeAU00vEkX2JnFOTht5dPGn8CNh41v1Me1D8F2H7laXuIBds= 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=FpCX1k5r; 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="FpCX1k5r" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2356ce55d33so20420085ad.0 for ; Thu, 10 Jul 2025 13:25:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179134; x=1752783934; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=uF/yydA2LLHLkSIXR9wu8iMwdqKiKLaNFSdET/2T+tA=; b=FpCX1k5rf9iyh9D+zyQBQZbvKMVZyJw+ahXBD15icWIu/Txa6HWXq1/D7TFNNUUfLU ZZAjgomoRpLf0aFzDOMRISF1TZWl6cd+dLqm80U4WWD9d4vPsihyIsZfpTMturbI1a9R U1QyopAki9aI35CNTPPbYgpxfeYsIhYIBErKES3PLkvTdNUBBzXW8lBPhVxok8ijtIU+ XGEiKvkTwwe4JBRN/ebwhgyC2uyL+/f3qpdk4cTG0mzOOpZlh4W3AjTx4SdgrgW/QESX 1sleaospW/XPQo/+9g5KmZKpH3hq+6oBbPRNHksBCxqsIVIQ2/v1+AdNxw+ccW/4aBi8 lZBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179134; x=1752783934; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=uF/yydA2LLHLkSIXR9wu8iMwdqKiKLaNFSdET/2T+tA=; b=aua9qwI1ZasH55HfYar52HdD52Jr2XnYFeqOvtao+JrCk7Sd/eWj6VcktlfXPxWARf 0CmUVAFe9XjEmPp7zCpO1I9XlqSEpxrmXmVxua2S37dYyGy4Lbg+0wjb0/+Eo9x9YZEf oYCxrzMQXupxoO2sxBck3Xcof7JhS3p+1nXaIpGdpOsH80TFigB6LolacNROIFIgGJ3w 3XK46SptFh/7NtH+UXNViPBKCTODatFj/p0ul3RqRUV41lqpCXSJJSjY3TLNQTxhMU45 SRQ3NS+1uK4KLsGCKlSr5xX9bHVXohUrYX/01DAgmdxZdN377GefpZo1qMBM5Gck6Ihl G+CA== X-Forwarded-Encrypted: i=1; AJvYcCUcI/iCEMZDEKnTMPW+aytMAOdIcPANNo++ghsi0mJvfC5OKb1Q5/W5a9UgkHY9vTljd2DPHwzq0P5w8fQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwynQqQcUdjhXKJxfmot8PrJhGCq7OQ/h6gDln8IMh1mXoRbbY9 VM13LBJ/zg7wsa3oXcQbUBTREWLFj1sCSWWrHjnTCkhiPsGqZ6UhmpGkXkbShFYI7ffXUo/9cnN 5MFGl3WrOFA== X-Google-Smtp-Source: AGHT+IEdeNQPsi/AdzYokjd2DvLs6QYXaJbhcV9Uib8NroSljelAdvCb6l9+amby28agUr9Ksqzk1J5He6fV X-Received: from plbkf4.prod.google.com ([2002:a17:903:5c4:b0:236:945a:3454]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:240b:b0:234:e3b7:5ce0 with SMTP id d9443c01a7336-23dede9fff5mr8127035ad.47.1752179133762; Thu, 10 Jul 2025 13:25:33 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:51 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-14-irogers@google.com> Subject: [PATCH v5 07/14] 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 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 --- 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 2025 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.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 4FEE8301130 for ; Thu, 10 Jul 2025 20:25:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179137; cv=none; b=ndX0vLDfdUIQmfCzM2ASSwzu3XMheU4P2jgUvW4g/lw9/zP+6SyJunhIxLUD8DW/cF8+FjeQz8lscjxjL8S4O0xrENJ3t0NKXs91D9UOza9HM7bgvD5xnlKzMpzpLew6VRpZyt+/+vNnChg9l3Xxbx2ZVfA3ncK9TUwIq9tkElk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179137; c=relaxed/simple; bh=djgGA+2uKhtnV1MR7VzStD3Qsfg+MK7coxDPgG/6gFk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=EiTvt4PF0Olc5yzL5kQGpMmfZtHe/hJguMiKYpNTyP/snMqYZF5GGsGHCMRRrBLaxDhUrGK1EdJwSWuM/nahpJRIFqkE43jVIsTwRYMDd/+UnVomz2RRfoCOGPbH+87Z1JOrqetNkxgGDBlopzRrYMY8MYI32l1VfIb1evN2xzk= 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=aJomvm+l; arc=none smtp.client-ip=209.85.215.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="aJomvm+l" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b2c36951518so1436968a12.2 for ; Thu, 10 Jul 2025 13:25:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179135; x=1752783935; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=U89VxtBTYyWaxU+pAq4vLFW77vwlkptU1zKa/exvlE4=; b=aJomvm+l9UwXRTWeQkOAwrIj31bpVPdVNqwOxi0dVpuoqDTlpdvo3+yaEjb8SjiIRT xmM/ccD50SkErx2PlMpyLk0KCSBizmHhZ8AfWBC1xoqEHtS6LZWdhClI7+Fir+ac1COJ GR+em0hc/frw1yozS8+yHNW6ZVVXq2lD1300YBE4JZdoTKZkwYvAR3Nx1/vOCjDGeh9f c5fNkfMR+rc+wJp4fnVF/uI84vnizxm3hywh2mvITe9ombC2Ia3G23UUQTo9cdBSmrbV vBuNGHZa6e2FxyDyXda/dtEbkkAdG43SokMbmoKFddWKgtoipXMXRCpm3z0IhW9ijd3N eJwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179135; x=1752783935; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=U89VxtBTYyWaxU+pAq4vLFW77vwlkptU1zKa/exvlE4=; b=QnwdE2YL4DcNtUHWCSQJgx6h8OZMy/pV1bjCOYMnIC3IfLwVzyG42H7BNq0rOvX6DO PR28Zcrf6sdmvr4HVxiuG6U+oCgJdkA93oiNjS83fFDr5h1tvWENVp8Dq+X4iBgs+xD/ qT/Eg2VMB7du2/Doh5L+qzGcIJHpPOvNcj6BVqPykaA82OP8W+umCbKCC7Iv2041NeaA E1B3irCirH0mQ+alVRIdoECMwL2eUdLVb5cZ+9s16IUdF+F5kbu37pZydWswoHnpzCzP JXlW97CzNUAewuW3Z2u1m3+1pXrFcgvx3NCyOKgGlSb8bYgFo9x0OJ0kFtu3ePZ93pKr 75WQ== X-Forwarded-Encrypted: i=1; AJvYcCWgjfGM3fc+UWjoR9ZanS25m/JqhVtkO7GTTaOzuQlDnDC4deUiEUAK9nn6DqZCQ0Y4cz/+3Ku48CXz4ss=@vger.kernel.org X-Gm-Message-State: AOJu0YwyfGGyAg7IXBue9AbXzOr3TRj/swQ5JDlf4sJsK7hwZaz/r37e 7NbiiCsjk6bhfOFvCNvm9i5g1U5eiDYMsgYmPNx2+X5IqYOri/2rjj0qi1nY5C5mTWVdNi/oSL1 RhseMF7weeg== X-Google-Smtp-Source: AGHT+IEldJ3fE4mVOinrGNL2piI9AKDZasaTiF+JfH86+D5IjOUCU7Kpi0Xv6/JgoFz0XVwb1FQVa+Nu5EPQ X-Received: from pgbcw1.prod.google.com ([2002:a05:6a02:4281:b0:b31:d53f:58f3]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:6d8d:b0:203:bb65:995a with SMTP id adf61e73a8af0-231202f2489mr1188003637.30.1752179135612; Thu, 10 Jul 2025 13:25:35 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:52 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-15-irogers@google.com> Subject: [PATCH v5 07/14] 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 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 --- 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 ad2437d132f3..0124db5ab3d1 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -628,6 +628,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 @@ -1663,6 +1795,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 @@ -1690,6 +1828,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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 2025 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.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 7176B306DB1 for ; Thu, 10 Jul 2025 20:25:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179141; cv=none; b=FXGgnJiYXqHNeROtX9I3GzQoMy5zMFz0/SVJ1YVgdY4h6HhgDUOrLAZFQjPSRdqrJk4Ai4M4Q+5gLMMMGy3nIKnc/Ai8lsrVt1OYXW0niFWf6758s4U2JOpBzwrK/NuTeGNzKzE1l+vNnakEsjPM3w+89pESt/24KHMqNf7uKi4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179141; c=relaxed/simple; bh=WFS1g6kYY+XgrAAa5iSXxbIVXwge/aB1XoG8Q1Q1zEI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=Ju07CU7uFXr37q3Eg2JkW3xx9/2O6sjm8TKL0HBhvxJ+clu9F2O+cPcUsb/VcUt+ZUB68bt/2X2dA5iy7B6Ur1T5PZgpVI83bZ6VcbgQmNgpDM2uQ7frAvFflV5aR0wKddZwHlOPpHkvM5ytOu0oHZHrBrhojvkC8Zb9x3EUWss= 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=KHlkjm/X; arc=none smtp.client-ip=209.85.215.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="KHlkjm/X" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b38ffb62492so1569692a12.0 for ; Thu, 10 Jul 2025 13:25:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179140; x=1752783940; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=nLmmHKES778Ih0J3i1L0ZkfJuaKP4hpTsElytjjdQfs=; b=KHlkjm/X5phLhyX7I1q/rihXyDgXNMz7gr42FWaE9jz6+X9xlKRv/DWItvkMsahS0E xx39SmnR2th1fmFr5ekOi/uSd2LItbnuzDLqMjCZXmeiG8RDM8IvRBNJrP+O21hr/UeS T2WE14vK2MFHNIreBpfvx/lhUEFS/OeFC3gOdqDpQEFon5zLDJUEhx36Sv1iYFqt5ggF 0icJnMdpaF7v0lKk+Z03vyP5H2+kmqvMKrP0Mb5TQVZ865Kda8P8oaoxyiM/dJfId4KQ 0fPfEPANbmEz0kRsC1Nm4OaiDP3lWAkgxnsgUmPpeOYZQesSQMVTlZJZBwVNjArIHxUX Aa+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179140; x=1752783940; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nLmmHKES778Ih0J3i1L0ZkfJuaKP4hpTsElytjjdQfs=; b=GJrrm5ZNKJKG/6pqWKKEQ8/9LQxNcTBbplFFOBmjU54BAgqeES/FIdLiZze1mtb8h2 GjJz1BA1ufUgY1M/Sv9zVqJHTqDmej3rFYERWndHK1ToARjsEVgRQWxywyBbjsdZjzSi F6HnwI9ZL8ie7CXx7uYQLzVZjymBtLp9Q8P0NYHm0gqk+3/mxh25R4jD1NLhRmpC5ZMZ ap6gDPAX6WuOMqF/l922K8PXKXy9E2f+1jTVxhS/fI9XlAL00VINv61frMp5Z8BakjnP Sqw4KsHcwLyEtXIAp2bjFM6J9FKnDbyjr2TaxjGUmQMaH3Ggv7h9rEZ3+VSxQGAg0s2h G1dA== X-Forwarded-Encrypted: i=1; AJvYcCVjnoTw8XQPaVwtinXlp3dJLdczmbLQm1cqEPGUrutgjtQFkuY7GNsmI0ecC6AJpu/7MEh2KfpIqT8PgzE=@vger.kernel.org X-Gm-Message-State: AOJu0YxYJeGS8Wl3MSjsBsoFqF7QLioF5KGSMQ1N+TJej4TAFmUBWAK3 wOt5JMlAvQsnCprOWL0fxxAjYHVc2k7uSwU+KQfxtpyQ/rsfxm8fNgvFLTR8ZO8a+KbjGnzf2tL A5dKiGyaxVQ== X-Google-Smtp-Source: AGHT+IEjFG/YTY29uA5hJ6qZ0TEChiwCH3/Mq1LeU8SbYbzUA0zgXqfOLwTrlnQOsn68ErSvSK7CsSstUNPX X-Received: from pfbbk21.prod.google.com ([2002:aa7:8315:0:b0:748:f3b0:4db2]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:72ab:b0:220:b0dc:24f2 with SMTP id adf61e73a8af0-231202f28eemr1287735637.34.1752179139740; Thu, 10 Jul 2025 13:25:39 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:54 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-17-irogers@google.com> Subject: [PATCH v5 08/14] 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 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 --- tools/perf/util/python.c | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 0124db5ab3d1..728ed27986b5 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -649,6 +649,67 @@ 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); + + if (!py_list) + return NULL; + + if (perf_pmu__for_each_event(ppmu->pmu, + /*skip_duplicate_pmus=3D*/false, + py_list, + pyrf_pmu__events_cb) !=3D 0) { + Py_DECREF(py_list); + return NULL; + } + return py_list; +} + static PyObject *pyrf_pmu__repr(PyObject *self) { struct pyrf_pmu *ppmu =3D (void *)self; @@ -659,6 +720,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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 7871C303DE3 for ; Thu, 10 Jul 2025 20:25:38 +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=1752179140; cv=none; b=aDMtsEX/CakGiIJdplOOHdMmgpvu/XtcreZmtxgWWfDOpUcRVxrCbFGwxqcoyT7LvpuWqNAg3+eJ2OF8koP1CvXievCh82yR2r1j1XSyypuyuofkbcsDaNmlCloX3Sz6K8C+igJ0dcy+C9ckCa9+yiLUWl+2dWlqMHRYGhUoUOw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179140; c=relaxed/simple; bh=QBQ6rMMGrCCqcqpv0nGcMrSiGZpXq85vCuSs2bWMZ9U=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=Utb4v7CMKzv0TpRAkENDE5M/paT89q8mXPGq2sbVUDkHbbDb2DXFctxA9G48/NbXgGTUeurPGN1V5kLhRjbO3thcruogPILp74b81PpvgXm96rObdlg2BQ5PMnyze3+eFgggSKx07+rQc/aihkVjKr3akWf/3gx3RgqBAm+QM9I= 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=OAPDmd55; 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="OAPDmd55" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2369dd58602so14050455ad.1 for ; Thu, 10 Jul 2025 13:25:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179138; x=1752783938; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=EP30FVHzqvLXJ2GVgWwMYde05oJPsW/Vmscvz9g3I8Q=; b=OAPDmd55/ELzovNVVrDPT+KQ54Y0O2dnNsf43Zd4rlZJUoLLL/o013BgYv7JKptigy +sMBdSAW2X8zjLGXLGi4W+ExhVJOCQsTTYDM3E3ZpHu4QL/mBqGjNw7BVt2wtPPNxsRT MX6Tz2XKA1DXp/2dfoUkaCi+nu7SxDVTVOoxCBVirFYGETPfIID5C0m/AonlWtEvtC2J IsnyH7S0gs9eOjHeHOIMlmxx1wUo/y2irWdyT50ZBtYSpuff/ZxFOWSerzn0ORLyv+jf S0kkRLBoAe120FnNuKvZfpKJvnRV8UZamGgxJ2ckUFuSVGr3oCgusGroDdWe0HJv2v9e oHQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179138; x=1752783938; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EP30FVHzqvLXJ2GVgWwMYde05oJPsW/Vmscvz9g3I8Q=; b=Nl9ATMgBBrzY9uur2HyTmadT3d/Hdh5h692DXe3eWkgykxbv0PJ4rDlnnqKFrlSHWO /saqE/Ms5EMYUeZJVLiLgYeUceva+xrL8rwqqgBLSw/+IFNEmdZ4AuP6tqRlh9L7pVPm Qj4hQHIyuyO+PnVT/Fx24HUjxsWAiCVfKG31HSyJPyWu6nFmQBnH/xftn+8kylSk8dMw 2BFmIlaqo8Z+1o8jJlrzyUknPlwUgq9+WeSGWnRrMolyrZoT7Sd5ZbOuZ6/MygsCPDJ5 3wR3mAbHr6l64f7nDLjv30dqY0v7yXimknOE0fBA6TmStHfR0Yp97MxD8/hhyN+v/WYZ YRew== X-Forwarded-Encrypted: i=1; AJvYcCWA/QcAPsxx9l+r+lSFxBYQvHc0mCu5Ub7oS1Yfcbo77Dbpg3QRrGCcwXfnH/qxDqWflSlmOqVSfMnewRk=@vger.kernel.org X-Gm-Message-State: AOJu0YzWqtwDkJLDoYN9egbzi7aDsR+AVCgUDwpBbniD5nfbqeoGY97j vQZewEWe7AXeehLowlxcMRppg4qZjOFxhwKR760MtHlQpsB1w+SJOircBdCp6Rb5iOPn8xfIt+H RcobzOQMTew== X-Google-Smtp-Source: AGHT+IFkYqyREbtIQSLbhz2UcEYkhDEn6YLjyav75c5U8o0BRcV3V2J2KJypDuFoK/YcyX7q/QxQUM0VeA/J X-Received: from plbms15.prod.google.com ([2002:a17:903:acf:b0:22e:4a61:5545]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:cec4:b0:23c:8f4c:6658 with SMTP id d9443c01a7336-23dee26d6d8mr4993875ad.25.1752179137825; Thu, 10 Jul 2025 13:25:37 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:53 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-16-irogers@google.com> Subject: [PATCH v5 08/14] 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 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 --- tools/perf/builtin-list.c | 17 +++++++++++++---- tools/perf/util/pmus.c | 2 ++ tools/perf/util/print-events.c | 5 +++++ tools/perf/util/print-events.h | 2 +- 4 files changed, 21 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/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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 62BD0306DD4 for ; Thu, 10 Jul 2025 20:25:42 +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=1752179144; cv=none; b=MkdLBKsk4d+cYzZ9VNgVuF8pnjxSpPiUWXvZct6ltlTG+Sf82VcT0Otv2c7exlqtfCLC97bssI5PV6jX6oxtA3VVNewpD3SPog7r8pUEm7qh9KZ5TJqVdrK3LvxkasxbeJYAQQrLJ/BWe8BdfeHYaaiqnlIX44mJ2lDAK5yoz3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179144; c=relaxed/simple; bh=sOTnWI/7IxHdKi9634fHq9XBXh6GwdebrpYxmKO3LjA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=AOv+7h7JdESKfsnB8+6hfQ0r7FQVh9/ONdmX78uE+Az8WAQHR5FJcLZ0gp3dWmvHP1Fa80zjYxRt0YAwdPKx17s1wOuUXhngyaLYT1nMKYHfbA7C7xI918W6iKvMENzD/VWQimSXhLm9LjWysUuMyc4QfQixmVJO6ejWd3fhv/0= 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=sM2uDXqJ; 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="sM2uDXqJ" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-23507382e64so13810615ad.2 for ; Thu, 10 Jul 2025 13:25:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179142; x=1752783942; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=A1mkViaojKTUojnp/iEqVcXRNkOKi/CXUSAokDzDaV8=; b=sM2uDXqJKxxYHP+zr3l658GvXpynxj6weo+B5EYT8MwkYGXVyYPIi2DlfGOSCTHFjH k889wWGDXMEil3r9e7LslF6sFmablVFGx995LD/irvfyyInmyLBUAiBdQj985f0vJeyM sqT9OWjTKZwxWnmBxQidOn/EEqAjDeWwmY6dKTQmbqgs9g+NvJ1tUHzJ5lev5bpv9FRW sIrTQNfGjM7iPZiWE3ZHycTzfk4TTtRSeEpAltjYgZL0c8ABPJ+5c2EMMt5ugDR3GtJc XohxZrZZuZB4fOO1M+HizaQWHftriqxTI8A9pBOJE/G/XZSYLdK3ahP1h8+WOR1rJpqe cL5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179142; x=1752783942; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=A1mkViaojKTUojnp/iEqVcXRNkOKi/CXUSAokDzDaV8=; b=lHoe1zvzg+Gy474qYiRodHpKG/5f82i5JwUYlpiblq9/NvYZlnktgQ25lRfE/faTCE oVkCbgUwtQKhsbOs7nLg3MYzr7AIX/V043ErPmEGQLT731ZjRI+7tNr1X28up/DWwAwl FwV8s3PZ2dov8bl8j1TvNVkp64qaKqP3Qa6s8BArfKJxURvOvcZ1aujSReNF70MJBX/F CfysjK1Z/FkY6SWsMyvD5rTBgwjnRkl0H4PWXfmPuE5pffZ//Tc7BXNZAmq7Rozvcmsu YWZvdbABGD5kS8YrtlF5J/uubeWr8bInUsjsABEOMd5wTv0qYqdyt1h8gCHLjD641x5M y8UQ== X-Forwarded-Encrypted: i=1; AJvYcCUVSSHGjjjScSiBPdQmQ2H9hCvycMJX6zoX83XYQ1G6Vix5IkEUsn1FV7lec03WdHk/laX4VJhpV2LSEfc=@vger.kernel.org X-Gm-Message-State: AOJu0YzNJ2Li1R5hivtoETBQ3SgAo/Hzkzwk+lAUXdEaQ/xboCciuC5S BL2IroYOOvBP/Xcw7YLI1B4X+dVfdNyS89F9Sv4vXW6DzFVm0dOtDaNuTPI5DBFznP6TQxPsFAj UiZ+URfo8iw== X-Google-Smtp-Source: AGHT+IFptwjHajv8/PTbi0CfjT7M9O6jf1Uppge+KOtYzHW8eKhu137UGQ1y9Jhh3fSMB3PNgjm85oI/BMBb X-Received: from plblm6.prod.google.com ([2002:a17:903:2986:b0:236:9738:9180]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:b8f:b0:236:748f:541a with SMTP id d9443c01a7336-23dee0efe5amr6472165ad.0.1752179141756; Thu, 10 Jul 2025 13:25:41 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:55 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-18-irogers@google.com> Subject: [PATCH v5 09/14] 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 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 --- tools/perf/python/ilist.py | 387 +++++++++++++++++++++++++++++++++++++ 1 file changed, 387 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..3e2fae1db738 --- /dev/null +++ b/tools/perf/python/ilist.py @@ -0,0 +1,387 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +"""Interactive perf list.""" + +import argparse +from typing import Any, Dict, 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: TreeNode[str] | No= ne =3D None) \ + -> Tuple[bool, TreeNode[str] | None]: + """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, tr= ee.root) + if len(self.search_results) < 1: + self.push_screen(ErrorScreen(f"Failed to find pmu/event {e= vent}")) + 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) + for event in sorted(pmu.events(), key=3Dlambda x: x["name"= ]): + if "name" in event: + e =3D event["name"].lower() + if "alias" in event: + pmu_node.add_leaf(f'{e} ({event["alias"]})', d= ata=3De) + else: + pmu_node.add_leaf(e, data=3De) + 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 6E0243074B5 for ; Thu, 10 Jul 2025 20:25:44 +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=1752179145; cv=none; b=AtTmZH10PURlWiKGOIDdU1sISs9dbIghoJYszaCttCj3CZRWWQqX+sqPOdUlQUUXogCJKu4YDkeBUECUQhnmdgrh4Aj/7z/9Wu9zawOmjU4l1w6GeSqqJmz8wKWKNoQuBExgaL5QDQCspVzB0V+WP6n3vX8t4JTEfkZ1seMoD08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179145; c=relaxed/simple; bh=3dXnQX59uCIqHGxrXpzMnI4Zl7s0lQpAP1vxN37XyBs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=H0RbIzf4WxRViWH6v2+ki6MU0NQDKEGkd8plHRfcws9h6JIt6l6Coo88SQg5CXjvd4wGHoScJk4elruzjMvATkA5k4lb0IScw9HtI4KJ5E2uzlZOVrlo1ESIJKB5DY2quo1Ydquow5tpg+3G/efXO8QQiqPgdsKCnCC8aHmFtCQ= 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=Ick4ZjV4; 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="Ick4ZjV4" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-74b29ee4f8bso1239007b3a.2 for ; Thu, 10 Jul 2025 13:25:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179144; x=1752783944; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=kKmR4p/5RIten4aKh3XJYKu49jHs+S3X2MC/LIpLWZY=; b=Ick4ZjV4qlrhgEoNy8Dnw+ZyGhUaNhHbCvgxueftZB4mGwp42Cq0nA1gPm6WpZ4EAH wARug9Tl3SF6LaVPXG2iSHTlkFq/980vdYpLTcqK+EegAV2hAOrMZI0cAtzYuc7dLSgv d0e+VpR4mWTD6q3OEtJxQhec0SuTtP6IoUSeJR7ztkAPTHAnuiVgNSK05faXw1nHrOu4 Tc/oyQNJvq4qe4VX8YHMbQL5fFwjCmnELAsQXjusd8qI2UhRk+oEmx3UCXZ+OZVt8ZzY w/GTQsjoqNSk4nRWwMXF+wvVvkS+PsqL+K19cU51cE+0vIv2TcCk0tCjcwC8zETr0+uI E1kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179144; x=1752783944; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kKmR4p/5RIten4aKh3XJYKu49jHs+S3X2MC/LIpLWZY=; b=Mgw2eF284ICjnqGYdL4AWCNY9H5Xze8dsB/oaXuZacoixFQgIQFcmXG5M3Gyxf0biE rMvyqDkny12EncWetaME7UENv4bgM2FWukihegCd/MQb+TF4ZEX8Vr0y4cOQhGFErNZI YCeGy2nYQv40KzgPWqzzNGxv5Oa+Tle4DSX9p6tqRjbexqYBlb945u7z0bpVWB6veEAw ZhZjMBX/s7ZbY0bXBu22k7fYa5j5JGevnSuCx2vIzl1bcAzSplrEjVdsk/VWz6XyLa6F cIobOKtdmuFaGmrBXNAXnaGusqU83u5wG6imDgWFZbYMCdlMv9Tf8b3IjfDbv+9ak/8N 1YYw== X-Forwarded-Encrypted: i=1; AJvYcCVaJnEcaj1/lHBWl692coiqj74l03oMlVTKmqyHpBtmjY6aaV6YzON3GyuIAHmJ+rzoMkqFrTDUdT1zJi0=@vger.kernel.org X-Gm-Message-State: AOJu0YxsvivWo/rv8LSLbtA1hSyRB0tRStKZku3StwmMl+ssWfFhte0U QVTRwZS82zCtv96yfPxZ61tUgcOxHs+3l1pv6u5q/S61c4MZw2aRaBKsxWleq40TqXX5EEpHpBn w2oBUIakIsA== X-Google-Smtp-Source: AGHT+IGMb6gzdDHDVJtMJQdjdiB2sSHyLIcSx+wq4io8/nN853oSogBXzIpKHEFOzru5HYy7zAazLRvW5hIP X-Received: from pgbdk14.prod.google.com ([2002:a05:6a02:c8e:b0:b31:c53b:ff59]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:1f8a:b0:222:180e:3f22 with SMTP id adf61e73a8af0-2313686203emr586614637.26.1752179143819; Thu, 10 Jul 2025 13:25:43 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:56 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-19-irogers@google.com> Subject: [PATCH v5 10/14] 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 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 --- tools/perf/util/python.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 728ed27986b5..2a8026a261ce 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1849,6 +1849,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", @@ -1862,6 +1896,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 "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 r= eturn an evlist.") + }, { .ml_name =3D "pmus", .ml_meth =3D (PyCFunction) pyrf__pmus, --=20 2.50.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 91863307AFB for ; Thu, 10 Jul 2025 20:25: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=1752179148; cv=none; b=SCWD+sx8r1toSHSMVUo06y06EXqZIuJOhsb7whiw8aDcuoI8j43DXBT7vbeNi2IBRlBnY6xZZsEfT225aQuriWBBP1VwWcPKYJCtP8Aips/mcHRc3GuRdsrPdjd8b9R41xCOzByFCBUd7xD2u8qDU8ebLGTHl1oP0/GJehLAWNc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179148; c=relaxed/simple; bh=CQ3wmaeOJWsKbbuQFhAuSaG0gA+aFq/bD2Cwcmzd5EM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=tFUnPcYJcl+f4JCgjOLUj3U2Tbihcypz/fAU1QH3vqM5xovp2Fu1zSFEYqW//NOQU91DVHPfGGNcmYg7X8FdgWQLzrGvU3VefbN6eEkGUwtgm9nG6t90RkJzY86tnubplV3tCshJQ+v5cdzoACOPYjSPpzMu3KU2QRUAhWt8ZuY= 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=HQjUL8LI; 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="HQjUL8LI" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7398d70abbfso1818293b3a.2 for ; Thu, 10 Jul 2025 13:25:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179146; x=1752783946; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ynfXIEdjbeoZVI+qyhuUZ2zNsB5tYJ4xhRzXaal67yM=; b=HQjUL8LIymyrW6bLpUuA12Hn+6ofnZQ7gyJIB5WHx5GvCoQUpeSA3m3I1+Ac3G1Vtq VtDaox6aZIOyUV4x2ZfoXI0V3s3IrV12iEbKCZGvgqNwpo79xYO1HN1jkqtgfrL1EyO8 3CFBgY2tQH0u0WSNXgUl/cbd0+1e6o9X3MOy2NQ1dWGLhZVC2HSsIi2aQM/Sa64Ms3Mm Kv8SGadU9L6phxnJZauyTMfASI5N4XBzFfLLguqcebjljHC9Z7k4F7QhFAgqQggFPfH1 WUmr/vEr5frapT6/UEQBG6fAgGYzXRuODs7IvrfJaxVu61gxisVVJ99w8Po21JAoTC1r 6pVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179146; x=1752783946; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ynfXIEdjbeoZVI+qyhuUZ2zNsB5tYJ4xhRzXaal67yM=; b=nhSSPzZfr5E9k8NlFSTzI1wmdQ2mKHiiovXcbDXN5sLjRz5eInx+6M86TJFyJo4XRb nxvAsfBXd7Wn/w823xn7+KK0XTHDLuLL1YcaLQWSzfbKvYwMb+z2wNE/0r+vNedCglET HWDGDzr0ZazDJ/xHHojL0+hL5qNf62AHP68yKVyha+fBW1/6cjgvNqTSvKKLtxej0d1c qPEZoZUMIGPSq+kdbrEPRRW57hxbL46NKlokQZ48lep4hnuPk9ryOj2uCz3G+2h2PM0T AhHhIsoWBfKJ+t1B0K+dXBnfbO6LU6lHQS+antEHrZEs8qu3npFikU1tNf8dEbCL9csj RTIg== X-Forwarded-Encrypted: i=1; AJvYcCXPcJ1OhdDQQqc/Dj8CUUx5u1HWLTW4VDzyWn0CXI3ZHn+c6p9+uw2pri1Z5zzsM2Zu/8BZuUfygtS2Scs=@vger.kernel.org X-Gm-Message-State: AOJu0YwDps0j63SW+0PKXGP7ZWHUygn+II5ZPigyubpv9nvUTAdWEmhI H1aAoUmmWiT1BR09I9HbRvf/SRW/8hQvlZ/4Ya8HhKcOQynO3PUkZrPHhWGJ63mvIfp2Xlo23uR zfXFMu9/LGQ== X-Google-Smtp-Source: AGHT+IG8YPAbK60VpT5SQev9TYDxaMb4IKlwjzUdgHQcj/ouij9X1EZdHSEJe9l1httCuYW99pmnhUbUIod4 X-Received: from pfbk29.prod.google.com ([2002:a05:6a00:b01d:b0:74b:54a2:ff33]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:aa7:8883:0:b0:736:43d6:f008 with SMTP id d2e1a72fcca58-74ee2a5c3f5mr464661b3a.12.1752179145974; Thu, 10 Jul 2025 13:25:45 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:57 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-20-irogers@google.com> Subject: [PATCH v5 11/14] 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 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 --- 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 2a8026a261ce..9377b64d73af 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1278,6 +1278,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) { @@ -1504,6 +1531,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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 2025 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.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 8C9F33093DB for ; Thu, 10 Jul 2025 20:25:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179150; cv=none; b=CYr4NJPJF+ZpezatgPovs7hvjl/RgPpr0+x30o7XqYUTboRbYwJXhP9cN8ZaBe1fMrdMbpZoKjNNjtDSjDKPAQ0KSV9ZjdB6smSFF4atfrrLJ8B/f/k4dFbs2gIs8HGzNB5+DhTI7F0KcQrrfl6vDN58/pcz296IQU9C0/2Bs+E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179150; c=relaxed/simple; bh=CfdxWrvHXRSBK1tr4aMkg7yCSGisXTuq2p3EGoheCNk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=k3aUkZA8Q3G4jEtAtRLDwodr/caWYy0YJkhG0UFZkUfaTLO46q8L93x9ZEH7FehiVSiR+j0OojqwqIsyxXCIoabwkpipkzH8NfIMHZSqBsM/VLC3sqLO50qztUKzMGzxyKqKIjxHBNu7LC3zyUOASTmxi5ibIhHT4tsovzajvcs= 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=I2Yo4mnD; arc=none smtp.client-ip=209.85.215.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="I2Yo4mnD" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b31bc3128fcso1927790a12.0 for ; Thu, 10 Jul 2025 13:25:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179148; x=1752783948; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=HXg6Ojthczu4oDT6PdQgfIf2viuURWIg6eqEDP0OVjo=; b=I2Yo4mnD4TlA8cfiDV1AfiRP8okpc0nXlo8SVIgeGQC9EpEGElGpkBl5OSjyHAB7CQ upx8ftcdG01XQSixJYCrF9BqJ09BajWttF8xdDgsAPxOuHJJXeuN1DE2nO0+1mPbkHKV NM0hxg6got3cfmNWXRM05Tp1B8GDW7iacIMYwNHeffgb/uA6jmnJhXJamsIrDUHUD+7D FCfqpcPGpf4xQXGZyfA69FBqKrWyk8paCrk80evgtb3GztQJeq7h9lGWOj1HI99JQurB HoGQCupsUQb0mWHv4juJlHOUGF88ZT2dCrM9y33K5Wx2IezaBYDjN0PtKH/puHIbhmgD vWCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179148; x=1752783948; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HXg6Ojthczu4oDT6PdQgfIf2viuURWIg6eqEDP0OVjo=; b=XIK5LSJuVzujspyg/7SOFLqZjQbkz5lEMrwPtA14gsqfIkyZrTEbRwPXuKeKRzTN0D UhgqIInpnCV2Sk032YLwoFZ20Ef201n9IEnmYJgtrAxk20302cRSQ2jNeA1Ygq6OTHBt 95KGy0CjGJtnhaskjRuX987NEQ2n+A4YHifW/K/JXIckiu82SH8cM3JYGO0RjY6tI9kQ 2BOtmMZ7wBfLu/H4NYjirGpcNJ0BCiaBFKIa7ckszrTIIjsioKj/IXJZpTrmlBAxwjxi AFE3TJrrNIzX90jA/GJEXuac1IteKenME2aslfeJDO9TWgroGNl6E9rE/CZTh3BVvF5O xHdA== X-Forwarded-Encrypted: i=1; AJvYcCUGkXwGOT2wh2ZPQxa/fmYLhtkufCctM1ugYSraf0z0X6Fyc4TyDz/hI3r1tmo5p/sw/144HKtocMfYm7E=@vger.kernel.org X-Gm-Message-State: AOJu0YwGEWnI0yBtwfzThrdPGiQZTXuWB2Mwek1UeGMNzF2MxdxxRaFm NfImEnxKU2jome0TMLOzTZs9fAqef6dlEcYQ3zvGciS8yII9Mw5zPHJ6B4FLJS/5cqNuR6O+p7D I4Z4gYIwWNg== X-Google-Smtp-Source: AGHT+IE/yLU0KCHJE4cQoL2XbEQ6RMGpKhtOlCJ+gDFn6pJdPy7axGkjhkFT/EE84qlViWiNcqSdUV4YgL+M X-Received: from plgk2.prod.google.com ([2002:a17:902:ce02:b0:231:de34:f9f6]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1211:b0:234:ef42:5d5b with SMTP id d9443c01a7336-23dede42694mr8470935ad.16.1752179148045; Thu, 10 Jul 2025 13:25:48 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:58 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-21-irogers@google.com> Subject: [PATCH v5 12/14] 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 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 --- tools/perf/util/python.c | 121 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 9377b64d73af..41d290c43b7e 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" @@ -1305,6 +1306,120 @@ 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; + + cpu_idx =3D perf_cpu_map__idx(pevlist->evlist.core.all_cpus, (struct perf= _cpu){.cpu =3D cpu}); + if (cpu_idx < 0) { + PyErr_Format(PyExc_TypeError, "CPU %d is not part of evsel's CPUs", cpu); + return NULL; + } + thread_idx =3D perf_thread_map__idx(pevlist->evlist.core.threads, thread); + if (thread_idx < 0) { + PyErr_Format(PyExc_TypeError, "Thread %d is not part of evsel's threads", + thread); + 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 *e =3D container_of(pos, struct metric_expr, nd); + + if (!strcmp(e->metric_name, metric)) { + mexp =3D e; + break; + } + } + } + if (!mexp) { + PyErr_Format(PyExc_TypeError, "Unknown metric '%s'", metric); + 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) { @@ -1537,6 +1652,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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 C0276309DA1 for ; Thu, 10 Jul 2025 20:25:50 +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=1752179152; cv=none; b=AEx2u29A+1urfZd/cXt6oqcKog+6KjVRGpIov2irfTbfBDQtUPKTQNVfAyLBXdKCsXSePx2p/NyX5JKIXJlkf5X5VZIMKdk7fFP3UYrA9uHroLNYuz5Md5zVd0bbAbnTaLJ8+3Uo0hhKxp6bTTr1SAO9A5jk9P+PLf9YjBOEe5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179152; c=relaxed/simple; bh=kDqb/r0HccawH5czjXeqp65wkcljd4SqQ1ZhN3nUBRU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=WMitAoXLV/LzzpalWCRXuWz9hIVc7JCDKkvL+sdMvYXE7JyTN12Ox/S8gSNPFuWxNOhgCpVCAbXb/ishNW4deiopcvBOFt41fn5UEGCJj9DNBFwkP16cT5Eu46ElTsTD5AXmqsrlja1U3Hyx9GyA0foAPfhZ8ZnH18Cis8s/4QI= 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=XCD1tdHz; 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="XCD1tdHz" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-23824a9bc29so20605515ad.3 for ; Thu, 10 Jul 2025 13:25:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179150; x=1752783950; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ORft+ikg92kHFRcEMbKO4fnQ+ouMdhF5CZrp1etPobk=; b=XCD1tdHzxsgeMM8v8UEmcCWN/WqDjJsAGAEZG+WDUEVr6QQZdS/B9n5PTX6d9AGBHn jDpXcO8bWHtldKUoqJECnyRxtCnMb15M2qdYYVnefQxxXXcnyAMN+INN7JHsOa31Eue5 P0tuozO66qwydOXfDuxNnZNc3RymvjTxgXYozmy24ctXp1ppivINiEXCkTONslnsfYaL ovIEC/xHxO5Zdwcdd4vjEb+XEj0FN0LLHOTaHa4VGWMLCJsrnWAYa2XIWtFZPChUKwZX drIcuTzVhoh1+jZr2ntu6aXWN2rHYc6HolylTibV9Vz+JGt2ik410AvU8z/7R9gIGO1H 1M9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179150; x=1752783950; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ORft+ikg92kHFRcEMbKO4fnQ+ouMdhF5CZrp1etPobk=; b=nApw/uV4gIrsWkaW3lPyvTIkQFhyo4TQ84RWLN5UGq33qFMdrshz6rYzyZDcf6l3V/ Ca+iBYtFU6AkKZCARj+3UYxuta3XO+AK56jRXjcqBhsw+SracKXw8A2ZXE3Me5wTGScV mVkNwbeLabOgfKcca6L5y/2zvrr9shpWjqYKbVAO5uMc51Tqi9ajLC8MKwMENFD/qds9 pUAVCjfbheI0c3CE94hEBl774l+npKaCFPo/iLwFqyQZt1ATXJsi6fJc9MqmXy/mr2nT OKcD1d5L03R14BiKfAmJiX4w8QCe+cvxMSznWyxQ/057GMCe9Yg7kM6feidUSYiWpZkh AwTA== X-Forwarded-Encrypted: i=1; AJvYcCXyWUNN8xXpGpx6mEMaJYHoiXMQVT0VFw1GUUOqR83qoVPe+Ws2L3yk+U86MxLtqh6ZUMv4JuGhXND+0Zw=@vger.kernel.org X-Gm-Message-State: AOJu0YzgSUgCllIjq/oiA2VJODmCAOEKTgwQunx6361sJAZhH9LEV1SP wtbrPZBD813LwYjD7FCUM93ZXjePX0KdHb9HuSR3OSrEs2YXSSEDoIisdu3x7GvNliqcKuSsm1f 4410SiGBJdw== X-Google-Smtp-Source: AGHT+IHC0xzzUx4vlB70IgesWtnJpsZCyr4s/kcJOXTS0/ZV/PNp3UFAWfeugrKN3KmuSXRti87Icy6VX0gr X-Received: from plbkp15.prod.google.com ([2002:a17:903:280f:b0:234:b3fc:8229]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:234e:b0:235:129a:175f with SMTP id d9443c01a7336-23dee23805dmr5885735ad.34.1752179150190; Thu, 10 Jul 2025 13:25:50 -0700 (PDT) Date: Thu, 10 Jul 2025 13:24:59 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-22-irogers@google.com> Subject: [PATCH v5 13/14] 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 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 --- tools/perf/util/python.c | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 41d290c43b7e..0ad14204c144 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -2037,7 +2037,90 @@ 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) { + 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.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 09:55:04 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 A8031280325 for ; Thu, 10 Jul 2025 20:25:52 +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=1752179154; cv=none; b=iLK7LVEG7Zfyefbr9jDilG0ex+J4JU8LoWDEWop0vSX+juhdXfw6YYjw3wpb6K26TDFrbRyn+NO+fQrMz284VO97kEk4HyQXRaLcRps+qGJu79ut2BiD+BYy/xgiNAHwVUcqlRvtLs703JRpzAPto5rfPb+9q/keoHFPrPS5DCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752179154; c=relaxed/simple; bh=4DBEBdTfWfkhLt8ag7FL9lGLt+srCnvLuSveHjPSawA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=pBcco1rSG5SG4RsWwipHDzVmgSSVjcH1q2Nb2iQbh0XQBp/Z2GJgN2WYmRyyUsrj4J8s8mQu7sMarP74e15QfHcRk4FZL7M9q2du/r5MbDlyan0sSkzUWB4BUv7rqZeUdNcv6dmZNp9vguR+a89Qbxf+i0clgT8/ar4WNrBba+8= 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=OjqXjJf7; 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="OjqXjJf7" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-23692793178so12462685ad.0 for ; Thu, 10 Jul 2025 13:25:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752179152; x=1752783952; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=BsThzVLcGqNGlV+OXH+rg8cRsNmgOdp9nQeDnnzr9WU=; b=OjqXjJf7XnKN1OGm7oK0J3lxWYUFeO3xbdB3nVoc1GuLldieq+kmgZzUF91JG80FLJ B4OGubnHxI0cVXwCUaMJAHqh6augeAqwZCtT8BVAEd5sexPohYf7k+mhQgU5cZ7Yfpf1 c5FVmuGismsBi9yemA3kiUSkXc1E8VPENbwOVfu/KkvhVlbDE5yXzlJNCS50MXjPw3cl FWxxEofjl+QNIGEBWaVuHHwdpwNfxRGpS61hbzkxd4NuXY3EC6xVjMP1RfSbBGtpfOCs 1UXxFopV28q2vNH95OEV5EXSL63Pwgi5HMpfnmsGlZoGD5xBzrsMJJwHAD14xqmpJPkb bhqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752179152; x=1752783952; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=BsThzVLcGqNGlV+OXH+rg8cRsNmgOdp9nQeDnnzr9WU=; b=uNC53p3csi5vVogY73gmxt7fawWHQmcXXhn3aH79OfZp1SNz+t/8bQ2BHIhnpehnol LMd1d4k6DjpYN/VNlcz0dM7Bo5hWkgfluTlCU6GfOrfuADtKO8r2HOYJ0McPKrvaSAZK TGCGJVXFaEDGzw9DAw8oZqp2RNSygAt7h8HKwpt+bmxyEtC1v5ATftG2Ye9UIfCzmmor +U4ENciUS+fHuQRaV7tQYd/nSMPonmWtlWTzdP2N2Jj7lQ1RqMR7Dp/acUwMgmg7vBmw GpmFpE4SdZDkhJRJFgaAQ+eXBXr8NqecdARCTm2lkt74TBxD5JsAmbwr8Y4NK4FTkvNj GtLw== X-Forwarded-Encrypted: i=1; AJvYcCUms0MNRM3ug3gWNBdN1oQrxvgv+6OMceb47ujFc9gImXdjhC0lSPTjesMohEprBA2Y9laZJ/IWjIqpgAc=@vger.kernel.org X-Gm-Message-State: AOJu0YxcwOcZvwFE1SSR53TV0NI3kNZxv0ROxiN3YWm9v3oqGa7rRVCE 1DVWInMy/ICyYN8AvsbDh02czNkDnkqcvTO1H5lu+P0XG9LG9qirb2IfuWHieJDDYdIUEk+bzyK 9fOReeM1Gig== X-Google-Smtp-Source: AGHT+IHQYfc387XBZ145UOjWYS/BKtWtK0qdQBrGBn7LKYCQI4V+mSPnGrGhMcYtG1G8Mkq6gsWECrNCf8my X-Received: from pjff3.prod.google.com ([2002:a17:90b:5623:b0:311:b3fb:9f74]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:24f:b0:235:f3df:bc26 with SMTP id d9443c01a7336-23dede2ebc5mr7901375ad.3.1752179151997; Thu, 10 Jul 2025 13:25:51 -0700 (PDT) Date: Thu, 10 Jul 2025 13:25:00 -0700 In-Reply-To: <20250710202500.1959672-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: <20250710202500.1959672-1-irogers@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250710202500.1959672-23-irogers@google.com> Subject: [PATCH v5 14/14] 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 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 --- tools/perf/python/ilist.py | 207 +++++++++++++++++++++++++++---------- 1 file changed, 153 insertions(+), 54 deletions(-) diff --git a/tools/perf/python/ilist.py b/tools/perf/python/ilist.py index 3e2fae1db738..0d46b44d2961 100755 --- a/tools/perf/python/ilist.py +++ b/tools/perf/python/ilist.py @@ -2,8 +2,11 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) """Interactive perf list.""" =20 +from abc import ABC, abstractmethod import argparse -from typing import Any, Dict, Tuple +from dataclasses import dataclass +from typing import Any, Dict, Optional, Tuple +import math import perf from textual import on from textual.app import App, ComposeResult @@ -14,6 +17,103 @@ 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 +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 @@ -123,8 +223,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 =20 @@ -180,15 +281,15 @@ 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) - def find_search_results(event: str, node: TreeNode[str], \ + tree: Tree[TreeValue] =3D self.query_one("#root", Tree) + def find_search_results(event: str, node: TreeNode[TreeValue],= \ cursor_seen: bool =3D False, \ - match_after_cursor: TreeNode[str] | No= ne =3D None) \ - -> Tuple[bool, TreeNode[str] | None]: + match_after_cursor: TreeNode[TreeValue= ] | None =3D None) \ + -> Tuple[bool, TreeNode[TreeValue] | None]: """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) @@ -222,17 +323,17 @@ class IListApp(App): =20 =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 =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): @@ -261,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) @@ -275,8 +375,10 @@ class IListApp(App): self.set_interval(self.interval, self.update_counts) =20 =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.""" + self.selected =3D value + # Remove previous event information. if self.evlist: self.evlist.disable() @@ -288,34 +390,13 @@ class IListApp(App): for line in lines: line.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. + self.query_one("#event_name", Label).update(value.name()) + self.query_one("#event_description", Static).update(value.descript= ion()) =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() @@ -323,7 +404,7 @@ 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 @@ -344,24 +425,44 @@ 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) for event in sorted(pmu.events(), key=3Dlambda x: x["name"= ]): if "name" in event: e =3D event["name"].lower() if "alias" in event: - pmu_node.add_leaf(f'{e} ({event["alias"]})', d= ata=3De) + pmu_node.add_leaf(f'{e} ({event["alias"]})', d= ata=3DPmuEvent(pmu_name, e)) else: - pmu_node.add_leaf(e, data=3De) + pmu_node.add_leaf(e, data=3DPmuEvent(pmu_name,= e)) + 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"), )) @@ -371,12 +472,10 @@ class IListApp(App): =20 =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.0.727.gbf7dc18ff4-goog