linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: James Morse <james.morse@arm.com>
To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Cc: James Morse <james.morse@arm.com>,
	D Scott Phillips OS <scott@os.amperecomputing.com>,
	carl@os.amperecomputing.com, lcherian@marvell.com,
	bobo.shaobowang@huawei.com, tan.shaopeng@fujitsu.com,
	baolin.wang@linux.alibaba.com,
	Jamie Iles <quic_jiles@quicinc.com>,
	Xin Hao <xhao@linux.alibaba.com>,
	peternewman@google.com, dfustini@baylibre.com,
	amitsinght@marvell.com, David Hildenbrand <david@kernel.org>,
	Dave Martin <dave.martin@arm.com>, Koba Ko <kobak@nvidia.com>,
	Shanker Donthineni <sdonthineni@nvidia.com>,
	fenghuay@nvidia.com, baisheng.gao@unisoc.com,
	Jonathan Cameron <jonathan.cameron@huawei.com>,
	Gavin Shan <gshan@redhat.com>, Ben Horgan <ben.horgan@arm.com>,
	rohit.mathew@arm.com, reinette.chatre@intel.com,
	Punit Agrawal <punit.agrawal@oss.qualcomm.com>
Subject: [RFC PATCH 19/38] arm_mpam: resctrl: pick classes for use as mbm counters
Date: Fri,  5 Dec 2025 21:58:42 +0000	[thread overview]
Message-ID: <20251205215901.17772-20-james.morse@arm.com> (raw)
In-Reply-To: <20251205215901.17772-1-james.morse@arm.com>

resctrl has two types of counters, NUMA-local and global. MPAM has only
bandwidth counters, but the position of the MSC may mean it counts
NUMA-local, or global traffic.

But the topology information is not available.

Apply a heuristic: the L2 or L3 supports bandwidth monitors, these are
probably NUMA-local. If the memory controller supports bandwidth
monitors, they are probably global.

This also allows us to assert that we don't have the same class
backing two different resctrl events.

Because the class or component backing the event may not be 'the L3',
it is necessary for mpam_resctrl_get_domain_from_cpu() to search
the monitor domains too. This matters the most for 'monitor only'
systems, where 'the L3' control domains may be empty, and the
ctrl_comp pointer NULL.

resctrl expects there to be enough monitors for every possible control
and monitor group to have one. Such a system gets called 'free running'
as the monitors can be programmed once and left running.
Any other platform will need to emulate ABMC.

Signed-off-by: James Morse <james.morse@arm.com>
---
 drivers/resctrl/mpam_internal.h |   8 ++
 drivers/resctrl/mpam_resctrl.c  | 141 ++++++++++++++++++++++++++++++--
 2 files changed, 144 insertions(+), 5 deletions(-)

