[RFC PATCH v2 05/11] x86/resctrl: Handle cache allocation setup failures

From: Tony Luck

Date: Tue Nov 03 2026 - 16:30:05 EST


rdt_get_cache_alloc_cfg() can fail when allocation of its control structure
fails or the CPU vendor is unsupported. The caller currently marks the
resource allocation-capable even when no control was created.

Return the control from rdt_get_cache_alloc_cfg() and mark the resource
allocation-capable only after successful setup. Free the allocated control
when the vendor is unsupported.

Signed-off-by: Tony Luck <tony.luck@xxxxxxxxx>
---
arch/x86/kernel/cpu/resctrl/core.c | 42 ++++++++++++++++++------------
1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 0b1de97af17d..6df8e3c03289 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -348,7 +348,7 @@ static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)
return true;
}

-static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
+static struct resctrl_ctrl *rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
{
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
struct resctrl_hw_ctrl *hw_ctrl;
@@ -361,7 +361,7 @@ static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
hw_res->num_closid = edx.split.cos_max + 1;
hw_ctrl = kzalloc_obj(*hw_ctrl);
if (!hw_ctrl)
- return;
+ return NULL;

hw_ctrl->r_ctrl.type = RESCTRL_CTRL_BITMAP;
hw_ctrl->r_ctrl.name = RESCTRL_CTRL_NAME_DEF;
@@ -380,15 +380,14 @@ static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
__set_bit(RESCTRL_BITMAP_FLAG_SPARSE, hw_ctrl->r_ctrl.bitmap.flags);
hw_ctrl->r_ctrl.bitmap.min_cbm_bits = 0;
} else {
- return;
+ kfree(hw_ctrl);
+ return NULL;
}

hw_ctrl->msr_base = idx == 1 ? MSR_IA32_L3_CBM_BASE: MSR_IA32_L2_CBM_BASE;
hw_ctrl->msr_update = cat_wrmsr;

- list_add(&hw_ctrl->r_ctrl.entry, &r->controls);
-
- r->alloc_capable = true;
+ return &hw_ctrl->r_ctrl;
}

static void rdt_get_cdp_config(int level)
@@ -1054,6 +1053,7 @@ static __init bool get_slow_mem_config(void)

static __init bool get_rdt_alloc_resources(void)
{
+ struct resctrl_ctrl *ctrl;
struct rdt_resource *r;
bool ret = false;

@@ -1065,20 +1065,28 @@ static __init bool get_rdt_alloc_resources(void)

if (rdt_cpu_has(X86_FEATURE_CAT_L3)) {
r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
- rdt_get_cache_alloc_cfg(1, r);
- if (rdt_cpu_has(X86_FEATURE_CDP_L3))
- rdt_get_cdp_l3_config();
- if (rdt_cpu_has(X86_FEATURE_SDCIAE))
- rdt_set_io_alloc_capable(r);
- ret = true;
+ ctrl = rdt_get_cache_alloc_cfg(1, r);
+ if (ctrl) {
+ if (rdt_cpu_has(X86_FEATURE_CDP_L3))
+ rdt_get_cdp_l3_config();
+ if (rdt_cpu_has(X86_FEATURE_SDCIAE))
+ rdt_set_io_alloc_capable(r);
+ list_add(&ctrl->entry, &r->controls);
+ r->alloc_capable = true;
+ ret = true;
+ }
}
if (rdt_cpu_has(X86_FEATURE_CAT_L2)) {
- /* CPUID 0x10.2 fields are same format at 0x10.1 */
+ /* CPUID 0x10.2 fields are same format as 0x10.1 */
r = &rdt_resources_all[RDT_RESOURCE_L2].r_resctrl;
- rdt_get_cache_alloc_cfg(2, r);
- if (rdt_cpu_has(X86_FEATURE_CDP_L2))
- rdt_get_cdp_l2_config();
- ret = true;
+ ctrl = rdt_get_cache_alloc_cfg(2, r);
+ if (ctrl) {
+ if (rdt_cpu_has(X86_FEATURE_CDP_L2))
+ rdt_get_cdp_l2_config();
+ list_add(&ctrl->entry, &r->controls);
+ r->alloc_capable = true;
+ ret = true;
+ }
}

if (get_mem_config())
--
2.56.0