From nobody Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 386144C6F; Fri, 9 Feb 2024 03:14:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448491; cv=none; b=uQGumUzI7KnbNoCFXd3L5Vb/h1QHatKHNz3qg53VxBY9revm6znP62UxNaDTqbph4kLDa993V7ITCIH6EbQt40cTyZuDDW1f0h0KDUT55RbR4K0N/42uyP7gCDmnkL3d2WB7i3G6buYBX4Nwx61qMzdHgodga1zsVuAUR4bAc0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448491; c=relaxed/simple; bh=eIAG1lzH2RfVMJ7M1xyrOqwbKw0bArWx7n920cAVzVs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H0aB33fujvyJRFmq+VIJUZuQ+ZArEHcIgmOo+3eqO2WZdNJkEYilMNUWHkDEltR7Y61OLpMdTzWxGWoifhkerN3t8y3kBq44ojQimgeC69ZNxAeV/RMzfYJwxj4MwReoh9tP8lHj3y9gcmJZ2ug8Dt01zMije9YCbC8Dw648CPE= 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=C6rpb2Ks; arc=none smtp.client-ip=192.198.163.19 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="C6rpb2Ks" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448489; x=1738984489; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eIAG1lzH2RfVMJ7M1xyrOqwbKw0bArWx7n920cAVzVs=; b=C6rpb2KsTN8biYoEuNKkES23bVx/kEGinN2MRJX3c/YyXLLZqk0nr8Yb Q3woLNgHYQTSpRFUmacu3c5+IE29tTYAkW/AXGv6dnzfs+UAHWLWKz5Ud s0TkCBPEQj8wwIcSWgaeuWz84CePZZitN6r98Y/D4F6FijzzMPcedaNqC qsmiH9qDTwUxo9ABn6/OLSo7tOqddRooWO2RGrImRiZjgGAqnGo0e18XP jrxnvsV2DXCY2FU1M7ZJE0nr7g/bcq8q6LzAwIUulpU1uXrceBKRWWcQF Y3F6F8EVutSM3c0R4R+ju3Y5UyWs9lap99PABe/vDE7vPH00OigV4XzTp A==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257875" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257875" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:47 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631404" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:47 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 01/15] perf stat: Add new field in stat_config to enable hardware aware grouping. Date: Thu, 8 Feb 2024 19:14:27 -0800 Message-ID: <20240209031441.943012-2-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 5fe9abc6a524..d08a40c4bae1 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2062,6 +2062,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 @@ -2095,6 +2096,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 @@ -2129,6 +2131,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; } @@ -2170,6 +2173,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 @@ -2702,6 +2706,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 ca3e0404f187..18df1af4bdd3 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 4357ba114822..a7798506465b 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -86,6 +86,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 495A64C92; Fri, 9 Feb 2024 03:14:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448492; cv=none; b=mwDqDLchTHinZDaWv7Pq04b5FGXuefc4dqUI4+ywNBaMJPlsp6me7iAyVCwji3SpWd+tpVMGM0su1c+7K+Fj48q+pHQxzOd6CyQcktqPDqylHcpibdasFyD8e5G6E7bLD6l7Umdkjr6xgHjCcs/pgIkPMTN4C/wHao2l3ytAUhU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448492; c=relaxed/simple; bh=YkcdAzNWIFPX0/ELSP1ZgYTdwPdrUl8xdN68jdAHQys=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dSCbA+XPy4pR2xf9vISr1tElG5r9PfAqiGbJNZp7usoj+hKskXbqlfQdO2xjr2pDb4EYOXafcU+Lr/bKXlorURm3tWITyoI9Ak0xbwNJx+6vuKo62bUnP07ykTIOpPjkILVUvW9tzgKT1NTtuo0fRdAyTZ/yiW7ChrWUt10ydg0= 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=b0P4bLkC; arc=none smtp.client-ip=192.198.163.19 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="b0P4bLkC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448491; x=1738984491; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YkcdAzNWIFPX0/ELSP1ZgYTdwPdrUl8xdN68jdAHQys=; b=b0P4bLkCijz+Xq4gOXhXDcvDJI2hbTEoBUYwpxT0ErIGpErFUbMGv0ot 4DNAvZpGM7JZFja8qyYA9/5dG0IctDexUduDVQb7zVhIRNE9bSI4P7xxH cjfwfesrj1eb+KsSwC0bVgVaXHdRROE9zY97mrI9CgbX8u+cKmZGN8OIQ yu/uPI2t3eTxcgqV6bXyChBRM1RQ4u6QGSHgRQlzNnOmKhM+zwUvMfxAO cWtW8HhTBmX/KpMU7f9r2IU7TWi9Ho2i3XyhuSRHuXhJnYyZAaySLVCOY rGmF1SpgNM6X3TbSA5ySfEDyqSpNBlhAdYNI9652BkeRABkv68ITbEVqv w==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257881" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257881" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631409" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:47 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 02/15] perf stat: Add basic functions for the hardware aware grouping Date: Thu, 8 Feb 2024 19:14:28 -0800 Message-ID: <20240209031441.943012-3-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 --- tools/perf/util/metricgroup.c | 218 +++++++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 18df1af4bdd3..ee638578afdd 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -157,6 +157,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,114 @@ 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 (ret) + goto out; + + if (combined) + expr__ctx_free(combined); + } + + 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 +1909,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 36FB04C89; Fri, 9 Feb 2024 03:14:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448492; cv=none; b=eXreRUxp1FSQaEnT+d7iUtmF4Lm3odsuSTuGO4x36ZX4MmCk1XAZG5QSkHZ6vG6CkPSULCYLncyjEBJhuJyM39Pwnp1IIPQY8LzYUxvAqC3sVYChWx/2nwyUOIx4GAiCi7H5xJNm408iSdHkOzWWMR/RDwQZWbkeJpNyxyYFSlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448492; c=relaxed/simple; bh=41xh2KqrEMxjoSEW6TMdownUge+f3VOfo3blzwhoK2c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gXbDF8lP+OlBTSwSUpmdbnBVByyS38VJVnG/iQ99PuebfOxjk+sVObmc/rc2aSIFQVLUNUCSrbjA1irhwOVySfdbT+AnCNE/Y09a3hKUpnWPXp4GnK3XUBEd55ifAaDPPwI2mexeleNg1FqK+eXth9Cl76bhlGQ9MKsoYISNmaQ= 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=NqzApKXV; arc=none smtp.client-ip=192.198.163.19 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="NqzApKXV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448490; x=1738984490; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=41xh2KqrEMxjoSEW6TMdownUge+f3VOfo3blzwhoK2c=; b=NqzApKXVG1IyxJIeeg+3HPlwpwnbWgzHyMmm/wZTlWtvSQLuPl1gqrz3 Gghw2Jq6CrE8p1xm8uVcZFPOnriLZgDVFsbEEHBpS+pPWiZASr+triTqA UJ93HL/DFXLDdsMHPy7K2zer4iCcVJNuIjxdF0Xw7+sqPdUW2BxB9y6GV jUrDRF2RwzIPcxWXvL5pWcyNQR0gWygN4Afn0yNxFUGKBWRFgDMhVbV1R 8Mpykbaf005L2KPuby/ikc+lXlX9qXtN7NCxf735Iflps97/+g9eeJh1B Oa3p4MSKctNqA+0u7AYEt2M79COryBBmyRQOT3K00yohJxza/wx9N3ZKp Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257890" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257890" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631415" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:47 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 03/15] perf pmu-events: Add functions in jevent.py to parse counter and event info for hardware aware grouping Date: Thu, 8 Feb 2024 19:14:29 -0800 Message-ID: <20240209031441.943012-4-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 Reviewed-by unless there's something I'm overlooking. --- tools/perf/pmu-events/jevents.py | 185 +++++++++++++++++++++++++++-- tools/perf/pmu-events/pmu-events.h | 34 +++++- 2 files changed, 207 insertions(+), 12 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 2c7e5d61ce92..bc91b7efa49a 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 @@ -47,10 +53,17 @@ _json_event_attributes =3D [ 'event', # Short things in alphabetical order. 'compat', 'deprecated', 'perpkg', 'unit', + # The list of counter(s) this event could use + 'counters', # Longer things (the last won't be iterated over during decompress). 'long_desc' ] =20 +# Attributes that are in pmu_unit_layout. +_json_layout_attributes =3D [ + 'pmu', 'desc', 'num_counters', 'num_fixed_counters' +] + # Attributes that are in pmu_metric rather than pmu_event. _json_metric_attributes =3D [ 'metric_name', 'metric_group', 'metric_expr', 'metric_threshold', @@ -58,7 +71,9 @@ _json_metric_attributes =3D [ 'default_metricgroup_name', 'aggr_mode', 'event_grouping' ] # Attributes that are bools or enum int values, encoded as '0', '1',... -_json_enum_attributes =3D ['aggr_mode', 'deprecated', 'event_grouping', 'p= erpkg'] +_json_enum_attributes =3D ['aggr_mode', 'deprecated', 'event_grouping', 'p= erpkg', + 'num_counters', 'num_fixed_counters' +] =20 def removesuffix(s: str, suffix: str) -> str: """Remove the suffix from a string @@ -334,6 +349,12 @@ 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 + self.counters =3D jd.get('Counter') + # Number of generic counter + self.num_counters =3D jd.get('NumCounters') + # Number of fixed counter + self.num_fixed_counters =3D jd.get('NumFixedCounters') filter =3D jd.get('Filter') self.unit =3D jd.get('ScaleUnit') self.perpkg =3D jd.get('PerPkg') @@ -405,8 +426,16 @@ 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' + 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': @@ -421,10 +450,10 @@ class JsonEvent: 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 @@ -461,6 +490,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.num_counters: + _arch_std_events[event.pmu.lower()] =3D event =20 =20 def add_events_table_entries(item: os.DirEntry, topic: str) -> None: @@ -470,6 +501,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.num_counters: + _pending_pmu_counts.append(e) =20 =20 def print_pending_events() -> None: @@ -510,7 +543,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""" @@ -565,7 +598,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""" @@ -583,6 +616,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), fix_none(j.num_counters)) + + 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' @@ -619,10 +681,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.num_counters: + _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.""" @@ -636,11 +700,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 @@ -674,6 +741,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. @@ -687,6 +760,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 /* @@ -731,6 +805,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}", @@ -742,6 +822,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}} }}, """) @@ -752,6 +836,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 }, } }; """) @@ -840,6 +925,24 @@ 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("""} + 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, @@ -995,6 +1098,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 { @@ -1090,6 +1208,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]; @@ -1111,6 +1256,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) { @@ -1139,6 +1294,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]; @@ -1295,6 +1463,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..e245e4738970 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; const char *pmu; const char *unit; bool perpkg; @@ -67,8 +72,20 @@ 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 num_counters; + /** + * Total number of fixed counters. + * Set to zero if no fixed counter on the unit.*/ + int num_fixed_counters; +}; + 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 +95,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 +118,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 216095227; Fri, 9 Feb 2024 03:14:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448492; cv=none; b=Q1ryN55mU/Cb/oGgn/9aykSJg07PzKc3Yg6HOzv9zYuhhbIzuav+bnyBGS6sMnd1XTG/8Eh8X2v3AG9h89eYBpAyv9LGmxL6wCO3K7E7Z6Koua4wQZaDhu+H2DVLeQl7LgEABXxU9aVLp24Mj/u5EL8ghiAzesESSQg/NMEK/dc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448492; c=relaxed/simple; bh=UeJbm2alYHDiXSHmzWkkiSfZ2SjtcJME+Lz2npuv+/w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LPkWtLMis0pE+r58iIQDTTKRu/tbbY+F1HrlGH2VMgsDknBIRmkixbTDBBqvnDTrwA1xn5gP1YwzpKyViAf/iDi1lNf/aP18AtfWFKP6zvay8ynGCFZq+3cpGhBQnlNrwXYM1eAgQ8FBeD1IynEnLxnsu1YSr6q0R/ojKIkWALQ= 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=CdHjXUcO; arc=none smtp.client-ip=192.198.163.19 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="CdHjXUcO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448491; x=1738984491; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UeJbm2alYHDiXSHmzWkkiSfZ2SjtcJME+Lz2npuv+/w=; b=CdHjXUcO25JYgNNUIOPM5iBL4fsjcLEYheOBaKdvLbVaWOjz+7/K0prN FnJod2SEPbC6xIbl2C9ocY3cQC2CzJrAJCbc6tHNzrWq/IC8HlYrxaPge ZvBQ7B8X9zkQcjJoj9C9xo608haZMItgzAUEjl1Nh4LXrU23q3kWpmNqv itOy2BhgMgesWgsDiPNrnR3xto2DLINJgXtFlpZBmrQJY3IaofMna2CHN MDGreMjxyFNC56gO2JaTwRlTaeHUFf3ZfGOBsKP75aMcNZFyHakjZLAJg 20L4bu+fge7yJw+tJgTH8DSa9yBbFr8vqgxj3DDXQAAVzoaK9gG9bfMes A==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257900" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257900" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631420" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:47 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 04/15] find_bit: add _find_last_and_bit() to support finding the most significant set bit Date: Thu, 8 Feb 2024 19:14:30 -0800 Message-ID: <20240209031441.943012-5-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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. Signed-off-by: Weilin Wang Reviewed-by: Ian Rogers --- 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..e475a7368e36 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 \ No newline at end of file --=20 2.42.0 From nobody Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 6813B6125; Fri, 9 Feb 2024 03:14:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448494; cv=none; b=nbA5aT7wNrbNfj7dr0Fi7wz2RiLuvz/EUdk1g2W7C2UI3Dz63MEuDRhQYktvvChMPyiKdep8vaSRghbNXbwUoysKF5dUwDABQNZxJ3BcIeZQjGAQ6+cNntXP8U6MtdC93zmsp11y798EvAS0qDNeSXbWXWk5zEqUZb5t4olr6MA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448494; c=relaxed/simple; bh=DjJPq4T9ViJb+2InPFFCi7oWrQjyZ8Rl/e9jnSYLBoc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aE13RwUhHYDOuqBoW5L5AsZn1pOxFcObgKfDK7dra2dlT7I6IivmfmtiQhl2VL18VUe/aEMLP8RrqXYWTJpwPkRl0neLjltuzS072O00mD4C9SPQB5zoNHQrHC2PGfyEkpq5UdNhMkKleMDLxSzYbt+oXpRc63iRCvyxNe32hWk= 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=cu2xU6wH; arc=none smtp.client-ip=192.198.163.19 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="cu2xU6wH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448493; x=1738984493; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DjJPq4T9ViJb+2InPFFCi7oWrQjyZ8Rl/e9jnSYLBoc=; b=cu2xU6wHEY8Lnm0RVlHFmw+kBa44yoPNQ4yyeNvZMHgsyIUj9qS3N8jH CWi2H9xJsxQzb6YSMfsyEYUblPzS7uj/svLyX1AByh8td+1CFcmIMyidd EY8yq1g/Lzj+2JOZKJQ7he07kf+VB54HxzBt/a4FktQluoJX58oxvyhEV wdydDKm/cYydpkv4H3qfg/QrhCIm9XyI1UFfGX9URqzTMFQFCJz4mXDpY BlWIMPEK4lO1WbQdyGsfVHwcBYlILM2AM1YTyBZRSbikeXHYnXvu8zQzG xMJ3OHeNP9hSdXliv76fSCDHUjS9J3cTvr8ypNnK7NZTa+ybhj6GLRHUd A==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257908" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257908" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631423" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:47 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 05/15] perf stat: Add functions to set counter bitmaps for hardware-grouping method Date: Thu, 8 Feb 2024 19:14:31 -0800 Message-ID: <20240209031441.943012-6-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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. Signed-off-by: Weilin Wang Reviewed-by: Ian Rogers --- tools/perf/util/metricgroup.c | 211 +++++++++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index ee638578afdd..2a917220fb34 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -157,6 +158,27 @@ 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 +1462,175 @@ 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 is 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); + 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 name; + e->free_counter =3D free_counter; + e->pmu_name =3D strdup(pmu_name); + 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 (ret) + 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 +1644,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 +1736,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 6810E611E; Fri, 9 Feb 2024 03:14:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448494; cv=none; b=UtAeKyECutJ/PpqFDGxWn7LRPhuVJ6fPJvN08UEEfqYYpFRPEwkXQNkRe+qbioYzmkqAdlt5wEtylPTgO6IszVU4gx64Q++v03VnEcmm/HX/33fckmDpfO8hEYQQy5bGctGPc9q1C8lKxHnOqGIMADavfd8xW/6ZO8MEF86sOCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448494; c=relaxed/simple; bh=Ptn1JpRP3StyuOfIWKSzj6sKJoeJjAtlLJUNbm0+pS8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sVe/Sbr5XQjX4IrJSmot5k/NJw1EH3JT3uPagMZGzNilidYRYIesyCSs4BsCLUQqy9Pm4iw3pCUrQaTFv/HGiRa8TnnAF1f3TejANvzD2N6n2XW/QSmiMKZe1QBoYk70nqDx2yShoaoz5G9hEV5W+9obCH5PB0L+0DDzlGoLE6g= 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=WrddKb/4; arc=none smtp.client-ip=192.198.163.19 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="WrddKb/4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448493; x=1738984493; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ptn1JpRP3StyuOfIWKSzj6sKJoeJjAtlLJUNbm0+pS8=; b=WrddKb/4rSojKTkCLJ5XBYuTuEUd2qohsIjSPd31BdD5Poais91vEMKy eA6EsC52iI2mvlEJNcNyG/kJdAgrtk7af8DJTHz+qMabCZNTH5rp8YGxh 5GNuMsRMvjvOvuvcR0Do00HyMfO5e3yUoC7gi/3E9WJIVoEP8MoHCg3gm LQ9T6W89Vc5Nati46u4zKM/9XT0iqWqrNYPGJiCW5Q4Ey9i6BVg6F767R /eTJOkeUd8cT/iF32zNL2B34CdYzeSD3zBOjF/MhwcySMrKssBeeUCyZ0 MiQhBKWLwUoS0MO2VfWp5y2zkQ1T6ANoa8zm0oUP7Wj2NNNdxml9lsJdP Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257909" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257909" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631428" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:47 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 06/15] perf stat: Add functions to get counter info Date: Thu, 8 Feb 2024 19:14:32 -0800 Message-ID: <20240209031441.943012-7-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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. Signed-off-by: Weilin Wang Reviewed-by: Ian Rogers --- tools/perf/util/metricgroup.c | 101 ++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 2a917220fb34..9061ed4ca015 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -179,6 +179,20 @@ 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 num_counters; + size_t num_fixed_counters; +}; + /** * Each group is one node in the group string list. */ @@ -1530,6 +1544,27 @@ static int parse_counter(const char *counter, return 0; } =20 +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); + free(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); + free(p); + } +} + static struct metricgroup__event_info *event_info__new(const char *name, const char *pmu_name, const char *counter, @@ -1548,7 +1583,7 @@ static struct metricgroup__event_info *event_info__ne= w(const char *name, =20 e->name =3D name; e->free_counter =3D free_counter; - e->pmu_name =3D strdup(pmu_name); + e->pmu_name =3D pmu_name; if (free_counter) { ret =3D set_counter_bitmap(0, e->counters); if (ret) @@ -1583,7 +1618,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) + return -EINVAL; + event =3D event_info__new(d->event_id, pe->pmu, pe->counters, /*free_cou= nter=3D*/false); if (!event) return -ENOMEM; list_add(&event->nd, d->list); @@ -1622,7 +1659,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 @@ -1631,6 +1668,57 @@ 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 pl->pmu; + l->num_counters =3D pl->num_counters; + l->num_fixed_counters =3D pl->num_fixed_counters; + pr_debug("create new pmu_layout: [pmu]=3D%s, [gp_size]=3D%ld, [fixed_size= ]=3D%ld\n", + l->name, l->num_counters, l->num_fixed_counters); + 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 @@ -1649,6 +1737,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) { @@ -1658,9 +1747,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 79F72FBF0; Fri, 9 Feb 2024 03:14:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448496; cv=none; b=qz3kM5DoMq8gQ6rf48/pO4LbEWxSYw+Aqdyj9+g9S8qiG28D2VAXp/qjngy0uVoeVGg04jhLAUlehqYAk3aKQo7GdrvQqtG0xBIwUS01/kIh8oNayLC1+EyQBlfTAjQBFR0q3tU0utQ4JpysO6syM62UlB8dTi+w8DYGOCD6vvQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448496; c=relaxed/simple; bh=dstIOELs4oGs/0dQrJIS3jxgee0OEbKkbpMgzEO7qmE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j/uHu6zWRBP+yZOzRkhTA54xHljloueEx31wCyJQPXaPIQ7GEYPXfIALXsj9NP4V0BH51NPJOK75HdzOQ3NWwCJQbFbULEN24sm1wahjb1R/CZdYxrgWbKBKKjZwqxGF6IotkCnsua9MQiifhuEMUJmJBqHj4Ax8MgRK4SR/fR4= 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=eqZhLYem; arc=none smtp.client-ip=192.198.163.19 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="eqZhLYem" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448495; x=1738984495; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dstIOELs4oGs/0dQrJIS3jxgee0OEbKkbpMgzEO7qmE=; b=eqZhLYem7ipIXGctCQMX5gIH43Psq/AkeoBwmsaEBaD+93ulCIWBESzV MWpvz7EtSLAuu60CvGWuPzNM5k0t0C6HcKsTebnZc8IeWnXtXkoq7lSU5 0GLSdHqcQZNLm+j92TVsd0oat/7bP68n5G99pPPGlNRS5Ii7q1z1G6KFi rPsdzOCE74S1sdujBsrD0Jx+2v6K0ORJjHxgakMZgM0jeh/gYzBMwGMN6 OkohqGHcDf0RzrcE2V09NPE+nKDzMY/bPH7oulRiyeIcEobXDx/5TFoJw 4w7/OnAd2Zyzkn6SDgYa3hy9JqbGDGu+ReTMV664qBv5Y+gRQ12lDKuRI Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257920" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257920" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631432" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:47 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 07/15] perf stat: Add functions to create new group and assign events into groups Date: Thu, 8 Feb 2024 19:14:33 -0800 Message-ID: <20240209031441.943012-8-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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. Signed-off-by: Weilin Wang Reviewed-by: Ian Rogers --- tools/perf/util/metricgroup.c | 296 ++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 9061ed4ca015..f86e9a0b0d65 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -192,6 +192,41 @@ struct metricgroup__pmu_counters { size_t num_counters; size_t num_fixed_counters; }; +/** + * 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 num_counters; + /** The number of fixed counters in the pmu(/core) if applicable. */ + size_t num_fixed_counters; + /** 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. @@ -1487,6 +1522,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) @@ -1544,6 +1607,38 @@ static int parse_counter(const char *counter, return 0; } =20 +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); + free(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__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); + group_list_free(g); + free(g); + } +} + static void metricgroup__free_event_info(struct list_head *event_info_list) { @@ -1719,6 +1814,203 @@ 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 e->name; + 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 num_counters, + size_t num_fixed_counters) +{ + INIT_LIST_HEAD(&new_group->event_head); + fill_counter_bitmap(new_group->gp_counters, 0, num_counters); + fill_counter_bitmap(new_group->fixed_counters, 0, num_fixed_counters); + 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 + malloc(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->num_counte= rs, + pmu_group_head->num_fixed_counters); + 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 e->pmu_name; + list_for_each_entry(p, pmu_info_list, nd) { + if (!strcasecmp(p->name, e->pmu_name)) { + pmu_group_head->num_counters =3D p->num_counters; + pmu_group_head->num_fixed_counters =3D p->num_fixed_counters; + 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 @@ -1750,6 +2042,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 10140CA7F; Fri, 9 Feb 2024 03:14:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448495; cv=none; b=gj5YcnWX77fYQrVD0/xSphAD0LrIvxjmkCn2I2sd46RtwA6h/Yy7N+bOnSljJhoRlKbPUptsLaRU0m34GVGYPCQkHhhSLv9RY4ThEij6WAycd7zhXvy39wxX59vvuoMvb4+9dqTSKubeoB3EzQ4FM56qVPifq5l2dOJ7OR9rkGA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448495; c=relaxed/simple; bh=nwvJ4bQEjdGfxAja5WB8p9z4vCfBey7kRZHlUv8cNoY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IACxRJjXL8UqG3XOYTQKlkp697zcmjP2zaAddsG7vS36mg/BYd3n7iiJy19pzHzdEKhkqXnaFI0dbvJ7+BAf6BCynQvUcSVx0AM3Qr1Ejv6Zn85aCNhKAc98VE8tJP/DCmD0zxsVPvsvkyNCrsMM4XFx6gtA9o/Vb5y7v5HW+Pw= 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=GrXXwEFZ; arc=none smtp.client-ip=192.198.163.19 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="GrXXwEFZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448493; x=1738984493; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nwvJ4bQEjdGfxAja5WB8p9z4vCfBey7kRZHlUv8cNoY=; b=GrXXwEFZTCDqS++vvYT9rQFT+PP9HfnlFc2/NUPyrZgqrmyTZWGKFgIR v7gPyojPnooKFDZO8BECWc5V5A/k3qjRBt2nOvows9FjOTZSFPMIoshhA lUieFzf/5jjEwT5SmZJLnSa89lbLfw7PUdRIxrSqjaqvcqV7CZI3B8CBG SwWbFd2xGp2hlwlhP0mZ7wuMQ+8g92SDNTMa9WUFjXiMFm/xEDPCJ0lhi c8rDARPyaPr759qF1mLq1j/HeYT7FO22kNUvlkcpqpBADb+AWzSQHBIos cdmPUT09DH6a9drc8LDb7RSgIAE09WQi4yfHjTwCf/kU3v+i0q31k6MDZ g==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257921" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257921" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631435" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 08/15] perf stat: Add build string function and topdown events handling in hardware-grouping Date: Thu, 8 Feb 2024 19:14:34 -0800 Message-ID: <20240209031441.943012-9-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 f86e9a0b0d65..660c6b9b5fa7 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1978,6 +1978,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, "}:W"); + 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. @@ -1989,8 +2079,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; @@ -2006,6 +2096,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; @@ -2035,8 +2126,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 8909CFC19; Fri, 9 Feb 2024 03:14:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448496; cv=none; b=BC+XIa+PXdpdhIQxfqB9ZhBuXoyH+uek6ypPMfv7XVJScs+Esn7MpTb49hVwFk3MaFkKe3hb8ZW17SV6wLOCaxGje5PgsUFyvQsXW1MAN63a/Q59+HtaERyUaWL4aM+5tQQZwazberMPxbvNzOOhNyXz8h5yOS/L6zFTBmj1lrs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448496; c=relaxed/simple; bh=QrlkCZNny4tWyjIwHE8jfNEOkLmWaf4ylMQufuD0nQI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W6DFCgbz2wtfLgqkYYFFwko0o0uFNvByrgyWAEfEcO6xgmy4E+0kzMg35y8CyyJzfKRTriJd05e9rZ3IRUFURDfDPguVpS5zGoaHOgRjz/aVCOXgH91iNpGFrxZodvWIzVXq//lE24WQoioJHPueOz6vAOVuMhga9WxSk0RoPMI= 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=ORB6GULE; arc=none smtp.client-ip=192.198.163.19 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="ORB6GULE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448495; x=1738984495; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QrlkCZNny4tWyjIwHE8jfNEOkLmWaf4ylMQufuD0nQI=; b=ORB6GULEezVp5amF0oxTFcOWmeUhYJkNtx+7sJfkXJmyI+oX61p+tclg u7icw3W57EyXw4aEeXYpWtQb29RJ1vgCncpW/VJS/bUxc7byWYo9BnEDl X4Sww2MKA/v0TluC9oAWYVwgHeJr/ywo2DIFY6g0ZjAlwkaOy/Ii0vyRN hdSzaj5n6gu58yWu24us2V0jr4VTTHrpZf4rpsmp2sDbapld3tBwpSV/c nxpGN/l2mTujB/ss/Vn7W9QU1ytoxN4w3tjBnETtVLZZS7JlJKEUnf8eQ NfPAOIw07gbn0Mc0wZT/vcjZ3B7gr4/xNJoJfdphd/d+TvWuIjQqJX8yQ Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257931" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257931" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631438" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 09/15] perf stat: Add function to handle special events in hardware-grouping Date: Thu, 8 Feb 2024 19:14:35 -0800 Message-ID: <20240209031441.943012-10-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 660c6b9b5fa7..a0579b0f81e5 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -160,6 +160,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. @@ -2102,6 +2116,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 @@ -2126,6 +2149,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; @@ -2597,8 +2631,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 2C77A12E52; Fri, 9 Feb 2024 03:14:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448496; cv=none; b=Gnk0PSvnW25q6CvsIbjvuURYKkWW07UCVaN0LKoqjbQ270IS80SKfNk2dsUX3hlH3SskwyS+z7/Ld1wCvTaiShE7UWarZnT4n4HNtj1k3bY3n1qwP6eZK2xs8xd3rjg+8UtE9N37+Pvuh9Wv3UaTyGRHHzvTylE5qxaQH4JD+vM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448496; c=relaxed/simple; bh=iGYgMhf+uN2QB4bkriW/0fEdhb3pg3tSD8oxatmuXLQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lSuCsbV2w9avXM7bo6Pn6JDOuw1M6eY1yNYicrm+O+itbLQQZVQ2M4A9SGe4kizHsU6kQveuQQOEhGo0II1fsIL83EbcIN5rlkc7BEUab4pNb0OJfXNcXvTeUXYrBOfMmxoJT8QxzpozTDxNF3xxoERPkfPR333mFrg1Tb7/grE= 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=dIHfv6p6; arc=none smtp.client-ip=192.198.163.19 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="dIHfv6p6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448495; x=1738984495; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iGYgMhf+uN2QB4bkriW/0fEdhb3pg3tSD8oxatmuXLQ=; b=dIHfv6p6e47SA/Yv1vmjZzsSp0HV3KJTK0NTy3LbvnFYIE91VbOKr7FK oK9iuEEAYC6CTC8GdBBwd9bdU0ISP9PITtn85m9PZfYYsE2CboYA39tir +urUoqx6zzQQbWUwD5QpkA4whS37zsrmziDXC+2CBEMoP8Usjign3j13X boR8OJf2ll2S0zQTIdrWErublOvHuJBRyXOhhETJHrG3ayRbLvcB5kHB3 Rf+cPBfj1vqbjpFhf6gacqFxOstuCZcPMMIG83hlLi1Wdej42a43MYg7B SPNmMsH+w4iX+878wxgyj/pO8+s7XilYiL8OHq2QxIQyYY/2yD2mDR4aM g==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257934" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257934" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631443" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 10/15] perf stat: Add function to combine metrics for hardware-grouping Date: Thu, 8 Feb 2024 19:14:36 -0800 Message-ID: <20240209031441.943012-11-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 a0579b0f81e5..fe115f0880f9 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1525,6 +1525,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]. */ @@ -1815,8 +1855,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; @@ -2248,6 +2287,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; } @@ -2370,7 +2411,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 988A01864C; Fri, 9 Feb 2024 03:14:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448498; cv=none; b=lt6LXKcazX53N4yR8nC/HW9liRo3wzLdeVi9dd0Y2tQbF1nS7pCmHtV/lU4xj7nPdQ/6XbWNCbJ/9ehnuAAGJaNjbpOtp4GCEEf4hiHQ8sVlNaI+L1nVDvdn0SnBkcamOITJQwHfqE8ST4Cf4YFAeYjKdpEIiwnMdAH/Jln0Cec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448498; c=relaxed/simple; bh=mL5H4TvbTCZl43JaCvHWfIfur/YIYIR57bOSDnbW6HY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d1MmKi/Xpuvb51FWD4O0rtlUJkNegwpRy5BSN7Dm3xtVfbnEEt1mPEvjW39myg8rb0UnhVRTJOHdxtVhwxnwaSVWpcMp9I7hM55hVAdIiLKQASli49qY9RThBMVaLeIk3dWoBZ6TBTfoxk/iQKTsikdy9D6t+Oqpn5MsG7w1r9g= 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=Lq5497B1; arc=none smtp.client-ip=192.198.163.19 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="Lq5497B1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448497; x=1738984497; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mL5H4TvbTCZl43JaCvHWfIfur/YIYIR57bOSDnbW6HY=; b=Lq5497B1TlTNJwvvzgE4f1s4aFE0i7U7kXKoMVhif80WuJvmsrV7mbnB BvntQpHhfZXiN3vJfrSe4lR1vstnIdoi56TMa5FAVHevwlDJ3w1YTSzqf HW7bDHcci8AVDmkU2MILm1ltP60GUIrO/B3zM+xP7QQ3o7WNaEoPW0YPg m+EXFsL4Qorhr4LZbKEWnfjOqsNX5Ve3lTw/w+HyD8lqB1T46yQOXz/ju lavxIztXgHI2KFwIrNEe0mR1VS9oDlpO9ja3I6BLEG2I8z6bYvcKaTMRy We6WfIrAIsdH4XVkSxc9HwJ0bywa04PnvvGgwe1gphT+aJG53FJl8fNaf g==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257942" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257942" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631446" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 11/15] perf stat: Handle taken alone in hardware-grouping Date: Thu, 8 Feb 2024 19:14:37 -0800 Message-ID: <20240209031441.943012-12-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 taken alone into consideration when grouping. Only one taken alone event is supported per group. Signed-off-by: Weilin Wang --- tools/perf/pmu-events/jevents.py | 7 ++++++- tools/perf/pmu-events/pmu-events.h | 1 + tools/perf/util/metricgroup.c | 20 +++++++++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index bc91b7efa49a..4fbb367a3228 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -56,7 +56,9 @@ _json_event_attributes =3D [ # The list of counter(s) this event could use 'counters', # Longer things (the last won't be iterated over during decompress). - 'long_desc' + 'long_desc', + # Taken alone event could not be collected in the same group with othe= r taken alone event + 'taken_alone' ] =20 # Attributes that are in pmu_unit_layout. @@ -355,6 +357,9 @@ class JsonEvent: self.num_counters =3D jd.get('NumCounters') # Number of fixed counter self.num_fixed_counters =3D jd.get('NumFixedCounters') + # If the event is taken alone event, which cannot be grouped with any = other + # taken alone event. + self.taken_alone =3D jd.get('TakenAlone') filter =3D jd.get('Filter') self.unit =3D jd.get('ScaleUnit') self.perpkg =3D jd.get('PerPkg') diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index e245e4738970..837edfeb676a 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -54,6 +54,7 @@ struct pmu_event { const char *unit; bool perpkg; bool deprecated; + bool taken_alone; }; =20 struct pmu_metric { diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index fe115f0880f9..95d3868819e3 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -189,6 +189,7 @@ struct metricgroup__event_info { /** The event uses special counters that we consider that as free counter * during the event grouping*/ bool free_counter; + bool taken_alone; /** The counters the event allowed to be collected on. */ DECLARE_BITMAP(counters, NR_COUNTERS); }; @@ -235,6 +236,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; + bool taken_alone; }; =20 struct metricgroup__group_events { @@ -1717,6 +1719,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, + bool taken_alone, bool free_counter) { int ret =3D 0; @@ -1731,6 +1734,7 @@ static struct metricgroup__event_info *event_info__ne= w(const char *name, pmu_name =3D "core"; =20 e->name =3D name; + e->taken_alone =3D taken_alone; e->free_counter =3D free_counter; e->pmu_name =3D pmu_name; if (free_counter) { @@ -1769,7 +1773,8 @@ static int metricgroup__add_metric_event_callback(con= st struct pmu_event *pe, if (!strcasecmp(pe->name, d->event_name)) { if (!pe->counters) return -EINVAL; - event =3D event_info__new(d->event_id, pe->pmu, pe->counters, /*free_cou= nter=3D*/false); + event =3D event_info__new(d->event_id, pe->pmu, pe->counters, + pe->taken_alone, /*free_counter=3D*/false); if (!event) return -ENOMEM; list_add(&event->nd, d->list); @@ -1892,6 +1897,8 @@ static int find_and_set_counters(struct metricgroup__= event_info *e, int ret; unsigned long find_bit =3D 0; =20 + if (e->taken_alone && current_group->taken_alone) + return -ENOSPC; if (e->free_counter) return 0; if (e->fixed_counter) { @@ -1926,11 +1933,13 @@ 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->taken_alone) + group->taken_alone =3D true; 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, @@ -1940,6 +1949,7 @@ static int insert_new_group(struct list_head *head, INIT_LIST_HEAD(&new_group->event_head); fill_counter_bitmap(new_group->gp_counters, 0, num_counters); fill_counter_bitmap(new_group->fixed_counters, 0, num_fixed_counters); + new_group->taken_alone =3D false; list_add_tail(&new_group->nd, head); return 0; } @@ -2143,8 +2153,8 @@ static int create_grouping(struct list_head *pmu_info= _list, //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); + pr_debug("Event name %s, [pmu]=3D%s, [counters]=3D%s, [taken_alone]=3D%d= \n", + e->name, e->pmu_name, bit_buf, e->taken_alone); ret =3D assign_event_grouping(e, pmu_info_list, &groups); if (ret) goto out; @@ -2191,7 +2201,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", false, /*free_counter=3D*/true); if (!event) goto err_out; --=20 2.42.0 From nobody Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 DAFDF1B942; Fri, 9 Feb 2024 03:14:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448498; cv=none; b=Ho3VBPkylD9d/eFT/hNUK/nIh/OL7wKB8Wk9MEYkHaybgvnlStYQ1uHDQzPMfzsHqz0f+nYB9TdpZKFMs+X4ynWzcrWJtqvk8M2Oc+MHOdgW2ZM/Z5mp2vL9JHpXTztq7kOhc0kYFiUHAtC/95qnCCtmJuOSB3m0e9eZCS6KEeM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448498; c=relaxed/simple; bh=4TtYi0lpyHo54jJPp5QX24oZBCSlhJrdo5RjQxIdVIQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fvkQRl9fC3Xk/1oWK1mNUi7+Pu5uz7WCaOvEL1grMaa31F3aGWUcXsaS6afKBU08Mwc7hPDjdzDrhqoxaCD0xErQYKC9TRK15GIQrgLMg2VzyFJ8x2z/x58ml4+sxLVe0jBfv7vPnq2z3qOC7wJyv9wqz1C+alb1WOlHiXE4e/Y= 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=YvX5ZOHU; arc=none smtp.client-ip=192.198.163.19 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="YvX5ZOHU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448497; x=1738984497; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4TtYi0lpyHo54jJPp5QX24oZBCSlhJrdo5RjQxIdVIQ=; b=YvX5ZOHUqwP3G1ate8wcnTfVlfuOyfr7O/qCqXAZ68Ge1r5b3JROXJLf 7cshPAcNRX5PM87/kclURq/Au/1RcycLx/Xvst0gwZMSDFdcYSrEcTiYr SKlNQU2emAolnmSDmFLQrPRiOX7/M8AfTrvDU8gdHsGQJzYZbR78/5Crd 0iMNelEADLrD6vwffGIj4V7t1WQ6dMrAktEic5y981ZJP2uP8IXgAd84X ZO47tYgfliOQ7n202VabwbSTqtzm57wNorgjJVWF3EHuHTNetSDEEIk0q HCnhqibMWTcXVnUOt/RhKid6vaUFMggutMT/nPyXBwVrjBoCpHplRPq0K w==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257945" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257945" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631450" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 12/15] perf stat: Handle NMI in hardware-grouping Date: Thu, 8 Feb 2024 19:14:38 -0800 Message-ID: <20240209031441.943012-13-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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. Signed-off-by: Weilin Wang Reviewed-by: Ian Rogers --- 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 95d3868819e3..f1eb73957765 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1947,6 +1947,10 @@ static int insert_new_group(struct list_head *head, size_t num_fixed_counters) { 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"); + num_counters -=3D 1; + } fill_counter_bitmap(new_group->gp_counters, 0, num_counters); fill_counter_bitmap(new_group->fixed_counters, 0, num_fixed_counters); new_group->taken_alone =3D false; --=20 2.42.0 From nobody Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 1D9961DA32; Fri, 9 Feb 2024 03:14:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448502; cv=none; b=IWMzUzqgihIKCZ+kytDKyTg9UExLVdx7a+BqX8KqiYmAjVU+6YHga8TiDm+h0xoMxtLV8kP5fm8oREF6eAsyo+ww//a//v7sps0/XWA7X1JqX9dIRXlc88n+sdf5O/Pz2qBp7hQc9CEY5fcG4N0nUbWfPqN1mip+AVEH7eUpHTo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448502; c=relaxed/simple; bh=nObyFR7ak2CI9RBnkdMxnonoYCxryMBB96Dff9fIYBo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dI65umDV6RloJtiyvk97h3nO8xhGXSd1vpz/sp7KlFJri9BnY8arp5cCwBkHEZiVy0YZSdm8XcQln6ZIejv3qPqYLBQuTQ2S96jF/TtY71wAvDCxbCqt6u1q932zEBNXrcitGMvktG6yKdxJgnPcb5TLh2kWoH+fnDA2+zDYnwA= 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=R9BoWN15; arc=none smtp.client-ip=192.198.163.19 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="R9BoWN15" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448497; x=1738984497; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nObyFR7ak2CI9RBnkdMxnonoYCxryMBB96Dff9fIYBo=; b=R9BoWN15C1kFRuH9fFbqY8GqeTunEeBspXuHep/iCV7ksZiGA5J9gem8 R3NMF7gRGmDlHThj1k49PQRoPA08YAEPwFV6t3ZFp1ZCVuplyJ6tKsyQG 4LIVdOs4kwJdrZcpX+WHOKviu0oFex1N2+pv4+HFrk+AVnryt9IjOSvFK PcYyMuuYhbZ8gvk7sDrtljhvszGu3Qso2O6EN9TR5mzmF7OvvO7wVkZpY qWpNydTUM1vCbydkdd7UtUt7/pPyx37jtPjUucRgtkilmk5j0EkJgGHnN NTrJ4MLbV3Nz5lSL5Y2/CHiTcW99V4qKKxk5Dm3eovLp4heSqrPb6KNMj g==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257948" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257948" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631457" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 13/15] perf stat: Code refactoring in hardware-grouping Date: Thu, 8 Feb 2024 19:14:39 -0800 Message-ID: <20240209031441.943012-14-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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. Signed-off-by: Weilin Wang --- tools/perf/util/metricgroup.c | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index f1eb73957765..cfdbb5f7fb77 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1896,9 +1896,10 @@ static int find_and_set_counters(struct metricgroup_= _event_info *e, { int ret; unsigned long find_bit =3D 0; - - if (e->taken_alone && current_group->taken_alone) + if (e->taken_alone && current_group->taken_alone) { + pr_debug("current group with taken alone event already\n"); return -ENOSPC; + } if (e->free_counter) return 0; if (e->fixed_counter) { @@ -2017,7 +2018,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; } @@ -2146,26 +2148,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, [taken_alone]=3D%d= \n", e->name, e->pmu_name, bit_buf, e->taken_alone); - ret =3D assign_event_grouping(e, pmu_info_list, &groups); + 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 @@ -2186,9 +2184,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; @@ -2220,8 +2217,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); @@ -2267,23 +2263,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); @@ -2303,7 +2301,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 CD97117BC8; Fri, 9 Feb 2024 03:14:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448500; cv=none; b=YzdRlW44EiA7EqkxrSv9D1fqoa13lhsrECxNsgpvWMRCe7Vz14vZO+a3ZUe2GRmF59W2gxW9+ySeJ+I7dwcYMfwce3kLa1elNsOOY/OMqbWm6OaxN7ZjyeUk3HTgF2bzgAd4tWGn3uXrKZ9u9Zbo4jIY4w3lZAg41PAU+Qyg6oM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448500; c=relaxed/simple; bh=vOPR8LxQn3WFF9Ql8k9wlrgDI26EFBXQsZ+EoLn19bY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LBKoshao74JjdfzhATgzKZFmFnbZTZ+crjNgxtc7BQnfysXtx+OufoXv1sjFiH7K4UvcG5dtttxTPfxry5Zgka+sZapfJrsVeDHhjVloi8mgQhVHsk4YKvsQZAjLhRDzA2GSm5Br6RgX/10lbLfhrKqmkXHHn2h6U+HDAI/yd34= 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=JohPDLCg; arc=none smtp.client-ip=192.198.163.19 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="JohPDLCg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448499; x=1738984499; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vOPR8LxQn3WFF9Ql8k9wlrgDI26EFBXQsZ+EoLn19bY=; b=JohPDLCgpzm4TsCU0oLQP7vwSbhqTbKm3ZVSGIJI1LCnhba8Ef+PsI1c OgG/J9KXdTYKPtdV5prmSettj8rjbEabGiIN1+JQj26hShThU1FTPwW/C a3QnQVeoeJd3hgre6h8nDWcFk8YM/boNAEUF+0r+w8Xyz/ef49O67XViV q47XO5grPHSJINMrZUdOUVEIHaui0irK9jGJzjK9N2IYYl0sBD5K9FHJo N4rJ7GOwPGacSex6/SLMCtso/Kakoz4aeQiMVfhteqVH1YYlIloAB84n3 560VYjipKK1omzGRb5jqZgCNwCIQ5TsEDOyc3SGOtwSdeeuBex8rUG3vY w==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257952" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257952" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631461" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 14/15] perf stat: Add tool events support in hardware-grouping Date: Thu, 8 Feb 2024 19:14:40 -0800 Message-ID: <20240209031441.943012-15-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 cfdbb5f7fb77..e5b8456d0405 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1486,6 +1486,35 @@ static void find_tool_events(const struct list_head = *metric_list, } } =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; +} + /** * build_combined_expr_ctx - Make an expr_parse_ctx with all !group_events * metric IDs, as the IDs are held in a set, @@ -2049,6 +2078,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; @@ -2056,8 +2086,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) { @@ -2129,6 +2163,12 @@ static int hw_aware_metricgroup__build_event_string(= struct list_head *group_strs } ret =3D strbuf_addf(events, "}:W"); RETURN_IF_NON_ZERO(ret); + + if (!strcmp(p->pmu_name, "default_core") && 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); } @@ -2214,6 +2254,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; @@ -2259,6 +2300,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; @@ -2272,7 +2314,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 @@ -2407,6 +2450,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; @@ -2425,11 +2469,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 Sat Feb 7 18:20:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 0C53D25610; Fri, 9 Feb 2024 03:14:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448501; cv=none; b=nQkAPqIHakcMJTnv2TOIk0oHQ5VQ2G96HowL3fIfgm6yfZiQ1EzWeWXf3TRrNoBe3PB0a17Y21LeSDCm2J2YxqApBBl68WU9AI0d2RUAIKjHCsUBv+RHlv5mNSnvXLNEsYQN6ZwU32Yp3/XR6c5oK+wb92x/eeFylf76O+CEkdg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707448501; c=relaxed/simple; bh=UHYv/wd8Tx2Q5u/rY/pti40zJf3hKXnFNuJLdQgtOuo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eG03dlf1P2vqToihW3g+2L0micwUf83CTGGbb6cDXVo8trX8+xa83Ub26FjFw5bjf5Zki6p9QP2iLXOUVYVMD4opfLTIzR5DqkAGcPu/BEux6KlBQjwSMEKVUg9pUdInnBfrBHeF4dxhwhXXVjEuHTU0zye0Myai/LvELv9kZqY= 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=MvnuPpkT; arc=none smtp.client-ip=192.198.163.19 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="MvnuPpkT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707448499; x=1738984499; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UHYv/wd8Tx2Q5u/rY/pti40zJf3hKXnFNuJLdQgtOuo=; b=MvnuPpkT2/KZ6zS4y8pvDvbb3cDm/0MOALVBKWSpREpLkoKfwRKwsRZV p6GXRuv6sFMhPfGdxQzDaR1xcR+yc9Jlf9F4slSBDmbe9GYbw0SpM5kAS RTilMKcykHgID+m2T2lpLs8dMWj7qyjgnoN6TWCpsVHwGrBcYt1/7Fd1W ga/L1VQH5H2rMsiBaGnzBko2+QzJtNtrVsVP4UyvaVkrRGHSblnSeXZe1 wOvbcWu68Iu1oubh9YMxzlKJr3Cur+u678p3NeGbvWv3fZeEXSzhIlyGp F4++1DbtKg6GSdAldW3yUdqNpRnaVsf5xWezLvO/MF/v1U3X/66iTVEAd Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10978"; a="1257954" X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="1257954" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2024 19:14:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,255,1701158400"; d="scan'208";a="32631469" Received: from b49691a74b80.jf.intel.com ([10.165.54.183]) by orviesa002.jf.intel.com with ESMTP; 08 Feb 2024 19:14:48 -0800 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 , Mark Rutland Subject: [RFC PATCH v4 15/15] perf stat: Add hardware-grouping cmd option to perf stat Date: Thu, 8 Feb 2024 19:14:41 -0800 Message-ID: <20240209031441.943012-16-weilin.wang@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240209031441.943012-1-weilin.wang@intel.com> References: <20240209031441.943012-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 Signed-off-by: Weilin Wang Reviewed-by: Ian Rogers --- 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 d08a40c4bae1..e30f7a856122 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1257,6 +1257,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