diff --git a/drivers/resctrl/mpam_internal.h b/drivers/resctrl/mpam_internal.h
index f9d2a1004c32..0984ac32f303 100644
--- a/drivers/resctrl/mpam_internal.h
+++ b/drivers/resctrl/mpam_internal.h
@@ -339,6 +339,14 @@ struct mpam_msc_ris {
 
 struct mpam_resctrl_dom {
 	struct mpam_component	*ctrl_comp;
+
+	/*
+	 * There is no single mon_comp because different events may be backed
+	 * by different class/components. mon_comp is indexed by the event
+	 * number.
+	 */
+	struct mpam_component   *mon_comp[QOS_NUM_EVENTS];
+
 	struct rdt_ctrl_domain	resctrl_ctrl_dom;
 	struct rdt_mon_domain	resctrl_mon_dom;
 };
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index fc1f054f187e..9978eb48c1f4 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -50,6 +50,14 @@ static bool exposed_mon_capable;
  */
 static bool cdp_enabled;
 
+/* Whether this num_mbw_mon could result in a free_running system */
+static int __mpam_monitors_free_running(u16 num_mbwu_mon)
+{
+	if (num_mbwu_mon >= resctrl_arch_system_num_rmid_idx())
+		return resctrl_arch_system_num_rmid_idx();
+	return 0;
+}
+
 bool resctrl_arch_alloc_capable(void)
 {
 	return exposed_alloc_capable;
@@ -290,6 +298,26 @@ static bool cache_has_usable_csu(struct mpam_class *class)
 	return (mpam_partid_max > 1) || (mpam_pmg_max != 0);
 }
 
+static bool class_has_usable_mbwu(struct mpam_class *class)
+{
+	struct mpam_props *cprops = &class->props;
+
+	if (!mpam_has_feature(mpam_feat_msmon_mbwu, cprops))
+		return false;
+
+	/*
+	 * resctrl expects the bandwidth counters to be free running,
+	 * which means we need as many monitors as resctrl has
+	 * control/monitor groups.
+	 */
+	if (__mpam_monitors_free_running(cprops->num_mbwu_mon)) {
+		pr_debug("monitors usable in free-running mode\n");
+		return true;
+	}
+
+	return false;
+}
+
 /*
  * Calculate the worst-case percentage change from each implemented step
  * in the control.
@@ -554,7 +582,7 @@ static void counter_update_class(enum resctrl_event_id evt_id,
 static void mpam_resctrl_pick_counters(void)
 {
 	struct mpam_class *class;
-	bool has_csu;
+	bool has_csu, has_mbwu;
 
 	lockdep_assert_cpus_held();
 
@@ -586,7 +614,37 @@ static void mpam_resctrl_pick_counters(void)
 				return;
 			}
 		}
+
+		has_mbwu = class_has_usable_mbwu(class);
+		if (has_mbwu && topology_matches_l3(class)) {
+			pr_debug("class %u has usable MBWU, and matches L3 topology",
+				 class->level);
+
+			/*
+			 * MBWU counters may be 'local' or 'total' depending on
+			 * where they are in the topology. Counters on caches
+			 * are assumed to be local. If it's on the memory
+			 * controller, its assumed to be global.
+			 */
+			switch (class->type) {
+			case MPAM_CLASS_CACHE:
+				counter_update_class(QOS_L3_MBM_LOCAL_EVENT_ID,
+						     class);
+				break;
+			case MPAM_CLASS_MEMORY:
+				counter_update_class(QOS_L3_MBM_TOTAL_EVENT_ID,
+						     class);
+				break;
+			default:
+				break;
+			}
+		}
 	}
