From nobody Thu Oct 2 04:45:11 2025 Received: from mail-oa1-f74.google.com (mail-oa1-f74.google.com [209.85.160.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 C4DE8286411 for ; Tue, 23 Sep 2025 04:19:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758601152; cv=none; b=AwWK1R3AO6GustsnRBLCayRXETp+Z1foGB5ftK5egs19SGX2sy8p6ce3gwmh9ZbKl7ofh62dcc+W/nqN15MDsY63zIRcIv489wZmzJb+sOsBIbem5VFq8MT+8H2G52hv/aJ7b6R7EF7cZtv1C/V3c6Tnk9FoIFI+j21ZemPjsOg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758601152; c=relaxed/simple; bh=CMduCjqBA/Wi7VhUjPRGoRK3mmj52zUlmUQaGY9zENA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ks8ESJN0W9RY15pWZ0hk6JaiQh7nAGR7bjpy9ySi0pk4ELvMXSsGTJhYAWyO7e1v5khZZuXCmXPy4LtHtEAcCua+S1nXhUo/pjj5sq7fJbjmBM45vV5Digu7+Dk4P9xR+DgXJGfxVXHamw5TTTksKvCopK5DuRUMMYyKpxXgk4w= 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=h4G5i6cf; arc=none smtp.client-ip=209.85.160.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="h4G5i6cf" Received: by mail-oa1-f74.google.com with SMTP id 586e51a60fabf-34881ca6496so1047767fac.3 for ; Mon, 22 Sep 2025 21:19:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758601150; x=1759205950; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=gXWsyKpVIm9tK1LP8X9UFZu1lqOtBLOTURfJn39imz4=; b=h4G5i6cfI/IoePa2DyrJtR7VQ/BcgxB7tTgQlpTyf1947uZ+Vte7oX7UroZt6xu5QX 7SK5HAiMShv8SB0tzjC34ybdOavSbqfpa2tNX34gsaYwuW0TssZFTEuZ9bfZiio8MKIW 3uB0yFjIU6qBXHjFMdCzEFcAriC+cuo2khTDneRGiuHwswy/TFa5Cw/UHajMFjHlzTqL vnHYlh2b6fhnYjIeGM3edsBVpNq13TzWMv+HyW0Q/jmOXwf4qoUMIIjIeXiY4e6p0PFn jptbNYzJVDURNR/wxJkEakMPbRAE5j9dIZwg352gDt414I2bQa2QE1Yzj/WUvA2oLE3L sQpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758601150; x=1759205950; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gXWsyKpVIm9tK1LP8X9UFZu1lqOtBLOTURfJn39imz4=; b=MAuJGcWHXPgwTxzAjdV3fWbJMf8xIGhAgkhfVsdiv9Niv+fa2CHf++p3Phs7DAmAn0 u5stDzdagmJCjd3D9hQ8Da6oDZ53cwBLgmX929ZyAUs082nSL4O+4YiX/y29Tc0IJS+f CwFKbG9OPrtB7HbcR50yGjHLByfluboIleiHxKgz4pjTWKM/gHG2XfgkV6Xvrb6T5LXQ TUQ9xrKV8Q6wl9jI4eTq7bioXcIk/0gWDwMdDp8ohcYV5bQOU69N/Jf9reC62QOaa9wT lwok64qCki5X/jClGh9rzyWnHTp8BAONCR+uHuANjnVVQ2aD3vUSkJljfyyDSLRKJ3wG A2Aw== X-Forwarded-Encrypted: i=1; AJvYcCUYhUmJJYO6uC0fEvRA3QNwV1nS8qYRIAt6Xy7YBHOJ7D4tPSjP3lzT0yXHvdS9kYyViN4/+W9ANr704Qg=@vger.kernel.org X-Gm-Message-State: AOJu0YzzdHmKk3v07q9kDiwSTxAXSBj77Z+NVMF3il1C79oB555hb7PZ KN7q/QOYo8prlfyTBZmAk9Wn+B0Wyjmu7EWp9merWXWQ047YJy6HQQFSZWPdxl6PzSPVPjexJaw QsyKPCe07zvCh2rLvTdamvlj4YW8bileiiBksiyxlWvHSN9nL+aSzupDwyzCCWvyFuS5iqLm2Mf 4= X-Google-Smtp-Source: AGHT+IFq3V7wUXQP4BsMt94Zw+8KGjZpLGI978bXeRdfbKs4qhenLUCWC19gS1jFzXNEJ2Cr8Bj+PJ7iHqZm X-Received: from oabqo3.prod.google.com ([2002:a05:6870:ff43:b0:32a:531e:81c7]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6871:c08a:b0:2b8:fab0:33c with SMTP id 586e51a60fabf-34c85be5bb9mr609448fac.23.1758601149899; Mon, 22 Sep 2025 21:19:09 -0700 (PDT) Date: Mon, 22 Sep 2025 21:18:29 -0700 In-Reply-To: <20250923041844.400164-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: <20250923041844.400164-1-irogers@google.com> X-Mailer: git-send-email 2.51.0.534.gc79095c0ca-goog Message-ID: <20250923041844.400164-11-irogers@google.com> Subject: [PATCH v5 10/25] 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 Cc: Thomas Richter 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 ``` Tested-by: Thomas Richter 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 c3c934da6083..f9c52eadac46 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -868,6 +868,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) @@ -919,6 +921,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; @@ -1076,6 +1080,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(parse_state->error, term->err_term, strdup(parse_events__term_type_str(term->type_term)), @@ -1098,10 +1104,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_state *parse_state) { + if (term->type_term =3D=3D PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG= ) { + if (check_type_val(term, parse_state->error, PARSE_EVENTS__TERM_TYPE_NUM= )) + return -EINVAL; + if (term->val.num >=3D PERF_COUNT_HW_MAX) { + parse_events_error__handle(parse_state->error, term->err_val, + strdup("too big"), + NULL); + return -EINVAL; + } + if (!check_pmu_is_core(attr->type, term, parse_state->error)) + 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, parse_state->error, 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(parse_state->error, term->err_val, + strdup("too big"), + NULL); + return -EINVAL; + } + if (!check_pmu_is_core(attr->type, term, parse_state->error)) + 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 @@ -1188,6 +1252,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: @@ -1327,6 +1393,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: @@ -1365,6 +1433,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 048b38e476f3..0db5e223e10d 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 294e943bcdb4..29a8d43a47a9 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -337,6 +337,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.534.gc79095c0ca-goog