Received: by 2002:ab2:5c0e:0:b0:1ef:a325:1205 with SMTP id i14csp183473lqk; Wed, 13 Mar 2024 22:53:43 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVVFjgRNgPIWDVkS+MCLhiS+PPA4Q47ht/VVN3y6RGu5LPH1+C3z6rs9wHUkIV7gRzf6TkM9jU/Qu4s4Ovj5uO6iTWIzKiaVzyHpJdRuQ== X-Google-Smtp-Source: AGHT+IHqeF3rzZA0bml3LduVjgV4hgmJ9+eXx5jdTIW5of0Wug+GKJ2YRMTv6vlqpOAVbJN4GmKf X-Received: by 2002:ac5:cdf3:0:b0:4d3:3f2b:dc63 with SMTP id v19-20020ac5cdf3000000b004d33f2bdc63mr897299vkn.5.1710395622949; Wed, 13 Mar 2024 22:53:42 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1710395622; cv=pass; d=google.com; s=arc-20160816; b=I80FFC6moZUft4lcrm2ITF6JWeR3NBBcvpiLCM2/9/70uzf/8Gqq/gw4Gc0Nbwuswm Znkjjq8z0ZS2SLpxufPtbJHROFQbC4jRTh8iFnMSvkW/dzF/U0+GV9e4yfRb2XKLI59B hJFUWSAEQVSG/m5+Bqo4uskgZVFdJinvxJa4JnVGQOiwO4z9i+d2uHAgpDsdx8rhocSs 4nOwbbcm8Y4BDHvmbbBjs7enARKezBQanUIrEpuXEUtHhxttI6oksrByAPHEYCmEa6yI F4GVI3+xIW566L4OXpcPll8hCN1A6fMeqaKDN83IpDwWlRNCdJylCf2QUWqKgBSJ4Qnr tmVA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=AeUUhq+4yzhedbfApHNS9dE0zQ4nQa4+W19zr8OUhx8=; fh=j9hLJF0F7n57KN2WmiIhpF6+du/xFDhRxgw6tC9drrc=; b=KauJOoRnrMkS4QNMBMj/ls8c64kcbXUS8MvNc0vgs1222YyfPldT6x8lMax15t4xOx eMkJrM0D74Cj4giR9iW6BQk2Shg9092hhE2KY6eOhLHAw4XvvPX3kpFk5ok5CIwDRybZ O2EM7bB6Kr8D/FK2392ewGTcVEkXGfqp1CuCoriDGFsSnJcRjQtkiFB8ZacWm89npJ8K AS8NA0SxIe/frl1j0xZTjHmwbwhvfiYu+J4qxlxBIJ0F29QEpWPvWgEc4LBIfr7Wq6C8 V0arD3YRU2PFyvgnQf0s2I+CXl0ZoVz2LpuafpnREhQp1nRwl80QDn8PxB9yRrYOxTID kZ6Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=wg07HEdT; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-102811-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-102811-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id a11-20020a05622a064b00b0042eb1805f13si335857qtb.470.2024.03.13.22.53.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Mar 2024 22:53:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-102811-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=wg07HEdT; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-102811-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-102811-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 959041C220B2 for ; Thu, 14 Mar 2024 05:53:42 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 327D518633; Thu, 14 Mar 2024 05:51:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wg07HEdT" Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 0694718048 for ; Thu, 14 Mar 2024 05:51:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710395506; cv=none; b=WPm35RfF7UdL2Bjgy/kg2JFThRcc+XqdwVTdBR18+IFElkvpyIPNkeNdPSGgtB3ATDXfwCLlWBwBe5QuwS1OLbVp+5cIpD8G+9E8qyHgZHl+jd0pqeWiywHXNhwOpUVYMmJKrzqLzaTX0lcrGg2DCJ5v73AaJMeGnYRK11QRYqQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710395506; c=relaxed/simple; bh=keY5cFKHjwhdpBjFcXwkRzglZaSf4GRCA+DhQhy2gDc=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=DY4KFRVrkUavNBm9m1Y2+X9ASt+rWj64P2EEeaiVW4Sv3mp95d7PUkJ1B2zvkzV4oVtnshwEMQ65jRmNV38QhTmnkPfyirNBv1qWemlu5ItYEa/ugFMJXA8yH5blemKVHZhzsEXk4oUFBUg5BTVviEIlg1JbE8224YauEoXxngI= 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=wg07HEdT; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-60a55cd262aso11678027b3.2 for ; Wed, 13 Mar 2024 22:51:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1710395503; x=1711000303; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=AeUUhq+4yzhedbfApHNS9dE0zQ4nQa4+W19zr8OUhx8=; b=wg07HEdT2Pi+kWJEvpN+jaEhEAn0savfeM/QYRC0nu+XpPZTeJNyc/eL1KHqY57qs4 /eEO8lFzD7j1aYP7aJWjHHR0elgxR4Mt2NYJPbgxiCoR5AQ2+SU8WYpFWunIW0YQbBr8 5EaDD8v66zq3UUDmhnRkdJaPd9/qjuKMLoqRkQWoLAx732tAE+fdAYPq8Ty5We6M5aaW md0cfpHv4FefOkHIQbQBlboWjIjSBX5m/UZWmiCNaLV+aeILOyDIvcWbhLsfrVdf3cWk HmJxtaZXScMeA9TvHh97H6mLLk8IfdoCWkDIfpi1nCw/ZR65Q9wgwCy4elK8dqIAK9rI TZXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710395503; x=1711000303; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=AeUUhq+4yzhedbfApHNS9dE0zQ4nQa4+W19zr8OUhx8=; b=KqJsfR1dEsNpssyaTVH5Mwk5AF7LS79FZt/9/nuaYtvwXuay3Vm2A0APwiZ3xQxEBX trQbmLAyUEauTcb+rnBH2yzT2qHBMq2QzYfOIka/7rvFnwo1xqD+kBKGcz/0IgUlQLY3 87dOVGT9N/5uGUaqkZvIPZemmsz928HD7z0XVnD9fErzxvYOWx8U3kfrchYiKKSsO7f0 i/6bMv8qMoEvrfEumkU9Sv++V+Rpi6pa7UQ/wWCKitXztO2G6Irdkoz+m/qISS+z4l8w Qp48ybndwcqhBKOfQfeVWTjY0GinkpXmiSF/7/pfhMP60vnxDc+ameuU6yvFHJ7pFjY5 nZMQ== X-Forwarded-Encrypted: i=1; AJvYcCUp6P15HE3aeuSt2N+1rQAO1oKqKlwNQ0K420tN55TYTW4fxYnOfhigEBviKVV84i8LJblj0T5bc4c5RPkgK6MlMBK05Jv+8bKbNFGj X-Gm-Message-State: AOJu0Yx9L3Cyf4vHZCA1j33A0T454qXwtywTsJ1tzvwViwNjIcHuj7rt VYtELNNUfeS51pfC0g9SOoDynNdSVW+VBTo+i9yPJq8rqnp9igTneRESs5lkIQsyhO2EjR8FH+0 7DzyeNw== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:449f:3bde:a4cd:806a]) (user=irogers job=sendgmr) by 2002:a05:6902:2181:b0:dc7:49a9:6666 with SMTP id dl1-20020a056902218100b00dc749a96666mr252533ybb.3.1710395503060; Wed, 13 Mar 2024 22:51:43 -0700 (PDT) Date: Wed, 13 Mar 2024 22:50:51 -0700 In-Reply-To: <20240314055051.1960527-1-irogers@google.com> Message-Id: <20240314055051.1960527-13-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240314055051.1960527-1-irogers@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Subject: [PATCH v3 12/12] perf jevents: Add load event json to verify and allow fallbacks From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , John Garry , Kan Liang , Jing Zhang , Thomas Richter , James Clark , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Andi Kleen , Kajol Jain , Sandipan Das , Ravi Bangoria , Perry Taylor , Samantha Alt , Caleb Biggers , Weilin Wang , Edward Baker , Stephane Eranian Content-Type: text/plain; charset="UTF-8" Add a LoadEvents function that loads all event json files in a directory. In the Event constructor ensure all events are defined in the event json except for legacy events like "cycles". If the initial event isn't found then legacy_event1 is used, and if that isn't found legacy_event2 is used. This allows a single Event to have multiple event names as models will often rename the same event over time. If the event doesn't exist an exception is raised. So that references to metrics can be added, add the MetricRef class. This doesn't validate as an event name and so provides an escape hatch for metrics to refer to each other. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/Build | 12 ++-- tools/perf/pmu-events/amd_metrics.py | 6 +- tools/perf/pmu-events/arm64_metrics.py | 6 +- tools/perf/pmu-events/intel_metrics.py | 6 +- tools/perf/pmu-events/metric.py | 77 +++++++++++++++++++++++++- 5 files changed, 95 insertions(+), 12 deletions(-) diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build index e2db33577707..a2c5c04e5c46 100644 --- a/tools/perf/pmu-events/Build +++ b/tools/perf/pmu-events/Build @@ -42,11 +42,11 @@ ZEN_METRICGROUPS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metricgroups.json) $(ZEN_METRICS): pmu-events/amd_metrics.py $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) arch > $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@ $(ZEN_METRICGROUPS): pmu-events/amd_metrics.py $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) arch > $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@ # Generate ARM Json ARMS = $(shell ls -d pmu-events/arch/arm64/arm/*) @@ -55,11 +55,11 @@ ARM_METRICGROUPS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metricgroups.json) $(ARM_METRICS): pmu-events/arm64_metrics.py $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call vendor_name,$@) $(call model_name,$@) arch > $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@ $(ARM_METRICGROUPS): pmu-events/arm64_metrics.py $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call vendor_name,$@) $(call model_name,$@) arch > $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@ # Generate Intel Json INTELS = $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v mapfile.csv) @@ -68,11 +68,11 @@ INTEL_METRICGROUPS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metricgroups.json $(INTEL_METRICS): pmu-events/intel_metrics.py $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) arch > $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@ $(INTEL_METRICGROUPS): pmu-events/intel_metrics.py $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) arch > $@ + $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@ GEN_JSON = $(patsubst %,$(OUTPUT)%,$(JSON)) \ $(ZEN_METRICS) $(ZEN_METRICGROUPS) \ diff --git a/tools/perf/pmu-events/amd_metrics.py b/tools/perf/pmu-events/amd_metrics.py index 7ab2ee4fdb17..4f728e7aae4a 100755 --- a/tools/perf/pmu-events/amd_metrics.py +++ b/tools/perf/pmu-events/amd_metrics.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, MetricGroup) +from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, LoadEvents, + MetricGroup) import argparse import json import os @@ -27,6 +28,9 @@ def main() -> None: ) _args = parser.parse_args() + directory = f"{_args.events_path}/x86/{_args.model}/" + LoadEvents(directory) + all_metrics = MetricGroup("",[]) if _args.metricgroups: diff --git a/tools/perf/pmu-events/arm64_metrics.py b/tools/perf/pmu-events/arm64_metrics.py index a9f0e6bc751b..c9aa2d827a82 100755 --- a/tools/perf/pmu-events/arm64_metrics.py +++ b/tools/perf/pmu-events/arm64_metrics.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, MetricGroup) +from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, LoadEvents, + MetricGroup) import argparse import json import os @@ -30,6 +31,9 @@ def main() -> None: all_metrics = MetricGroup("",[]) + directory = f"{_args.events_path}/arm64/{_args.vendor}/{_args.model}/" + LoadEvents(directory) + if _args.metricgroups: print(JsonEncodeMetricGroupDescriptions(all_metrics)) else: diff --git a/tools/perf/pmu-events/intel_metrics.py b/tools/perf/pmu-events/intel_metrics.py index f004c27640d2..04a19d05c6c1 100755 --- a/tools/perf/pmu-events/intel_metrics.py +++ b/tools/perf/pmu-events/intel_metrics.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, MetricGroup) +from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, LoadEvents, + MetricGroup) import argparse import json import os @@ -27,6 +28,9 @@ def main() -> None: ) _args = parser.parse_args() + directory = f"{_args.events_path}/x86/{_args.model}/" + LoadEvents(directory) + all_metrics = MetricGroup("",[]) if _args.metricgroups: diff --git a/tools/perf/pmu-events/metric.py b/tools/perf/pmu-events/metric.py index dd8fd06940e6..03312cd6d491 100644 --- a/tools/perf/pmu-events/metric.py +++ b/tools/perf/pmu-events/metric.py @@ -3,10 +3,50 @@ import ast import decimal import json +import os import re from enum import Enum from typing import Dict, List, Optional, Set, Tuple, Union +all_events = set() + +def LoadEvents(directory: str) -> None: + """Populate a global set of all known events for the purpose of validating Event names""" + global all_events + all_events = { + "context\-switches", + "cycles", + "duration_time", + "instructions", + "l2_itlb_misses", + } + for file in os.listdir(os.fsencode(directory)): + filename = os.fsdecode(file) + if filename.endswith(".json"): + for x in json.load(open(f"{directory}/{filename}")): + if "EventName" in x: + all_events.add(x["EventName"]) + elif "ArchStdEvent" in x: + all_events.add(x["ArchStdEvent"]) + + +def CheckEvent(name: str) -> bool: + """Check the event name exists in the set of all loaded events""" + global all_events + if len(all_events) == 0: + # No events loaded so assume any event is good. + return True + + if ':' in name: + # Remove trailing modifier. + name = name[:name.find(':')] + elif '/' in name: + # Name could begin with a PMU or an event, for now assume it is good. + return True + + return name in all_events + + class MetricConstraint(Enum): GROUPED_EVENTS = 0 NO_GROUP_EVENTS = 1 @@ -317,9 +357,18 @@ def _FixEscapes(s: str) -> str: class Event(Expression): """An event in an expression.""" - def __init__(self, name: str, legacy_name: str = ''): - self.name = _FixEscapes(name) - self.legacy_name = _FixEscapes(legacy_name) + def __init__(self, *args: str): + error = "" + for name in args: + if CheckEvent(name): + self.name = _FixEscapes(name) + return + if error: + error += " or " + name + else: + error = name + global all_events + raise Exception(f"No event {error} in:\n{all_events}") def ToPerfJson(self): result = re.sub('/', '@', self.name) @@ -338,6 +387,28 @@ class Event(Expression): return self +class MetricRef(Expression): + """A metric reference in an expression.""" + + def __init__(self, name: str): + self.name = _FixEscapes(name) + + def ToPerfJson(self): + return self.name + + def ToPython(self): + return f'MetricRef(r"{self.name}")' + + def Simplify(self) -> Expression: + return self + + def Equals(self, other: Expression) -> bool: + return isinstance(other, MetricRef) and self.name == other.name + + def Substitute(self, name: str, expression: Expression) -> Expression: + return self + + class Constant(Expression): """A constant within the expression tree.""" -- 2.44.0.278.ge034bb2e1d-goog