[RFC PATCH 26/31] x86/resctrl: Allow control writes from any CPU for MMIO controllers

From: Chen Yu

Date: Sun Aug 02 2026 - 12:20:04 EST


Programming a control that lives in domain-local MSR space must run on a
CPU that belongs to the target domain, so resctrl_arch_update_domains()
issues the hw_update() via an IPI. MMIO based controls (e.g. the ERDT
MARC registers) have no such affinity requirement and can be programmed
from the current CPU, making the IPI pure overhead.

Introduce RESCTRL_CTRL_FLAG_ANY_CPU to describe a control whose hardware
can be programmed from any CPU, mirroring the mon_evt::any_cpu flag used
on the monitoring read path. Set it on the MARC controllers at creation
time.

Signed-off-by: Chen Yu <yu.c.chen@xxxxxxxxx>
---
arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 11 ++++++++++-
arch/x86/kernel/cpu/resctrl/erdt.c | 2 ++
include/linux/resctrl.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
index 1dd59d36e86c..7bacb8bf2e27 100644
--- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
+++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
@@ -19,6 +19,15 @@

#include "internal.h"

+static void ctrl_hw_update(struct resctrl_ctrl *ctrl, struct rdt_ctrl_domain *d,
+ struct hw_param *m)
+{
+ if (ctrl->flags & RESCTRL_CTRL_FLAG_ANY_CPU)
+ rdt_ctrl_update(m);
+ else
+ smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, m, 1);
+}
+
int resctrl_arch_update_one(struct rdt_resource *r, struct resctrl_ctrl *ctrl,
struct rdt_ctrl_domain *d, u32 closid,
enum resctrl_conf_type t, u32 cfg_val)
@@ -81,7 +90,7 @@ static void _resctrl_arch_update_domains(struct rdt_resource *r,
}
}
if (hw_param.res)
- smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, &hw_param, 1);
+ ctrl_hw_update(ctrl, d, &hw_param);
}
}

diff --git a/arch/x86/kernel/cpu/resctrl/erdt.c b/arch/x86/kernel/cpu/resctrl/erdt.c
index c25aff805b12..8f087defffac 100644
--- a/arch/x86/kernel/cpu/resctrl/erdt.c
+++ b/arch/x86/kernel/cpu/resctrl/erdt.c
@@ -369,6 +369,8 @@ __init bool erdt_get_mem_config(struct rdt_resource *r)
hw_ctrl->r_ctrl.scalar.unit = RESCTRL_CTRL_UNIT_ALL;

hw_ctrl->hw_update = marc_hw_update;
+ /* MARC controls live in MMIO, program from any CPU. */
+ hw_ctrl->r_ctrl.flags |= RESCTRL_CTRL_FLAG_ANY_CPU;
list_add_tail(&hw_ctrl->r_ctrl.entry, &r->controls);
}
}
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 3969db01f4cc..8260b09aa323 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -386,6 +386,7 @@ resctrl_ctrl_name_region(unsigned int region, unsigned int type)
/* Flags for rdt_resource::flags and resctrl_ctrl::flags */
#define RESCTRL_CTRL_FLAG_LINEAR BIT(0)
#define RESCTRL_CTRL_FLAG_SPARSE_BITMASKS BIT(1)
+#define RESCTRL_CTRL_FLAG_ANY_CPU BIT(2)

/**
* struct resctrl_ctrl - A resource control
--
2.43.0