Re: [PATCH 05/11] fs/resctrl: Use accurate type for rdt_resource::rid

Luck, Tony
2026-03-03T18:21:04Z

On Mon, Mar 02, 2026 at 10:46:11AM -0800, Reinette Chatre wrote:

> - /* Must be the last */
> - RDT_NUM_RESOURCES,
> + /* Additions to enum need to update RDT_NUM_RESOURCES. */
> };
>
> +#define RDT_NUM_RESOURCES (RDT_RESOURCE_PERF_PKG + 1)

Alternative approach that doesn't rely on developers reading
that comment and updating the define.

Replace the RDT_NUM_RESOURCES #define with a variable initialized
to ARRAY_SIZE(rdt_resources_all).

-Tony

From b31a874c7199347d875fd6e9505d41aa2639eafd Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
Date: Mon, 2 Mar 2026 10:46:11 -0800
Subject: [PATCH] fs/resctrl: Use accurate type for rdt_resource::rid

Every resctrl resource has a unique ID described by enum resctrl_res_level.
enum resctrl_res_level is used in all resource ID initializations and all
resource ID comparisons. All functions consuming the resource ID expects an
enum resctrl_res_level. Of the four structures that contain a resource ID
(struct mon_data, struct mon_evt, struct rdt_domain_hdr, and struct
rdt_resource) only struct rdt_resource does not use enum resctrl_res_level.

Switch the type of rdt_resource::rid to be enum resctrl_res_level to make
it obvious what values are valid, match the type everywhere this member is
used, and obtain benefits from tools that can flag any enum misuse.

Use a variable rdt_num_resources to replace the define of RDT_NUM_RESOURCES
in the enum to enable tools to catch when a switch() on the resource ID does
not handle all the resources and thus help flag which switch statements need
an update when a new resource is added.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
include/linux/resctrl.h | 11 +++++------
arch/x86/kernel/cpu/resctrl/core.c | 9 ++++++---
2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 006e57fd7ca5..ef2efa2e4b39 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -27,13 +27,15 @@ int proc_resctrl_show(struct seq_file *m,

#endif

+extern int rdt_num_resources;
+
/* max value for struct rdt_domain's mbps_val */
#define MBA_MAX_MBPS U32_MAX

/* Walk all possible resources, with variants for only controls or monitors. */
#define for_each_rdt_resource(_r) \
for ((_r) = resctrl_arch_get_resource(0); \
- (_r) && (_r)->rid < RDT_NUM_RESOURCES; \
+ (_r) && (_r)->rid < rdt_num_resources; \
(_r) = resctrl_arch_get_resource((_r)->rid + 1))

#define for_each_capable_rdt_resource(r) \
@@ -54,9 +56,6 @@ enum resctrl_res_level {
RDT_RESOURCE_MBA,
RDT_RESOURCE_SMBA,
RDT_RESOURCE_PERF_PKG,
-
- /* Must be the last */
- RDT_NUM_RESOURCES,
};

/**
@@ -319,7 +318,7 @@ struct resctrl_mon {
* @cdp_capable: Is the CDP feature available on this resource
*/
struct rdt_resource {
- int rid;
+ enum resctrl_res_level rid;
bool alloc_capable;
bool mon_capable;
enum resctrl_scope ctrl_scope;
@@ -336,7 +335,7 @@ struct rdt_resource {

/*
* Get the resource that exists at this level. If the level is not supported
- * a dummy/not-capable resource can be returned. Levels >= RDT_NUM_RESOURCES
+ * a dummy/not-capable resource can be returned. Levels >= rdt_num_resources
* will return NULL.
*/
struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l);
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index db787c4dee61..2557bb639555 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -16,6 +16,7 @@

#define pr_fmt(fmt) "resctrl: " fmt

+#include <linux/array_size.h>
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/err.h>
@@ -57,7 +58,7 @@ static void mba_wrmsr_amd(struct msr_param *m);
#define ctrl_domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].r_resctrl.ctrl_domains)
#define mon_domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].r_resctrl.mon_domains)

-struct rdt_hw_resource rdt_resources_all[RDT_NUM_RESOURCES] = {
+struct rdt_hw_resource rdt_resources_all[] = {
[RDT_RESOURCE_L3] =
{
.r_resctrl = {
@@ -110,6 +111,8 @@ struct rdt_hw_resource rdt_resources_all[RDT_NUM_RESOURCES] = {
},
};

+int rdt_num_resources = ARRAY_SIZE(rdt_resources_all);
+
/**
* resctrl_arch_system_num_rmid_idx - Compute number of supported RMIDs
* (minimum across all mon_capable resource)
@@ -131,7 +134,7 @@ u32 resctrl_arch_system_num_rmid_idx(void)

struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
{
- if (l >= RDT_NUM_RESOURCES)
+ if (l >= rdt_num_resources)
return NULL;

return &rdt_resources_all[l].r_resctrl;
@@ -1121,7 +1124,7 @@ static int __init resctrl_arch_late_init(void)
int state, ret, i;

/* for_each_rdt_resource() requires all rid to be initialised. */
- for (i = 0; i < RDT_NUM_RESOURCES; i++)
+ for (i = 0; i < rdt_num_resources; i++)
rdt_resources_all[i].r_resctrl.rid = i;

/*
--
2.53.0