From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 830BA22EE0; Fri, 12 Apr 2024 21:08:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956092; cv=none; b=MfAdeblt0/wHLruIotCelve/BZwHM2uQXBfsm7wpEEVjhLYudToWZ7mHZdMd0u+0+E4yXQpkfyHeyeOaTrv4PI7wBcnkGR84xeK8326VulUYevg95UlshYeYadnAEXyuevQBtlk5PUVK+regkkO6iNMPlNLf6MI0RN19Lg9xukA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956092; c=relaxed/simple; bh=UQMRzkNEk2MsDjXOZVo9LUR5e+ngNGOU38dE+7tP6BQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OL2FeTlbh2IHOthptiWU9qY/AS5+vUL9+3fy64vQAai0hUACEVDFaEKWZFZmGUYw/ZySXqx40UVAHFcNjiFxRUjOpn7iGf2ftlAfTKQiq8uLrUB3WXIVnGzSgxN+j4m2F2dfW/LZi6fhmivsNNJjOvfBxiMNT0+YgE+NRWk21s0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=aa9INqXT; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="aa9INqXT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956091; x=1744492091; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UQMRzkNEk2MsDjXOZVo9LUR5e+ngNGOU38dE+7tP6BQ=; b=aa9INqXTdnzun1GgoZbCFTAtowFJ/o/1VCcZUgc8WtEvnkqO2rb+MsHS YqGzlWgBTOT9vrffpdutynvu9cO9O7S+fS92u1jBeef5CYXgo4/6blVDZ cep8spx1LtWAJVuwd/F1lm+SITIOKUIfssK6p3Fyhc8zT7v2at4SAJYZR yj2kNGFFSRHgsPjc13Af6Po/F0wqLXhFikiihUE6ZCMX4DxYNH0xNjl1G t0Q35p6bVr0XyyoPRlbjGh7yHEdKPAlGBDFXq2RmRE+ALfMdA+wAD6fTg yW2JgnCg82GJe2qOf4tvWUMFIowzCyY/KHxhmsIRjjlWH+1B0Gmr/UMhY A==; X-CSE-ConnectionGUID: IBFxIFwSQ0OhR3GgfcPSyw== X-CSE-MsgGUID: BYUeEIVrQQ67Xqgi5nHgGQ== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575422" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575422" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:08 -0700 X-CSE-ConnectionGUID: 0OzVMJMnRB243szEzy5XEw== X-CSE-MsgGUID: K7l+l18oSE2zu0tu91c+oQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772064" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:08 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 01/16] perf stat: Add new field in stat_config to enable hardware aware grouping. Date: Fri, 12 Apr 2024 14:07:41 -0700 Message-ID: <20240412210756.309828-2-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Hardware counter and event information could be used to help creating event groups that better utilize hardware counters and improve multiplexing. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/builtin-stat.c | 5 +++++ tools/perf/util/metricgroup.c | 5 +++++ tools/perf/util/metricgroup.h | 1 + tools/perf/util/stat.h | 1 + 4 files changed, 12 insertions(+) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6bba1a89d030..c4a5f0984295 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2106,6 +2106,7 @@ static int add_default_attributes(void) stat_config.metric_no_threshold, stat_config.user_requested_cpu_list, stat_config.system_wide, + stat_config.hardware_aware_grouping, &stat_config.metric_events); } =20 @@ -2139,6 +2140,7 @@ static int add_default_attributes(void) stat_config.metric_no_threshold, stat_config.user_requested_cpu_list, stat_config.system_wide, + stat_config.hardware_aware_grouping, &stat_config.metric_events); } =20 @@ -2173,6 +2175,7 @@ static int add_default_attributes(void) /*metric_no_threshold=3D*/true, stat_config.user_requested_cpu_list, stat_config.system_wide, + stat_config.hardware_aware_grouping, &stat_config.metric_events) < 0) return -1; } @@ -2214,6 +2217,7 @@ static int add_default_attributes(void) /*metric_no_threshold=3D*/true, stat_config.user_requested_cpu_list, stat_config.system_wide, + stat_config.hardware_aware_grouping, &stat_config.metric_events) < 0) return -1; =20 @@ -2748,6 +2752,7 @@ int cmd_stat(int argc, const char **argv) stat_config.metric_no_threshold, stat_config.user_requested_cpu_list, stat_config.system_wide, + stat_config.hardware_aware_grouping, &stat_config.metric_events); =20 zfree(&metrics); diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 79ef6095ab28..11613450725a 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1690,12 +1690,17 @@ int metricgroup__parse_groups(struct evlist *perf_e= vlist, bool metric_no_threshold, const char *user_requested_cpu_list, bool system_wide, + bool hardware_aware_grouping, struct rblist *metric_events) { const struct pmu_metrics_table *table =3D pmu_metrics_table__find(); =20 if (!table) return -EINVAL; + if (hardware_aware_grouping) { + pr_debug("Use hardware aware grouping instead of traditional metric grou= ping method\n"); + } + =20 return parse_groups(perf_evlist, pmu, str, metric_no_group, metric_no_mer= ge, metric_no_threshold, user_requested_cpu_list, system_wide, diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index d5325c6ec8e1..779f6ede1b51 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -77,6 +77,7 @@ int metricgroup__parse_groups(struct evlist *perf_evlist, bool metric_no_threshold, const char *user_requested_cpu_list, bool system_wide, + bool hardware_aware_grouping, struct rblist *metric_events); int metricgroup__parse_groups_test(struct evlist *evlist, const struct pmu_metrics_table *table, diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index d6e5c8787ba2..fd7a187551bd 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -87,6 +87,7 @@ struct perf_stat_config { bool metric_no_group; bool metric_no_merge; bool metric_no_threshold; + bool hardware_aware_grouping; bool stop_read_counter; bool iostat_run; char *user_requested_cpu_list; --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8A6714EC4E; Fri, 12 Apr 2024 21:08:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956093; cv=none; b=WpwC124fvgXd9YuXppTe+XT9uRMGSFyDmVWBf5pvkTsumQVbgk2DHQvOZya8tTp3o7YNEEwV4GIh/icK3/uKgFJI5zd4hkeCfSY/Q39W0daB17R3ft0xkCww17xvPQd0LF6w/fuDKMy35Whxup9Krdi8BV4ul9LyAU7MEAyQ1oM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956093; c=relaxed/simple; bh=jrGEwUkQrx0gWiHEFipxTmPDR21ywI4PC3wG+b+Tglc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hHJqjubTCAthj6hzn3NP2PlXS53luZnCROyVS6d1hWUIUUg4K0bH5UbvM4Bm/ytNojRSobIcpc0m8GZ/yj+BdjJdFGHHO3mqaw7E8L/6qgRGo64qE2YwfIYCOyGTZJqZ6SqSAI+IFWgFIE0GcUrQKPWiK3o0JcJFVy36dXJkzBw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=k61d9ZKb; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="k61d9ZKb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956092; x=1744492092; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jrGEwUkQrx0gWiHEFipxTmPDR21ywI4PC3wG+b+Tglc=; b=k61d9ZKbUjJdpKlh7bq8P4VEfvyV4c32/l+XIvoJ4XiUAXWGJkr/Cy9P SmnPXi4xDhD5miBknU7PZyUj8UZOhFgIKgX55m75y5VX38rJJ9wVS32oI bwNsT3zS6qfsmA3XdXec4SjqaxDG5RJaa/PfTc3fmFMtG0le0wwX/fVyl v87/Xdd78Qn0J3S4Lk9yr5jAIcd8Zyqq/qyTwTAzLX5HJs84Tjz0eEuZ4 KI/wAFSVwWPF2imqg9L6E5zr9znGFjsL+Zhx0d2HlsvIip44wPB5OHQ1t RYiVboTdUnJjRH7ufe3vWY3Hz9Enea9D1D81kEZgeO+kPIfEUU4gQm2ON g==; X-CSE-ConnectionGUID: 9Yi/SYetSkGEpv/WMgRknQ== X-CSE-MsgGUID: m8b1BOHpQS6rdHjoXd1GWw== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575427" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575427" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:09 -0700 X-CSE-ConnectionGUID: 1U/+mOOrTwGgQ+dR2NwowQ== X-CSE-MsgGUID: 4/3GmXmaSQmHJWBSV9TONQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772069" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:08 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 02/16] perf stat: Add basic functions for the hardware aware grouping Date: Fri, 12 Apr 2024 14:07:42 -0700 Message-ID: <20240412210756.309828-3-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add the first set of functions for the hardware aware grouping method. Func= tion hw_aware_parse_groups() is the entry point of this metric grouping method. = It does metric grouping on a combined list of events and will create a list of grouping strings as final results of the grouping method. These grouping st= rings will be used in the same manner as existing metric grouping process. This method will fall back to normal grouping when hardware aware grouping return with err so that perf stat still executes and returns with correct result. Signed-off-by: Weilin Wang Reviewed-by: Ian Rogers --- tools/perf/util/metricgroup.c | 217 +++++++++++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 11613450725a..8047f03b2b1f 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -159,6 +159,14 @@ struct metric { struct evlist *evlist; }; =20 +/** + * Each group is one node in the group string list. + */ +struct metricgroup__group_strs { + struct list_head nd; + struct strbuf grouping_str; +}; + static void metric__watchdog_constraint_hint(const char *name, bool foot) { static bool violate_nmi_constraint; @@ -1432,6 +1440,101 @@ static int build_combined_expr_ctx(const struct lis= t_head *metric_list, return ret; } =20 +/** + * hw_aware_build_grouping - Build event groupings by reading counter + * requirement of the events and counter available on the system from + * pmu-events. + * @ctx: the event identifiers parsed from metrics. + * @groupings: header to the list of final event grouping. + * @modifier: any modifiers added to the events. + */ +static int hw_aware_build_grouping(struct expr_parse_ctx *ctx __maybe_unus= ed, + struct list_head *groupings __maybe_unused, + const char *modifier __maybe_unused) +{ + int ret =3D 0; + + pr_debug("This is a placeholder\n"); + return ret; +} + +static void group_str_free(struct metricgroup__group_strs *g) +{ + if (!g) + return; + + strbuf_release(&g->grouping_str); + free(g); +} + +static void metricgroup__free_grouping_strs(struct list_head + *grouping_strs) +{ + struct metricgroup__group_strs *g, *tmp; + + list_for_each_entry_safe(g, tmp, grouping_strs, nd) { + list_del_init(&g->nd); + group_str_free(g); + } +} + +/** + * hw_aware_parse_ids - Build the event string for the ids and parse them + * creating an evlist. The encoded metric_ids are decoded. Events are plac= ed + * into groups based on event counter requirements and counter availabilit= ies of + * the system. + * @metric_no_merge: is metric sharing explicitly disabled. + * @fake_pmu: used when testing metrics not supported by the current CPU. + * @ids: the event identifiers parsed from a metric. + * @modifier: any modifiers added to the events. + * @out_evlist: the created list of events. + */ +static int hw_aware_parse_ids(struct perf_pmu *fake_pmu, + struct expr_parse_ctx *ids, const char *modifier, + struct evlist **out_evlist) +{ + struct parse_events_error parse_error; + struct evlist *parsed_evlist; + LIST_HEAD(groupings); + struct metricgroup__group_strs *group; + int ret; + + *out_evlist =3D NULL; + ret =3D hw_aware_build_grouping(ids, &groupings, modifier); + if (ret) { + metricgroup__free_grouping_strs(&groupings); + return ret; + } + + parsed_evlist =3D evlist__new(); + if (!parsed_evlist) { + ret =3D -ENOMEM; + goto err_out; + } + list_for_each_entry(group, &groupings, nd) { + struct strbuf *events =3D &group->grouping_str; + + pr_debug("Parsing metric events '%s'\n", events->buf); + parse_events_error__init(&parse_error); + ret =3D __parse_events(parsed_evlist, events->buf, /*pmu_filter=3D*/NULL, + &parse_error, fake_pmu, /*warn_if_reordered=3D*/false); + if (ret) { + parse_events_error__print(&parse_error, events->buf); + goto err_out; + } + ret =3D decode_all_metric_ids(parsed_evlist, modifier); + if (ret) + goto err_out; + } + *out_evlist =3D parsed_evlist; + parsed_evlist =3D NULL; +err_out: + parse_events_error__exit(&parse_error); + evlist__delete(parsed_evlist); + metricgroup__free_grouping_strs(&groupings); + return ret; +} + /** * parse_ids - Build the event string for the ids and parse them creating = an * evlist. The encoded metric_ids are decoded. @@ -1520,6 +1623,113 @@ static int parse_ids(bool metric_no_merge, struct p= erf_pmu *fake_pmu, return ret; } =20 +static int hw_aware_parse_groups(struct evlist *perf_evlist, + const char *pmu, const char *str, + bool metric_no_threshold, + const char *user_requested_cpu_list, + bool system_wide, + struct perf_pmu *fake_pmu, + struct rblist *metric_events_list, + const struct pmu_metrics_table *table) +{ + struct evlist *combined_evlist =3D NULL; + LIST_HEAD(metric_list); + struct metric *m; + int ret; + bool metric_no_group =3D false; + bool metric_no_merge =3D false; + + if (metric_events_list->nr_entries =3D=3D 0) + metricgroup__rblist_init(metric_events_list); + ret =3D metricgroup__add_metric_list(pmu, str, metric_no_group, metric_no= _threshold, + user_requested_cpu_list, + system_wide, &metric_list, table); + if (ret) + goto out; + + /* Sort metrics from largest to smallest. */ + list_sort(NULL, &metric_list, metric_list_cmp); + + if (!metric_no_merge) { + struct expr_parse_ctx *combined =3D NULL; + + ret =3D build_combined_expr_ctx(&metric_list, &combined); + + if (!ret && combined && hashmap__size(combined->ids)) { + ret =3D hw_aware_parse_ids(fake_pmu, combined, + /*modifier=3D*/NULL, + &combined_evlist); + } + + if (combined) + expr__ctx_free(combined); + if (ret) + goto out; + } + + list_for_each_entry(m, &metric_list, nd) { + struct metric_expr *expr; + struct metric_event *me; + struct evsel **metric_events; + + ret =3D setup_metric_events(fake_pmu ? "all" : m->pmu, m->pctx->ids, + combined_evlist, &metric_events); + if (ret) { + pr_debug("Cannot resolve IDs for %s: %s\n", + m->metric_name, m->metric_expr); + goto out; + } + + me =3D metricgroup__lookup(metric_events_list, metric_events[0], true); + + expr =3D malloc(sizeof(struct metric_expr)); + if (!expr) { + ret =3D -ENOMEM; + free(metric_events); + goto out; + } + + expr->metric_refs =3D m->metric_refs; + m->metric_refs =3D NULL; + expr->metric_expr =3D m->metric_expr; + if (m->modifier) { + char *tmp; + + if (asprintf(&tmp, "%s:%s", m->metric_name, m->modifier) < 0) + expr->metric_name =3D NULL; + else + expr->metric_name =3D tmp; + } else { + expr->metric_name =3D strdup(m->metric_name); + } + + if (!expr->metric_name) { + ret =3D -ENOMEM; + free(metric_events); + goto out; + } + expr->metric_threshold =3D m->metric_threshold; + expr->metric_unit =3D m->metric_unit; + expr->metric_events =3D metric_events; + expr->runtime =3D m->pctx->sctx.runtime; + list_add(&expr->nd, &me->head); + } + + if (combined_evlist) { + evlist__splice_list_tail(perf_evlist, &combined_evlist->core.entries); + evlist__delete(combined_evlist); + } + + list_for_each_entry(m, &metric_list, nd) { + if (m->evlist) + evlist__splice_list_tail(perf_evlist, &m->evlist->core.entries); + } + +out: + metricgroup__free_metrics(&metric_list); + return ret; +} + static int parse_groups(struct evlist *perf_evlist, const char *pmu, const char *str, bool metric_no_group, @@ -1698,10 +1908,15 @@ int metricgroup__parse_groups(struct evlist *perf_e= vlist, if (!table) return -EINVAL; if (hardware_aware_grouping) { + int ret; pr_debug("Use hardware aware grouping instead of traditional metric grou= ping method\n"); + ret =3D hw_aware_parse_groups(perf_evlist, pmu, str, + metric_no_threshold, user_requested_cpu_list, system_wide, + /*fake_pmu=3D*/NULL, metric_events, table); + if (!ret) + return 0; } =20 - return parse_groups(perf_evlist, pmu, str, metric_no_group, metric_no_mer= ge, metric_no_threshold, user_requested_cpu_list, system_wide, /*fake_pmu=3D*/NULL, metric_events, table); --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ADBC514F9EE; Fri, 12 Apr 2024 21:08:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956094; cv=none; b=Jsa0azSx3nPSIS8mToowpT+n+aDMOe1ZVAfVjC2LsvZijY7o2dXjrh8XLAf9j2ca4ikXrZRsHHqwezqkz8EHNFEVPPT3tM6nFFSZvkZgES17t6m92i/UYvEckutdXoQew3jB6vDeStuqxrhIpJuN9Vs93yrwO96PmYFQmsuLhbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956094; c=relaxed/simple; bh=RSQACh79WPB7eGVa8CzwZnGcQp0J/Vc8zTGf+lXaQ3o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fLVjc6Ry6Tcu15GVGVPPdgr4BCOfOZcMk3aoohh7Hm51ARwasc2BF9ddiWmi74IXZbiX41a9A9yOTtc8SbJbMduLGWeZvUfq5DWxyDXsKeBofTPu+T0vd7kI5y7wTwYQ+BwFNZSJsgjg3sdNjLWpBxNYSvLa2YlrfT+VQ0wZ8jY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=kcmUgQsM; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="kcmUgQsM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956092; x=1744492092; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RSQACh79WPB7eGVa8CzwZnGcQp0J/Vc8zTGf+lXaQ3o=; b=kcmUgQsMmwS8VbPKPbjfZytKVcdo/w6ueKBiwVgJD+qOaIXPQnfkWNM2 LG2KoNSKeZoRYhewQ5aQzZS09yYcGWcfQbhkAPjn7TLzum19bl5pHGgjc aO153K8PnmXJkcT77Nv38JDPU4rInbab+SHG40zJ/mmpnpU39w2fTXAYT 7t/4r39JfsIcNO8UvFgy+Vt6nDim3jwS6PVZyp7UjSAbynnSQs4TZT4By LlvATyq0ytJwBbQms5Co/KPyCOw4plXo0zvhXCreZuG9Agx5zcrXdFvWK wn3yJo1FNvZplHD8B6MxVrF35hCzDYf1Q8Tu+fDoM+crZ8YskeCEC/K2I g==; X-CSE-ConnectionGUID: 42CKc83jQvK1zm6cHO8xvA== X-CSE-MsgGUID: AcdJxMAVTsS2z25f4vBhXA== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575441" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575441" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:10 -0700 X-CSE-ConnectionGUID: rS1OwYZ3SbGpqae4OkNUAg== X-CSE-MsgGUID: WitCjcZLRXm3EfeB75cOqA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772078" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:09 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 03/16] perf pmu-events: Add functions in jevent.py to parse counter and event info for hardware aware grouping Date: Fri, 12 Apr 2024 14:07:43 -0700 Message-ID: <20240412210756.309828-4-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang These functions are added to parse event counter restrictions and counter availability info from json files so that the metric grouping method could do grouping based on the counter restriction of events and the counters that are available on the system. Signed-off-by: Weilin Wang --- tools/perf/pmu-events/jevents.py | 204 +++++++++++++++++++++++++++-- tools/perf/pmu-events/pmu-events.h | 32 ++++- 2 files changed, 224 insertions(+), 12 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index e42efc16723e..7cfd86d77fea 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -23,6 +23,8 @@ _metric_tables =3D [] _sys_metric_tables =3D [] # Mapping between sys event table names and sys metric table names. _sys_event_table_to_metric_table_mapping =3D {} +# List of regular PMU counter layout tables. +_pmu_layouts_tables =3D [] # Map from an event name to an architecture standard # JsonEvent. Architecture standard events are in json files in the top # f'{_args.starting_dir}/{_args.arch}' directory. @@ -31,6 +33,10 @@ _arch_std_events =3D {} _pending_events =3D [] # Name of events table to be written out _pending_events_tblname =3D None +# PMU counter layout to write out when the layout table is closed +_pending_pmu_counts =3D [] +# Name of PMU counter layout table to be written out +_pending_pmu_counts_tblname =3D None # Metrics to write out when the table is closed _pending_metrics =3D [] # Name of metrics table to be written out @@ -51,6 +57,11 @@ _json_event_attributes =3D [ 'long_desc' ] =20 +# Attributes that are in pmu_unit_layout. +_json_layout_attributes =3D [ + 'pmu', 'desc' +] + # Attributes that are in pmu_metric rather than pmu_event. _json_metric_attributes =3D [ 'metric_name', 'metric_group', 'metric_expr', 'metric_threshold', @@ -265,7 +276,7 @@ class JsonEvent: =20 def unit_to_pmu(unit: str) -> Optional[str]: """Convert a JSON Unit to Linux PMU name.""" - if not unit: + if not unit or unit =3D=3D "core": return 'default_core' # Comment brought over from jevents.c: # it's not realistic to keep adding these, we need something more sc= alable ... @@ -334,6 +345,19 @@ class JsonEvent: if 'Errata' in jd: extra_desc +=3D ' Spec update: ' + jd['Errata'] self.pmu =3D unit_to_pmu(jd.get('Unit')) + # The list of counter(s) the event could be collected with + class Counter: + gp =3D str() + fixed =3D str() + self.counters =3D {'list': str(), 'num': Counter()} + self.counters['list'] =3D jd.get('Counter') + # Number of generic counter + self.counters['num'].gp =3D jd.get('CountersNumGeneric') + # Number of fixed counter + self.counters['num'].fixed =3D jd.get('CountersNumFixed') + # If the event uses an MSR, other event uses the same MSR could not be + # schedule to collect at the same time. + self.msr =3D jd.get('MSRIndex') filter =3D jd.get('Filter') self.unit =3D jd.get('ScaleUnit') self.perpkg =3D jd.get('PerPkg') @@ -409,8 +433,20 @@ class JsonEvent: s +=3D f'\t{attr} =3D {value},\n' return s + '}' =20 - def build_c_string(self, metric: bool) -> str: + def build_c_string(self, metric: bool, layout: bool) -> str: s =3D '' + if layout: + for attr in _json_layout_attributes: + x =3D getattr(self, attr) + if attr in _json_enum_attributes: + s +=3D x if x else '0' + else: + s +=3D f'{x}\\000' if x else '\\000' + x =3D self.counters['num'].gp + s +=3D x if x else '0' + x =3D self.counters['num'].fixed + s +=3D x if x else '0' + return s for attr in _json_metric_attributes if metric else _json_event_attribu= tes: x =3D getattr(self, attr) if metric and x and attr =3D=3D 'metric_expr': @@ -423,12 +459,15 @@ class JsonEvent: s +=3D x if x else '0' else: s +=3D f'{x}\\000' if x else '\\000' + if not metric: + x =3D self.counters['list'] + s +=3D f'{x}\\000' if x else '\\000' return s =20 - def to_c_string(self, metric: bool) -> str: + def to_c_string(self, metric: bool, layout: bool) -> str: """Representation of the event as a C struct initializer.""" =20 - s =3D self.build_c_string(metric) + s =3D self.build_c_string(metric, layout) return f'{{ { _bcs.offsets[s] } }}, /* {s} */\n' =20 =20 @@ -465,6 +504,8 @@ def preprocess_arch_std_files(archpath: str) -> None: _arch_std_events[event.name.lower()] =3D event if event.metric_name: _arch_std_events[event.metric_name.lower()] =3D event + if event.counters['num'].gp: + _arch_std_events[event.pmu.lower()] =3D event =20 =20 def add_events_table_entries(item: os.DirEntry, topic: str) -> None: @@ -474,6 +515,8 @@ def add_events_table_entries(item: os.DirEntry, topic: = str) -> None: _pending_events.append(e) if e.metric_name: _pending_metrics.append(e) + if e.counters['num'].gp: + _pending_pmu_counts.append(e) =20 =20 def print_pending_events() -> None: @@ -514,7 +557,7 @@ def print_pending_events() -> None: last_pmu =3D event.pmu pmus.add((event.pmu, pmu_name)) =20 - _args.output_file.write(event.to_c_string(metric=3DFalse)) + _args.output_file.write(event.to_c_string(metric=3DFalse, layout=3DFal= se)) _pending_events =3D [] =20 _args.output_file.write(f""" @@ -569,7 +612,7 @@ def print_pending_metrics() -> None: last_pmu =3D metric.pmu pmus.add((metric.pmu, pmu_name)) =20 - _args.output_file.write(metric.to_c_string(metric=3DTrue)) + _args.output_file.write(metric.to_c_string(metric=3DTrue, layout=3DFal= se)) _pending_metrics =3D [] =20 _args.output_file.write(f""" @@ -587,6 +630,35 @@ const struct pmu_table_entry {_pending_metrics_tblname= }[] =3D {{ """) _args.output_file.write('};\n\n') =20 +def print_pending_pmu_counter_layout_table() -> None: + '''Print counter layout data from counter.json file to counter layout ta= ble in + c-string''' + + def pmu_counts_cmp_key(j: JsonEvent) -> Tuple[bool, str, str]: + def fix_none(s: Optional[str]) -> str: + if s is None: + return '' + return s + + return (j.desc is not None, fix_none(j.pmu)) + + global _pending_pmu_counts + if not _pending_pmu_counts: + return + + global _pending_pmu_counts_tblname + global pmu_layouts_tables + _pmu_layouts_tables.append(_pending_pmu_counts_tblname) + + _args.output_file.write( + f'static const struct compact_pmu_event {_pending_pmu_counts_tblname= }[] =3D {{\n') + + for pmu_layout in sorted(_pending_pmu_counts, key=3Dpmu_counts_cmp_key): + _args.output_file.write(pmu_layout.to_c_string(metric=3DFalse, layout= =3DTrue)) + _pending_pmu_counts =3D [] + + _args.output_file.write('};\n\n') + def get_topic(topic: str) -> str: if topic.endswith('metrics.json'): return 'metrics' @@ -623,10 +695,12 @@ def preprocess_one_file(parents: Sequence[str], item:= os.DirEntry) -> None: pmu_name =3D f"{event.pmu}\\000" if event.name: _bcs.add(pmu_name, metric=3DFalse) - _bcs.add(event.build_c_string(metric=3DFalse), metric=3DFalse) + _bcs.add(event.build_c_string(metric=3DFalse, layout=3DFalse), metri= c=3DFalse) if event.metric_name: _bcs.add(pmu_name, metric=3DTrue) - _bcs.add(event.build_c_string(metric=3DTrue), metric=3DTrue) + _bcs.add(event.build_c_string(metric=3DTrue, layout=3DFalse), metric= =3DTrue) + if event.counters['num'].gp: + _bcs.add(event.build_c_string(metric=3DFalse, layout=3DTrue), metric= =3DFalse) =20 def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None: """Process a JSON file during the main walk.""" @@ -640,11 +714,14 @@ def process_one_file(parents: Sequence[str], item: os= .DirEntry) -> None: if item.is_dir() and is_leaf_dir(item.path): print_pending_events() print_pending_metrics() + print_pending_pmu_counter_layout_table() =20 global _pending_events_tblname _pending_events_tblname =3D file_name_to_table_name('pmu_events_', par= ents, item.name) global _pending_metrics_tblname _pending_metrics_tblname =3D file_name_to_table_name('pmu_metrics_', p= arents, item.name) + global _pending_pmu_counts_tblname + _pending_pmu_counts_tblname =3D file_name_to_table_name('pmu_layouts_'= , parents, item.name) =20 if item.name =3D=3D 'sys': _sys_event_table_to_metric_table_mapping[_pending_events_tblname] = =3D _pending_metrics_tblname @@ -678,6 +755,12 @@ struct pmu_metrics_table { uint32_t num_pmus; }; =20 +/* Struct used to make the PMU counter layout table implementation opaque = to callers. */ +struct pmu_layouts_table { + const struct compact_pmu_event *entries; + size_t length; +}; + /* * Map a CPU to its table of PMU events. The CPU is identified by the * cpuid field, which is an arch-specific identifier for the CPU. @@ -691,6 +774,7 @@ struct pmu_events_map { const char *cpuid; struct pmu_events_table event_table; struct pmu_metrics_table metric_table; + struct pmu_layouts_table layout_table; }; =20 /* @@ -735,6 +819,12 @@ const struct pmu_events_map pmu_events_map[] =3D { metric_size =3D '0' if event_size =3D=3D '0' and metric_size =3D=3D '0': continue + layout_tblname =3D file_name_to_table_name('pmu_layouts_', [],= row[2].replace('/', '_')) + if layout_tblname in _pmu_layouts_tables: + layout_size =3D f'ARRAY_SIZE({layout_tblname})' + else: + layout_tblname =3D 'NULL' + layout_size =3D '0' cpuid =3D row[0].replace('\\', '\\\\') _args.output_file.write(f"""{{ \t.arch =3D "{arch}", @@ -746,6 +836,10 @@ const struct pmu_events_map pmu_events_map[] =3D { \t.metric_table =3D {{ \t\t.pmus =3D {metric_tblname}, \t\t.num_pmus =3D {metric_size} +\t}}, +\t.layout_table =3D {{ +\t\t.entries =3D {layout_tblname}, +\t\t.length =3D {layout_size} \t}} }}, """) @@ -756,6 +850,7 @@ const struct pmu_events_map pmu_events_map[] =3D { \t.cpuid =3D 0, \t.event_table =3D { 0, 0 }, \t.metric_table =3D { 0, 0 }, +\t.layout_table =3D { 0, 0 }, } }; """) @@ -824,6 +919,9 @@ static void decompress_event(int offset, struct pmu_eve= nt *pe) _args.output_file.write('\tp++;') else: _args.output_file.write('\twhile (*p++);') + _args.output_file.write('\twhile (*p++);') + _args.output_file.write(f'\n\tpe->counters_list =3D ') + _args.output_file.write("(*p =3D=3D '\\0' ? NULL : p);\n") _args.output_file.write("""} =20 static void decompress_metric(int offset, struct pmu_metric *pm) @@ -844,6 +942,30 @@ static void decompress_metric(int offset, struct pmu_m= etric *pm) _args.output_file.write('\twhile (*p++);') _args.output_file.write("""} =20 +static void decompress_layout(int offset, struct pmu_layout *pm) +{ +\tconst char *p =3D &big_c_string[offset]; +""") + for attr in _json_layout_attributes: + _args.output_file.write(f'\n\tpm->{attr} =3D ') + if attr in _json_enum_attributes: + _args.output_file.write("*p - '0';\n") + else: + _args.output_file.write("(*p =3D=3D '\\0' ? NULL : p);\n") + if attr =3D=3D _json_layout_attributes[-1]: + continue + if attr in _json_enum_attributes: + _args.output_file.write('\tp++;') + else: + _args.output_file.write('\twhile (*p++);') + _args.output_file.write('\tp++;') + _args.output_file.write(f'\n\tpm->counters_num_gp =3D ') + _args.output_file.write("*p - '0';\n") + _args.output_file.write('\tp++;') + _args.output_file.write(f'\n\tpm->counters_num_fixed =3D ') + _args.output_file.write("*p - '0';\n") + _args.output_file.write("""} + static int pmu_events_table__for_each_event_pmu(const struct pmu_events_ta= ble *table, const struct pmu_table_ent= ry *pmu, pmu_event_iter_fn fn, @@ -999,6 +1121,21 @@ int pmu_metrics_table__for_each_metric(const struct p= mu_metrics_table *table, return 0; } =20 +int pmu_layouts_table__for_each_layout(const struct pmu_layouts_table *tab= le, + pmu_layout_iter_fn fn, + void *data) { + for (size_t i =3D 0; i < table->length; i++) { + struct pmu_layout pm; + int ret; + + decompress_layout(table->entries[i].offset, &pm); + ret =3D fn(&pm, data); + if (ret) + return ret; + } + return 0; +} + static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu) { static struct { @@ -1094,6 +1231,33 @@ const struct pmu_metrics_table *perf_pmu__find_metri= cs_table(struct perf_pmu *pm return NULL; } =20 +const struct pmu_layouts_table *perf_pmu__find_layouts_table(struct perf_p= mu *pmu) +{ + const struct pmu_layouts_table *table =3D NULL; + char *cpuid =3D perf_pmu__getcpuid(pmu); + int i; + + /* on some platforms which uses cpus map, cpuid can be NULL for + * PMUs other than CORE PMUs. + */ + if (!cpuid) + return NULL; + + i =3D 0; + for (;;) { + const struct pmu_events_map *map =3D &pmu_events_map[i++]; + if (!map->arch) + break; + + if (!strcmp_cpuid_str(map->cpuid, cpuid)) { + table =3D &map->layout_table; + break; + } + } + free(cpuid); + return table; +} + const struct pmu_events_table *find_core_events_table(const char *arch, co= nst char *cpuid) { for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; @@ -1115,6 +1279,16 @@ const struct pmu_metrics_table *find_core_metrics_ta= ble(const char *arch, const } return NULL; } +const struct pmu_layouts_table *find_core_layouts_table(const char *arch, = const char *cpuid) +{ + for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; + tables->arch; + tables++) { + if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(table= s->cpuid, cpuid)) + return &tables->layout_table; + } + return NULL; +} =20 int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) { @@ -1143,6 +1317,19 @@ int pmu_for_each_core_metric(pmu_metric_iter_fn fn, = void *data) return 0; } =20 +int pmu_for_each_core_layout(pmu_layout_iter_fn fn, void *data) +{ + for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; + tables->arch; + tables++) { + int ret =3D pmu_layouts_table__for_each_layout(&tables->la= yout_table, fn, data); + + if (ret) + return ret; + } + return 0; +} + const struct pmu_events_table *find_sys_events_table(const char *name) { for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; @@ -1299,6 +1486,7 @@ struct pmu_table_entry { ftw(arch_path, [], process_one_file) print_pending_events() print_pending_metrics() + print_pending_pmu_counter_layout_table() =20 print_mapping_table(archs) print_system_mapping_table() diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index f5aa96f1685c..5b42a18693cf 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -45,6 +45,11 @@ struct pmu_event { const char *desc; const char *topic; const char *long_desc; + /** + * The list of counter(s) the event could be collected on. + * eg., "0,1,2,3,4,5,6,7". + */ + const char *counters_list; const char *pmu; const char *unit; bool perpkg; @@ -67,8 +72,18 @@ struct pmu_metric { enum metric_event_groups event_grouping; }; =20 +struct pmu_layout { + const char *pmu; + const char *desc; + /** Total number of generic counters*/ + int counters_num_gp; + /** Total number of fixed counters. Set to zero if no fixed counter on th= e unit.*/ + int counters_num_fixed; +}; + struct pmu_events_table; struct pmu_metrics_table; +struct pmu_layouts_table; =20 typedef int (*pmu_event_iter_fn)(const struct pmu_event *pe, const struct pmu_events_table *table, @@ -78,15 +93,21 @@ typedef int (*pmu_metric_iter_fn)(const struct pmu_metr= ic *pm, const struct pmu_metrics_table *table, void *data); =20 +typedef int (*pmu_layout_iter_fn)(const struct pmu_layout *pm, + void *data); + int pmu_events_table__for_each_event(const struct pmu_events_table *table, struct perf_pmu *pmu, pmu_event_iter_fn fn, void *data); int pmu_events_table__find_event(const struct pmu_events_table *table, - struct perf_pmu *pmu, - const char *name, - pmu_event_iter_fn fn, - void *data); + struct perf_pmu *pmu, + const char *name, + pmu_event_iter_fn fn, + void *data); +int pmu_layouts_table__for_each_layout(const struct pmu_layouts_table *tab= le, + pmu_layout_iter_fn fn, + void *data); size_t pmu_events_table__num_events(const struct pmu_events_table *table, struct perf_pmu *pmu); =20 @@ -95,10 +116,13 @@ int pmu_metrics_table__for_each_metric(const struct pm= u_metrics_table *table, pm =20 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu= *pmu); const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_p= mu *pmu); +const struct pmu_layouts_table *perf_pmu__find_layouts_table(struct perf_p= mu *pmu); const struct pmu_events_table *find_core_events_table(const char *arch, co= nst char *cpuid); const struct pmu_metrics_table *find_core_metrics_table(const char *arch, = const char *cpuid); +const struct pmu_layouts_table *find_core_layouts_table(const char *arch, = const char *cpuid); int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data); int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data); +int pmu_for_each_core_layout(pmu_layout_iter_fn fn, void *data); =20 const struct pmu_events_table *find_sys_events_table(const char *name); const struct pmu_metrics_table *find_sys_metrics_table(const char *name); --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C5611509BC; Fri, 12 Apr 2024 21:08:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956094; cv=none; b=B7QUD9LJBtwHLWTo2xwEXczHaSPWyrjeQgZe5KRBLGp1SQZa7pif5413JmIt//J2STTzSIz8jsrL6T7AVVGSFMigo94doTzhGK8pQLZoxtc1K10uAgPvYcuRt9FNQpEggcqqZEmKdPAg/xkQDJYKGUzVix68HrS1Days4fhfVqc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956094; c=relaxed/simple; bh=V5KLu8trmUCEspTvQ7KsyT2WAjK8jQQIxMfMXLVO6oU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rTdSkg8wArn44Zggrvm5JiX/BPgWt+z6IZJ6odJUQspUBvXyEAJVE98Lvtw+2PCWrjoDlJ22kimePXxcf4tTrW3q315MEUr2k+M9TB5+X+ubAQ/Mq6UwJsF5XgDrKa4Rlm5EF8yTJZMejUjMw+Y6+7Clr1Dfe9FUWij8WhuE9XM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=domLGK0B; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="domLGK0B" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956093; x=1744492093; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=V5KLu8trmUCEspTvQ7KsyT2WAjK8jQQIxMfMXLVO6oU=; b=domLGK0B8i1ndl5ubLT+Bc12u/fEJVYuqvMa+tAEWJuu2q0/zj/4CRqE 26LEx5JAyQCTcQmLB+mm+so04Qraht3ARv5O0tlkLXOJ7+3rMnh8nhnVb OdZoWWiRftI44SR240JwCA9ZKKCuqeuHlCzvOdtvvzmPxccF0b5wgJM+f jA2IqaXjVgrGljCTAMZ/3yNSl/u6LkcxpOJtFREK9CQd4m6V7BQB3jBVQ Z2+Fs7W7CnmO5Bbnq0N714x2Ro6VzM8OuwQQ6Hx+uWJ26hQu0iIQpt0U8 TVP7cEu2EEp5G81+zO8PrtJU+vAWc62bPA/FliUHJ0HI8HMF5EVi6diOX Q==; X-CSE-ConnectionGUID: EBEpOOC8Qs6Eg09N28Kb2w== X-CSE-MsgGUID: xZRvo+KwSR218HqlfXF8fg== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575447" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575447" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: XECMUHdWTwKJlOWtbSem2g== X-CSE-MsgGUID: Y/wT9ZQCTKSK4DolA0AWLw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772082" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:09 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 04/16] find_bit: add _find_last_and_bit() to support finding the most significant set bit Date: Fri, 12 Apr 2024 14:07:44 -0700 Message-ID: <20240412210756.309828-5-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang This function is required for more efficient PMU counter assignment. When we use bitmap to log available PMU counters and counters that support a given event, we want to find a most significant set bit so that we could starting assigning counters with larger index first. This is helpful because counters with smaller indexes usually are more generic and support more events. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/include/linux/find.h | 18 ++++++++++++++++++ tools/lib/find_bit.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tools/include/linux/find.h b/tools/include/linux/find.h index 38c0a542b0e2..fce336ec2b96 100644 --- a/tools/include/linux/find.h +++ b/tools/include/linux/find.h @@ -18,6 +18,8 @@ extern unsigned long _find_first_bit(const unsigned long = *addr, unsigned long si extern unsigned long _find_first_and_bit(const unsigned long *addr1, const unsigned long *addr2, unsigned long size); extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsig= ned long size); +extern unsigned long _find_last_and_bit(const unsigned long *addr1, + const unsigned long *addr2, unsigned long size); =20 #ifndef find_next_bit /** @@ -174,4 +176,20 @@ unsigned long find_first_zero_bit(const unsigned long = *addr, unsigned long size) } #endif =20 +#ifndef find_last_and_bit +static inline +unsigned long find_last_and_bit(const unsigned long *addr1, + const unsigned long *addr2, + unsigned long size) +{ + if (small_const_nbits(size)) { + unsigned long val =3D *addr1 & *addr2 & GENMASK(size - 1, 0); + + return val ? __fls(val) : size; + } + + return _find_last_and_bit(addr1, addr2, size); +} +#endif + #endif /*__LINUX_FIND_H_ */ diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c index 6a3dc167d30e..a84817d80c46 100644 --- a/tools/lib/find_bit.c +++ b/tools/lib/find_bit.c @@ -67,6 +67,27 @@ out: \ sz; \ }) =20 +/* + * Common helper for find_bit() function family + * @FETCH: The expression that fetches and pre-processes each word of bitm= ap(s) + * @MUNGE: The expression that post-processes a word containing found bit = (may be empty) + * @size: The bitmap size in bits + */ +#define FIND_LAST_BIT(FETCH, MUNGE, size) \ +({ \ + unsigned long idx, val, sz =3D (size); \ + \ + for (idx =3D ((size - 1) / BITS_PER_LONG); idx >=3D 0; idx--) { \ + val =3D (FETCH); \ + if (val) { \ + sz =3D min(idx * BITS_PER_LONG + __fls(MUNGE(val)), sz); \ + break; \ + } \ + } \ + \ + sz; \ +}) + #ifndef find_first_bit /* * Find the first set bit in a memory region. @@ -121,3 +142,15 @@ unsigned long _find_next_zero_bit(const unsigned long = *addr, unsigned long nbits return FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start); } #endif + +#ifndef find_last_and_bit +/* + * Find the last set bit in two memory regions. + */ +unsigned long _find_last_and_bit(const unsigned long *addr1, + const unsigned long *addr2, + unsigned long size) +{ + return FIND_LAST_BIT(addr1[idx] & addr2[idx], /* nop */, size); +} +#endif --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B0CB1514E9; Fri, 12 Apr 2024 21:08:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956095; cv=none; b=Radh04TmG4xeRqmBFsUHwIwRXWQmVE/jXfnNGf+7grhzls8hIA+iPpafwewKr67SjV41NL4bMUl7jPII0fDBYA3P8o0mzQCxG6+t10+RCuBD71dkFlY6vff6fywDIre5yRgUWBc0rOEtMDX99mPA+IZDMaSqrqPiuxlFwQ5O+Uc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956095; c=relaxed/simple; bh=kmD3Ow0z4vDuQgPB5ElG6sRuBpbFzXyR93y6Lfu2zDw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r8AvShsdHa3OCJ8aPssVGgy2x0CL6frCsWiwbCMM+yDub6SqSChu+q76dw+LPfB9Zqw4nMZYWEGiLd0aKzppI99kZsQB5kOJeSV+PO6CNSAcsg1IFtjGrORv9SIdUV8mTE94hjrTokM81qQtnRruI4iulbmf+pfxIR69eMJFck4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=hJO8hpZI; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="hJO8hpZI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956093; x=1744492093; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kmD3Ow0z4vDuQgPB5ElG6sRuBpbFzXyR93y6Lfu2zDw=; b=hJO8hpZIg9M7pXoHNDzUtSyd+GEJkJGtemYSg82DsYLoRL/ZZocSLy1j 9XJGGNpHaO9BBUtOdCI707aexsezm3RHW/ipD4s08h4/C9sP2q8H7upHv Q2WcuAHAWJoBEcqp3PTL0hxbPZH5SEBkupsgSBLX079hObc8gmueqcvI7 7+nnjop5H5YtndUb3gFY0b793ZNcckPhFnVmgvB11iMEv6XqH2ILsY5/J C4qEjIX1f/7SyWHW1JhpHISYeJf3JFjTUOBgoS3AdA/yT6A75pdf+JjRP SERFvli3XidIYnkh3yNjHqPcf2B8QItz7OGcNQBR3gHbjINWoxzb+CF/l w==; X-CSE-ConnectionGUID: ON+oiIkZSpe7OCN2DY08jg== X-CSE-MsgGUID: w/cI+8lWS9+wO9p42RgHNg== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575452" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575452" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: HrkS4uKzRNO0KV46ALHd5A== X-CSE-MsgGUID: PAsh3twkTaipIdGqQ0kXuQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772087" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:09 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 05/16] perf stat: Add functions to set counter bitmaps for hardware-grouping method Date: Fri, 12 Apr 2024 14:07:45 -0700 Message-ID: <20240412210756.309828-6-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add metricgroup__event_info data structure to represent an event in the metric grouping context; the list of counters and the PMU name an event should be collected with. Add functions to parse event counter info from pmu-events and generate a list of metricgroup__event_info data to prepare grouping. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 219 +++++++++++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8047f03b2b1f..1a7ac17f7ae1 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -159,6 +160,29 @@ struct metric { struct evlist *evlist; }; =20 +/* Maximum number of counters per PMU*/ +#define NR_COUNTERS 16 + +/** + * An event used in a metric. This info is for metric grouping. + */ +struct metricgroup__event_info { + struct list_head nd; + /** The name of the event. */ + const char *name; + /** The name of the pmu the event be collected on. */ + const char *pmu_name; + /** The event uses fixed counter. */ + bool fixed_counter; + /** + * The event uses special counters that we consider that as free counter + * during the event grouping. + */ + bool free_counter; + /** The counters the event allowed to be collected on. */ + DECLARE_BITMAP(counters, NR_COUNTERS); +}; + /** * Each group is one node in the group string list. */ @@ -1440,6 +1464,181 @@ static int build_combined_expr_ctx(const struct lis= t_head *metric_list, return ret; } =20 +/** + * set_counter_bitmap - The counter bitmap: [0-15]. + */ +static int set_counter_bitmap(int pos, unsigned long *bitmap) +{ + if (pos >=3D NR_COUNTERS || pos < 0) + return -EINVAL; + __set_bit(pos, bitmap); + return 0; +} + +static int parse_fixed_counter(const char *counter, + unsigned long *bitmap, + bool *fixed) +{ + int ret =3D -ENOENT; + /* TODO: this pattern maybe different on some other platforms */ + const char *pattern =3D "Fixed counter "; + int pos =3D 0; + + if (!strncmp(counter, pattern, strlen(pattern))) { + pos =3D atoi(counter + strlen(pattern)); + ret =3D set_counter_bitmap(pos, bitmap); + if (ret) + return ret; + *fixed =3D true; + return 0; + } + return ret; +} + +/** + * parse_counter - Parse event counter info from pmu-events and set up bit= map + * accordingly. + * + * @counter: counter info string to be parsed. + * @bitmap: bitmap to set based on counter info parsed. + * @fixed: is set to true if the event uses fixed counter. + */ +static int parse_counter(const char *counter, + unsigned long *bitmap, + bool *fixed) +{ + int ret =3D 0; + char *p; + char *tok; + int pos =3D 0; + + ret =3D parse_fixed_counter(counter, bitmap, fixed); + /* ret=3D=3D0 means matched with fixed counter */ + if (ret =3D=3D 0) + return ret; + + p =3D strdup(counter); + if (!p) + return -ENOMEM; + tok =3D strtok(p, ","); + if (!tok) + return -ENOENT; + + while (tok) { + pos =3D atoi(tok); + ret =3D set_counter_bitmap(pos, bitmap); + if (ret) + return ret; + tok =3D strtok(NULL, ","); + } + return 0; +} + +static struct metricgroup__event_info *event_info__new(const char *name, + const char *pmu_name, + const char *counter, + bool free_counter) +{ + int ret =3D 0; + char *bit_buf =3D malloc(NR_COUNTERS); + bool fixed_counter =3D false; + struct metricgroup__event_info *e; + + e =3D zalloc(sizeof(*e)); + if (!e) + return NULL; + if (!pmu_name) + pmu_name =3D "core"; + + e->name =3D strdup(name); + e->pmu_name =3D strdup(pmu_name); + if (!e->pmu_name || !e->name) + return NULL; + e->free_counter =3D free_counter; + if (free_counter) { + ret =3D set_counter_bitmap(0, e->counters); + if (ret) + return NULL; + } else { + ret =3D parse_counter(counter, e->counters, &fixed_counter); + if (ret) + return NULL; + e->fixed_counter =3D fixed_counter; + } + + bitmap_scnprintf(e->counters, NR_COUNTERS, bit_buf, NR_COUNTERS); + pr_debug("Event %s requires pmu %s counter: %s bitmap %s, [pmu=3D%s]\n", + e->name, e->pmu_name, counter, bit_buf, pmu_name); + + return e; +} + +struct metricgroup__add_metric_event_data { + struct list_head *list; + /* pure event name, exclude umask and other info*/ + const char *event_name; + /* event name and umask if applicable*/ + const char *event_id; +}; + +static int metricgroup__add_metric_event_callback(const struct pmu_event *= pe, + const struct pmu_events_table *table __maybe_unused, + void *data) +{ + struct metricgroup__event_info *event; + struct metricgroup__add_metric_event_data *d =3D data; + + if (!strcasecmp(pe->name, d->event_name)) { + event =3D event_info__new(d->event_id, pe->pmu, pe->counter, /*free_coun= ter=3D*/false); + if (!event) + return -ENOMEM; + list_add(&event->nd, d->list); + } + + return 0; +} + +/** + * get_metricgroup_events - Find counter requirement of events from the + * pmu_events table + * @full_id: the full event identifiers. + * @table: pmu_events table that is searched for event data. + * @event_info_list: the list that the new event counter info added to. + */ +static int get_metricgroup_events(const char *full_id, + const struct pmu_events_table *table, + struct list_head *event_info_list) +{ + LIST_HEAD(list); + int ret =3D 0; + const char *id; + const char *rsep, *sep =3D strchr(full_id, '@'); + + if (sep) { + rsep =3D strchr(full_id, ','); + id =3D strndup(sep + 1, rsep - sep - 1); + if (!id) { + ret =3D -ENOMEM; + goto out; + } + } else { + id =3D full_id; + } + { + struct metricgroup__add_metric_event_data data =3D { + .list =3D &list, + .event_name =3D id, + .event_id =3D full_id, + }; + ret =3D pmu_events_table_for_each_event(table, + metricgroup__add_metric_event_callback, &data); + } + +out: + list_splice(&list, event_info_list); + return ret; +} + /** * hw_aware_build_grouping - Build event groupings by reading counter * requirement of the events and counter available on the system from @@ -1453,9 +1652,25 @@ static int hw_aware_build_grouping(struct expr_parse= _ctx *ctx __maybe_unused, const char *modifier __maybe_unused) { int ret =3D 0; + struct hashmap_entry *cur; + LIST_HEAD(pmu_info_list); + LIST_HEAD(event_info_list); + size_t bkt; + const struct pmu_events_table *etable =3D perf_pmu__find_events_table(NUL= L); + +#define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0) + hashmap__for_each_entry(ctx->ids, cur, bkt) { + const char *id =3D cur->pkey; + + pr_debug("found event %s\n", id); + + ret =3D get_metricgroup_events(id, etable, &event_info_list); + if (ret) + return ret; + } =20 - pr_debug("This is a placeholder\n"); return ret; +#undef RETURN_IF_NON_ZERO } =20 static void group_str_free(struct metricgroup__group_strs *g) @@ -1529,8 +1744,6 @@ static int hw_aware_parse_ids(struct perf_pmu *fake_p= mu, *out_evlist =3D parsed_evlist; parsed_evlist =3D NULL; err_out: - parse_events_error__exit(&parse_error); - evlist__delete(parsed_evlist); metricgroup__free_grouping_strs(&groupings); return ret; } --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 95A9215216F; Fri, 12 Apr 2024 21:08:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956096; cv=none; b=adm72HS1YmbCw7TrFXIV/fsfhpGUSrgYDF8vMeDonZaQxcjaBuz/WwvMzwXQ7QY2TcjAJF4loJTe30o0nMbcPOSeo7HmYDAsleEqtV4hwep28/q4uqRVAN8jGoM4m+2O6CsVSuBIatgaKp6CnFT0qu9fF0D2wsPjtcVq6jDH+18= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956096; c=relaxed/simple; bh=HNG8EA0UJsyVjaeRiH+XOJfw23G7htj/ITVnQAFcHlM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=coSbb/Wyaf+Xk2gL7DEcx79yqWFCJaCTSmYYU9lsEG46O9hp3lM798OQYM0uphO87T4hH0n2PPR/+xHZKI776atXkMaT3MyJ00rK8zXrBpWxamklI8mYRhQqrTJ8ECg5zq8A9B+D1tyeWK3mfGhoxsUSqggGF1AMlUyi9HEbYNw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=WBcYE4pN; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="WBcYE4pN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956094; x=1744492094; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HNG8EA0UJsyVjaeRiH+XOJfw23G7htj/ITVnQAFcHlM=; b=WBcYE4pN28ZG7qlt8FjFbg09VzyegWSbLy6ZaWGE0qUx9BA6d6g5n1HJ 0nY+EqlhVLpF9K3nK//OYIcV66uexIKOMZkdVQ0dGNPSCB6nwGLSyCEWq YRNZCcGLlaVyYmkzcLOmL5m6lcAxN9nupe36uo0uZ1XOyxm2f/Bj3BkDH zFA7E3OHHEAD8rOY7i4UJv/FWHeamLF6bP2U0HQaqC7yvY8j4NiviGPuw JD6XzsWhJDOQ9NUUt0xHms119JoLwCOUHqP2ZZA+8xAIkYlttLG696RWD 9G0JLsyanv6TMoFG58j/Xj1bkDujGUMKN/gErKYNzK4GiG7wL/WMQv8Zp g==; X-CSE-ConnectionGUID: BiaxjMYOSiG9qsU2gLg/Zg== X-CSE-MsgGUID: oupYbsNCQmuW0Z0D6nxrIA== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575458" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575458" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: F5JMx7SoQviC7CYtIddpnQ== X-CSE-MsgGUID: iNcuMAGvR5uYvaFCY+8y7A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772095" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:10 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 06/16] perf stat: Add functions to get counter info Date: Fri, 12 Apr 2024 14:07:46 -0700 Message-ID: <20240412210756.309828-7-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add data structure metricgroup__pmu_counters to represent hardware counters available in the system. Add functions to parse pmu-events and create the list of pmu_info_list to hold the counter information of the system. Add functions to free pmu_info_list and event_info_list before exit grouping for hardware-grouping method This method would fall back to normal grouping when event json files do not support hardware aware grouping. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 115 +++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 1a7ac17f7ae1..78a5410cdc09 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -183,6 +183,21 @@ struct metricgroup__event_info { DECLARE_BITMAP(counters, NR_COUNTERS); }; =20 +/** + * A node is the counter availability of a pmu. + * This info is built up at the beginning from JSON file and + * used as a reference in metric grouping process. + */ +struct metricgroup__pmu_counters { + struct list_head nd; + /** The name of the pmu the event collected on. */ + const char *name; + /** The number of gp counters in the pmu. */ + size_t counters_num_gp; + /** The number of fixed counters in the pmu. */ + size_t counters_num_fixed; +}; + /** * Each group is one node in the group string list. */ @@ -1534,6 +1549,40 @@ static int parse_counter(const char *counter, return 0; } =20 +static void metricgroup__event_info__delete(struct metricgroup__event_info= *e) +{ + zfree(&e->name); + zfree(&e->pmu_name); + free(e); +} + +static void metricgroup__pmu_counter__delete(struct metricgroup__pmu_count= ers *p) +{ + zfree(&p->name); + free(p); +} + +static void metricgroup__free_event_info(struct list_head + *event_info_list) +{ + struct metricgroup__event_info *e, *tmp; + + list_for_each_entry_safe(e, tmp, event_info_list, nd) { + list_del_init(&e->nd); + metricgroup__event_info__delete(e); + } +} + +static void metricgroup__free_pmu_info(struct list_head *pmu_info_list) +{ + struct metricgroup__pmu_counters *p, *tmp; + + list_for_each_entry_safe(p, tmp, pmu_info_list, nd) { + list_del_init(&p->nd); + metricgroup__pmu_counter__delete(p); + } +} + static struct metricgroup__event_info *event_info__new(const char *name, const char *pmu_name, const char *counter, @@ -1589,7 +1638,9 @@ static int metricgroup__add_metric_event_callback(con= st struct pmu_event *pe, struct metricgroup__add_metric_event_data *d =3D data; =20 if (!strcasecmp(pe->name, d->event_name)) { - event =3D event_info__new(d->event_id, pe->pmu, pe->counter, /*free_coun= ter=3D*/false); + if (!pe->counters_list) + return -EINVAL; + event =3D event_info__new(d->event_id, pe->pmu, pe->counters_list, /*fre= e_counter=3D*/false); if (!event) return -ENOMEM; list_add(&event->nd, d->list); @@ -1630,7 +1681,7 @@ static int get_metricgroup_events(const char *full_id, .event_name =3D id, .event_id =3D full_id, }; - ret =3D pmu_events_table_for_each_event(table, + ret =3D pmu_events_table__for_each_event(table, /*pmu=3D*/NULL, metricgroup__add_metric_event_callback, &data); } =20 @@ -1639,6 +1690,59 @@ static int get_metricgroup_events(const char *full_i= d, return ret; } =20 +static struct metricgroup__pmu_counters *pmu_layout__new(const struct pmu_= layout *pl) +{ + struct metricgroup__pmu_counters *l; + + l =3D zalloc(sizeof(*l)); + + if (!l) + return NULL; + + l->name =3D strdup(pl->pmu); + if (!l->name) + return NULL; + l->counters_num_gp =3D pl->counters_num_gp; + l->counters_num_fixed =3D pl->counters_num_fixed; + pr_debug("create new pmu_layout: [pmu]=3D%s, [gp_size]=3D%ld, [fixed_size= ]=3D%ld\n", + l->name, l->counters_num_gp, l->counters_num_fixed); + return l; +} + +static int metricgroup__add_pmu_layout_callback(const struct pmu_layout *p= l, + void *data) +{ + struct metricgroup__pmu_counters *pmu; + struct list_head *d =3D data; + int ret =3D 0; + + pmu =3D pmu_layout__new(pl); + if (!pmu) + return -ENOMEM; + list_add(&pmu->nd, d); + return ret; +} + +/** + * get_pmu_counter_layouts - Find counter info of the architecture from + * the pmu_layouts table + * @pmu_info_list: the list that the new counter info of a pmu is added to. + * @table: pmu_layouts table that is searched for counter info. + */ +static int get_pmu_counter_layouts(struct list_head *pmu_info_list, + const struct pmu_layouts_table + *table) +{ + LIST_HEAD(list); + int ret; + + ret =3D pmu_layouts_table__for_each_layout(table, + metricgroup__add_pmu_layout_callback, &list); + + list_splice(&list, pmu_info_list); + return ret; +} + /** * hw_aware_build_grouping - Build event groupings by reading counter * requirement of the events and counter available on the system from @@ -1657,6 +1761,7 @@ static int hw_aware_build_grouping(struct expr_parse_= ctx *ctx __maybe_unused, LIST_HEAD(event_info_list); size_t bkt; const struct pmu_events_table *etable =3D perf_pmu__find_events_table(NUL= L); + const struct pmu_layouts_table *ltable =3D perf_pmu__find_layouts_table(N= ULL); =20 #define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0) hashmap__for_each_entry(ctx->ids, cur, bkt) { @@ -1666,9 +1771,13 @@ static int hw_aware_build_grouping(struct expr_parse= _ctx *ctx __maybe_unused, =20 ret =3D get_metricgroup_events(id, etable, &event_info_list); if (ret) - return ret; + goto err_out; } + ret =3D get_pmu_counter_layouts(&pmu_info_list, ltable); =20 +err_out: + metricgroup__free_event_info(&event_info_list); + metricgroup__free_pmu_info(&pmu_info_list); return ret; #undef RETURN_IF_NON_ZERO } --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC60815217C; Fri, 12 Apr 2024 21:08:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956096; cv=none; b=CLyU1I0cBY3OP7rKnUtpjvHrhDiRqpe5rTUdDUaWdiwcgRX8wxhRMd5Y8kdqjjVlKYjaHqHALNbGiqwQ46qaSYtuEOBG+r+YOAXTffoeOml4bKWOPhHryjznA8SsgeJoxgIaHuGHXf8PXJyQAeMDKaQ4BcMQi2M2k17vKYciGGw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956096; c=relaxed/simple; bh=3G5vPmPoY93BCGh4iP1v3nkrv6rcRRcpZupfl5XIttc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VNrK9yUHg5kCyMI4GpruO+X72cx38BrfbpipN8Ek8ElAWPhFpsuWLK60DMc8WlbPjd+9MZlvdNXRXZaFwHps9YbuuU9trQ4+L/T3fo3ruQUP2PxAkUzH0GzK39ZKxpiv6EJNk2iXqbxMNeDIPt/8IgH/PES8jsETtUqqxfqoGJg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=g4xV2MQD; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="g4xV2MQD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956095; x=1744492095; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3G5vPmPoY93BCGh4iP1v3nkrv6rcRRcpZupfl5XIttc=; b=g4xV2MQDCuUgLe/E6MkbFM2EsS0U2GDUtqsMe1skHg/vfb5l3RD7DxOl b6lCqwdUKT/H4NjS2Sn10CQ33La98t1+U02XlaOAa3zbqnacuSmiuF9OU fGQ+qipN1WJ0Li9EcYOqb/R/P9yZEWPJe0CHnMpjWKc5uorwNvfy349Fp TtkwaPAUJ/43GBMCR1J4tCfGjJndQuDYUgiFTZIhXDmEPmnqADSCkqZXa 89S3Nr6sn3BdvUDifT4REfmNzkkdWnS0p0g/oBsVzPktAWYHwvZ/NKvzl ISooSM0D4pTFycHfl/5zjz24D2tD6QGMfyOP4ZRs315hWAvgQFB4NTt0m A==; X-CSE-ConnectionGUID: L1wnH5B0TguXHcBA1SyS/Q== X-CSE-MsgGUID: U6nFcpvlTk67A+o5vCmogA== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575465" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575465" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: LqTrlZhaThGONSQAynYuQQ== X-CSE-MsgGUID: +wNQatQ0TbK+Qe+tmg5SRQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772098" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:10 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 07/16] perf stat: Add functions to create new group and assign events into groups Date: Fri, 12 Apr 2024 14:07:47 -0700 Message-ID: <20240412210756.309828-8-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add struct metricgroup__pmu_group_list to hold the lists of groups from different PMUs. Each PMU has one separate list. Add struct metricgroup__group as one node (one group in the grouping result) of the metricgroup__pmu_group_list. It uses two bitmaps to log counter availabilities(gp counters and fixed counters). Add functions to create group and assign event into the groups based on the event restrictions (struct metricgroup__event_info) and counter availability (pmu_info_list and bitmaps). New group is inserted into the list of groups. Add functions to handle counter bitmaps. Add functions do find and insert operations to handle inserting event into groups. Add function to fill all bits of one counter bitmap. Add functions to create new groups when no counter is available in all the existing groups. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 312 ++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 78a5410cdc09..88c86664c90c 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -197,6 +197,41 @@ struct metricgroup__pmu_counters { /** The number of fixed counters in the pmu. */ size_t counters_num_fixed; }; +/** + * A list of event groups for this pmu. + * This is updated during the grouping. + */ +struct metricgroup__pmu_group_list { + struct list_head nd; + /** The name of the pmu(/core) the events collected on. */ + const char *pmu_name; + /** The number of gp counters in the pmu(/core). */ + size_t counters_num_gp; + /** The number of fixed counters in the pmu(/core) if applicable. */ + size_t counters_num_fixed; + /** Head to the list of groups using this pmu(/core)*/ + struct list_head group_head; +}; +/** + * This is one node in the metricgroup__pmu_group_list. + * It represents on group. + */ +struct metricgroup__group { + struct list_head nd; + /** The bitmaps represent availability of the counters. + * They are updated once the corresponding counter is used by + * an event (event inserted into the group). + */ + DECLARE_BITMAP(gp_counters, NR_COUNTERS); + DECLARE_BITMAP(fixed_counters, NR_COUNTERS); + /** Head to the list of event names in this group*/ + struct list_head event_head; +}; + +struct metricgroup__group_events { + struct list_head nd; + const char *event_name; +}; =20 /** * Each group is one node in the group string list. @@ -1490,6 +1525,34 @@ static int set_counter_bitmap(int pos, unsigned long= *bitmap) return 0; } =20 +/** + * Returns 0 on success. Finds the last counter that is not used in pmu_co= unters + * and supports the event, included in event_counters. + */ +static int find_counter_bitmap(const unsigned long *pmu_counters, + const unsigned long *event_counters, + unsigned long *bit) +{ + /*It is helpful to assign from the highest bit because some events can + *only be collected using GP0-3. + */ + unsigned long find_bit =3D find_last_and_bit(pmu_counters, event_counters= , NR_COUNTERS); + + if (find_bit =3D=3D NR_COUNTERS) + return -ERANGE; + *bit =3D find_bit; + return 0; +} + +static int use_counter_bitmap(unsigned long *bitmap, + unsigned long find_bit) +{ + if (find_bit >=3D NR_COUNTERS) + return -EINVAL; + __clear_bit(find_bit, bitmap); + return 0; +} + static int parse_fixed_counter(const char *counter, unsigned long *bitmap, bool *fixed) @@ -1562,6 +1625,50 @@ static void metricgroup__pmu_counter__delete(struct = metricgroup__pmu_counters *p free(p); } =20 +static void metricgroup__group_event__delete(struct metricgroup__group_eve= nts *g) +{ + zfree(&g->event_name); + free(g); +} + +static void group_event_list_free(struct metricgroup__group *groups) +{ + struct metricgroup__group_events *e, *tmp; + + list_for_each_entry_safe(e, tmp, &groups->event_head, nd) { + list_del_init(&e->nd); + metricgroup__group_event__delete(e); + } +} + +static void group_list_free(struct metricgroup__pmu_group_list *groups) +{ + struct metricgroup__group *g, *tmp; + + list_for_each_entry_safe(g, tmp, &groups->group_head, nd) { + list_del_init(&g->nd); + group_event_list_free(g); + free(g); + } +} + +static void metricgroup__pmu_group_list__delete(struct metricgroup__pmu_gr= oup_list *g) +{ + group_list_free(g); + zfree(&g->pmu_name); + free(g); +} + +static void metricgroup__free_group_list(struct list_head *groups) +{ + struct metricgroup__pmu_group_list *g, *tmp; + + list_for_each_entry_safe(g, tmp, groups, nd) { + list_del_init(&g->nd); + metricgroup__pmu_group_list__delete(g); + } +} + static void metricgroup__free_event_info(struct list_head *event_info_list) { @@ -1743,6 +1850,207 @@ static int get_pmu_counter_layouts(struct list_head= *pmu_info_list, return ret; } =20 +static int fill_counter_bitmap(unsigned long *bitmap, int start, int size) +{ + int ret; + + bitmap_zero(bitmap, NR_COUNTERS); + + for (int pos =3D start; pos < start + size; pos++) { + ret =3D set_counter_bitmap(pos, bitmap); + if (ret) + return ret; + } + return 0; +} + +/** + * Find if there is a counter available for event e in current_group. If a + * counter is available, use this counter by filling the bit in the correct + * counter bitmap. Otherwise, return error (-ERANGE). + */ +static int find_and_set_counters(struct metricgroup__event_info *e, + struct metricgroup__group *current_group) +{ + int ret; + unsigned long find_bit =3D 0; + + if (e->free_counter) + return 0; + if (e->fixed_counter) { + ret =3D find_counter_bitmap(current_group->fixed_counters, e->counters, + &find_bit); + if (ret) + return ret; + pr_debug("found counter for [event]=3D%s [e->fixed_counters]=3D%lu\n", + e->name, *current_group->fixed_counters); + ret =3D use_counter_bitmap(current_group->fixed_counters, find_bit); + } else { + ret =3D find_counter_bitmap(current_group->gp_counters, e->counters, + &find_bit); + if (ret) + return ret; + pr_debug("found counter for [event]=3D%s [e->gp_counters]=3D%lu\n", + e->name, *current_group->gp_counters); + ret =3D use_counter_bitmap(current_group->gp_counters, find_bit); + } + return ret; +} + +static int _insert_event(struct metricgroup__event_info *e, + struct metricgroup__group *group) +{ + struct metricgroup__group_events *event =3D malloc(sizeof(struct metricgr= oup__group_events)); + + if (!event) + return -ENOMEM; + event->event_name =3D strdup(e->name); + if (!event->event_name) + return -ENOMEM; + if (e->fixed_counter) + list_add(&event->nd, &group->event_head); + else + list_add_tail(&event->nd, &group->event_head); + return 0; +} + +/** + * Insert the new_group node at the end of the group list. + */ +static int insert_new_group(struct list_head *head, + struct metricgroup__group *new_group, + size_t counters_num_gp, + size_t counters_num_fixed) +{ + INIT_LIST_HEAD(&new_group->event_head); + fill_counter_bitmap(new_group->gp_counters, 0, counters_num_gp); + fill_counter_bitmap(new_group->fixed_counters, 0, counters_num_fixed); + list_add_tail(&new_group->nd, head); + return 0; +} + +/** + * Insert event e into a group capable to include it + * + */ +static int insert_event_to_group(struct metricgroup__event_info *e, + struct metricgroup__pmu_group_list *pmu_group_head) +{ + struct metricgroup__group *g; + int ret; + struct list_head *head; + + list_for_each_entry(g, &pmu_group_head->group_head, nd) { + ret =3D find_and_set_counters(e, g); + if (!ret) { /* return if successfully find and set counter*/ + ret =3D _insert_event(e, g); + return ret; + } + } + /* + * We were not able to find an existing group to insert this event. + * Continue to create a new group and insert the event in it. + */ + { + struct metricgroup__group *current_group =3D + zalloc(sizeof(struct metricgroup__group)); + + if (!current_group) + return -ENOMEM; + pr_debug("create_new_group for [event] %s\n", e->name); + + head =3D &pmu_group_head->group_head; + ret =3D insert_new_group(head, current_group, pmu_group_head->counters_n= um_gp, + pmu_group_head->counters_num_fixed); + if (ret) + return ret; + ret =3D find_and_set_counters(e, current_group); + if (ret) + return ret; + ret =3D _insert_event(e, current_group); + } + + return ret; +} + +/** + * assign_event_grouping - Assign an event into a group. If existing group + * cannot include it, create a new group and insert the event to it. + */ +static int assign_event_grouping(struct metricgroup__event_info *e, + struct list_head *pmu_info_list, + struct list_head *groups) +{ + int ret =3D 0; + + struct metricgroup__pmu_group_list *g =3D NULL; + struct metricgroup__pmu_group_list *pmu_group_head =3D NULL; + + list_for_each_entry(g, groups, nd) { + if (!strcasecmp(g->pmu_name, e->pmu_name)) { + pr_debug("found group for event %s in pmu %s\n", e->name, g->pmu_name); + pmu_group_head =3D g; + break; + } + } + if (!pmu_group_head) { + struct metricgroup__pmu_counters *p; + + pmu_group_head =3D malloc(sizeof(struct metricgroup__pmu_group_list)); + if (!pmu_group_head) + return -ENOMEM; + INIT_LIST_HEAD(&pmu_group_head->group_head); + pr_debug("create new group for event %s in pmu %s\n", e->name, e->pmu_na= me); + pmu_group_head->pmu_name =3D strdup(e->pmu_name); + if (!pmu_group_head->pmu_name) + return -ENOMEM; + list_for_each_entry(p, pmu_info_list, nd) { + if (!strcasecmp(p->name, e->pmu_name)) { + pmu_group_head->counters_num_gp =3D p->counters_num_gp; + pmu_group_head->counters_num_fixed =3D p->counters_num_fixed; + break; + } + } + list_add_tail(&pmu_group_head->nd, groups); + } + + ret =3D insert_event_to_group(e, pmu_group_head); + return ret; +} + +/** + * create_grouping - Create a list of groups and place all the events of + * event_info_list into these groups. + * @pmu_info_list: the list of PMU units info based on pmu-events data, us= ed for + * creating new groups. + * @event_info_list: the list of events to be grouped. + * @groupings: the list of groups with events placed in. + * @modifier: any modifiers added to the events. + */ +static int create_grouping(struct list_head *pmu_info_list, + struct list_head *event_info_list, + struct list_head *groupings __maybe_unused, + const char *modifier __maybe_unused) +{ + int ret =3D 0; + struct metricgroup__event_info *e; + LIST_HEAD(groups); + char *bit_buf =3D malloc(NR_COUNTERS); + + //TODO: for each new core group, we should consider to add events that us= es fixed counters + list_for_each_entry(e, event_info_list, nd) { + bitmap_scnprintf(e->counters, NR_COUNTERS, bit_buf, NR_COUNTERS); + pr_debug("Event name %s, [pmu]=3D%s, [counters]=3D%s\n", e->name, + e->pmu_name, bit_buf); + ret =3D assign_event_grouping(e, pmu_info_list, &groups); + if (ret) + goto out; + } +out: + metricgroup__free_group_list(&groups); + return ret; +}; + /** * hw_aware_build_grouping - Build event groupings by reading counter * requirement of the events and counter available on the system from @@ -1774,6 +2082,10 @@ static int hw_aware_build_grouping(struct expr_parse= _ctx *ctx __maybe_unused, goto err_out; } ret =3D get_pmu_counter_layouts(&pmu_info_list, ltable); + if (ret) + goto err_out; + ret =3D create_grouping(&pmu_info_list, &event_info_list, groupings, + modifier); =20 err_out: metricgroup__free_event_info(&event_info_list); --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54AD0152519; Fri, 12 Apr 2024 21:08:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956098; cv=none; b=ueYpwkp+rMpqnAPGVn5yWx9jN1iTEiEUgBQAUmBqvC3ZtpM3SX0QIY5j8XUZfKBQzNU92pzxt6Jm9lIus++his8ZryqYnRxhtfmKREEvm7IdAc5E7d2awiQd2s3y4Wp8ot4rgry8vJKwrDUzcyAZGwmqkMnPPnBUK8Z8OWAsAx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956098; c=relaxed/simple; bh=DV3uTwrh+Qu4EgrPMg7ey229zxW4jOgVXR6iSOG6fp4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=apOZZv1qL7Rt2AUb91SvE0T0Y1Jo0O91mgf6x9etbvQplitO+ve9H3JSKLV67Ai+zFrUVuCJSphqODDSl4Xr6mzHZouAMqtjCJPNFsiWvT8KlcXPHtPEpbNsVNwMjDMXdd51GPav8Y7GAuZ2AXeft8A/9kzoouSLPsFwIjjRfPQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=BGdumuUj; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BGdumuUj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956096; x=1744492096; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DV3uTwrh+Qu4EgrPMg7ey229zxW4jOgVXR6iSOG6fp4=; b=BGdumuUj24+fGQgwI2pkaSV1i6JRIYBknVElGmYY+7fu0us6rGxWOHne 0YRePACsLVBlfOp9ZKEczPvHl/3c0fb5fzTwUyn7cMjoT/tvyZcd7N32f ycUHOxp2ruxdf8VRJqpQDVFhFT4JJ5vmnw5mrZl/79fGe8WntuvU80leS HRgB4xrEyRDDUq2I8ecTkktL7NrsJ/h/cY8Eo3zlEmzBSxwD/wweBfCnf s9hQ3TkDW5wRl32HefpelfILwBNvi3eW41mqNd6I5rgTBIFXK/j0T1/Ln cTm335s8BD6r/+GjZrqk4bQikKDBgi3UJjh0MLeSQbvT0JbgDcfgnwax4 A==; X-CSE-ConnectionGUID: DDgm+IDqQcODYhyvVmieWQ== X-CSE-MsgGUID: XcZrwr1FQ+ejpT+EXtpq6w== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575473" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575473" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: AA2x1v9kT6m+UvTXJXpS5g== X-CSE-MsgGUID: bOzImhUCSe+2pF9AkjRTNw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772101" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:10 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 08/16] perf stat: Add build string function and topdown events handling in hardware-grouping Date: Fri, 12 Apr 2024 14:07:48 -0700 Message-ID: <20240412210756.309828-9-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add the function to generate final grouping strings. This function is very similar to the existing metricgroup__build_event_string() function. The difference is that the input data includes a list of grouping lists. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 97 +++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 88c86664c90c..04d988ace734 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -2018,6 +2018,96 @@ static int assign_event_grouping(struct metricgroup_= _event_info *e, return ret; } =20 +static int hw_aware_metricgroup__build_event_string(struct list_head *grou= p_strs, + const char *modifier, + struct list_head *groups) +{ + struct metricgroup__pmu_group_list *p; + struct metricgroup__group *g; + struct metricgroup__group_events *ge; + bool no_group =3D true; + int ret =3D 0; + +#define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0) + + list_for_each_entry(p, groups, nd) { + list_for_each_entry(g, &p->group_head, nd) { + struct strbuf *events; + struct metricgroup__group_strs *new_group_str =3D + malloc(sizeof(struct metricgroup__group_strs)); + + if (!new_group_str) + return -ENOMEM; + strbuf_init(&new_group_str->grouping_str, 0); + events =3D &new_group_str->grouping_str; + ret =3D strbuf_addch(events, '{'); + RETURN_IF_NON_ZERO(ret); + no_group =3D true; + list_for_each_entry(ge, &g->event_head, nd) { + const char *sep, *rsep, *id =3D ge->event_name; + + pr_debug("found event %s\n", id); + + /* Separate events with commas and open the group if necessary. */ + if (!no_group) { + ret =3D strbuf_addch(events, ','); + RETURN_IF_NON_ZERO(ret); + } + /* + * Encode the ID as an event string. Add a qualifier for + * metric_id that is the original name except with characters + * that parse-events can't parse replaced. For example, + * 'msr@tsc@' gets added as msr/tsc,metric-id=3Dmsr!3tsc!3/ + */ + sep =3D strchr(id, '@'); + if (sep) { + ret =3D strbuf_add(events, id, sep - id); + RETURN_IF_NON_ZERO(ret); + ret =3D strbuf_addch(events, '/'); + RETURN_IF_NON_ZERO(ret); + rsep =3D strrchr(sep, '@'); + ret =3D strbuf_add(events, sep + 1, rsep - sep - 1); + RETURN_IF_NON_ZERO(ret); + ret =3D strbuf_addstr(events, ",metric-id=3D"); + RETURN_IF_NON_ZERO(ret); + sep =3D rsep; + } else { + sep =3D strchr(id, ':'); + if (sep) { + ret =3D strbuf_add(events, id, sep - id); + RETURN_IF_NON_ZERO(ret); + } else { + ret =3D strbuf_addstr(events, id); + RETURN_IF_NON_ZERO(ret); + } + ret =3D strbuf_addstr(events, "/metric-id=3D"); + RETURN_IF_NON_ZERO(ret); + } + ret =3D encode_metric_id(events, id); + RETURN_IF_NON_ZERO(ret); + ret =3D strbuf_addstr(events, "/"); + RETURN_IF_NON_ZERO(ret); + + if (sep) { + ret =3D strbuf_addstr(events, sep + 1); + RETURN_IF_NON_ZERO(ret); + } + if (modifier) { + ret =3D strbuf_addstr(events, modifier); + RETURN_IF_NON_ZERO(ret); + } + no_group =3D false; + } + ret =3D strbuf_addf(events, "}"); + RETURN_IF_NON_ZERO(ret); + pr_debug("events-buf: %s\n", events->buf); + list_add_tail(&new_group_str->nd, group_strs); + } + } + return ret; +#undef RETURN_IF_NON_ZERO +} + /** * create_grouping - Create a list of groups and place all the events of * event_info_list into these groups. @@ -2029,8 +2119,8 @@ static int assign_event_grouping(struct metricgroup__= event_info *e, */ static int create_grouping(struct list_head *pmu_info_list, struct list_head *event_info_list, - struct list_head *groupings __maybe_unused, - const char *modifier __maybe_unused) + struct list_head *groupings, + const char *modifier) { int ret =3D 0; struct metricgroup__event_info *e; @@ -2046,6 +2136,7 @@ static int create_grouping(struct list_head *pmu_info= _list, if (ret) goto out; } + ret =3D hw_aware_metricgroup__build_event_string(groupings, modifier, &gr= oups); out: metricgroup__free_group_list(&groups); return ret; @@ -2075,8 +2166,6 @@ static int hw_aware_build_grouping(struct expr_parse_= ctx *ctx __maybe_unused, hashmap__for_each_entry(ctx->ids, cur, bkt) { const char *id =3D cur->pkey; =20 - pr_debug("found event %s\n", id); - ret =3D get_metricgroup_events(id, etable, &event_info_list); if (ret) goto err_out; --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64D38152194; Fri, 12 Apr 2024 21:08:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956096; cv=none; b=pjLTU0LtBsbZkzOYlnclDKCgfun4nNswQ+JC5UEdEfkYnDWmvHqtKXgNSswXEux+zULxThweMJtVoqowq+ARwVBM8TPnkVRDscinAZTE/JlhWgITF63Cz3rOTvrEpe53iSXfBis9zPouqEZ1Sy3DqO0SEXwUZ0lgnR5TkN4WqPE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956096; c=relaxed/simple; bh=3hTJ9fWLDhNtE9cyNQKOk+MI436+hVx2AKwZNmm7sEg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Px6Mg6+Tm7eu1o6RR65noOMFItUKdmqo2kXId4nF2aTOVK2kwsGUG5FkT7WZs6S407A/f9+m8UfPPt+mjhu7R+Vbsgo4qwIBtgIcsCgqvBUzVIQ8Ue5zgPanVdQzK5D6RVzBetsavhcIOcvSoXJyQl4uI6XRXCaqd+khruV0DHQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Nq3GnpvR; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Nq3GnpvR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956095; x=1744492095; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3hTJ9fWLDhNtE9cyNQKOk+MI436+hVx2AKwZNmm7sEg=; b=Nq3GnpvRrj3oCPUH3j+Vxk6Pemmu+qjT8bUFEjWf33gbp6ts7kWG3SuB pH0BPkCyoj1Ej60X2S8bOyYuKRa8ki2Vk8rBNEiwp7AbsQqkU8C5G9GUS XlojAR5bbVOs+jqeZzhdKGhLZjq+5DDsX65rN2/rvosi4ZwOth3+wGVFu mtLFHhh/xrXfDrnPqeXUBwJmsGLnJP2bx5WBPdYSfYD6nB1x7srGk3zEC 0nnnSOTq8LhLA34Azwc7HT3VgyqV1TE0Ba4ox9J8S+39pWaqy7c33BrA/ DEDWapOcSJJzABfxsxDr3TSnzOtIPod2ChFtEawLalosqim4V4Lw2S2Ve g==; X-CSE-ConnectionGUID: kDkQcVOjTiWTmdlGZKvRSg== X-CSE-MsgGUID: Tf5R7+oKRNujPfoy+1KrIg== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575470" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575470" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: WnX19+FeQbCkCN15FrM1kQ== X-CSE-MsgGUID: HQYVwZRmSnCEh3FtHj3Opg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772105" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:10 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 09/16] perf stat: Add function to handle special events in hardware-grouping Date: Fri, 12 Apr 2024 14:07:49 -0700 Message-ID: <20240412210756.309828-10-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang There are some special events like topdown events and TSC that are not described in pmu-event JSON files. Add support to handle this type of events. This should be considered as a temporary solution because including these events in JSON files would be a better solution. Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 04d988ace734..681aacc15787 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -162,6 +162,20 @@ struct metric { =20 /* Maximum number of counters per PMU*/ #define NR_COUNTERS 16 +/* Special events that are not described in pmu-event JSON files. + * topdown-* and TSC use dedicated registers, set as free + * counter for grouping purpose + */ +enum special_events { + TOPDOWN =3D 0, + TSC =3D 1, + SPECIAL_EVENT_MAX, +}; + +static const char *const special_event_names[SPECIAL_EVENT_MAX] =3D { + "topdown-", + "TSC", +}; =20 /** * An event used in a metric. This info is for metric grouping. @@ -2142,6 +2156,15 @@ static int create_grouping(struct list_head *pmu_inf= o_list, return ret; }; =20 +static bool is_special_event(const char *id) +{ + for (int i =3D 0; i < SPECIAL_EVENT_MAX; i++) { + if (!strncmp(id, special_event_names[i], strlen(special_event_names[i]))) + return true; + } + return false; +} + /** * hw_aware_build_grouping - Build event groupings by reading counter * requirement of the events and counter available on the system from @@ -2166,6 +2189,17 @@ static int hw_aware_build_grouping(struct expr_parse= _ctx *ctx __maybe_unused, hashmap__for_each_entry(ctx->ids, cur, bkt) { const char *id =3D cur->pkey; =20 + if (is_special_event(id)) { + struct metricgroup__event_info *event; + + event =3D event_info__new(id, "default_core", "0", + /*free_counter=3D*/true); + if (!event) + goto err_out; + + list_add(&event->nd, &event_info_list); + continue; + } ret =3D get_metricgroup_events(id, etable, &event_info_list); if (ret) goto err_out; @@ -2636,8 +2670,10 @@ int metricgroup__parse_groups(struct evlist *perf_ev= list, ret =3D hw_aware_parse_groups(perf_evlist, pmu, str, metric_no_threshold, user_requested_cpu_list, system_wide, /*fake_pmu=3D*/NULL, metric_events, table); - if (!ret) + if (!ret) { + pr_info("Hardware aware grouping completed\n"); return 0; + } } =20 return parse_groups(perf_evlist, pmu, str, metric_no_group, metric_no_mer= ge, --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9FDD6152527; Fri, 12 Apr 2024 21:08:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956098; cv=none; b=rQ5RFaLGfwCcqOn2Li6eohmU0HvHJLu6s7tl8efmfYL31ysAUl9zWzKm9VXCytkgePKJRAxAzkeCH+XEqsgVUQkEZvzCMO69FwmFlMl1XbXGgBLu0Lje38D/Exa9jk4p9xH/4+X87C9OyEMcXrwWuuVFj7c5Wp7g4Pld67MlMzQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956098; c=relaxed/simple; bh=QkVtBQWWBMMe1MNkeP0H8yozIjK/9HP9b2M/bd9n5rI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NRL49wY4w9Etc6bshtlG2G7j8Y541iJc+S9qxCVonmX8jRbUpgxESUQ6TtG50xNS68BiahSqXw2dZykDwtuEy/I6olnIjdIXs4lo8wHHbacaVefvV7kC6Ji/Vp/SgFOB4o5pvlCSJlJ/q4+7b5CfFZSkMq9+bnMJe0Ho10Zxm8o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=AxV0iNPg; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="AxV0iNPg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956096; x=1744492096; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QkVtBQWWBMMe1MNkeP0H8yozIjK/9HP9b2M/bd9n5rI=; b=AxV0iNPgRfNDHLAx2GA9T37UiNxf0Ju8RGbd9H1F5q0TfZ0fMkOozWHQ YB9n/uu8pN/9AHw74glxd39oYQCjLxgt1P8APYhVAT+xguWhIpKMEimKf WQH5PGk7599nKKMM9Hnxfx5MKEUzrrUcY/6eoxLqtsD7LGWAgpwn9Svx3 +CR/8Akr3uZm39wvBySkrdS5HxV1k3gOAxTCrsdcXXUk1uCKmTE84t72s Rb97oO6sNjwvuWr9tP827WPzx4+pStd3II95/Y2797weZo5DbOXi2qoby yIWc3NwYW/HGv27D5q/RIY6Ak7/opmGJ8wDI7Dgg7z+bGj9YVRGfNTT4S w==; X-CSE-ConnectionGUID: j+9YggPBQ02gntylHSuP2g== X-CSE-MsgGUID: +DhTQty5RJKupYEQVavYFA== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575478" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575478" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: CP8JkpW1QJCivNJxMLE4Pw== X-CSE-MsgGUID: CLNit7O2RaucMSlIVoQdiw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772108" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:10 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 10/16] perf stat: Add function to combine metrics for hardware-grouping Date: Fri, 12 Apr 2024 14:07:50 -0700 Message-ID: <20240412210756.309828-11-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang This function is very similar to the existing build_combined_expr_ctx(). Should be able to reuse current function instead of adding a new one. Will fix this later. Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 47 ++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 681aacc15787..b9e46dff1e17 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1528,6 +1528,46 @@ static int build_combined_expr_ctx(const struct list= _head *metric_list, return ret; } =20 +/** + * hw_aware_build_combined_expr_ctx - Make an expr_parse_ctx with all !gro= up_events + * metric IDs, as the IDs are held in a set, + * duplicates will be removed. + * @metric_list: List to take metrics from. + * @combined: Out argument for result. + */ +static int hw_aware_build_combined_expr_ctx(const struct list_head *metric= _list, + struct expr_parse_ctx **combined) +{ + struct hashmap_entry *cur; + size_t bkt; + struct metric *m; + char *dup; + int ret; + + *combined =3D expr__ctx_new(); + if (!*combined) + return -ENOMEM; + + list_for_each_entry(m, metric_list, nd) { + hashmap__for_each_entry(m->pctx->ids, cur, bkt) { + pr_debug2("metric: %s\n", m->metric_name); + dup =3D strdup(cur->pkey); + if (!dup) { + ret =3D -ENOMEM; + goto err_out; + } + ret =3D expr__add_id(*combined, dup); + if (ret) + goto err_out; + } + } + return 0; +err_out: + expr__ctx_free(*combined); + *combined =3D NULL; + return ret; +} + /** * set_counter_bitmap - The counter bitmap: [0-15]. */ @@ -1851,8 +1891,7 @@ static int metricgroup__add_pmu_layout_callback(const= struct pmu_layout *pl, * @table: pmu_layouts table that is searched for counter info. */ static int get_pmu_counter_layouts(struct list_head *pmu_info_list, - const struct pmu_layouts_table - *table) + const struct pmu_layouts_table *table) { LIST_HEAD(list); int ret; @@ -2288,6 +2327,8 @@ static int hw_aware_parse_ids(struct perf_pmu *fake_p= mu, *out_evlist =3D parsed_evlist; parsed_evlist =3D NULL; err_out: + parse_events_error__exit(&parse_error); + evlist__delete(parsed_evlist); metricgroup__free_grouping_strs(&groupings); return ret; } @@ -2410,7 +2451,7 @@ static int hw_aware_parse_groups(struct evlist *perf_= evlist, if (!metric_no_merge) { struct expr_parse_ctx *combined =3D NULL; =20 - ret =3D build_combined_expr_ctx(&metric_list, &combined); + ret =3D hw_aware_build_combined_expr_ctx(&metric_list, &combined); =20 if (!ret && combined && hashmap__size(combined->ids)) { ret =3D hw_aware_parse_ids(fake_pmu, combined, --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F164515253B; Fri, 12 Apr 2024 21:08:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956098; cv=none; b=Es0RDZ9tuDNTCyRnhyBLwTO93/LFn4xzKUfX0U71jgrmpJOn451PORAPYF1n+Aemx2A2FCHq8zNbTanGg8EIXW+HCyjFi8OaPYb54SnJ3cqLU409meswCol9el6BECrZCAUbtZKxs3+DJSse7X3pQLPXZ0FVK9t4MfTBNqY668o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956098; c=relaxed/simple; bh=ogrxKE2gR5mVkVtp7MLCNz0k+qduvC4zFBtBAG24Xhg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tPNVgv8bxUHshS29qtoa8vMw9chn/qbYbk3Yj41EY/hXohSQPEGHge7fUG9/kZj2Q01bKN/2iMT0GRonLilsLF4xicSpnMo/5ZeSSBZcFUkuvdXu/hZ5aDqttlcGEYeAPiBVVB/S3GCYJmR9ruLpaNGMVnRnzTXbhqyqHNqJaiU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=RUHLddYj; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="RUHLddYj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956097; x=1744492097; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ogrxKE2gR5mVkVtp7MLCNz0k+qduvC4zFBtBAG24Xhg=; b=RUHLddYjbcNDu3mYWdyD8JHX7tTlkj7VEBOmua+Wk5SVpHCDu0rsb/Y8 B+4jf+vy7cRH/WQJrORtb1le1W7fvbosEG/RO8kDL/uf/+IRot7LknUbo RSEwEEHUlsUSI8Ty1SwtkmtJyDl9xqg8fgsx8+Wrlz53R1c0VNYnbjPM9 UIoIKMlGPVSQ1DOH285FemsdNdam3VrQSnSU4yz8HWrOm6U9RhX+i49f4 yX9ZFBVYve0SkQNCjZSj8fjtmS5pVrJjQrwNl4C3010Pm0sAAMkPXfPV2 3rweNbLw/aXHj859c5Nax/2L1xnKbhmj9c23b/ZoHajA1euwhjY4KryL/ g==; X-CSE-ConnectionGUID: TPbLbcXtTwqXpq/+4cud4Q== X-CSE-MsgGUID: S0DG0pzESvme0MhmGkG43A== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575486" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575486" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: ishY4e1mTE2web46tuLqAg== X-CSE-MsgGUID: bwfcFw67RAeYZSDash3Scw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772111" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:10 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 11/16] perf stat: Add partial support on MSR in hardware-grouping Date: Fri, 12 Apr 2024 14:07:51 -0700 Message-ID: <20240412210756.309828-12-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add MSR usage into consideration when grouping. Each group can only include one event that requires one specific MSR. Currently, we only support events that requries one MSR. For some OCR events that have multiple MSRs in their MSRIndex field, this commit will treat them as one "large MSR". We're planning to improve this part in future. Signed-off-by: Weilin Wang --- tools/perf/pmu-events/jevents.py | 4 +++- tools/perf/pmu-events/pmu-events.h | 6 ++++++ tools/perf/util/metricgroup.c | 27 ++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 7cfd86d77fea..66531c2df224 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -54,7 +54,9 @@ _json_event_attributes =3D [ # Short things in alphabetical order. 'compat', 'deprecated', 'perpkg', 'unit', # Longer things (the last won't be iterated over during decompress). - 'long_desc' + 'long_desc', + # MSRIndex required by the event. NULL if no MSR is required. + 'msr' ] =20 # Attributes that are in pmu_unit_layout. diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 5b42a18693cf..76ec2b431dce 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -54,6 +54,12 @@ struct pmu_event { const char *unit; bool perpkg; bool deprecated; + /* + * MSR is another resource that restricts grouping. Currently, we + * support only MSRIndex 0x3F6 and 0x3F7. TODO: add support for all the + * MSRs related to event grouping. + */ + const char *msr; }; =20 struct pmu_metric { diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index b9e46dff1e17..9548654c9f6d 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -193,6 +193,7 @@ struct metricgroup__event_info { * during the event grouping. */ bool free_counter; + const char *msr; /** The counters the event allowed to be collected on. */ DECLARE_BITMAP(counters, NR_COUNTERS); }; @@ -240,6 +241,7 @@ struct metricgroup__group { DECLARE_BITMAP(fixed_counters, NR_COUNTERS); /** Head to the list of event names in this group*/ struct list_head event_head; + const char *msr; }; =20 struct metricgroup__group_events { @@ -1747,6 +1749,7 @@ static void metricgroup__free_pmu_info(struct list_he= ad *pmu_info_list) static struct metricgroup__event_info *event_info__new(const char *name, const char *pmu_name, const char *counter, + const char *msr, bool free_counter) { int ret =3D 0; @@ -1764,6 +1767,11 @@ static struct metricgroup__event_info *event_info__n= ew(const char *name, e->pmu_name =3D strdup(pmu_name); if (!e->pmu_name || !e->name) return NULL; + if (msr) { + e->msr =3D strdup(msr); + if (!e->msr) + return NULL; + } e->free_counter =3D free_counter; if (free_counter) { ret =3D set_counter_bitmap(0, e->counters); @@ -1801,7 +1809,8 @@ static int metricgroup__add_metric_event_callback(con= st struct pmu_event *pe, if (!strcasecmp(pe->name, d->event_name)) { if (!pe->counters_list) return -EINVAL; - event =3D event_info__new(d->event_id, pe->pmu, pe->counters_list, /*fre= e_counter=3D*/false); + event =3D event_info__new(d->event_id, pe->pmu, pe->counters_list, + pe->msr, /*free_counter=3D*/false); if (!event) return -ENOMEM; list_add(&event->nd, d->list); @@ -1927,7 +1936,9 @@ static int find_and_set_counters(struct metricgroup__= event_info *e, { int ret; unsigned long find_bit =3D 0; - + if (e->msr !=3D NULL && current_group->msr !=3D NULL && !strcmp(e->msr, c= urrent_group->msr)) { + pr_debug("current group uses the required MSR %s already\n", e->msr); + return -ENOSPC; if (e->free_counter) return 0; if (e->fixed_counter) { @@ -1964,11 +1975,17 @@ static int _insert_event(struct metricgroup__event_= info *e, list_add(&event->nd, &group->event_head); else list_add_tail(&event->nd, &group->event_head); + if (e->msr !=3D NULL) { + group->msr =3D strdup(e->msr); + pr_debug("Add event %s to group, uses MSR %s\n", e->name, e->msr); + if (!group->msr) + return -ENOMEM; + } return 0; } =20 /** - * Insert the new_group node at the end of the group list. + * Initialize the new group and insert it to the end of the group list. */ static int insert_new_group(struct list_head *head, struct metricgroup__group *new_group, @@ -2185,7 +2202,7 @@ static int create_grouping(struct list_head *pmu_info= _list, bitmap_scnprintf(e->counters, NR_COUNTERS, bit_buf, NR_COUNTERS); pr_debug("Event name %s, [pmu]=3D%s, [counters]=3D%s\n", e->name, e->pmu_name, bit_buf); - ret =3D assign_event_grouping(e, pmu_info_list, &groups); + ret =3D assign_event_grouping(e, pmu_info_list, grouping); if (ret) goto out; } @@ -2231,7 +2248,7 @@ static int hw_aware_build_grouping(struct expr_parse_= ctx *ctx __maybe_unused, if (is_special_event(id)) { struct metricgroup__event_info *event; =20 - event =3D event_info__new(id, "default_core", "0", + event =3D event_info__new(id, "default_core", "0", /*msr=3D*/NULL, /*free_counter=3D*/true); if (!event) goto err_out; --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B965152E0F; Fri, 12 Apr 2024 21:08:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956099; cv=none; b=CR7Ap3jCtrlDq6TvsUdvvEJ+HTcDCCGGPyPnvMS0XRgcB30G211X74CJKhHSMrW4VsYzs+fchHKo/o41ij2DmOO4gD7eN3BFfIQXaUjUfbdKQ15ccYBUbn/FB/vGbAtvGtlzl4BshG0ncFTuXdXPNL1CCH4/auX4u0qmuVygTRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956099; c=relaxed/simple; bh=SLRT/YXI45DriY5Ez7bnNSFDk+ZX/MfZJIlKThgJlpo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=STs532n8rtLNapoRpwnbAWvSvEVBlj8ksMbFlR2qdlO6yUbqLECBI4f/PeYbon0x0gYlQhsi00PQq6vjgaVd6JupSaDVoewlhVU/iW+kWlhwajxaUGmTBHsdsQHECBxyNAdIBmPAr7N+6u+TNfi5FQPRRJT+Cuq15+vIe37xzjw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=S9JR3dqg; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="S9JR3dqg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956098; x=1744492098; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SLRT/YXI45DriY5Ez7bnNSFDk+ZX/MfZJIlKThgJlpo=; b=S9JR3dqgFcs1uLSZHjEky6YDOKt5GjzkFyghurYh9ees58qjKM4zo2kO cfcHvB+4NIXLwboXP1n36YE0qCshFtaI4Z431rW6g6hMAXmEUnttq6sDt yDDzdCNz9j4FTCJ2akk9Sev46k8hVD9qxrDXjgViy96Alj6U6dAsMouci /SskbRmmxdhyvTbofya6Zv64QusWGcOJVxiMxettAdzqeyQ9DAqKpsAcE guR66npLcz/YIkxz8r9od7NkEsy21hwbetzNm8tzw3cgXHK5Tr7J6gQhP iAFVP/P2laY4FNa9doWjnunAGqvjmmuMOGbA//paaHDrCMPIaXSgpAHVS g==; X-CSE-ConnectionGUID: j83IAigkQAyJXzlZfgLi7Q== X-CSE-MsgGUID: WP9QZJH3T7uZ8A5pBmfOiQ== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575488" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575488" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:11 -0700 X-CSE-ConnectionGUID: sqyXSFLWTg+rLmERYp2xNg== X-CSE-MsgGUID: F1OduXFwQFO6CrRLWdmANw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772114" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:11 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 12/16] perf stat: Handle NMI in hardware-grouping Date: Fri, 12 Apr 2024 14:07:52 -0700 Message-ID: <20240412210756.309828-13-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add an easy nmi watchdog support in grouping. When nmi watchdog is enabled, we reduce the total num of events could be assigned to one group by 1. A more efficient solution will be added in later. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 9548654c9f6d..31036035484c 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1993,6 +1993,10 @@ static int insert_new_group(struct list_head *head, size_t counters_num_fixed) { INIT_LIST_HEAD(&new_group->event_head); + if (sysctl__nmi_watchdog_enabled()) { + pr_debug("NMI watchdog is enabled. Reduce num of counters by 1\n"); + counters_num_gp -=3D 1; + } fill_counter_bitmap(new_group->gp_counters, 0, counters_num_gp); fill_counter_bitmap(new_group->fixed_counters, 0, counters_num_fixed); list_add_tail(&new_group->nd, head); --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 577B2152E1D; Fri, 12 Apr 2024 21:08:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956100; cv=none; b=gcX4YMSl5Pcazf9W026gNXzU9D+QHYchxDqTmDkBn7QveGidv/wd57BXKwQ6ZRZGvvv2U3TB2Q/7LZfxdZ2w7CU4Ppi5mYGpzmraQ5FvZTrz+nq6XfQzuzxQ4UpUVpKUbRCVm8TmpTReC6WDGJ8GJ4F4PMF0lbdck4XcS7Xu+Iw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956100; c=relaxed/simple; bh=9kqT2qBiVTRhOHGmVy0/cf4XF6kfZ88bRzpyn6BQtTs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SGzhLk6dOWlSbPfT+DzR4LDRLJUJaDcvUOMTYKKjb36RD8YchVplwcgsxldtO/0G9dfduQx5P+F4lyXj4vt3HguzJJA7XjBHyeAqSB8d8WEd7HpE2qOHWP6xANBK8rgPiokSHJsFMPSv2RaloNT06RbctDLX/0BjzbLK0BdtZZs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=DlCeTDyX; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="DlCeTDyX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956098; x=1744492098; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9kqT2qBiVTRhOHGmVy0/cf4XF6kfZ88bRzpyn6BQtTs=; b=DlCeTDyXMbCcqQ4/VFCgtEEGyEzM57G2qCnKsAJBs7kFiMzM3l0pLXUs poxdAfEMavm7t7fv91zo1dfOzuEcoc2QlF5vimiglokBmEZUhvF3FEV4h tbGiHJvDPaqDHlpSlkUPzPgrnxHdNNST+U0OCP8pR/5uyvao2X7Gl6Pun Eoni/VCxLkTIhAOV2oBWAlQkCjxrUAQNIc4GwRv1fIquKamjLlHk5Pxrd gYvaz2FPa7IagQnOF6TfApDZ+AJ6s/GIJeStIPaTUYl+WpFfe3//SsOYz KpjuWEkbb2DbKmnWX8Hn/G2pESIq6KLIUob7C9az8IR+V5TFoFVt+L1/8 w==; X-CSE-ConnectionGUID: 36JEms7aTYmh1O8IPfqJ3Q== X-CSE-MsgGUID: k32WOPb0StyP9BvZ8D03+w== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575493" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575493" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:12 -0700 X-CSE-ConnectionGUID: KW6cz7Q9Qky0dx+LMdbnPA== X-CSE-MsgGUID: QPvs95gvQymHpNdEgiggug== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772117" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:11 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 13/16] perf stat: Code refactoring in hardware-grouping Date: Fri, 12 Apr 2024 14:07:53 -0700 Message-ID: <20240412210756.309828-14-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Decouple the step to generate final grouping strings out from the build_grouping step so that we could do single metric grouping and then merge groups if needed later. Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 31036035484c..c6db21a2c340 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1939,6 +1939,7 @@ static int find_and_set_counters(struct metricgroup__= event_info *e, if (e->msr !=3D NULL && current_group->msr !=3D NULL && !strcmp(e->msr, c= urrent_group->msr)) { pr_debug("current group uses the required MSR %s already\n", e->msr); return -ENOSPC; + } if (e->free_counter) return 0; if (e->fixed_counter) { @@ -2062,7 +2063,8 @@ static int assign_event_grouping(struct metricgroup__= event_info *e, =20 list_for_each_entry(g, groups, nd) { if (!strcasecmp(g->pmu_name, e->pmu_name)) { - pr_debug("found group for event %s in pmu %s\n", e->name, g->pmu_name); + pr_debug("found group header for event %s in pmu %s\n", + e->name, g->pmu_name); pmu_group_head =3D g; break; } @@ -2193,26 +2195,22 @@ static int hw_aware_metricgroup__build_event_string= (struct list_head *group_strs */ static int create_grouping(struct list_head *pmu_info_list, struct list_head *event_info_list, - struct list_head *groupings, - const char *modifier) + struct list_head *grouping) { int ret =3D 0; struct metricgroup__event_info *e; - LIST_HEAD(groups); char *bit_buf =3D malloc(NR_COUNTERS); =20 - //TODO: for each new core group, we should consider to add events that us= es fixed counters + //TODO: for each new core group, we could consider to add events that + //uses fixed counters list_for_each_entry(e, event_info_list, nd) { bitmap_scnprintf(e->counters, NR_COUNTERS, bit_buf, NR_COUNTERS); pr_debug("Event name %s, [pmu]=3D%s, [counters]=3D%s\n", e->name, e->pmu_name, bit_buf); ret =3D assign_event_grouping(e, pmu_info_list, grouping); if (ret) - goto out; + return ret; } - ret =3D hw_aware_metricgroup__build_event_string(groupings, modifier, &gr= oups); -out: - metricgroup__free_group_list(&groups); return ret; }; =20 @@ -2233,9 +2231,8 @@ static bool is_special_event(const char *id) * @groupings: header to the list of final event grouping. * @modifier: any modifiers added to the events. */ -static int hw_aware_build_grouping(struct expr_parse_ctx *ctx __maybe_unus= ed, - struct list_head *groupings __maybe_unused, - const char *modifier __maybe_unused) +static int hw_aware_build_grouping(struct expr_parse_ctx *ctx, + struct list_head *grouping) { int ret =3D 0; struct hashmap_entry *cur; @@ -2267,8 +2264,7 @@ static int hw_aware_build_grouping(struct expr_parse_= ctx *ctx __maybe_unused, ret =3D get_pmu_counter_layouts(&pmu_info_list, ltable); if (ret) goto err_out; - ret =3D create_grouping(&pmu_info_list, &event_info_list, groupings, - modifier); + ret =3D create_grouping(&pmu_info_list, &event_info_list, grouping); =20 err_out: metricgroup__free_event_info(&event_info_list); @@ -2314,23 +2310,25 @@ static int hw_aware_parse_ids(struct perf_pmu *fake= _pmu, { struct parse_events_error parse_error; struct evlist *parsed_evlist; - LIST_HEAD(groupings); + LIST_HEAD(grouping_str); + LIST_HEAD(grouping); struct metricgroup__group_strs *group; int ret; =20 *out_evlist =3D NULL; - ret =3D hw_aware_build_grouping(ids, &groupings, modifier); - if (ret) { - metricgroup__free_grouping_strs(&groupings); - return ret; - } + ret =3D hw_aware_build_grouping(ids, &grouping); + if (ret) + goto out; + ret =3D hw_aware_metricgroup__build_event_string(&grouping_str, modifier,= &grouping); + if (ret) + goto out; =20 parsed_evlist =3D evlist__new(); if (!parsed_evlist) { ret =3D -ENOMEM; goto err_out; } - list_for_each_entry(group, &groupings, nd) { + list_for_each_entry(group, &grouping_str, nd) { struct strbuf *events =3D &group->grouping_str; =20 pr_debug("Parsing metric events '%s'\n", events->buf); @@ -2350,7 +2348,9 @@ static int hw_aware_parse_ids(struct perf_pmu *fake_p= mu, err_out: parse_events_error__exit(&parse_error); evlist__delete(parsed_evlist); - metricgroup__free_grouping_strs(&groupings); +out: + metricgroup__free_group_list(&grouping); + metricgroup__free_grouping_strs(&grouping_str); return ret; } =20 --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C779D1534F7; Fri, 12 Apr 2024 21:08:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956100; cv=none; b=lkNXpAVlwV7rg1XWDZLs9qfIOeGQJrmpHC1voSrqKMKmhgYj9aixkZqs5SkSeNsQ+YuIDlcHzaTvF4SxG81Nm+hr3GwjIcNj/THDl2YEBBmn6ifcwDqKOkEYg+m67ZpSyUcCfB4kEO8rB7hb63HQu+dd6LQTf+O8HR7a3BihSYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956100; c=relaxed/simple; bh=XkrdL1qPBlybD5gbCiARJ41rqvwqqxSL8T+Bt5/xD44=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U9OlGVDgkNRXyI9bvjeN8o8/enAEFB7C/SbcLWSQPatMffyaxRsC7ZzubwtNJ++LrcbhyoG7GaJK5q3AzbpK0TNZ8kPN2QzdiwEdDhmGlw4JAFt3+rXrWarEw4SNHRTSjeRqBYyGdawExgg6tg6nxBRuHzeLMOms7AclqKEBVgs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=SGpQeDp+; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="SGpQeDp+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956099; x=1744492099; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=XkrdL1qPBlybD5gbCiARJ41rqvwqqxSL8T+Bt5/xD44=; b=SGpQeDp+0mthp68HynJSvsoFibO9a6NX0+VY/bvqps8zggGfIFRYEnY1 7gyVZz8kkQi2A6yPUNQWthWsiBDgQxLS/3jVQf3AH8KydkHNVx73GQrj0 IVAjVTlI9jZm1fRacm1FAQVtN0TqEDtgL8Huf0PurO4oeumSYgeJAhG1O SuD9p4D3DijoD8X4d/8mOulVTvnuinVxdnugGKgpqrd1Py1cMy7633r6c cWzvHnGpZWMb6n1FGxIrv6VWhHNjQP6pnNgDklWRHTJfFLr/jx8ey/DJu /SXDGpBu6M7YBmHhb3RAvCxeavAQ6qAMZMh1eF27zzU+K/q9ab61lL1p/ A==; X-CSE-ConnectionGUID: PtoONbTTQ2iBqLJKFU3UTQ== X-CSE-MsgGUID: iOwKmo+1Reuz91DdsD05eA== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575498" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575498" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:12 -0700 X-CSE-ConnectionGUID: Mu/KI6kFQ7aXfDNChUyE9w== X-CSE-MsgGUID: 2eVRs6F5QVy3jKIvdSc6cw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772120" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:11 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 14/16] perf stat: Add tool events support in hardware-grouping Date: Fri, 12 Apr 2024 14:07:54 -0700 Message-ID: <20240412210756.309828-15-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add tool events into default_core grouping strings if find tool events so that metrics use tool events could be correctly calculated. Need this step to support TopdownL4-L5. Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 49 ++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index c6db21a2c340..86b6528e5a44 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -763,6 +763,35 @@ static int decode_all_metric_ids(struct evlist *perf_e= vlist, const char *modifie return ret; } =20 +/** + * get_tool_event_str - Generate and return a string with all the used tool + * event names. + */ +static int get_tool_event_str(struct strbuf *events, + const bool tool_events[PERF_TOOL_MAX], + bool *has_tool_event) +{ + int i =3D 0; + int ret; + + perf_tool_event__for_each_event(i) { + if (tool_events[i]) { + const char *tmp =3D strdup(perf_tool_event__to_str(i)); + + if (!tmp) + return -ENOMEM; + *has_tool_event =3D true; + ret =3D strbuf_addstr(events, ","); + if (ret) + return ret; + ret =3D strbuf_addstr(events, tmp); + if (ret) + return ret; + } + } + return 0; +} + static int metricgroup__build_event_string(struct strbuf *events, const struct expr_parse_ctx *ctx, const char *modifier, @@ -2096,6 +2125,7 @@ static int assign_event_grouping(struct metricgroup__= event_info *e, =20 static int hw_aware_metricgroup__build_event_string(struct list_head *grou= p_strs, const char *modifier, + const bool tool_events[PERF_TOOL_MAX], struct list_head *groups) { struct metricgroup__pmu_group_list *p; @@ -2103,8 +2133,12 @@ static int hw_aware_metricgroup__build_event_string(= struct list_head *group_strs struct metricgroup__group_events *ge; bool no_group =3D true; int ret =3D 0; + struct strbuf tool_event_str =3D STRBUF_INIT; + bool has_tool_event =3D false; =20 #define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0) + ret =3D get_tool_event_str(&tool_event_str, tool_events, &has_tool_event); + RETURN_IF_NON_ZERO(ret); =20 list_for_each_entry(p, groups, nd) { list_for_each_entry(g, &p->group_head, nd) { @@ -2176,6 +2210,12 @@ static int hw_aware_metricgroup__build_event_string(= struct list_head *group_strs } ret =3D strbuf_addf(events, "}"); RETURN_IF_NON_ZERO(ret); + + if (has_tool_event) { + ret =3D strbuf_addstr(events, tool_event_str.buf); + RETURN_IF_NON_ZERO(ret); + } + pr_debug("events-buf: %s\n", events->buf); list_add_tail(&new_group_str->nd, group_strs); } @@ -2261,6 +2301,7 @@ static int hw_aware_build_grouping(struct expr_parse_= ctx *ctx, if (ret) goto err_out; } + ret =3D get_pmu_counter_layouts(&pmu_info_list, ltable); if (ret) goto err_out; @@ -2306,6 +2347,7 @@ static void metricgroup__free_grouping_strs(struct li= st_head */ static int hw_aware_parse_ids(struct perf_pmu *fake_pmu, struct expr_parse_ctx *ids, const char *modifier, + const bool tool_events[PERF_TOOL_MAX], struct evlist **out_evlist) { struct parse_events_error parse_error; @@ -2319,7 +2361,8 @@ static int hw_aware_parse_ids(struct perf_pmu *fake_p= mu, ret =3D hw_aware_build_grouping(ids, &grouping); if (ret) goto out; - ret =3D hw_aware_metricgroup__build_event_string(&grouping_str, modifier,= &grouping); + ret =3D hw_aware_metricgroup__build_event_string(&grouping_str, modifier, + tool_events, &grouping); if (ret) goto out; =20 @@ -2454,6 +2497,7 @@ static int hw_aware_parse_groups(struct evlist *perf_= evlist, struct evlist *combined_evlist =3D NULL; LIST_HEAD(metric_list); struct metric *m; + bool tool_events[PERF_TOOL_MAX] =3D {false}; int ret; bool metric_no_group =3D false; bool metric_no_merge =3D false; @@ -2472,11 +2516,14 @@ static int hw_aware_parse_groups(struct evlist *per= f_evlist, if (!metric_no_merge) { struct expr_parse_ctx *combined =3D NULL; =20 + find_tool_events(&metric_list, tool_events); + ret =3D hw_aware_build_combined_expr_ctx(&metric_list, &combined); =20 if (!ret && combined && hashmap__size(combined->ids)) { ret =3D hw_aware_parse_ids(fake_pmu, combined, /*modifier=3D*/NULL, + tool_events, &combined_evlist); } =20 --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AADE2153569; Fri, 12 Apr 2024 21:08:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956101; cv=none; b=NXqy3ZC1/p7+rpfHreZ3AXua9isyvxb8xxJPDPTeVdEeCM6qCNuuYFNxWSDLbv3VPnuY+bUD4VYYwhZqeERzG6siIUzlbL5eUQ08Zlwpi8SROxYIQSpJxdA9E4xGVhTkgd5gwKHdP6/1h4V6n8d2PU7toAy3HdtwjY2vBFWgHdI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956101; c=relaxed/simple; bh=jJTUOTvTBpXp5NYD72GuR6rMpvYJe5VM3t1ZmRAIhXU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gyW/aIT0i6BUujKNQW6XOy7UmPM88E36SWdDrN4vSr2JuEXzEdUU/Y2JKcyx2/AJ0Sd5fbkFxZx1Pa/fSm46leDfuXdZ9lnqsbEhqe3YaZup89nkoiJdq2z/J5JbyYG0EuU0scwxd9dEtFNEv7dIpAaioZ1r5dqfFI0zQuJa4ag= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=lzekSNZu; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lzekSNZu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956099; x=1744492099; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jJTUOTvTBpXp5NYD72GuR6rMpvYJe5VM3t1ZmRAIhXU=; b=lzekSNZu/3BWrWnYP8obrTXutXbw0Gj6CxG8MTSv6u2tIKvjoc2DPoXz RAtA7pypg39p7XE3FqDjVlfJgaBpAOcsbO5IwOyftVIQ4LSCziMhpO0k8 mFeaM0sUN3HX5E31ugr+fcg9MKnLiX5Vkfrcw00H/YuofXq89Ykohsswo QNC7/FR4HZ314ta1D8GUF2v682BiJVY013X815uU8mHuJOuXD7B0XT0xO RA4pMc2PQ6szpQns1fC8JLIs6VX3+V/5iD1ckysfbz/hOdpyHVNyLAcWp LSO1RwjGWqrleRkhJxKNlNoF+A2gTkP+GSeiZys2yoKs2BqD2kWKAyV6y A==; X-CSE-ConnectionGUID: COKkI826Shq1aCCO0unaYA== X-CSE-MsgGUID: biVfDhJ/TCmDRULw5WBoAg== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575503" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575503" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:12 -0700 X-CSE-ConnectionGUID: D3DXYr+/QxKYI/HnblX2Pw== X-CSE-MsgGUID: cw69BwKxSxabsTpxKzSxYQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772123" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:11 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 15/16] perf stat: use tool event helper function in metricgroup__build_event_string Date: Fri, 12 Apr 2024 14:07:55 -0700 Message-ID: <20240412210756.309828-16-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang We want to include all used tool events in each event group to ensure sharing events so that help improve multiplexing. This change updates parse_id and metricgroupg__build_event_string to use the get_tool_event_str helper function to generate tool event string instead of inserting temporary tool event ids and generate string from the tool event ids. Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 61 +++++++++++++---------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 86b6528e5a44..39746d18f078 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -774,6 +774,18 @@ static int get_tool_event_str(struct strbuf *events, int i =3D 0; int ret; =20 + /* + * We may fail to share events between metrics because a tool + * event isn't present in one metric. For example, a ratio of + * cache misses doesn't need duration_time but the same events + * may be used for a misses per second. Events without sharing + * implies multiplexing, that is best avoided, so place + * all tool events in every group. + * This function helps place all tool events in every group by + * generating the tool event strbuf that to be added in event + * group strings. + */ + perf_tool_event__for_each_event(i) { if (tool_events[i]) { const char *tmp =3D strdup(perf_tool_event__to_str(i)); @@ -795,15 +807,18 @@ static int get_tool_event_str(struct strbuf *events, static int metricgroup__build_event_string(struct strbuf *events, const struct expr_parse_ctx *ctx, const char *modifier, - bool group_events) + bool group_events, + const bool tool_events[PERF_TOOL_MAX]) { struct hashmap_entry *cur; size_t bkt; bool no_group =3D true, has_tool_events =3D false; - bool tool_events[PERF_TOOL_MAX] =3D {false}; int ret =3D 0; + struct strbuf tool_event_str =3D STRBUF_INIT; =20 #define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0) + ret =3D get_tool_event_str(&tool_event_str, tool_events, &has_tool_events= ); + RETURN_IF_NON_ZERO(ret); =20 hashmap__for_each_entry(ctx->ids, cur, bkt) { const char *sep, *rsep, *id =3D cur->pkey; @@ -814,8 +829,6 @@ static int metricgroup__build_event_string(struct strbu= f *events, /* Always move tool events outside of the group. */ ev =3D perf_tool_event__from_str(id); if (ev !=3D PERF_TOOL_NONE) { - has_tool_events =3D true; - tool_events[ev] =3D true; continue; } /* Separate events with commas and open the group if necessary. */ @@ -879,19 +892,8 @@ static int metricgroup__build_event_string(struct strb= uf *events, RETURN_IF_NON_ZERO(ret); } if (has_tool_events) { - int i; - - perf_tool_event__for_each_event(i) { - if (tool_events[i]) { - if (!no_group) { - ret =3D strbuf_addch(events, ','); - RETURN_IF_NON_ZERO(ret); - } - no_group =3D false; - ret =3D strbuf_addstr(events, perf_tool_event__to_str(i)); - RETURN_IF_NON_ZERO(ret); - } - } + ret =3D strbuf_addstr(events, tool_event_str.buf); + RETURN_IF_NON_ZERO(ret); } =20 return ret; @@ -2421,32 +2423,13 @@ static int parse_ids(bool metric_no_merge, struct p= erf_pmu *fake_pmu, =20 *out_evlist =3D NULL; if (!metric_no_merge || hashmap__size(ids->ids) =3D=3D 0) { - bool added_event =3D false; - int i; /* - * We may fail to share events between metrics because a tool - * event isn't present in one metric. For example, a ratio of - * cache misses doesn't need duration_time but the same events - * may be used for a misses per second. Events without sharing - * implies multiplexing, that is best avoided, so place - * all tool events in every group. - * - * Also, there may be no ids/events in the expression parsing + * There may be no ids/events in the expression parsing * context because of constant evaluation, e.g.: * event1 if #smt_on else 0 * Add a tool event to avoid a parse error on an empty string. */ - perf_tool_event__for_each_event(i) { - if (tool_events[i]) { - char *tmp =3D strdup(perf_tool_event__to_str(i)); - - if (!tmp) - return -ENOMEM; - ids__insert(ids->ids, tmp); - added_event =3D true; - } - } - if (!added_event && hashmap__size(ids->ids) =3D=3D 0) { + if (hashmap__size(ids->ids) =3D=3D 0) { char *tmp =3D strdup("duration_time"); =20 if (!tmp) @@ -2455,7 +2438,7 @@ static int parse_ids(bool metric_no_merge, struct per= f_pmu *fake_pmu, } } ret =3D metricgroup__build_event_string(&events, ids, modifier, - group_events); + group_events, tool_events); if (ret) return ret; =20 --=20 2.42.0 From nobody Sun Dec 28 02:52:01 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FEB4153800; Fri, 12 Apr 2024 21:08:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956101; cv=none; b=fvoi/ZynIMuRoDEI7X0VqmYij9ArSqYFaJ/v3BkGGUCIwoqEDMNb5Aor/w3jKgqeU9goMFYECcp4bbD7mX2SxNS7eO18QVPlnSKz2DMZQTt8Q2dDzbh636inXd6b44G1l+TAMjdALYeBWgXzMlkTNAHzRwVSh6yJq8qOh/oGyX8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712956101; c=relaxed/simple; bh=bd4PQWlSFr0I9pEM8FxSoW1pVNhaL0iIOylEleDEVQU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CAm2evZxmqlStTpTJo8z2nmu5iVyGhDVwLdpgKB7/ghyWvYEfu9YrvzS/BXAY70PKhZObgnMh44Q6kRm3H/bfuXpPUS7roJ7g/Um5dHAs+tdORgw7m8QmjVl9sydopuYVVLggCQ8T1FOGRuHFuo3IZ/djTWzg0cQJywZrm8Anck= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=LsdAPOMw; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="LsdAPOMw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712956100; x=1744492100; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bd4PQWlSFr0I9pEM8FxSoW1pVNhaL0iIOylEleDEVQU=; b=LsdAPOMwlG2FqUnspiBDu4qmStxwqYSF64I7icUgMDznGS03DVfCCb+J DSY3AwbWJhUr7w041ozjuKWUiYJpIlvKA7kY1/M4d6bnxRrlBZJOntf25 UwzZHS9E6LDCtjDyuWAG1BDPfbqZ6R/xh3xS0wLh0n8TptyIjaiFIKl03 U6qZfizK60M5Euf1flJg9SJssKPzPmosOiMPpSlKcQQYOcUc0MliKL0fP n4Lwuie5fGjXfxdQ5LiXqn+i1QFiO4vDTt2Q56GmXcfMJzqYMvRahFGIr a6Flbm+nt2oYWsNQFRQZMBOHYmndsi9RpLPWiBo1isk0re/sTKa6Ti2Ta Q==; X-CSE-ConnectionGUID: Ixi9ogX3Tbeprexk6qypeA== X-CSE-MsgGUID: ZJjArDDrQWeJqsvVbXcEvA== X-IronPort-AV: E=McAfee;i="6600,9927,11042"; a="19575508" X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="19575508" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 14:08:12 -0700 X-CSE-ConnectionGUID: vZJWBqgWQ8yT8B2mIDpbHA== X-CSE-MsgGUID: dnWJWx1SSaqJwNi2OhIeqw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,197,1708416000"; d="scan'208";a="21772126" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa006.jf.intel.com with ESMTP; 12 Apr 2024 14:08:11 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Kan Liang , Namhyung Kim , Arnaldo Carvalho de Melo , Peter Zijlstra , Ingo Molnar , Alexander Shishkin , Jiri Olsa , Adrian Hunter Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers Subject: [RFC PATCH v5 16/16] perf stat: Add hardware-grouping cmd option to perf stat Date: Fri, 12 Apr 2024 14:07:56 -0700 Message-ID: <20240412210756.309828-17-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240412210756.309828-1-weilin.wang@intel.com> References: <20240412210756.309828-1-weilin.wang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add a cmd option to allow user to choose this new metric grouping method. $ perf stat -M TopdownL1 -a --hardware-grouping Reviewed-by: Ian Rogers Signed-off-by: Weilin Wang --- tools/perf/builtin-stat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index c4a5f0984295..8c33e3f8bc80 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1259,6 +1259,8 @@ static struct option stat_options[] =3D { "don't try to share events between metrics in a group"), OPT_BOOLEAN(0, "metric-no-threshold", &stat_config.metric_no_threshold, "disable adding events for the metric threshold calculation"), + OPT_BOOLEAN(0, "hardware-grouping", &stat_config.hardware_aware_grouping, + "Use hardware aware metric grouping method"), OPT_BOOLEAN(0, "topdown", &topdown_run, "measure top-down statistics"), OPT_UINTEGER(0, "td-level", &stat_config.topdown_level, --=20 2.42.0