From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED7CD171AA; Wed, 31 Jul 2024 15:33:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722440031; cv=none; b=SZTAZKsSh5W55Ei/f64QGxk/zjtU8Emf33mOoECkyJa2LJRO95+V2BhfM6wXbA3jeMJicEZswwgZUE1QhkSNblMwMuZOS8myDtQ+QrokF1EQiH14JTbBMJIj4n4e/PuzoAcCkqj3TgM+OmPrvz/RwhglESx7z8a8AFXqFByMkAU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722440031; c=relaxed/simple; bh=/Nrsve+fIEBkvS4+bfpFr4nsqhWgs3twUGs5q+9wcxA=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=QvxOEVo6XaD+ju2uvTP2pRDjVKMtW4xz6WIybRq7H4C0t36Cjr5Om6BNsvzbVyfv3rirhUo0Z/Ex7WqQX6uqqGkajNxKVdovQqRVPsJ4XgVlZo45ZuC+AigmUws+V+qoj+x8zRxXbQbPNmVaOVbN25CTtvfrkjNtV9aUYKXZ8qQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bdfUK3+7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bdfUK3+7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F127CC116B1; Wed, 31 Jul 2024 15:33:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722440030; bh=/Nrsve+fIEBkvS4+bfpFr4nsqhWgs3twUGs5q+9wcxA=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=bdfUK3+756ldUGBjKirf1xpxWBTjOb6mZtwnG3ri0Hbix4lBXhNVuuhPZiBZ4EWw2 +XytAwAkkvKw4kNE/Rh7B6eFEFglQn0lqBsKN3Joa3YI5Z1S13cBIsO94Miup1BaBy MzREuUcV2vNw89bEf+njCDzjP+bpSlkK2ZPeIfPRXiByXcJX1a71jldgStRvqKYEGu ankbn4MQmO9gYS2LQG5yafD3RTTW4e7uap64B8C8psed0vODgziTnVAthuOAaIRzd8 SYqZspQudyaMfFPHLsbIuCGnlygzKaqKumq+JD8PNrXSkIoHP0x50ND2RkDdmXF0oQ cSPmlODK6WpTA== Date: Wed, 31 Jul 2024 12:33:47 -0300 From: Arnaldo Carvalho de Melo To: Ian Rogers Cc: John Garry , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Adrian Hunter , Kan Liang , Jing Zhang , Xu Yang , Sandipan Das , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, philip.li@intel.com, oliver.sang@intel.com, Weilin Wang Subject: Re: [PATCH v3 2/2] perf jevents: Autogenerate empty-pmu-events.c Message-ID: References: <20240730191744.3097329-1-irogers@google.com> <20240730191744.3097329-3-irogers@google.com> Precedence: bulk X-Mailing-List: linux-perf-users@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: On Wed, Jul 31, 2024 at 07:08:18AM -0700, Ian Rogers wrote: > On Wed, Jul 31, 2024 at 6:18 AM Arnaldo Carvalho de Melo > wrote: > > > > On Tue, Jul 30, 2024 at 12:17:44PM -0700, Ian Rogers wrote: > > > empty-pmu-events.c exists so that builds may occur without python > > > being installed on a system. Manually updating empty-pmu-events.c to > > > be in sync with jevents.py is a pain, let's use jevents.py to generate > > > empty-pmu-events.c. > > > > What am I missing here? > > > > If it exists so that we can build on a system without python how can we > > use python to generate it? > > > > Now having python in the system is a requirement and thus we don't need > > empty-pmu-events.c anymore? > > > > Can you guys please clarify that? > > The requirement for python hasn't changed. > > Case 1: no python or NO_JEVENTS=1 > Build happens using empty-pmu-events.c that is checked in, no python > is required. > > Case 2: python > pmu-events.c is created by jevents.py (requiring python) and then built. > This change adds a step where the empty-pmu-events.c is created using > jevents.py and that file is diffed against the checked in version. > This stops the checked in empty-pmu-events.c diverging if changes are > made to jevents.py. If the diff causes the build to fail then you just > copy the diff empty-pmu-events.c over the checked in one. I'll try and add your explanation to the log message, thanks for clarifying it! - Arnaldo > Thanks, > Ian > > > - Arnaldo > > > > > 1) change jevents.py so that an arch and model of none cause > > > generation of a pmu-events.c without any json. Add a SPDX and > > > autogenerated warning to the start of the file. > > > > 2) change Build so that if a generated pmu-events.c for arch none and > > > model none doesn't match empty-pmu-events.c the build fails with a > > > cat of the differences. Update Makefile.perf to clean up the files > > > used for this. > > > > > > 3) update empty-pmu-events.c to match the output of jevents.py with > > > arch and mode of none. > > > > > > Signed-off-by: Ian Rogers > > > Reviewed-by: John Garry > > > --- > > > tools/perf/Makefile.perf | 2 + > > > tools/perf/pmu-events/Build | 12 +- > > > tools/perf/pmu-events/empty-pmu-events.c | 894 ++++++++++++++--------- > > > tools/perf/pmu-events/jevents.py | 6 +- > > > 4 files changed, 562 insertions(+), 352 deletions(-) > > > > > > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf > > > index 175e4c7898f0..76bb0925849a 100644 > > > --- a/tools/perf/Makefile.perf > > > +++ b/tools/perf/Makefile.perf > > > @@ -1252,6 +1252,8 @@ clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $( > > > $(OUTPUT)util/intel-pt-decoder/inat-tables.c \ > > > $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ > > > $(OUTPUT)pmu-events/pmu-events.c \ > > > + $(OUTPUT)pmu-events/test-empty-pmu-events.c \ > > > + $(OUTPUT)pmu-events/empty-pmu-events.log \ > > > $(OUTPUT)pmu-events/metric_test.log \ > > > $(OUTPUT)$(fadvise_advice_array) \ > > > $(OUTPUT)$(fsconfig_arrays) \ > > > diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build > > > index 1d18bb89402e..c3fa43c49706 100644 > > > --- a/tools/perf/pmu-events/Build > > > +++ b/tools/perf/pmu-events/Build > > > @@ -11,6 +11,8 @@ METRIC_TEST_PY = pmu-events/metric_test.py > > > EMPTY_PMU_EVENTS_C = pmu-events/empty-pmu-events.c > > > PMU_EVENTS_C = $(OUTPUT)pmu-events/pmu-events.c > > > METRIC_TEST_LOG = $(OUTPUT)pmu-events/metric_test.log > > > +TEST_EMPTY_PMU_EVENTS_C = $(OUTPUT)pmu-events/test-empty-pmu-events.c > > > +EMPTY_PMU_EVENTS_TEST_LOG = $(OUTPUT)pmu-events/empty-pmu-events.log > > > > > > ifeq ($(JEVENTS_ARCH),) > > > JEVENTS_ARCH=$(SRCARCH) > > > @@ -31,7 +33,15 @@ $(METRIC_TEST_LOG): $(METRIC_TEST_PY) $(METRIC_PY) > > > $(call rule_mkdir) > > > $(Q)$(call echo-cmd,test)$(PYTHON) $< 2> $@ || (cat $@ && false) > > > > > > -$(PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) > > > +$(TEST_EMPTY_PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) > > > + $(call rule_mkdir) > > > + $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) none none pmu-events/arch $@ > > > + > > > +$(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C) > > > + $(call rule_mkdir) > > > + $(Q)$(call echo-cmd,test)diff -u $? 2> $@ || (cat $@ && false) > > > + > > > +$(PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) $(EMPTY_PMU_EVENTS_TEST_LOG) > > > $(call rule_mkdir) > > > $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) pmu-events/arch $@ > > > endif > > > diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c > > > index 13727421d424..c592079982fb 100644 > > > --- a/tools/perf/pmu-events/empty-pmu-events.c > > > +++ b/tools/perf/pmu-events/empty-pmu-events.c > > > @@ -1,196 +1,193 @@ > > > -// SPDX-License-Identifier: GPL-2.0 > > > -/* > > > - * An empty pmu-events.c file used when there is no architecture json files in > > > - * arch or when the jevents.py script cannot be run. > > > - * > > > - * The test cpu/soc is provided for testing. > > > - */ > > > -#include "pmu-events/pmu-events.h" > > > + > > > +/* SPDX-License-Identifier: GPL-2.0 */ > > > +/* THIS FILE WAS AUTOGENERATED BY jevents.py arch=none model=none ! */ > > > + > > > +#include > > > #include "util/header.h" > > > #include "util/pmu.h" > > > #include > > > #include > > > > > > -static const struct pmu_event pmu_events__test_soc_cpu[] = { > > > - { > > > - .name = "l3_cache_rd", > > > - .event = "event=0x40", > > > - .desc = "L3 cache access, read", > > > - .topic = "cache", > > > - .long_desc = "Attributable Level 3 cache access, read", > > > - }, > > > - { > > > - .name = "segment_reg_loads.any", > > > - .event = "event=0x6,period=200000,umask=0x80", > > > - .desc = "Number of segment register loads", > > > - .topic = "other", > > > - }, > > > - { > > > - .name = "dispatch_blocked.any", > > > - .event = "event=0x9,period=200000,umask=0x20", > > > - .desc = "Memory cluster signals to block micro-op dispatch for any reason", > > > - .topic = "other", > > > - }, > > > - { > > > - .name = "eist_trans", > > > - .event = "event=0x3a,period=200000,umask=0x0", > > > - .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", > > > - .topic = "other", > > > - }, > > > - { > > > - .name = "uncore_hisi_ddrc.flux_wcmd", > > > - .event = "event=0x2", > > > - .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ", > > > - .topic = "uncore", > > > - .long_desc = "DDRC write commands", > > > - .pmu = "hisi_sccl,ddrc", > > > - }, > > > - { > > > - .name = "unc_cbo_xsnp_response.miss_eviction", > > > - .event = "event=0x22,umask=0x81", > > > - .desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core. Unit: uncore_cbox ", > > > - .topic = "uncore", > > > - .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", > > > - .pmu = "uncore_cbox", > > > - }, > > > - { > > > - .name = "event-hyphen", > > > - .event = "event=0xe0,umask=0x00", > > > - .desc = "UNC_CBO_HYPHEN. Unit: uncore_cbox ", > > > - .topic = "uncore", > > > - .long_desc = "UNC_CBO_HYPHEN", > > > - .pmu = "uncore_cbox", > > > - }, > > > - { > > > - .name = "event-two-hyph", > > > - .event = "event=0xc0,umask=0x00", > > > - .desc = "UNC_CBO_TWO_HYPH. Unit: uncore_cbox ", > > > - .topic = "uncore", > > > - .long_desc = "UNC_CBO_TWO_HYPH", > > > - .pmu = "uncore_cbox", > > > - }, > > > - { > > > - .name = "uncore_hisi_l3c.rd_hit_cpipe", > > > - .event = "event=0x7", > > > - .desc = "Total read hits. Unit: hisi_sccl,l3c ", > > > - .topic = "uncore", > > > - .long_desc = "Total read hits", > > > - .pmu = "hisi_sccl,l3c", > > > - }, > > > - { > > > - .name = "uncore_imc_free_running.cache_miss", > > > - .event = "event=0x12", > > > - .desc = "Total cache misses. Unit: uncore_imc_free_running ", > > > - .topic = "uncore", > > > - .long_desc = "Total cache misses", > > > - .pmu = "uncore_imc_free_running", > > > - }, > > > - { > > > - .name = "uncore_imc.cache_hits", > > > - .event = "event=0x34", > > > - .desc = "Total cache hits. Unit: uncore_imc ", > > > - .topic = "uncore", > > > - .long_desc = "Total cache hits", > > > - .pmu = "uncore_imc", > > > - }, > > > - { > > > - .name = "bp_l1_btb_correct", > > > - .event = "event=0x8a", > > > - .desc = "L1 BTB Correction", > > > - .topic = "branch", > > > - }, > > > - { > > > - .name = "bp_l2_btb_correct", > > > - .event = "event=0x8b", > > > - .desc = "L2 BTB Correction", > > > - .topic = "branch", > > > - }, > > > - { > > > - .name = 0, > > > - .event = 0, > > > - .desc = 0, > > > - }, > > > +struct compact_pmu_event { > > > + int offset; > > > }; > > > > > > -static const struct pmu_metric pmu_metrics__test_soc_cpu[] = { > > > - { > > > - .metric_expr = "1 / IPC", > > > - .metric_name = "CPI", > > > - }, > > > - { > > > - .metric_expr = "inst_retired.any / cpu_clk_unhalted.thread", > > > - .metric_name = "IPC", > > > - .metric_group = "group1", > > > - }, > > > - { > > > - .metric_expr = "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalted.thread / 2 ) * " > > > - "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) )))", > > > - .metric_name = "Frontend_Bound_SMT", > > > - }, > > > - { > > > - .metric_expr = "l1d\\-loads\\-misses / inst_retired.any", > > > - .metric_name = "dcache_miss_cpi", > > > - }, > > > - { > > > - .metric_expr = "l1i\\-loads\\-misses / inst_retired.any", > > > - .metric_name = "icache_miss_cycles", > > > - }, > > > - { > > > - .metric_expr = "(dcache_miss_cpi + icache_miss_cycles)", > > > - .metric_name = "cache_miss_cycles", > > > - .metric_group = "group1", > > > - }, > > > - { > > > - .metric_expr = "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit", > > > - .metric_name = "DCache_L2_All_Hits", > > > - }, > > > - { > > > - .metric_expr = "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + " > > > - "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", > > > - .metric_name = "DCache_L2_All_Miss", > > > - }, > > > - { > > > - .metric_expr = "DCache_L2_All_Hits + DCache_L2_All_Miss", > > > - .metric_name = "DCache_L2_All", > > > - }, > > > - { > > > - .metric_expr = "d_ratio(DCache_L2_All_Hits, DCache_L2_All)", > > > - .metric_name = "DCache_L2_Hits", > > > - }, > > > - { > > > - .metric_expr = "d_ratio(DCache_L2_All_Miss, DCache_L2_All)", > > > - .metric_name = "DCache_L2_Misses", > > > - }, > > > - { > > > - .metric_expr = "ipc + M2", > > > - .metric_name = "M1", > > > - }, > > > - { > > > - .metric_expr = "ipc + M1", > > > - .metric_name = "M2", > > > - }, > > > - { > > > - .metric_expr = "1/M3", > > > - .metric_name = "M3", > > > - }, > > > - { > > > - .metric_expr = "64 * l1d.replacement / 1000000000 / duration_time", > > > - .metric_name = "L1D_Cache_Fill_BW", > > > - }, > > > - { > > > - .metric_expr = 0, > > > - .metric_name = 0, > > > - }, > > > +struct pmu_table_entry { > > > + const struct compact_pmu_event *entries; > > > + uint32_t num_entries; > > > + struct compact_pmu_event pmu_name; > > > +}; > > > + > > > +static const char *const big_c_string = > > > +/* offset=0 */ "default_core\000" > > > +/* offset=13 */ "bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=0x8a\000\00000\000\000" > > > +/* offset=72 */ "bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=0x8b\000\00000\000\000" > > > +/* offset=131 */ "l3_cache_rd\000cache\000L3 cache access, read\000event=0x40\000\00000\000Attributable Level 3 cache access, read\000" > > > +/* offset=226 */ "segment_reg_loads.any\000other\000Number of segment register loads\000event=6,period=200000,umask=0x80\000\00000\000\000" > > > +/* offset=325 */ "dispatch_blocked.any\000other\000Memory cluster signals to block micro-op dispatch for any reason\000event=9,period=200000,umask=0x20\000\00000\000\000" > > > +/* offset=455 */ "eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions\000event=0x3a,period=200000\000\00000\000\000" > > > +/* offset=570 */ "hisi_sccl,ddrc\000" > > > +/* offset=585 */ "uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\000event=2\000\00000\000DDRC write commands\000" > > > +/* offset=671 */ "uncore_cbox\000" > > > +/* offset=683 */ "unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000event=0x22,umask=0x81\000\00000\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000" > > > +/* offset=914 */ "event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=0xe0\000\00000\000UNC_CBO_HYPHEN\000" > > > +/* offset=979 */ "event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=0xc0\000\00000\000UNC_CBO_TWO_HYPH\000" > > > +/* offset=1050 */ "hisi_sccl,l3c\000" > > > +/* offset=1064 */ "uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000event=7\000\00000\000Total read hits\000" > > > +/* offset=1144 */ "uncore_imc_free_running\000" > > > +/* offset=1168 */ "uncore_imc_free_running.cache_miss\000uncore\000Total cache misses\000event=0x12\000\00000\000Total cache misses\000" > > > +/* offset=1263 */ "uncore_imc\000" > > > +/* offset=1274 */ "uncore_imc.cache_hits\000uncore\000Total cache hits\000event=0x34\000\00000\000Total cache hits\000" > > > +/* offset=1352 */ "uncore_sys_ddr_pmu\000" > > > +/* offset=1371 */ "sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\000event=0x2b\000v8\00000\000\000" > > > +/* offset=1444 */ "uncore_sys_ccn_pmu\000" > > > +/* offset=1463 */ "sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\000config=0x2c\0000x01\00000\000\000" > > > +/* offset=1537 */ "uncore_sys_cmn_pmu\000" > > > +/* offset=1556 */ "sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache misses in first lookup result (high priority)\000eventid=1,type=5\000(434|436|43c|43a).*\00000\000\000" > > > +/* offset=1696 */ "CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000" > > > +/* offset=1718 */ "IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\000\000\000\000\000\000\000\00000" > > > +/* offset=1781 */ "Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000" > > > +/* offset=1947 */ "dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000" > > > +/* offset=2011 */ "icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000" > > > +/* offset=2078 */ "cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_cycles\000\000\000\000\000\000\000\00000" > > > +/* offset=2149 */ "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=2243 */ "DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\000\000\000\000\000\000\00000" > > > +/* offset=2377 */ "DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\000\000\000\000\000\000\000\00000" > > > +/* offset=2441 */ "DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_All)\000\000\000\000\000\000\000\00000" > > > +/* offset=2509 */ "DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2_All)\000\000\000\000\000\000\000\00000" > > > +/* offset=2579 */ "M1\000\000ipc + M2\000\000\000\000\000\000\000\00000" > > > +/* offset=2601 */ "M2\000\000ipc + M1\000\000\000\000\000\000\000\00000" > > > +/* offset=2623 */ "M3\000\0001 / M3\000\000\000\000\000\000\000\00000" > > > +/* offset=2643 */ "L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duration_time\000\000\000\000\000\000\000\00000" > > > +; > > > + > > > +static const struct compact_pmu_event pmu_events__test_soc_cpu_default_core[] = { > > > +{ 13 }, /* bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=0x8a\000\00000\000\000 */ > > > +{ 72 }, /* bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=0x8b\000\00000\000\000 */ > > > +{ 325 }, /* dispatch_blocked.any\000other\000Memory cluster signals to block micro-op dispatch for any reason\000event=9,period=200000,umask=0x20\000\00000\000\000 */ > > > +{ 455 }, /* eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions\000event=0x3a,period=200000\000\00000\000\000 */ > > > +{ 131 }, /* l3_cache_rd\000cache\000L3 cache access, read\000event=0x40\000\00000\000Attributable Level 3 cache access, read\000 */ > > > +{ 226 }, /* segment_reg_loads.any\000other\000Number of segment register loads\000event=6,period=200000,umask=0x80\000\00000\000\000 */ > > > +}; > > > +static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_ddrc[] = { > > > +{ 585 }, /* uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\000event=2\000\00000\000DDRC write commands\000 */ > > > +}; > > > +static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_l3c[] = { > > > +{ 1064 }, /* uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000event=7\000\00000\000Total read hits\000 */ > > > +}; > > > +static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_cbox[] = { > > > +{ 914 }, /* event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=0xe0\000\00000\000UNC_CBO_HYPHEN\000 */ > > > +{ 979 }, /* event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=0xc0\000\00000\000UNC_CBO_TWO_HYPH\000 */ > > > +{ 683 }, /* unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000event=0x22,umask=0x81\000\00000\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000 */ > > > +}; > > > +static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc[] = { > > > +{ 1274 }, /* uncore_imc.cache_hits\000uncore\000Total cache hits\000event=0x34\000\00000\000Total cache hits\000 */ > > > +}; > > > +static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc_free_running[] = { > > > +{ 1168 }, /* uncore_imc_free_running.cache_miss\000uncore\000Total cache misses\000event=0x12\000\00000\000Total cache misses\000 */ > > > + > > > +}; > > > + > > > +const struct pmu_table_entry pmu_events__test_soc_cpu[] = { > > > +{ > > > + .entries = pmu_events__test_soc_cpu_default_core, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_default_core), > > > + .pmu_name = { 0 /* default_core\000 */ }, > > > +}, > > > +{ > > > + .entries = pmu_events__test_soc_cpu_hisi_sccl_ddrc, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_ddrc), > > > + .pmu_name = { 570 /* hisi_sccl,ddrc\000 */ }, > > > +}, > > > +{ > > > + .entries = pmu_events__test_soc_cpu_hisi_sccl_l3c, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_l3c), > > > + .pmu_name = { 1050 /* hisi_sccl,l3c\000 */ }, > > > +}, > > > +{ > > > + .entries = pmu_events__test_soc_cpu_uncore_cbox, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_cbox), > > > + .pmu_name = { 671 /* uncore_cbox\000 */ }, > > > +}, > > > +{ > > > + .entries = pmu_events__test_soc_cpu_uncore_imc, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc), > > > + .pmu_name = { 1263 /* uncore_imc\000 */ }, > > > +}, > > > +{ > > > + .entries = pmu_events__test_soc_cpu_uncore_imc_free_running, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc_free_running), > > > + .pmu_name = { 1144 /* uncore_imc_free_running\000 */ }, > > > +}, > > > }; > > > > > > +static const struct compact_pmu_event pmu_metrics__test_soc_cpu_default_core[] = { > > > +{ 1696 }, /* CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000 */ > > > +{ 2377 }, /* DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\000\000\000\000\000\000\000\00000 */ > > > +{ 2149 }, /* 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 */ > > > +{ 2243 }, /* DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\000\000\000\000\000\000\00000 */ > > > +{ 2441 }, /* DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_All)\000\000\000\000\000\000\000\00000 */ > > > +{ 2509 }, /* DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2_All)\000\000\000\000\000\000\000\00000 */ > > > +{ 1781 }, /* Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000 */ > > > +{ 1718 }, /* IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\000\000\000\000\000\000\000\00000 */ > > > +{ 2643 }, /* L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duration_time\000\000\000\000\000\000\000\00000 */ > > > +{ 2579 }, /* M1\000\000ipc + M2\000\000\000\000\000\000\000\00000 */ > > > +{ 2601 }, /* M2\000\000ipc + M1\000\000\000\000\000\000\000\00000 */ > > > +{ 2623 }, /* M3\000\0001 / M3\000\000\000\000\000\000\000\00000 */ > > > +{ 2078 }, /* cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_cycles\000\000\000\000\000\000\000\00000 */ > > > +{ 1947 }, /* dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000 */ > > > +{ 2011 }, /* icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000 */ > > > + > > > +}; > > > + > > > +const struct pmu_table_entry pmu_metrics__test_soc_cpu[] = { > > > +{ > > > + .entries = pmu_metrics__test_soc_cpu_default_core, > > > + .num_entries = ARRAY_SIZE(pmu_metrics__test_soc_cpu_default_core), > > > + .pmu_name = { 0 /* default_core\000 */ }, > > > +}, > > > +}; > > > + > > > +static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_ccn_pmu[] = { > > > +{ 1463 }, /* sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\000config=0x2c\0000x01\00000\000\000 */ > > > +}; > > > +static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_cmn_pmu[] = { > > > +{ 1556 }, /* sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache misses in first lookup result (high priority)\000eventid=1,type=5\000(434|436|43c|43a).*\00000\000\000 */ > > > +}; > > > +static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_ddr_pmu[] = { > > > +{ 1371 }, /* sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\000event=0x2b\000v8\00000\000\000 */ > > > + > > > +}; > > > + > > > +const struct pmu_table_entry pmu_events__test_soc_sys[] = { > > > +{ > > > + .entries = pmu_events__test_soc_sys_uncore_sys_ccn_pmu, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ccn_pmu), > > > + .pmu_name = { 1444 /* uncore_sys_ccn_pmu\000 */ }, > > > +}, > > > +{ > > > + .entries = pmu_events__test_soc_sys_uncore_sys_cmn_pmu, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_cmn_pmu), > > > + .pmu_name = { 1537 /* uncore_sys_cmn_pmu\000 */ }, > > > +}, > > > +{ > > > + .entries = pmu_events__test_soc_sys_uncore_sys_ddr_pmu, > > > + .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ddr_pmu), > > > + .pmu_name = { 1352 /* uncore_sys_ddr_pmu\000 */ }, > > > +}, > > > +}; > > > + > > > + > > > /* Struct used to make the PMU event table implementation opaque to callers. */ > > > struct pmu_events_table { > > > - const struct pmu_event *entries; > > > + const struct pmu_table_entry *pmus; > > > + uint32_t num_pmus; > > > }; > > > > > > /* Struct used to make the PMU metric table implementation opaque to callers. */ > > > struct pmu_metrics_table { > > > - const struct pmu_metric *entries; > > > + const struct pmu_table_entry *pmus; > > > + uint32_t num_pmus; > > > }; > > > > > > /* > > > @@ -202,92 +199,191 @@ struct pmu_metrics_table { > > > * The cpuid can contain any character other than the comma. > > > */ > > > struct pmu_events_map { > > > - const char *arch; > > > - const char *cpuid; > > > - const struct pmu_events_table event_table; > > > - const struct pmu_metrics_table metric_table; > > > + const char *arch; > > > + const char *cpuid; > > > + struct pmu_events_table event_table; > > > + struct pmu_metrics_table metric_table; > > > }; > > > > > > /* > > > * Global table mapping each known CPU for the architecture to its > > > * table of PMU events. > > > */ > > > -static const struct pmu_events_map pmu_events_map[] = { > > > - { > > > - .arch = "testarch", > > > - .cpuid = "testcpu", > > > - .event_table = { pmu_events__test_soc_cpu }, > > > - .metric_table = { pmu_metrics__test_soc_cpu }, > > > - }, > > > - { > > > - .arch = 0, > > > - .cpuid = 0, > > > - .event_table = { 0 }, > > > - .metric_table = { 0 }, > > > - }, > > > -}; > > > - > > > -static const struct pmu_event pmu_events__test_soc_sys[] = { > > > - { > > > - .name = "sys_ddr_pmu.write_cycles", > > > - .event = "event=0x2b", > > > - .desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", > > > - .compat = "v8", > > > - .topic = "uncore", > > > - .pmu = "uncore_sys_ddr_pmu", > > > - }, > > > - { > > > - .name = "sys_ccn_pmu.read_cycles", > > > - .event = "config=0x2c", > > > - .desc = "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ", > > > - .compat = "0x01", > > > - .topic = "uncore", > > > - .pmu = "uncore_sys_ccn_pmu", > > > - }, > > > - { > > > - .name = "sys_cmn_pmu.hnf_cache_miss", > > > - .event = "eventid=0x1,type=0x5", > > > - .desc = "Counts total cache misses in first lookup result (high priority). Unit: uncore_sys_cmn_pmu ", > > > - .compat = "(434|436|43c|43a).*", > > > - .topic = "uncore", > > > - .pmu = "uncore_sys_cmn_pmu", > > > - }, > > > - { > > > - .name = 0, > > > - .event = 0, > > > - .desc = 0, > > > - }, > > > +const struct pmu_events_map pmu_events_map[] = { > > > +{ > > > + .arch = "testarch", > > > + .cpuid = "testcpu", > > > + .event_table = { > > > + .pmus = pmu_events__test_soc_cpu, > > > + .num_pmus = ARRAY_SIZE(pmu_events__test_soc_cpu), > > > + }, > > > + .metric_table = { > > > + .pmus = pmu_metrics__test_soc_cpu, > > > + .num_pmus = ARRAY_SIZE(pmu_metrics__test_soc_cpu), > > > + } > > > +}, > > > +{ > > > + .arch = 0, > > > + .cpuid = 0, > > > + .event_table = { 0, 0 }, > > > + .metric_table = { 0, 0 }, > > > +} > > > }; > > > > > > struct pmu_sys_events { > > > const char *name; > > > - const struct pmu_events_table table; > > > + struct pmu_events_table event_table; > > > + struct pmu_metrics_table metric_table; > > > }; > > > > > > static const struct pmu_sys_events pmu_sys_event_tables[] = { > > > { > > > - .table = { pmu_events__test_soc_sys }, > > > + .event_table = { > > > + .pmus = pmu_events__test_soc_sys, > > > + .num_pmus = ARRAY_SIZE(pmu_events__test_soc_sys) > > > + }, > > > .name = "pmu_events__test_soc_sys", > > > }, > > > { > > > - .table = { 0 } > > > + .event_table = { 0, 0 }, > > > + .metric_table = { 0, 0 }, > > > }, > > > }; > > > > > > -int pmu_events_table__for_each_event(const struct pmu_events_table *table, struct perf_pmu *pmu, > > > - pmu_event_iter_fn fn, void *data) > > > +static void decompress_event(int offset, struct pmu_event *pe) > > > +{ > > > + const char *p = &big_c_string[offset]; > > > + > > > + pe->name = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pe->topic = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pe->desc = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pe->event = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pe->compat = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pe->deprecated = *p - '0'; > > > + p++; > > > + pe->perpkg = *p - '0'; > > > + p++; > > > + pe->unit = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pe->long_desc = (*p == '\0' ? NULL : p); > > > +} > > > + > > > +static void decompress_metric(int offset, struct pmu_metric *pm) > > > { > > > - for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { > > > - int ret; > > > + const char *p = &big_c_string[offset]; > > > + > > > + pm->metric_name = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->metric_group = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->metric_expr = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->metric_threshold = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->desc = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->long_desc = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->unit = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->compat = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->metricgroup_no_group = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->default_metricgroup_name = (*p == '\0' ? NULL : p); > > > + while (*p++); > > > + pm->aggr_mode = *p - '0'; > > > + p++; > > > + pm->event_grouping = *p - '0'; > > > +} > > > > > > - if (pmu && !pmu__name_match(pmu, pe->pmu)) > > > +static int pmu_events_table__for_each_event_pmu(const struct pmu_events_table *table, > > > + const struct pmu_table_entry *pmu, > > > + pmu_event_iter_fn fn, > > > + void *data) > > > +{ > > > + int ret; > > > + struct pmu_event pe = { > > > + .pmu = &big_c_string[pmu->pmu_name.offset], > > > + }; > > > + > > > + for (uint32_t i = 0; i < pmu->num_entries; i++) { > > > + decompress_event(pmu->entries[i].offset, &pe); > > > + if (!pe.name) > > > continue; > > > + ret = fn(&pe, table, data); > > > + if (ret) > > > + return ret; > > > + } > > > + return 0; > > > + } > > > + > > > +static int pmu_events_table__find_event_pmu(const struct pmu_events_table *table, > > > + const struct pmu_table_entry *pmu, > > > + const char *name, > > > + pmu_event_iter_fn fn, > > > + void *data) > > > +{ > > > + struct pmu_event pe = { > > > + .pmu = &big_c_string[pmu->pmu_name.offset], > > > + }; > > > + int low = 0, high = pmu->num_entries - 1; > > > > > > - ret = fn(pe, table, data); > > > - if (ret) > > > - return ret; > > > - } > > > - return 0; > > > + while (low <= high) { > > > + int cmp, mid = (low + high) / 2; > > > + > > > + decompress_event(pmu->entries[mid].offset, &pe); > > > + > > > + if (!pe.name && !name) > > > + goto do_call; > > > + > > > + if (!pe.name && name) { > > > + low = mid + 1; > > > + continue; > > > + } > > > + if (pe.name && !name) { > > > + high = mid - 1; > > > + continue; > > > + } > > > + > > > + cmp = strcasecmp(pe.name, name); > > > + if (cmp < 0) { > > > + low = mid + 1; > > > + continue; > > > + } > > > + if (cmp > 0) { > > > + high = mid - 1; > > > + continue; > > > + } > > > + do_call: > > > + return fn ? fn(&pe, table, data) : 0; > > > + } > > > + return PMU_EVENTS__NOT_FOUND; > > > +} > > > + > > > +int pmu_events_table__for_each_event(const struct pmu_events_table *table, > > > + struct perf_pmu *pmu, > > > + pmu_event_iter_fn fn, > > > + void *data) > > > +{ > > > + for (size_t i = 0; i < table->num_pmus; i++) { > > > + const struct pmu_table_entry *table_pmu = &table->pmus[i]; > > > + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; > > > + int ret; > > > + > > > + if (pmu && !pmu__name_match(pmu, pmu_name)) > > > + continue; > > > + > > > + ret = pmu_events_table__for_each_event_pmu(table, table_pmu, fn, data); > > > + if (pmu || ret) > > > + return ret; > > > + } > > > + return 0; > > > } > > > > > > int pmu_events_table__find_event(const struct pmu_events_table *table, > > > @@ -296,14 +392,19 @@ int pmu_events_table__find_event(const struct pmu_events_table *table, > > > pmu_event_iter_fn fn, > > > void *data) > > > { > > > - for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { > > > - if (pmu && !pmu__name_match(pmu, pe->pmu)) > > > + for (size_t i = 0; i < table->num_pmus; i++) { > > > + const struct pmu_table_entry *table_pmu = &table->pmus[i]; > > > + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; > > > + int ret; > > > + > > > + if (!pmu__name_match(pmu, pmu_name)) > > > continue; > > > > > > - if (!strcasecmp(pe->name, name)) > > > - return fn(pe, table, data); > > > - } > > > - return -1000; > > > + ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data); > > > + if (ret != PMU_EVENTS__NOT_FOUND) > > > + return ret; > > > + } > > > + return PMU_EVENTS__NOT_FOUND; > > > } > > > > > > size_t pmu_events_table__num_events(const struct pmu_events_table *table, > > > @@ -311,160 +412,253 @@ size_t pmu_events_table__num_events(const struct pmu_events_table *table, > > > { > > > size_t count = 0; > > > > > > - for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { > > > - if (pmu && !pmu__name_match(pmu, pe->pmu)) > > > - continue; > > > + for (size_t i = 0; i < table->num_pmus; i++) { > > > + const struct pmu_table_entry *table_pmu = &table->pmus[i]; > > > + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; > > > > > > - count++; > > > - } > > > + if (pmu__name_match(pmu, pmu_name)) > > > + count += table_pmu->num_entries; > > > + } > > > return count; > > > } > > > > > > -int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn, > > > - void *data) > > > +static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics_table *table, > > > + const struct pmu_table_entry *pmu, > > > + pmu_metric_iter_fn fn, > > > + void *data) > > > +{ > > > + int ret; > > > + struct pmu_metric pm = { > > > + .pmu = &big_c_string[pmu->pmu_name.offset], > > > + }; > > > + > > > + for (uint32_t i = 0; i < pmu->num_entries; i++) { > > > + decompress_metric(pmu->entries[i].offset, &pm); > > > + if (!pm.metric_expr) > > > + continue; > > > + ret = fn(&pm, table, data); > > > + if (ret) > > > + return ret; > > > + } > > > + return 0; > > > +} > > > + > > > +int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, > > > + pmu_metric_iter_fn fn, > > > + void *data) > > > { > > > - for (const struct pmu_metric *pm = &table->entries[0]; pm->metric_expr; pm++) { > > > - int ret = fn(pm, table, data); > > > + for (size_t i = 0; i < table->num_pmus; i++) { > > > + int ret = pmu_metrics_table__for_each_metric_pmu(table, &table->pmus[i], > > > + fn, data); > > > + > > > + if (ret) > > > + return ret; > > > + } > > > + return 0; > > > +} > > > > > > - if (ret) > > > - return ret; > > > - } > > > - return 0; > > > +static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu) > > > +{ > > > + static struct { > > > + const struct pmu_events_map *map; > > > + struct perf_pmu *pmu; > > > + } last_result; > > > + static struct { > > > + const struct pmu_events_map *map; > > > + char *cpuid; > > > + } last_map_search; > > > + static bool has_last_result, has_last_map_search; > > > + const struct pmu_events_map *map = NULL; > > > + char *cpuid = NULL; > > > + size_t i; > > > + > > > + if (has_last_result && last_result.pmu == pmu) > > > + return last_result.map; > > > + > > > + cpuid = perf_pmu__getcpuid(pmu); > > > + > > > + /* > > > + * On some platforms which uses cpus map, cpuid can be NULL for > > > + * PMUs other than CORE PMUs. > > > + */ > > > + if (!cpuid) > > > + goto out_update_last_result; > > > + > > > + if (has_last_map_search && !strcmp(last_map_search.cpuid, cpuid)) { > > > + map = last_map_search.map; > > > + free(cpuid); > > > + } else { > > > + i = 0; > > > + for (;;) { > > > + map = &pmu_events_map[i++]; > > > + > > > + if (!map->arch) { > > > + map = NULL; > > > + break; > > > + } > > > + > > > + if (!strcmp_cpuid_str(map->cpuid, cpuid)) > > > + break; > > > + } > > > + free(last_map_search.cpuid); > > > + last_map_search.cpuid = cpuid; > > > + last_map_search.map = map; > > > + has_last_map_search = true; > > > + } > > > +out_update_last_result: > > > + last_result.pmu = pmu; > > > + last_result.map = map; > > > + has_last_result = true; > > > + return map; > > > } > > > > > > const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu) > > > { > > > - const struct pmu_events_table *table = NULL; > > > - char *cpuid = perf_pmu__getcpuid(pmu); > > > - int i; > > > + const struct pmu_events_map *map = map_for_pmu(pmu); > > > > > > - /* on some platforms which uses cpus map, cpuid can be NULL for > > > - * PMUs other than CORE PMUs. > > > - */ > > > - if (!cpuid) > > > - return NULL; > > > + if (!map) > > > + return NULL; > > > > > > - i = 0; > > > - for (;;) { > > > - const struct pmu_events_map *map = &pmu_events_map[i++]; > > > + if (!pmu) > > > + return &map->event_table; > > > > > > - if (!map->cpuid) > > > - break; > > > + for (size_t i = 0; i < map->event_table.num_pmus; i++) { > > > + const struct pmu_table_entry *table_pmu = &map->event_table.pmus[i]; > > > + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; > > > > > > - if (!strcmp_cpuid_str(map->cpuid, cpuid)) { > > > - table = &map->event_table; > > > - break; > > > - } > > > - } > > > - free(cpuid); > > > - return table; > > > + if (pmu__name_match(pmu, pmu_name)) > > > + return &map->event_table; > > > + } > > > + return NULL; > > > } > > > > > > const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu) > > > { > > > - const struct pmu_metrics_table *table = NULL; > > > - char *cpuid = perf_pmu__getcpuid(pmu); > > > - int i; > > > + const struct pmu_events_map *map = map_for_pmu(pmu); > > > > > > - /* on some platforms which uses cpus map, cpuid can be NULL for > > > - * PMUs other than CORE PMUs. > > > - */ > > > - if (!cpuid) > > > - return NULL; > > > + if (!map) > > > + return NULL; > > > > > > - i = 0; > > > - for (;;) { > > > - const struct pmu_events_map *map = &pmu_events_map[i++]; > > > + if (!pmu) > > > + return &map->metric_table; > > > > > > - if (!map->cpuid) > > > - break; > > > + for (size_t i = 0; i < map->metric_table.num_pmus; i++) { > > > + const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i]; > > > + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; > > > > > > - if (!strcmp_cpuid_str(map->cpuid, cpuid)) { > > > - table = &map->metric_table; > > > - break; > > > - } > > > - } > > > - free(cpuid); > > > - return table; > > > + if (pmu__name_match(pmu, pmu_name)) > > > + return &map->metric_table; > > > + } > > > + return NULL; > > > } > > > > > > const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid) > > > { > > > - for (const struct pmu_events_map *tables = &pmu_events_map[0]; > > > - tables->arch; > > > - tables++) { > > > - if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) > > > - return &tables->event_table; > > > - } > > > - return NULL; > > > + for (const struct pmu_events_map *tables = &pmu_events_map[0]; > > > + tables->arch; > > > + tables++) { > > > + if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) > > > + return &tables->event_table; > > > + } > > > + return NULL; > > > } > > > > > > const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid) > > > { > > > - for (const struct pmu_events_map *tables = &pmu_events_map[0]; > > > - tables->arch; > > > - tables++) { > > > - if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) > > > - return &tables->metric_table; > > > - } > > > - return NULL; > > > + for (const struct pmu_events_map *tables = &pmu_events_map[0]; > > > + tables->arch; > > > + tables++) { > > > + if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) > > > + return &tables->metric_table; > > > + } > > > + return NULL; > > > } > > > > > > int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) > > > { > > > - for (const struct pmu_events_map *tables = &pmu_events_map[0]; tables->arch; tables++) { > > > - int ret = pmu_events_table__for_each_event(&tables->event_table, > > > - /*pmu=*/ NULL, fn, data); > > > - > > > - if (ret) > > > - return ret; > > > - } > > > - return 0; > > > + for (const struct pmu_events_map *tables = &pmu_events_map[0]; > > > + tables->arch; > > > + tables++) { > > > + int ret = pmu_events_table__for_each_event(&tables->event_table, > > > + /*pmu=*/ NULL, fn, data); > > > + > > > + if (ret) > > > + return ret; > > > + } > > > + return 0; > > > } > > > > > > int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data) > > > { > > > - for (const struct pmu_events_map *tables = &pmu_events_map[0]; > > > - tables->arch; > > > - tables++) { > > > - int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data); > > > - > > > - if (ret) > > > - return ret; > > > - } > > > - return 0; > > > + for (const struct pmu_events_map *tables = &pmu_events_map[0]; > > > + tables->arch; > > > + tables++) { > > > + int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data); > > > + > > > + if (ret) > > > + return ret; > > > + } > > > + return 0; > > > } > > > > > > const struct pmu_events_table *find_sys_events_table(const char *name) > > > { > > > - for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; > > > - tables->name; > > > - tables++) { > > > - if (!strcmp(tables->name, name)) > > > - return &tables->table; > > > - } > > > - return NULL; > > > + for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; > > > + tables->name; > > > + tables++) { > > > + if (!strcmp(tables->name, name)) > > > + return &tables->event_table; > > > + } > > > + return NULL; > > > } > > > > > > int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) > > > { > > > - for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; > > > - tables->name; > > > - tables++) { > > > - int ret = pmu_events_table__for_each_event(&tables->table, /*pmu=*/ NULL, fn, data); > > > - > > > - if (ret) > > > - return ret; > > > - } > > > - return 0; > > > + for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; > > > + tables->name; > > > + tables++) { > > > + int ret = pmu_events_table__for_each_event(&tables->event_table, > > > + /*pmu=*/ NULL, fn, data); > > > + > > > + if (ret) > > > + return ret; > > > + } > > > + return 0; > > > } > > > > > > -int pmu_for_each_sys_metric(pmu_metric_iter_fn fn __maybe_unused, void *data __maybe_unused) > > > +int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data) > > > { > > > - return 0; > > > + for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; > > > + tables->name; > > > + tables++) { > > > + int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data); > > > + > > > + if (ret) > > > + return ret; > > > + } > > > + return 0; > > > } > > > > > > -const char *describe_metricgroup(const char *group __maybe_unused) > > > +static const int metricgroups[][2] = { > > > + > > > +}; > > > + > > > +const char *describe_metricgroup(const char *group) > > > { > > > - return NULL; > > > + int low = 0, high = (int)ARRAY_SIZE(metricgroups) - 1; > > > + > > > + while (low <= high) { > > > + int mid = (low + high) / 2; > > > + const char *mgroup = &big_c_string[metricgroups[mid][0]]; > > > + int cmp = strcmp(mgroup, group); > > > + > > > + if (cmp == 0) { > > > + return &big_c_string[metricgroups[mid][1]]; > > > + } else if (cmp < 0) { > > > + low = mid + 1; > > > + } else { > > > + high = mid - 1; > > > + } > > > + } > > > + return NULL; > > > } > > > diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py > > > index 731776e29f47..fcf0158438b5 100755 > > > --- a/tools/perf/pmu-events/jevents.py > > > +++ b/tools/perf/pmu-events/jevents.py > > > @@ -1256,6 +1256,10 @@ such as "arm/cortex-a34".''', > > > 'output_file', type=argparse.FileType('w', encoding='utf-8'), nargs='?', default=sys.stdout) > > > _args = ap.parse_args() > > > > > > + _args.output_file.write(f""" > > > +/* SPDX-License-Identifier: GPL-2.0 */ > > > +/* THIS FILE WAS AUTOGENERATED BY jevents.py arch={_args.arch} model={_args.model} ! */ > > > +""") > > > _args.output_file.write(""" > > > #include > > > #include "util/header.h" > > > @@ -1281,7 +1285,7 @@ struct pmu_table_entry { > > > if item.name == _args.arch or _args.arch == 'all' or item.name == 'test': > > > archs.append(item.name) > > > > > > - if len(archs) < 2: > > > + if len(archs) < 2 and _args.arch != 'none': > > > raise IOError(f'Missing architecture directory \'{_args.arch}\'') > > > > > > archs.sort() > > > -- > > > 2.46.0.rc2.264.g509ed76dc8-goog > > >