From mboxrd@z Thu Jan 1 00:00:00 1970 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 1490E2BEC28 for ; Thu, 28 Aug 2025 21:00:10 +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=1756414813; cv=none; b=HxKNEB8KWTr8xK+1jz36LZaGzOBnb8JQ0ueFBeINYf+1KmVU35LEYG0kmFLmiZ0AMwLiJ57wm4CJjVGHuvZ62e2Aiw4kucUTcCR2OCx2JIvyOiA25MoRmR07ZR8RtlwxkvoaqxUnfLSEI5yQ93W28UEqKgTSK6CKYEE6ddRpPuo= 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.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="y9ZKIfxp" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2445806b18aso15739045ad.1 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=bVJtgPnEhAAkoAQFJYNHzPTYzsXAvOKZDbrrv7Orx37YiV3O5xOJBK6TNJizf+um+y 73Ru+QAmgD1lMYhm80EHYWGHxGn6gilWxOwxZ93OzKLK/RSv6DvSbi8w2u0CJtDCU6hT g0vcS4HVOiEMZW7HaSWQTC3848P+Isq+RQX329TDhWlJjh3YyytGXRcnvIxCtuytFpaa pWCkUoHFQeYHTknxZhfFMbu3wPshy2vGZdrbV8fRMRfuEZyT855LOAdpjIjxWPjMb79N Fu7Vfr3tSb4w8SKcRuqZwUFo+FfdIiXmjwtGcIG/US5sZB1vGPqHancplTvxS+6OCcop kuHA== X-Forwarded-Encrypted: i=1; AJvYcCUq+MaaB8Rn1uZMYvwo4l9/5/ZjuNXYAn4DRv6xHN4hjGug/kMFyLBJJ20TV3NRLwnlIz8=@vger.kernel.org X-Gm-Message-State: AOJu0YzsdZMf+PH6jrybA20mfHj4Qq00NkR/Q0JwtnljNSy+AwJ3/wFM mprXb4p3udgx0DXR8IxjYDIpbCTxDdAEGo+SH8XA/qd9SJWHaEBQ3XJGZJqE7PDzv83GIznICtg iJrSN5pycT7iXVlM+8u/bClZym08fl5mfunmyOvJqVBzKKdLQT4mlYvb6/c6vXE0= 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: bpf@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 Content-Type: text/plain; charset="UTF-8" X-ccpol: medium 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=1/,cpu/legacy-cache-config=0x10001/' true Using CPUID GenuineIntel-6-8D-1 Attempt to add: cpu/legacy-hardware-config=0x1/ ..after resolving event: cpu/legacy-hardware-config=0x1/ Attempt to add: cpu/legacy-cache-config=0x10001/ ..after resolving event: cpu/legacy-cache-config=0x10001/ 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 = 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 = 4 cpu/legacy-hardware-config=1/: -1: 1364046 414756 414756 cpu/legacy-cache-config=0x10001/: -1: 57453 414756 414756 cpu/legacy-hardware-config=1/: 1364046 414756 414756 cpu/legacy-cache-config=0x10001/: 57453 414756 414756 Performance counter stats for 'true': 1,364,046 cpu/legacy-hardware-config=1/ 57,453 cpu/legacy-cache-config=0x10001/ 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_events__term_type term_type) [PARSE_EVENTS__TERM_TYPE_RAW] = "raw", [PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE] = "legacy-cache", [PARSE_EVENTS__TERM_TYPE_HARDWARE] = "hardware", + [PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG] = "legacy-hardware-config", + [PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG] = "legacy-cache-config", [PARSE_EVENTS__TERM_TYPE_CPU] = "cpu", }; if ((unsigned int)term_type >= __PARSE_EVENTS__TERM_TYPE_NR) @@ -911,6 +913,8 @@ config_term_avail(enum parse_events__term_type term_type, 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 } +static bool check_pmu_is_core(__u32 type, const struct parse_events_term *term, + struct parse_events_error *err) +{ + struct perf_pmu *pmu = NULL; + + /* Avoid loading all PMUs with perf_pmus__find_by_type, just scan the core ones. */ + while ((pmu = perf_pmus__scan_core(pmu)) != NULL) { + if (pmu->type == 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 == PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG) { + if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_NUM)) + return -EINVAL; + if (term->val.num >= 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 = term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |= (__u64)attr->type << PERF_PMU_TYPE_SHIFT; + attr->type = PERF_TYPE_HARDWARE; + return 0; + } + if (term->type_term == 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 = term->val.num & 0xFF; + cache_op = (term->val.num >> 8) & 0xFF; + cache_result = (term->val.num >> 16) & 0xFF; + if ((term->val.num & ~0xFFFFFF) || + cache_type >= PERF_COUNT_HW_CACHE_MAX || + cache_op >= PERF_COUNT_HW_CACHE_OP_MAX || + cache_result >= 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 = term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |= (__u64)attr->type << PERF_PMU_TYPE_SHIFT; + attr->type = PERF_TYPE_HW_CACHE; + return 0; + } if (term->type_term == PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE) { struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type); @@ -1180,6 +1244,8 @@ static int config_term_tracepoint(struct perf_event_attr *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, struct 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) }; 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_SAMPLE_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_LEGACY_HARDWARE_CONFIG); } +legacy-cache-config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG); } cpu-cycles|cycles { return hw_term(yyscanner, PERF_COUNT_HW_CPU_CYCLES); } stalled-cycles-frontend|idle-cycles-frontend { return hw_term(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } stalled-cycles-backend|idle-cycles-backend { return hw_term(yyscanner, PERF_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 *pmu, assert(term->type_val == 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 == PARSE_EVENTS__TERM_TYPE_NUM); + assert(term->val.num < PERF_COUNT_HW_MAX); + assert(pmu->is_core); + attr->config = term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |= (__u64)pmu->type << PERF_PMU_TYPE_SHIFT; + attr->type = PERF_TYPE_HARDWARE; + break; + case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: { +#ifndef NDEBUG + int cache_type = term->val.num & 0xFF; + int cache_op = (term->val.num >> 8) & 0xFF; + int cache_result = (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 == PARSE_EVENTS__TERM_TYPE_NUM); + assert((term->val.num & ~0xFFFFFF) == 0); + assert(pmu->is_core); + attr->config = term->val.num; + if (perf_pmus__supports_extended_type()) + attr->config |= (__u64)pmu->type << PERF_PMU_TYPE_SHIFT; + attr->type = 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, void *state, pmu_format_call "config1=0..0xffffffffffffffff", "config2=0..0xffffffffffffffff", "config3=0..0xffffffffffffffff", + "legacy-hardware-config=0..9,", + "legacy-cache-config=0..0xffffff,", "name=string", "period=number", "freq=number", -- 2.51.0.318.gd7df087d1a-goog