From nobody Fri Oct 3 16:41:00 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 BB91B342CB6 for ; Thu, 28 Aug 2025 21:00:10 +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=1756414813; cv=none; b=UdpfNTsg6+AQCZ8n8Ai7bjLuUvN8tE/+hJVGcIVidiEZ4BcfFxkgeSbS7VqowK7n4pc4LnoydNKhws5UfXuuFn7RiEo1tUeyvaECk/BifIAouxXElBdowv1GsWeATCNMf54U7pLwfzXgLWap9w0GvCrbwaqkQEhijdPGEpD3MW4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756414813; c=relaxed/simple; bh=X42WdZdn268cHVVRkgCtodeu48yxGl9Bk6CL9/MFbE8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=N/PAo0bWi48Dtt8rQXVuEL/BjPiz5veP7TWGzpjOI/K9kqFwZZiRxqnIpsC41hl3Xtd0LPmZST2y4/gproPsf3t5cG67CpYmOpKhmYh/AeReRaOIFMxscvwAjPs5CwYqfzbL5+MIX7ZG/CX5t0kjWuSio5IciVu6a1GvrtLcwCo= 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=y9ZKIfxp; 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="y9ZKIfxp" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-246eb38205fso15937045ad.0 for ; Thu, 28 Aug 2025 14:00:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1756414810; x=1757019610; 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=raVnQQrUsMLBKUlzhVWn42yShZxCM0U3C2BVrtenBbI=; b=y9ZKIfxpgkJj5J5bkeHKuWVUHuFdiKRjLmiizLoT6vM5TVRSj+UjesNPm7ott85nHK hILykGaSM0f2m+x7uhTxhpG+uNbycEzg/cU2v+A/dWPkbZ7M1Y0tHyacjc4/kTdt8hG9 TC6YYyo3U/L+JlumGklEw0DtueAGs4Yz1HOkFkUoJO/hDD/MG6QxlmhJurODyJePf5F9 SBW6me58NAOesOfdIM3rLLk26iI6LOCM4Ux3yMxsZV0dtR8OxkUAPOCacQx3x6Na7lcL XNchjjeC4dW0Xi9+OkOGhohGY6XG5ZrZMnpTFVHl+Y9TRe+fe5ut3RpkvewxauX7bfA7 kOQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756414810; x=1757019610; 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=raVnQQrUsMLBKUlzhVWn42yShZxCM0U3C2BVrtenBbI=; b=hylZR2osseQFB8lCnv0jAEAsy3X2ckOxWu0IY3z5bLyBcYuj+yoNSIhuj/m/AJmwtl 47dXiaAoEiJVGlHi2FV61cdEhm6jg0LOX9SBkmjCNJuNFdhlMuDB9VQTuC+V5CcMRHvP 6WLdoP4dNbICtLAIGvDNyojq1WIjl/kKJZU9JlO3biIm64lAnNJ0VP3EGdJWIqchM+vF MAmkhxI+muBQ24N8hIMLNU1lhuqaNdSu21lnud0rfZRidFx7ch0rk6cufLJyPBWsqk4e EFM8UX9LbldswozULzCmn/5B+M1G+Xwy5BCliVcOV3WH1AAYrdf9DOYAM0U3hosSIb1i s5OQ== X-Forwarded-Encrypted: i=1; AJvYcCUKWd3g+5tS+/EEZ+NI7iotcyWQMs716E/3OpHGqAFTOx7xcKvyzRTY2E29QfLjvsM7aVXE9ssHWurQ9nE=@vger.kernel.org X-Gm-Message-State: AOJu0YwtJnoiD/EJ2aZFuggII6jnEF4+HjCgX+CF7juuKdmeyIwYSP8g iu6qabMJNcfaV07wk5F1pNXOHHkVUdE85eD6XputigiMv2ZCznpI5ISvrAp2seGUapDtKL1j1xV qfPnZijvMo+r8COhGO9KFNGQET+XWV84oemTGMGyDNuhturumsMnqEwi8bpUqLvbuOPcTehrqrE 8= X-Google-Smtp-Source: AGHT+IG7zD9HQ83vhEHzgcwj0S2zFT3t86/dQmC0Eg/KReMgNxR5eLfXSMv3Dcqe9AGzRvUbzUtLkUSyuYaC X-Received: from pllm1.prod.google.com ([2002:a17:902:7681:b0:248:f76d:2c69]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:943:b0:243:47f:c41 with SMTP id d9443c01a7336-2462efae4fdmr313798465ad.57.1756414810005; Thu, 28 Aug 2025 14:00:10 -0700 (PDT) Date: Thu, 28 Aug 2025 13:59:24 -0700 In-Reply-To: <20250828205930.4007284-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: <20250828205930.4007284-1-irogers@google.com> X-Mailer: git-send-email 2.51.0.318.gd7df087d1a-goog Message-ID: <20250828205930.4007284-10-irogers@google.com> Subject: [PATCH v3 09/15] perf parse-events: Add terms for legacy hardware and cache config 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 , Thomas Falcon , Andi Kleen , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, bpf@vger.kernel.org, Atish Patra , Beeman Strong , Leo Yan , Vince Weaver X-ccpol: medium Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the PMU terms legacy-hardware-config and legacy-cache-config. These terms are similar to the config term in that their values are assigned to the perf_event_attr config value. They differ in that the PMU type is switched to be either PERF_TYPE_HARDWARE or PERF_TYPE_HW_CACHE, and the PMU type is moved into the extended type information of the config value. This will allow later patches to add legacy events to json. An example use of the terms is in the following: ``` $ perf stat -vv -e 'cpu/legacy-hardware-config=3D1/,cpu/legacy-cache-config= =3D0x10001/' true Using CPUID GenuineIntel-6-8D-1 Attempt to add: cpu/legacy-hardware-config=3D0x1/ ..after resolving event: cpu/legacy-hardware-config=3D0x1/ Attempt to add: cpu/legacy-cache-config=3D0x10001/ ..after resolving event: cpu/legacy-cache-config=3D0x10001/ Control descriptor is not initialized ------------------------------------------------------------ perf_event_attr: type 0 (PERF_TYPE_HARDWARE) size 136 config 0x1 (PERF_COUNT_HW_INSTRUCTIONS) sample_type IDENTIFIER read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING disabled 1 inherit 1 enable_on_exec 1 ------------------------------------------------------------ sys_perf_event_open: pid 994937 cpu -1 group_fd -1 flags 0x8 =3D 3 ------------------------------------------------------------ perf_event_attr: type 3 (PERF_TYPE_HW_CACHE) size 136 config 0x10001 (PERF_COUNT_HW_CACHE_RESULT_MISS= | PERF_COUNT_HW_CACHE_OP_READ | PERF_COUNT_HW_CACHE_L1I) sample_type IDENTIFIER read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING disabled 1 inherit 1 enable_on_exec 1 ------------------------------------------------------------ sys_perf_event_open: pid 994937 cpu -1 group_fd -1 flags 0x8 =3D 4 cpu/legacy-hardware-config=3D1/: -1: 1364046 414756 414756 cpu/legacy-cache-config=3D0x10001/: -1: 57453 414756 414756 cpu/legacy-hardware-config=3D1/: 1364046 414756 414756 cpu/legacy-cache-config=3D0x10001/: 57453 414756 414756 Performance counter stats for 'true': 1,364,046 cpu/legacy-hardware-config=3D1/ 57,453 cpu/legacy-cache-config=3D0x10001/ 0.001988593 seconds time elapsed 0.002194000 seconds user 0.000000000 seconds sys ``` Signed-off-by: Ian Rogers --- tools/perf/util/parse-events.c | 70 ++++++++++++++++++++++++++++++++++ tools/perf/util/parse-events.h | 4 +- tools/perf/util/parse-events.l | 2 + tools/perf/util/pmu.c | 30 +++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 37aa392ddaf2..be3e86e7b157 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -860,6 +860,8 @@ const char *parse_events__term_type_str(enum parse_even= ts__term_type term_type) [PARSE_EVENTS__TERM_TYPE_RAW] =3D "raw", [PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE] =3D "legacy-cache", [PARSE_EVENTS__TERM_TYPE_HARDWARE] =3D "hardware", + [PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG] =3D "legacy-hardware-co= nfig", + [PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG] =3D "legacy-cache-config", [PARSE_EVENTS__TERM_TYPE_CPU] =3D "cpu", }; if ((unsigned int)term_type >=3D __PARSE_EVENTS__TERM_TYPE_NR) @@ -911,6 +913,8 @@ config_term_avail(enum parse_events__term_type term_typ= e, struct parse_events_er case PARSE_EVENTS__TERM_TYPE_RAW: case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE: case PARSE_EVENTS__TERM_TYPE_HARDWARE: + case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: + case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: default: if (!err) return false; @@ -1068,6 +1072,8 @@ do { \ case PARSE_EVENTS__TERM_TYPE_USER: case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE: case PARSE_EVENTS__TERM_TYPE_HARDWARE: + case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: + case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: default: parse_events_error__handle(err, term->err_term, strdup(parse_events__term_type_str(term->type_term)), @@ -1090,10 +1096,68 @@ do { \ #undef CHECK_TYPE_VAL } =20 +static bool check_pmu_is_core(__u32 type, const struct parse_events_term *= term, + struct parse_events_error *err) +{ + struct perf_pmu *pmu =3D NULL; + + /* Avoid loading all PMUs with perf_pmus__find_by_type, just scan the cor= e ones. */ + while ((pmu =3D perf_pmus__scan_core(pmu)) !=3D NULL) { + if (pmu->type =3D=3D type) + return true; + } + parse_events_error__handle(err, term->err_val, + strdup("needs a core PMU"), + NULL); + return false; +} + static int config_term_pmu(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err) { + if (term->type_term =3D=3D PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG= ) { + if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_NUM)) + return -EINVAL; + if (term->val.num >=3D PERF_COUNT_HW_MAX) { + parse_events_error__handle(err, term->err_val, + strdup("too big"), + NULL); + return -EINVAL; + } + if (!check_pmu_is_core(attr->type, term, err)) + return -EINVAL; + attr->config =3D term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |=3D (__u64)attr->type << PERF_PMU_TYPE_SHIFT; + attr->type =3D PERF_TYPE_HARDWARE; + return 0; + } + if (term->type_term =3D=3D PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG) { + int cache_type, cache_op, cache_result; + + if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_NUM)) + return -EINVAL; + cache_type =3D term->val.num & 0xFF; + cache_op =3D (term->val.num >> 8) & 0xFF; + cache_result =3D (term->val.num >> 16) & 0xFF; + if ((term->val.num & ~0xFFFFFF) || + cache_type >=3D PERF_COUNT_HW_CACHE_MAX || + cache_op >=3D PERF_COUNT_HW_CACHE_OP_MAX || + cache_result >=3D PERF_COUNT_HW_CACHE_RESULT_MAX) { + parse_events_error__handle(err, term->err_val, + strdup("too big"), + NULL); + return -EINVAL; + } + if (!check_pmu_is_core(attr->type, term, err)) + return -EINVAL; + attr->config =3D term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |=3D (__u64)attr->type << PERF_PMU_TYPE_SHIFT; + attr->type =3D PERF_TYPE_HW_CACHE; + return 0; + } if (term->type_term =3D=3D PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE) { struct perf_pmu *pmu =3D perf_pmus__find_by_type(attr->type); =20 @@ -1180,6 +1244,8 @@ static int config_term_tracepoint(struct perf_event_a= ttr *attr, case PARSE_EVENTS__TERM_TYPE_CONFIG1: case PARSE_EVENTS__TERM_TYPE_CONFIG2: case PARSE_EVENTS__TERM_TYPE_CONFIG3: + case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: + case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: case PARSE_EVENTS__TERM_TYPE_NAME: case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: @@ -1321,6 +1387,8 @@ do { \ case PARSE_EVENTS__TERM_TYPE_CONFIG1: case PARSE_EVENTS__TERM_TYPE_CONFIG2: case PARSE_EVENTS__TERM_TYPE_CONFIG3: + case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: + case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: case PARSE_EVENTS__TERM_TYPE_NAME: case PARSE_EVENTS__TERM_TYPE_METRIC_ID: case PARSE_EVENTS__TERM_TYPE_RAW: @@ -1359,6 +1427,8 @@ static int get_config_chgs(struct perf_pmu *pmu, stru= ct parse_events_terms *head case PARSE_EVENTS__TERM_TYPE_CONFIG1: case PARSE_EVENTS__TERM_TYPE_CONFIG2: case PARSE_EVENTS__TERM_TYPE_CONFIG3: + case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: + case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: case PARSE_EVENTS__TERM_TYPE_NAME: case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 660303e591ad..a64f0741cb4b 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -82,7 +82,9 @@ enum parse_events__term_type { PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE, PARSE_EVENTS__TERM_TYPE_HARDWARE, PARSE_EVENTS__TERM_TYPE_CPU, -#define __PARSE_EVENTS__TERM_TYPE_NR (PARSE_EVENTS__TERM_TYPE_CPU + 1) + PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG, + PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG, +#define __PARSE_EVENTS__TERM_TYPE_NR (PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE= _CONFIG + 1) }; =20 struct parse_events_term { diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 2034590eb789..b5058b6b49d3 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -336,6 +336,8 @@ aux-action { return term(yyscanner, PARSE_EVENTS__TERM= _TYPE_AUX_ACTION); } aux-sample-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_SAMP= LE_SIZE); } metric-id { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_METRIC_ID); } cpu { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CPU); } +legacy-hardware-config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_L= EGACY_HARDWARE_CONFIG); } +legacy-cache-config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_LEGAC= Y_CACHE_CONFIG); } cpu-cycles|cycles { return hw_term(yyscanner, PERF_COUNT_HW_CPU_CYCLES)= ; } stalled-cycles-frontend|idle-cycles-frontend { return hw_term(yyscanner, P= ERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } stalled-cycles-backend|idle-cycles-backend { return hw_term(yyscanner, PER= F_COUNT_HW_STALLED_CYCLES_BACKEND); } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 36b880bf6bbf..f718eb41af88 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1532,6 +1532,34 @@ static int pmu_config_term(const struct perf_pmu *pm= u, assert(term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_NUM); pmu_format_value(bits, term->val.num, &attr->config3, zero); break; + case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: + assert(term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_NUM); + assert(term->val.num < PERF_COUNT_HW_MAX); + assert(pmu->is_core); + attr->config =3D term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |=3D (__u64)pmu->type << PERF_PMU_TYPE_SHIFT; + attr->type =3D PERF_TYPE_HARDWARE; + break; + case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: { +#ifndef NDEBUG + int cache_type =3D term->val.num & 0xFF; + int cache_op =3D (term->val.num >> 8) & 0xFF; + int cache_result =3D (term->val.num >> 16) & 0xFF; + + assert(cache_type < PERF_COUNT_HW_CACHE_MAX); + assert(cache_op < PERF_COUNT_HW_CACHE_OP_MAX); + assert(cache_result < PERF_COUNT_HW_CACHE_RESULT_MAX); +#endif + assert(term->type_val =3D=3D PARSE_EVENTS__TERM_TYPE_NUM); + assert((term->val.num & ~0xFFFFFF) =3D=3D 0); + assert(pmu->is_core); + attr->config =3D term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |=3D (__u64)pmu->type << PERF_PMU_TYPE_SHIFT; + attr->type =3D PERF_TYPE_HW_CACHE; + break; + } case PARSE_EVENTS__TERM_TYPE_USER: /* Not hardcoded. */ return -EINVAL; case PARSE_EVENTS__TERM_TYPE_NAME ... PARSE_EVENTS__TERM_TYPE_CPU: @@ -1923,6 +1951,8 @@ int perf_pmu__for_each_format(struct perf_pmu *pmu, v= oid *state, pmu_format_call "config1=3D0..0xffffffffffffffff", "config2=3D0..0xffffffffffffffff", "config3=3D0..0xffffffffffffffff", + "legacy-hardware-config=3D0..9,", + "legacy-cache-config=3D0..0xffffff,", "name=3Dstring", "period=3Dnumber", "freq=3Dnumber", --=20 2.51.0.318.gd7df087d1a-goog