drivers/resctrl/mpam_devices.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
Some MPAM MSCs (like L2 MSC) shares the same power domain with its
associated CPUs. Therefore, in scenarios where only partial cores power
up, the MSCs belonging to the un-powered cores don't need and should not
be accessed, otherwise bus-access fault would occur.
In such non-full core boot scenarios, the MSCs corresponding to offline
CPUs should skip. If the MSC's accessibility mask doesn't contain any
online CPU, this MSC remains uninitialized.
During initialization of class->props, skip any MSC that is not powered
up, so that ensure the class->props member unaffected from uninitialized
vmsc->props in mpam_enable_init_class_features() and
mpam_enable_merge_{class|vmsc}_features().
Signed-off-by: Zeng Heng <zengheng4@huawei.com>
---
Change in v2:
- Add check for the MSC probe status in mpam_enable_merge_class_features()
v1: https://lore.kernel.org/all/20260107031336.3599175-1-zengheng4@huawei.com/
drivers/resctrl/mpam_devices.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
index e6c9ddaa60e2..feb33931a83d 100644
--- a/drivers/resctrl/mpam_devices.c
+++ b/drivers/resctrl/mpam_devices.c
@@ -2335,10 +2335,12 @@ static void mpam_enable_init_class_features(struct mpam_class *class)
struct mpam_vmsc *vmsc;
struct mpam_component *comp;
- comp = list_first_entry(&class->components,
- struct mpam_component, class_list);
- vmsc = list_first_entry(&comp->vmsc,
- struct mpam_vmsc, comp_list);
+ list_for_each_entry(comp, &class->components, class_list) {
+ list_for_each_entry(vmsc, &comp->vmsc, comp_list) {
+ if (vmsc->msc->probed)
+ break;
+ }
+ }
class->props = vmsc->props;
}
@@ -2350,6 +2352,9 @@ static void mpam_enable_merge_vmsc_features(struct mpam_component *comp)
struct mpam_class *class = comp->class;
list_for_each_entry(vmsc, &comp->vmsc, comp_list) {
+ if (!vmsc->msc->probed)
+ continue;
+
list_for_each_entry(ris, &vmsc->ris, vmsc_list) {
__vmsc_props_mismatch(vmsc, ris);
class->nrdy_usec = max(class->nrdy_usec,
@@ -2363,8 +2368,12 @@ static void mpam_enable_merge_class_features(struct mpam_component *comp)
struct mpam_vmsc *vmsc;
struct mpam_class *class = comp->class;
- list_for_each_entry(vmsc, &comp->vmsc, comp_list)
+ list_for_each_entry(vmsc, &comp->vmsc, comp_list) {
+ if (!vmsc->msc->probed)
+ continue;
+
__class_props_mismatch(class, vmsc);
+ }
}
/*
@@ -2890,6 +2899,7 @@ void mpam_disable(struct work_struct *ignored)
*/
void mpam_enable(struct work_struct *work)
{
+ cpumask_t mask;
static atomic_t once;
struct mpam_msc *msc;
bool all_devices_probed = true;
@@ -2899,8 +2909,11 @@ void mpam_enable(struct work_struct *work)
list_for_each_entry_srcu(msc, &mpam_all_msc, all_msc_list,
srcu_read_lock_held(&mpam_srcu)) {
mutex_lock(&msc->probe_lock);
- if (!msc->probed)
- all_devices_probed = false;
+ if (!msc->probed) {
+ cpumask_and(&mask, &msc->accessibility, cpu_online_mask);
+ if (!cpumask_empty(&mask))
+ all_devices_probed = false;
+ }
mutex_unlock(&msc->probe_lock);
if (!all_devices_probed)
--
2.25.1
© 2016 - 2026 Red Hat, Inc.