From nobody Fri Feb 13 14:09:41 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2721FCE7A81 for ; Mon, 25 Sep 2023 06:20:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232207AbjIYGU2 (ORCPT ); Mon, 25 Sep 2023 02:20:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232062AbjIYGUM (ORCPT ); Mon, 25 Sep 2023 02:20:12 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47044CC4; Sun, 24 Sep 2023 23:19:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695622797; x=1727158797; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qG1e1YClORB9MUuLJIL/q/m6xLgbd/H000c70OIVGno=; b=WwYgouzY2Q0ZVggO/4okx++7M4dbn3hJ4+b6WnY7wxgTdIyIpd/WKJc4 waROqpxbBOcGCd5HvpStC1ac/kX+mIVOTr5aA0bJBcwUoeVLWLz6gjc/h 65/FsgXv1cMpsLKnWe6+vqIjrTMp4PBjbLyvxV8oVpiyixPFZTTm8mwDn iIHJaqS8T+KDA3PNpKOoRHiFxe5m6RdGVAEXh2gptRw+OBULR3SVCJdgy g4Lmmv09hIQ9mMiyYMYhp+M/0uvxpe3CQ4TNkEoOMDSvUKTk5ughReu05 Hhwcq02nGtkenWjuglf8LdIogt5vNO6UlZBixYLvfv1jOLaj8gk0f8OoZ g==; X-IronPort-AV: E=McAfee;i="6600,9927,10843"; a="445279459" X-IronPort-AV: E=Sophos;i="6.03,174,1694761200"; d="scan'208";a="445279459" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2023 23:19:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10843"; a="818494360" X-IronPort-AV: E=Sophos;i="6.03,174,1694761200"; d="scan'208";a="818494360" Received: from b49691a75598.jf.intel.com ([10.54.34.22]) by fmsmga004.fm.intel.com with ESMTP; 24 Sep 2023 23:19:17 -0700 From: weilin.wang@intel.com To: weilin.wang@intel.com, Ian Rogers , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Adrian Hunter , Kan Liang Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Perry Taylor , Samantha Alt , Caleb Biggers , Mark Rutland Subject: [RFC PATCH 11/25] perf stat: Add utility functions to hardware-grouping method Date: Sun, 24 Sep 2023 23:18:10 -0700 Message-Id: <20230925061824.3818631-12-weilin.wang@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20230925061824.3818631-1-weilin.wang@intel.com> References: <20230925061824.3818631-1-weilin.wang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Weilin Wang Add functions to handle counter bitmaps. Add functions do find and insert operations to handle inserting event into groups. Signed-off-by: Weilin Wang --- tools/lib/bitmap.c | 20 ++++++ tools/perf/util/metricgroup.c | 115 +++++++++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 2 deletions(-) diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c index c3e487196..a96dbf001 100644 --- a/tools/lib/bitmap.c +++ b/tools/lib/bitmap.c @@ -100,3 +100,23 @@ bool __bitmap_intersects(const unsigned long *bitmap1, return true; return false; } + +void bitmap_clear(unsigned long *map, unsigned int start, int len) +{ + unsigned long *p =3D map + BIT_WORD(start); + const unsigned int size =3D start + len; + int bits_to_clear =3D BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_clear =3D BITMAP_FIRST_WORD_MASK(start); + + while (len - bits_to_clear >=3D 0) { + *p &=3D ~mask_to_clear; + len -=3D bits_to_clear; + bits_to_clear =3D BITS_PER_LONG; + mask_to_clear =3D ~0UL; + p++; + } + if (len) { + mask_to_clear &=3D BITMAP_LAST_WORD_MASK(size); + *p &=3D ~mask_to_clear; + } +} diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index de6a6a1d7..68d56087b 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1450,6 +1450,27 @@ static int set_counter_bitmap(int pos, unsigned long= *bitmap) return 0; } =20 +static int find_counter_bitmap(unsigned long *addr1, + unsigned long *addr2, + unsigned long *bit) +{ + unsigned long find_bit =3D find_next_and_bit(addr1, addr2, NR_COUNTERS, 0= ); + + 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; + bitmap_clear(bitmap, find_bit, 1); + return 0; +} + static int parse_fixed_counter(const char *counter, unsigned long *bitmap, bool *fixed) @@ -1681,12 +1702,102 @@ static int get_pmu_counter_layouts(struct list_hea= d *pmu_info_list, return ret; } =20 +/** + * Find if there is a counter available for event e in current_group. If a + * counter is available, use this counter by fill the bit in the correct c= ounter + * 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 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 metric= group__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 create_new_group(head, current_group, pmu_group_head->size, + // pmu_group_head->fixed_size); + 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 __maybe_unused, + struct list_head *pmu_info_list, struct list_head *groups) { int ret =3D 0; @@ -1717,7 +1828,7 @@ static int assign_event_grouping(struct metricgroup__= event_info *e, list_add_tail(&pmu_group_head->nd, groups); } =20 - //ret =3D insert_event_to_group(e, pmu_group_head, pmu_info_list); + ret =3D insert_event_to_group(e, pmu_group_head); return ret; } =20 --=20 2.39.3