From nobody Thu Oct 2 18:06:27 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F4CA2E2EEF for ; Sun, 14 Sep 2025 18:11:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757873510; cv=none; b=TlZDmW8nznZ0zUqgLi5cAAcoDQtuzGQ5EcQ4EFQRkQbIxKRDW4+9cwKMCm//dV5lCa64pOoFzxsxqZLCoFKg7ohmHKYRXwIxFCxd4b+jGs+68WChpjmwlPX4z2qsBpKwnUYB3NCztEKYb1cW6NV3T5bUld239nDHaMbMDBtjCzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757873510; c=relaxed/simple; bh=WKJmdW/QS3Vg/zoMYS4X9jo6VYU3aVoBuhOAIZJhpnk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=VVAMBRTb+VOl7aCqzdHxBsWlCDt8qmskGNxr2CylEbCsfYN2avrg/VYdFEF6zmqYOtthT1DuKRc0+oI2aX4cXrIRAE6Tnph97H4MpHqXplZ894mdEzDZYs+x7dBKktPeUv1YD/CwZzo+YNH2gg5gPNKIDJQI7tjssGOAScu2hgI= 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=4UecZqZp; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="4UecZqZp" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7761c58f77fso1470742b3a.2 for ; Sun, 14 Sep 2025 11:11:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1757873507; x=1758478307; 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=VxqFXms/BNp01M+1oeQcy5+HAiXBg1PYlTWo4PvS2WI=; b=4UecZqZpoUgWdhak/S+KWoSogDOFTUCUipeY+I31SqIK2AK3Kr09bdkvPNK87at5kY 5xDytEzmiDRiMXnvLtzHT3Pjukpr8sdUeZEqiC47VlAEnAvSWsdgqyhSULglZN9CKUkG 2sO2ZMBU1Nx8vFMF/2LmX91vOb/k1BG+GqeUrNmBcsLAlzxCBO20sUZ9TFiTyCsY1trl xZ+Sb+KtQU/gQkqargN5cI+PC+OfIblpM/LJD75UAEhacZIjG7RgQtO7yk82icSsEIMu B8++zt0cOFEzyF0XLmLhAYHH4oy8ZMj7OSQOKm3B5hDreQ+Wng5yiyYhGps5svqS7WCl nIPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757873507; x=1758478307; 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=VxqFXms/BNp01M+1oeQcy5+HAiXBg1PYlTWo4PvS2WI=; b=lMWbKb/Fb7DRAS3nO67F6kY8H5YhJwe3GTYBBL1x0l2hqfGbgGe0/ZnGVgvAISC9nl CtwxUP+Wqg9Z8XvknTsAvsBQhWqk1ZCboiwbEfecSAWrDLbxkCJmArY6L+m3/IAuBQD8 9SleufeHCBx0VaGJJMH5qtT65zb5ypRXLyILa612L3tTyt3cWnDffTaMOgzbJry3nhdX V5k9j9reKPxD2JUbezsJWM9QCyb4wlSoqLh9Y2A/DaG2OWAN9VUADhl0D5HSjmJDawUq 4zV91VfzrDKo9Kll4+tY/We7Sm0L5Br9xBFRfPAYgCLHDwyTD/gGLBfFcbccBogijz9C F8SA== X-Forwarded-Encrypted: i=1; AJvYcCUHn5E3L5R48IsR6jdyAcZtbq40BUDzm9S+GGGHCPvi+W5J9VQIZkT+NHprrFP2S6IYDJ4UNdVrE3bNecw=@vger.kernel.org X-Gm-Message-State: AOJu0Yzmljd79apMp4Er2bRnlAuqet34yw6Rjy8Zd8rmMiCL9A+BShVS dy5BzCDxQahx2Ql8QsxIAnhTw5RJEUVabdcjz1aeMhWnPqiTiS+IFsPSp0AMMhQfL9SNlLMrLHq sL0O5nwFXPg== X-Google-Smtp-Source: AGHT+IH+mDq0R4BboQlnZEeWfMAUqTJRdoez1AfKunzzOkpPpDDC1Z/L7r1h0IzTFyT0v0M7ftj5iqFpJjZ7 X-Received: from pjbdy13.prod.google.com ([2002:a17:90b:6cd:b0:32e:2c41:7def]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7fa9:b0:240:489:be9a with SMTP id adf61e73a8af0-2602aa8a67dmr12742990637.23.1757873507337; Sun, 14 Sep 2025 11:11:47 -0700 (PDT) Date: Sun, 14 Sep 2025 11:11:11 -0700 In-Reply-To: <20250914181121.1952748-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: <20250914181121.1952748-1-irogers@google.com> X-Mailer: git-send-email 2.51.0.384.g4c02a37b29-goog Message-ID: <20250914181121.1952748-12-irogers@google.com> Subject: [PATCH v4 11/21] perf pmu: Add and use legacy_terms in alias information 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 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support to finding/adding events from the default_core event table. If an event already exists from sysfs/json then the default_core configuration is saved in the legacy_terms string. Lazily use the legacy_terms string to set a legacy hardware or cache event as deprecated if the core PMU doesn't support it. Use the legacy terms string to set the alternate_hw_config, avoiding the value needing to be passed from the parse_events parser. Signed-off-by: Ian Rogers Tested-by: Thomas Richter --- tools/perf/util/pmu.c | 137 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 117 insertions(+), 20 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f718eb41af88..7f5bdb6688db 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -69,6 +69,11 @@ struct perf_pmu_alias { char *topic; /** @terms: Owned copy of the event terms. */ char *terms; + /** + * @legacy_terms: If the event aliases a legacy event, holds a copy + * ofthe legacy event string. + */ + char *legacy_terms; /** * @pmu_name: The name copied from the json struct pmu_event. This can * differ from the PMU name as it won't have suffixes. @@ -101,6 +106,12 @@ struct perf_pmu_alias { * default. */ bool deprecated; + /** + * @legacy_deprecated_checked: Legacy events may not be supported by the + * PMU need to be checked. If they aren't supported they are marked + * deprecated. + */ + bool legacy_deprecated_checked; /** @from_sysfs: Was the alias from sysfs or a json event? */ bool from_sysfs; /** @info_loaded: Have the scale, unit and other values been read from di= sk? */ @@ -430,6 +441,7 @@ static void perf_pmu_free_alias(struct perf_pmu_alias *= alias) zfree(&alias->topic); zfree(&alias->pmu_name); zfree(&alias->terms); + zfree(&alias->legacy_terms); free(alias); } =20 @@ -522,6 +534,7 @@ static void read_alias_info(struct perf_pmu *pmu, struc= t perf_pmu_alias *alias) struct update_alias_data { struct perf_pmu *pmu; struct perf_pmu_alias *alias; + bool legacy; }; =20 static int update_alias(const struct pmu_event *pe, @@ -537,8 +550,13 @@ static int update_alias(const struct pmu_event *pe, assign_str(pe->name, "topic", &data->alias->topic, pe->topic); data->alias->per_pkg =3D pe->perpkg; if (pe->event) { - zfree(&data->alias->terms); - data->alias->terms =3D strdup(pe->event); + if (data->legacy) { + zfree(&data->alias->legacy_terms); + data->alias->legacy_terms =3D strdup(pe->event); + } else { + zfree(&data->alias->terms); + data->alias->terms =3D strdup(pe->event); + } } if (!ret && pe->unit) { char *unit; @@ -628,7 +646,6 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, co= nst char *name, return ret; } } - alias->name =3D strdup(name); alias->desc =3D desc ? strdup(desc) : NULL; alias->long_desc =3D long_desc ? strdup(long_desc) : NULL; @@ -645,15 +662,29 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, = const char *name, default: case EVENT_SRC_SYSFS: alias->from_sysfs =3D true; - if (pmu->events_table) { + if (pmu->events_table || pmu->is_core) { /* Update an event from sysfs with json data. */ struct update_alias_data data =3D { .pmu =3D pmu, .alias =3D alias, + .legacy =3D false, }; - if (pmu_events_table__find_event(pmu->events_table, pmu, name, - update_alias, &data) =3D=3D 0) + if ((pmu_events_table__find_event(pmu->events_table, pmu, name, + update_alias, &data) =3D=3D 0)) { + /* + * Override sysfs encodings with json encodings + * specific to the cpuid. + */ pmu->cpu_common_json_aliases++; + } + if (pmu->is_core) { + /* Add in legacy encodings. */ + data.legacy =3D true; + if (pmu_events_table__find_event( + perf_pmu__default_core_events_table(), + pmu, name, update_alias, &data) =3D=3D 0) + pmu->cpu_common_json_aliases++; + } } pmu->sysfs_aliases++; break; @@ -1054,13 +1085,16 @@ void pmu_add_cpu_aliases_table(struct perf_pmu *pmu= , const struct pmu_events_tab =20 static void pmu_add_cpu_aliases(struct perf_pmu *pmu) { - if (!pmu->events_table) + if (!pmu->events_table && !pmu->is_core) return; =20 if (pmu->cpu_aliases_added) return; =20 pmu_add_cpu_aliases_table(pmu, pmu->events_table); + if (pmu->is_core) + pmu_add_cpu_aliases_table(pmu, perf_pmu__default_core_events_table()); + pmu->cpu_aliases_added =3D true; } =20 @@ -1738,10 +1772,14 @@ static struct perf_pmu_alias *pmu_find_alias(struct= perf_pmu *pmu, return alias; =20 /* Alias doesn't exist, try to get it from the json events. */ - if (pmu->events_table && - pmu_events_table__find_event(pmu->events_table, pmu, name, - pmu_add_cpu_aliases_map_callback, - pmu) =3D=3D 0) { + if ((pmu_events_table__find_event(pmu->events_table, pmu, name, + pmu_add_cpu_aliases_map_callback, + pmu) =3D=3D 0) || + (pmu->is_core && + pmu_events_table__find_event(perf_pmu__default_core_events_table(), + pmu, name, + pmu_add_cpu_aliases_map_callback, + pmu) =3D=3D 0)) { alias =3D perf_pmu__find_alias(pmu, name, /*load=3D*/ false); } return alias; @@ -1865,6 +1903,20 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, stru= ct parse_events_terms *head_ if (ret) return ret; =20 + if (alias->legacy_terms) { + struct perf_event_attr attr =3D {.config =3D 0,}; + + ret =3D perf_pmu__parse_terms_to_attr(pmu, alias->legacy_terms, &attr); + if (ret) { + parse_events_error__handle(err, term->err_term, + strdup("Error evaluating legacy terms"), + NULL); + return ret; + } + if (attr.type =3D=3D PERF_TYPE_HARDWARE) + *alternate_hw_config =3D attr.config & PERF_HW_EVENT_MASK; + } + if (alias->per_pkg) info->per_pkg =3D true; =20 @@ -2033,9 +2085,13 @@ bool perf_pmu__have_event(struct perf_pmu *pmu, cons= t char *name) return drm_pmu__have_event(pmu, name); if (perf_pmu__find_alias(pmu, name, /*load=3D*/ true) !=3D NULL) return true; - if (pmu->cpu_aliases_added || !pmu->events_table) + if (pmu->cpu_aliases_added || (!pmu->events_table && !pmu->is_core)) return false; - return pmu_events_table__find_event(pmu->events_table, pmu, name, NULL, N= ULL) =3D=3D 0; + if (pmu_events_table__find_event(pmu->events_table, pmu, name, NULL, NULL= ) =3D=3D 0) + return true; + return pmu->is_core && + pmu_events_table__find_event(perf_pmu__default_core_events_table(), + pmu, name, NULL, NULL) =3D=3D 0; } =20 size_t perf_pmu__num_events(struct perf_pmu *pmu) @@ -2052,13 +2108,18 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu) pmu_aliases_parse(pmu); nr =3D pmu->sysfs_aliases + pmu->sys_json_aliases; =20 - if (pmu->cpu_aliases_added) - nr +=3D pmu->cpu_json_aliases; - else if (pmu->events_table) - nr +=3D pmu_events_table__num_events(pmu->events_table, pmu) - - pmu->cpu_common_json_aliases; - else + if (pmu->cpu_aliases_added) { + nr +=3D pmu->cpu_json_aliases; + } else if (pmu->events_table || pmu->is_core) { + nr +=3D pmu_events_table__num_events(pmu->events_table, pmu); + if (pmu->is_core) { + nr +=3D pmu_events_table__num_events( + perf_pmu__default_core_events_table(), pmu); + } + nr -=3D pmu->cpu_common_json_aliases; + } else { assert(pmu->cpu_json_aliases =3D=3D 0 && pmu->cpu_common_json_aliases = =3D=3D 0); + } =20 if (perf_pmu__is_tool(pmu)) nr -=3D tool_pmu__num_skip_events(); @@ -2120,6 +2181,42 @@ static char *format_alias(char *buf, int len, const = struct perf_pmu *pmu, return buf; } =20 +static bool perf_pmu_alias__check_deprecated(struct perf_pmu *pmu, struct = perf_pmu_alias *alias) +{ + struct perf_event_attr attr =3D {.config =3D 0,}; + const char *check_terms; + bool has_legacy_config; + + if (alias->legacy_deprecated_checked) + return alias->deprecated; + + alias->legacy_deprecated_checked =3D true; + if (alias->deprecated) + return true; + + check_terms =3D alias->terms; + has_legacy_config =3D + strstr(check_terms, "legacy-hardware-config=3D") !=3D NULL || + strstr(check_terms, "legacy-cache-config=3D") !=3D NULL; + if (!has_legacy_config && alias->legacy_terms) { + check_terms =3D alias->legacy_terms; + has_legacy_config =3D + strstr(check_terms, "legacy-hardware-config=3D") !=3D NULL || + strstr(check_terms, "legacy-cache-config=3D") !=3D NULL; + } + if (!has_legacy_config) + return false; + + if (perf_pmu__parse_terms_to_attr(pmu, check_terms, &attr) !=3D 0) { + /* Parsing failed, set as deprecated. */ + alias->deprecated =3D true; + } else if (attr.type < PERF_TYPE_MAX) { + /* Flag unsupported legacy events as deprecated. */ + alias->deprecated =3D !is_event_supported(attr.type, attr.config); + } + return alias->deprecated; +} + int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmu= s, void *state, pmu_event_callback cb) { @@ -2177,7 +2274,7 @@ int perf_pmu__for_each_event(struct perf_pmu *pmu, bo= ol skip_duplicate_pmus, "%.*s/%s/", (int)pmu_name_len, info.pmu_name, event->terms) + 1; info.str =3D event->terms; info.topic =3D event->topic; - info.deprecated =3D event->deprecated; + info.deprecated =3D perf_pmu_alias__check_deprecated(pmu, event); ret =3D cb(state, &info); if (ret) goto out; --=20 2.51.0.384.g4c02a37b29-goog