+
+	/* Allocation of MBWU monitors assumes that the class is unique... */
+	if (mpam_resctrl_counters[QOS_L3_MBM_LOCAL_EVENT_ID].class)
+		WARN_ON_ONCE(mpam_resctrl_counters[QOS_L3_MBM_LOCAL_EVENT_ID].class ==
+			     mpam_resctrl_counters[QOS_L3_MBM_TOTAL_EVENT_ID].class);
 }
 
 static int mpam_resctrl_control_init(struct mpam_resctrl_res *res,
@@ -910,6 +968,20 @@ static bool mpam_resctrl_offline_domain_hdr(unsigned int cpu,
 	return false;
 }
 
+static struct mpam_component *find_component(struct mpam_class *victim, int cpu)
+{
+	struct mpam_component *victim_comp;
+
+	guard(srcu)(&mpam_srcu);
+	list_for_each_entry_srcu(victim_comp, &victim->components, class_list,
+				 srcu_read_lock_held(&mpam_srcu)) {
+		if (cpumask_test_cpu(cpu, &victim_comp->affinity))
+			return victim_comp;
+	}
+
+	return NULL;
+}
+
 static struct mpam_resctrl_dom *
 mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
 {
@@ -959,8 +1031,32 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
 	}
 
 	if (exposed_mon_capable) {
+		int i;
+		struct mpam_component *mon_comp, *any_mon_comp;
+
+		/*
+		 * Even if the monitor domain is backed by a different
+		 * component, the L3 component IDs need to be used... only
+		 * there may be no ctrl_comp for the L3.
+		 * Search each event's class list for a component with
+		 * overlapping CPUs and set up the dom->mon_comp array.
+		 */
+		for (i = 0; i < QOS_NUM_EVENTS; i++) {
+			struct mpam_resctrl_mon *mon;
+
+			mon = &mpam_resctrl_counters[i];
+			if (!mon->class)
+				continue;       // dummy resource
+
+			mon_comp = find_component(mon->class, cpu);
+			dom->mon_comp[i] = mon_comp;
+			if (mon_comp)
+				any_mon_comp = mon_comp;
+		}
+		WARN_ON_ONCE(!any_mon_comp);
+
 		mon_d = &dom->resctrl_mon_dom;
-		mpam_resctrl_domain_hdr_init(cpu, ctrl_comp, &mon_d->hdr);
+		mpam_resctrl_domain_hdr_init(cpu, any_mon_comp, &mon_d->hdr);
 		mon_d->hdr.type = RESCTRL_MON_DOMAIN;
 		/* TODO: this list should be sorted */
 		list_add_tail_rcu(&mon_d->hdr.list, &r->mon_domains);
@@ -982,16 +1078,47 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
 	return dom;
 }
 
+/*
+ * We know all the monitors are associated with the L3, even if there are no
+ * controls and therefore no control component. Find the cache-id for the CPU
+ * and use that to search for existing resctrl domains.
+ * This relies on mpam_resctrl_pick_domain_id() using the L3 cache-id
+ * for anything that is not a cache.
+ */
+static struct mpam_resctrl_dom *mpam_resctrl_get_mon_domain_from_cpu(int cpu)
+{
+	u32 cache_id;
+	struct rdt_mon_domain *mon_d;
+	struct mpam_resctrl_dom *dom;
+	struct mpam_resctrl_res *l3 = &mpam_resctrl_controls[RDT_RESOURCE_L3];
+
+	if (!l3->class)
+		return NULL;
+	/* TODO: how does this order with cacheinfo updates under cpuhp? */
+	cache_id = get_cpu_cacheinfo_id(cpu, 3);
+	if (cache_id == ~0)
+		return NULL;
+
+	list_for_each_entry(mon_d, &l3->resctrl_res.mon_domains, hdr.list) {
+		dom = container_of(mon_d, struct mpam_resctrl_dom, resctrl_mon_dom);
+
+		if (mon_d->hdr.id == cache_id)
+			return dom;
+	}
+
+	return NULL;
+}
+
 static struct mpam_resctrl_dom *
 mpam_resctrl_get_domain_from_cpu(int cpu, struct mpam_resctrl_res *res)
 {
 	struct mpam_resctrl_dom *dom;
 	struct rdt_ctrl_domain *ctrl_d;
+	struct rdt_resource *r = &res->resctrl_res;
 
 	lockdep_assert_cpus_held();
 
-	list_for_each_entry_rcu(ctrl_d, &res->resctrl_res.ctrl_domains,
-				hdr.list) {
+	list_for_each_entry_rcu(ctrl_d, &r->ctrl_domains, hdr.list) {
 		dom = container_of(ctrl_d, struct mpam_resctrl_dom,
 				   resctrl_ctrl_dom);
 
@@ -999,7 +1126,11 @@ mpam_resctrl_get_domain_from_cpu(int cpu, struct mpam_resctrl_res *res)
 			return dom;
 	}
 
-	return NULL;
+	if (r->rid != RDT_RESOURCE_L3)
+		return NULL;
+
+	/* Search the mon domain list too - needed on monitor only platforms. */
+	return mpam_resctrl_get_mon_domain_from_cpu(cpu);
 }
 
 int mpam_resctrl_online_cpu(unsigned int cpu)
-- 
2.39.5



  parent reply	other threads:[~2025-12-05 22:00 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-05 21:58 [RFC PATCH 00/38] arm_mpam: Add KVM/arm64 and resctrl glue code James Morse
2025-12-05 21:58 ` [RFC PATCH 01/38] arm64: mpam: Context switch the MPAM registers James Morse
2025-12-05 23:53   ` Fenghua Yu
2025-12-09 15:08     ` Ben Horgan
2025-12-09 14:49   ` Ben Horgan
2025-12-12 12:30   ` Ben Horgan
2025-12-18 10:35   ` Jonathan Cameron
2025-12-18 14:52     ` Ben Horgan
2025-12-18 14:55       ` Ben Horgan
2025-12-18 15:38         ` Jonathan Cameron
2025-12-18 15:54           ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 02/38] arm64: mpam: Re-initialise MPAM regs when CPU comes online James Morse
2025-12-09 15:13   ` Ben Horgan
2025-12-11 11:23     ` Ben Horgan
2025-12-11 11:32       ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 03/38] arm64: mpam: Advertise the CPUs MPAM limits to the driver James Morse
2025-12-18 10:38   ` Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 04/38] arm64: mpam: Add cpu_pm notifier to restore MPAM sysregs James Morse
2025-12-11 13:41   ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 05/38] arm64: mpam: Add helpers to change a task or cpu's MPAM PARTID/PMG values James Morse
2025-12-18 10:44   ` Jonathan Cameron
2025-12-19 11:56     ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 06/38] KVM: arm64: Force guest EL1 to use user-space's partid configuration James Morse
2025-12-09 15:32   ` Ben Horgan
2025-12-12 11:31   ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 07/38] arm_mpam: resctrl: Add boilerplate cpuhp and domain allocation James Morse
2025-12-09 15:43   ` Ben Horgan
2025-12-18 11:30   ` Jonathan Cameron
2025-12-19 12:02     ` Ben Horgan
2025-12-22 11:48       ` Jonathan Cameron
2026-01-02 11:07         ` Ben Horgan
2025-12-19 12:17     ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 08/38] arm_mpam: resctrl: Pick the caches we will use as resctrl resources James Morse
2025-12-09 15:57   ` Ben Horgan
2025-12-16 10:14     ` Ben Horgan
2025-12-18 11:38   ` Jonathan Cameron
2025-12-19 12:04     ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 09/38] arm_mpam: resctrl: Implement resctrl_arch_reset_all_ctrls() James Morse
2025-12-05 21:58 ` [RFC PATCH 10/38] arm_mpam: resctrl: Add resctrl_arch_get_config() James Morse
2025-12-05 21:58 ` [RFC PATCH 11/38] arm_mpam: resctrl: Implement helpers to update configuration James Morse
2025-12-18 11:47   ` Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 12/38] arm_mpam: resctrl: Add plumbing against arm64 task and cpu hooks James Morse
2025-12-05 21:58 ` [RFC PATCH 13/38] arm_mpam: resctrl: Add CDP emulation James Morse
2025-12-16 13:49   ` Ben Horgan
2025-12-16 14:24   ` Ben Horgan
2025-12-18 11:58   ` Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 14/38] arm_mpam: resctrl: Add rmid index helpers James Morse
2025-12-05 21:58 ` [RFC PATCH 15/38] arm_mpam: resctrl: Convert to/from MPAMs fixed-point formats James Morse
2025-12-05 21:58 ` [RFC PATCH 16/38] arm_mpam: resctrl: Add support for 'MB' resource James Morse
2025-12-12  4:27   ` Gavin Shan
2025-12-16 15:56     ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 17/38] arm_mpam: resctrl: Add kunit test for control format conversions James Morse
2025-12-05 21:58 ` [RFC PATCH 18/38] arm_mpam: resctrl: Add support for csu counters James Morse
2025-12-16 13:55   ` Ben Horgan
2025-12-18 13:20   ` Jonathan Cameron
2025-12-19 12:06     ` Ben Horgan
2025-12-05 21:58 ` James Morse [this message]
2025-12-18 13:36   ` [RFC PATCH 19/38] arm_mpam: resctrl: pick classes for use as mbm counters Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 20/38] arm_mpam: resctrl: Pre-allocate free running monitors James Morse
2025-12-05 21:58 ` [RFC PATCH 21/38] arm_mpam: resctrl: Pre-allocate assignable monitors James Morse
2025-12-18 13:42   ` Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 22/38] arm_mpam: resctrl: Add kunit test for ABMC/CDP interactions James Morse
2025-12-05 21:58 ` [RFC PATCH 23/38] arm_mpam: resctrl: Add resctrl_arch_config_cntr() for ABMC use James Morse
2025-12-05 21:58 ` [RFC PATCH 24/38] arm_mpam: resctrl: Allow resctrl to allocate monitors James Morse
2025-12-16 16:58   ` Ben Horgan
2025-12-18 13:49   ` Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 25/38] arm_mpam: resctrl: Add resctrl_arch_rmid_read() and resctrl_arch_reset_rmid() James Morse
2025-12-18 13:53   ` Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 26/38] arm_mpam: resctrl: Add resctrl_arch_cntr_read() & resctrl_arch_reset_cntr() James Morse
2025-12-05 21:58 ` [RFC PATCH 27/38] arm_mpam: resctrl: Add empty definitions for assorted resctrl functions James Morse
2025-12-09 16:31   ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 28/38] arm64: mpam: Select ARCH_HAS_CPU_RESCTRL James Morse
2025-12-09 16:33   ` Ben Horgan
2025-12-18 13:55   ` Jonathan Cameron
2025-12-05 21:58 ` [RFC PATCH 29/38] arm_mpam: resctrl: Call resctrl_init() on platforms that can support resctrl James Morse
2025-12-05 21:58 ` [RFC PATCH 30/38] arm_mpam: resctrl: Call resctrl_exit() in the event of errors James Morse
2025-12-05 21:58 ` [RFC PATCH 31/38] arm_mpam: resctrl: Update the rmid reallocation limit James Morse
2025-12-06  0:06   ` Fenghua Yu
2025-12-09 16:36     ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 32/38] arm_mpam: resctrl: Sort the order of the domain lists James Morse
2025-12-05 21:58 ` [RFC PATCH 33/38] arm_mpam: Generate a configuration for min controls James Morse
2025-12-09 16:45   ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 34/38] arm_mpam: Add quirk framework James Morse
2025-12-18 14:04   ` Jonathan Cameron
2025-12-19 12:19     ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 35/38] arm_mpam: Add workaround for T241-MPAM-1 James Morse
2025-12-10 12:20   ` Ben Horgan
2025-12-05 21:58 ` [RFC PATCH 36/38] arm_mpam: Add workaround for T241-MPAM-4 James Morse
2025-12-09 16:58   ` Ben Horgan
2025-12-05 21:59 ` [RFC PATCH 37/38] arm_mpam: Add workaround for T241-MPAM-6 James Morse
2025-12-09 17:06   ` Ben Horgan
2025-12-05 21:59 ` [RFC PATCH 38/38] arm_mpam: Quirk CMN-650's CSU NRDY behaviour James Morse
2025-12-09 14:40 ` [RFC PATCH 00/38] arm_mpam: Add KVM/arm64 and resctrl glue code Ben Horgan
2025-12-09 15:53   ` Peter Newman
2025-12-09 16:14     ` Ben Horgan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251205215901.17772-20-james.morse@arm.com \
    --to=james.morse@arm.com \
    --cc=amitsinght@marvell.com \
    --cc=baisheng.gao@unisoc.com \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=ben.horgan@arm.com \
    --cc=bobo.shaobowang@huawei.com \
    --cc=carl@os.amperecomputing.com \
    --cc=dave.martin@arm.com \
    --cc=david@kernel.org \
    --cc=dfustini@baylibre.com \
    --cc=fenghuay@nvidia.com \
    --cc=gshan@redhat.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=kobak@nvidia.com \
    --cc=lcherian@marvell.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peternewman@google.com \
    --cc=punit.agrawal@oss.qualcomm.com \
    --cc=quic_jiles@quicinc.com \
    --cc=reinette.chatre@intel.com \
    --cc=rohit.mathew@arm.com \
    --cc=scott@os.amperecomputing.com \
    --cc=sdonthineni@nvidia.com \
    --cc=tan.shaopeng@fujitsu.com \
    --cc=xhao@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).