[PATCH 09/10] x86/resctrl: Update __mon_event_count() for Sub-NUMA domains

From: Tony Luck
Date: Wed Mar 27 2024 - 16:06:59 EST


Chack the flag to see if the request is for a file that must
calculate the sum of RMID counters from all sibling domains.

Note that when reading RMID counters to sum across SUBL3 domains
it is OK to read from any CPU in the parent L3 domain.

Signed-off-by: Tony Luck <tony.luck@xxxxxxxxx>
---
include/linux/resctrl.h | 2 +
arch/x86/kernel/cpu/resctrl/monitor.c | 56 ++++++++++++++++++++++++---
2 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index b7ade7627e08..4cf256053f53 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -177,6 +177,7 @@ enum resctrl_scope {
* @evt_list: List of monitoring events
* @parent: Parent of this resource
* @child: Child of this resource
+ * @num_siblings: Number of sibling domains that share a parent
* @fflags: flags to choose base and info files
* @cdp_capable: Is the CDP feature available on this resource
*/
@@ -200,6 +201,7 @@ struct rdt_resource {
struct list_head evt_list;
struct rdt_resource *parent;
struct rdt_resource *child;
+ int num_siblings;
unsigned long fflags;
bool cdp_capable;
};
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 95455cb187eb..1ba40d5f5d77 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -279,12 +279,24 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
struct arch_mbm_state *am;
u64 msr_val, chunks;
- int ret;
+ int cpu, ret;

resctrl_arch_rmid_read_context_check();

- if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask))
- return -EINVAL;
+ /* This sanity check is now heavyweight. Keep it? */
+ cpu = smp_processor_id();
+ if (r->parent) {
+ struct rdt_domain *pd;
+
+ pd = rdt_find_domain(r->parent, d->parent, NULL);
+ if (WARN_ON_ONCE(!pd))
+ return -EINVAL;
+ if (!cpumask_test_cpu(cpu, &pd->cpu_mask))
+ return -EINVAL;
+ } else {
+ if (!cpumask_test_cpu(cpu, &d->cpu_mask))
+ return -EINVAL;
+ }

ret = __rmid_read(rmid, eventid, &msr_val);
if (ret)
@@ -538,7 +550,7 @@ static struct mbm_state *get_mbm_state(struct rdt_domain *d, u32 closid,
}
}

-static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)
+static int ___mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr, u64 *rrval)
{
struct mbm_state *m;
u64 tval = 0;
@@ -556,11 +568,44 @@ static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)
if (rr->err)
return rr->err;

- rr->val += tval;
+ *rrval += tval;

return 0;
}

+static u32 get_node_rmid(struct rdt_resource *r, struct rdt_domain *d, u32 rmid)
+{
+ int cpu = cpumask_any(&d->cpu_mask);
+
+ return rmid + (cpu_to_node(cpu) % r->num_siblings) * r->num_rmid;
+}
+
+static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)
+{
+ struct rdt_domain *d;
+ struct rmid_read tmp;
+ u32 node_rmid;
+ int ret = 0;
+
+ if (!rr->sumdomains) {
+ node_rmid = get_node_rmid(rr->r, rr->d, rmid);
+ return ___mon_event_count(closid, node_rmid, rr, &rr->val);
+ }
+
+ tmp = *rr;
+ list_for_each_entry(d, &rr->r->domains, list) {
+ if (d->parent == rr->d->parent) {
+ tmp.d = d;
+ node_rmid = get_node_rmid(rr->r, d, rmid);
+ ret = ___mon_event_count(closid, node_rmid, &tmp, &rr->val);
+ if (ret)
+ break;
+ }
+ }
+
+ return ret;
+}
+
/*
* mbm_bw_count() - Update bw count from values previously read by
* __mon_event_count().
@@ -1039,6 +1084,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
*/
resctrl_rmid_realloc_threshold = resctrl_arch_round_mon_val(threshold);

+ r->num_siblings = 1;
rdt_l3_mon_resource = r;

ret = dom_data_init(rdt_l3_mon_resource);
--
2.44.0