From: Fenghua Yu <fenghuay@nvidia.com>
To: Reinette Chatre <reinette.chatre@intel.com>,
Tony Luck <tony.luck@intel.com>, Ben Horgan <ben.horgan@arm.com>,
James Morse <james.morse@arm.com>,
Dave Martin <Dave.Martin@arm.com>,
Shaopeng Tan <tan.shaopeng@fujitsu.com>,
Chen Yu <yu.c.chen@intel.com>, Babu Moger <babu.moger@amd.com>,
Drew Fustini <fustini@kernel.org>,
Vikram Sethi <vsethi@nvidia.com>,
Shanker Donthineni <sdonthineni@nvidia.com>,
Newton Liu <newtonl@nvidia.com>, Gavin Shan <gshan@redhat.com>
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
Fenghua Yu <fenghuay@nvidia.com>
Subject: [PATCH 05/23] resctrl: Add nested resource_schemata support for emulated controls
Date: Thu, 16 Jul 2026 14:02:55 -0700 [thread overview]
Message-ID: <20260716210329.2914625-5-fenghuay@nvidia.com> (raw)
In-Reply-To: <cover.1784217438.git.fenghuay@nvidia.com>
Some architectures expose an alternate, hardware-native control that
emulates a legacy control (for example a node-scoped bandwidth control
emulating the L3-shaped MB control). Represent this relationship with a
new resctrl_ctrl::emulated_by pointer stored on the emulated (default)
control, pointing at the control that emulates it, and add a
RESCTRL_CTRL_NAME_NODE control name for the node-scoped variant.
Build the resource_schemata tree accordingly: create the default control
directory first, then nest each emulating control beneath the default
control it emulates, while non-emulated controls remain directly under
resource_schemata. Creating the default directory up front makes the
layout independent of the order controls appear in the list.
Architecture backends set emulated_by during control init; until then the
nesting branch is never taken and all controls remain directly under
resource_schemata.
Factor the per-control directory creation into
resctrl_ctrl_create_subdir() and fix its error and ownership handling so
the newly created directory (not its parent) is validated and gets its
uid/gid applied.
Signed-off-by: Fenghua Yu <fenghuay@nvidia.com>
---
arch/x86/kernel/cpu/resctrl/core.c | 2 +
fs/resctrl/ctrlmondata.c | 1 +
fs/resctrl/rdtgroup.c | 67 ++++++++++++++++++++++++------
include/linux/resctrl.h | 7 +++-
4 files changed, 63 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 07c6ebb7fc43..5575a16caeab 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -214,6 +214,8 @@ static __init bool __temporary_multiple_mba_intel_controls(struct rdt_resource *
case RESCTRL_CTRL_NAME_MAX:
hw_ctrl->msr_update = update_temporary_max;
break;
+ default:
+ break;
}
return true;
diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c
index d95ab8ad36e2..1f832a838115 100644
--- a/fs/resctrl/ctrlmondata.c
+++ b/fs/resctrl/ctrlmondata.c
@@ -304,6 +304,7 @@ static const char * const resctrl_ctrl_name[] = {
[RESCTRL_CTRL_NAME_DEF] = "",
[RESCTRL_CTRL_NAME_MIN] = "MIN",
[RESCTRL_CTRL_NAME_MAX] = "MAX",
+ [RESCTRL_CTRL_NAME_NODE] = "NODE",
};
const char *resctrl_ctrl_name_str(enum resctrl_ctrl_name name)
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index a3aad9b1ff6e..3bec23728847 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -2781,6 +2781,26 @@ static int resctrl_ctrl_add_files(struct kernfs_node *kn)
return ret;
}
+static int resctrl_ctrl_create_subdir(struct kernfs_node *kn_dir,
+ struct rdt_resource_final *f,
+ struct resctrl_ctrl *ctrl, struct kernfs_node **kn_ctrl)
+{
+ char ctrl_full_name[20];
+ int ret;
+
+ ret = snprintf(ctrl_full_name, sizeof(ctrl_full_name), "%s%s%s",
+ f->name, resctrl_ctrl_is_default(ctrl) ? "" : "_",
+ resctrl_ctrl_is_default(ctrl) ? "" : resctrl_ctrl_name_str(ctrl->name));
+ if (ret >= sizeof(ctrl_full_name))
+ return -ENOSPC;
+
+ *kn_ctrl = kernfs_create_dir(kn_dir, ctrl_full_name, kn_dir->mode, ctrl);
+ if (IS_ERR(*kn_ctrl))
+ return PTR_ERR(*kn_ctrl);
+
+ return rdtgroup_kn_set_ugid(*kn_ctrl);
+}
+
/*
* No need to cleanup on exit - caller calls the recursive kernfs_remove()
* on failure.
@@ -2788,10 +2808,9 @@ static int resctrl_ctrl_add_files(struct kernfs_node *kn)
static int resctrl_mkdir_schemata_dir(struct kernfs_node *kn,
struct rdt_resource_final *f)
{
- struct kernfs_node *kn_subdir, *kn_ctrl;
+ struct kernfs_node *kn_subdir, *kn_ctrl, *kn_ctrl_def = NULL;
+ struct resctrl_ctrl *ctrl, *ctrl_def = NULL;
struct rdt_resource *r = f->res;
- struct resctrl_ctrl *ctrl;
- char ctrl_full_name[20];
int ret;
kn_subdir = kernfs_create_dir(kn, "resource_schemata", kn->mode, f);
@@ -2808,19 +2827,41 @@ static int resctrl_mkdir_schemata_dir(struct kernfs_node *kn,
return ret;
}
+ /*
+ * Create the default control sub-dir first. Emulated controls are
+ * nested underneath it and may be iterated before it, so it has to
+ * exist before the rest of the controls are created.
+ */
for_each_resource_ctrl(ctrl, f->res) {
- ret = snprintf(ctrl_full_name, sizeof(ctrl_full_name), "%s%s%s",
- f->name, resctrl_ctrl_is_default(ctrl) ? "" : "_",
- resctrl_ctrl_is_default(ctrl) ? "" : resctrl_ctrl_name_str(ctrl->name));
- if (ret >= sizeof(ctrl_full_name))
- return -ENOSPC;
+ if (ctrl->name != RESCTRL_CTRL_NAME_DEF)
+ continue;
- kn_ctrl = kernfs_create_dir(kn_subdir, ctrl_full_name, kn_subdir->mode,
- ctrl);
- if (IS_ERR(kn_ctrl))
- return PTR_ERR(kn_ctrl);
+ ret = resctrl_ctrl_create_subdir(kn_subdir, f, ctrl, &kn_ctrl_def);
+ if (ret)
+ return ret;
+ ret = resctrl_add_ctrl_files(kn_ctrl_def, ctrl);
+ if (ret)
+ return ret;
+ ctrl_def = ctrl;
+ break;
+ }
- ret = rdtgroup_kn_set_ugid(kn_ctrl);
+ for_each_resource_ctrl(ctrl, f->res) {
+ if (ctrl->name == RESCTRL_CTRL_NAME_DEF)
+ continue;
+
+ /*
+ * In legacy mode the emulating control is nested under the
+ * default control it emulates (the default control's
+ * emulated_by points at it). In native mode there is no
+ * emulation, so every control sits directly under
+ * resource_schemata.
+ */
+ if (r->mode == RESCTRL_CTRL_LEGACY &&
+ ctrl_def && ctrl_def->emulated_by == ctrl)
+ ret = resctrl_ctrl_create_subdir(kn_ctrl_def, f, ctrl, &kn_ctrl);
+ else
+ ret = resctrl_ctrl_create_subdir(kn_subdir, f, ctrl, &kn_ctrl);
if (ret)
return ret;
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 5d8ea12ae16b..06482e766087 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -362,12 +362,14 @@ struct resctrl_mon {
* has the same name as the resource.
* @RESCTRL_CTRL_NAME_MIN: "MIN"
* @RESCTRL_CTRL_NAME_MAX: "MAX"
+ * @RESCTRL_CTRL_NAME_NODE: "NODE"
*/
enum resctrl_ctrl_name {
RESCTRL_CTRL_NAME_DEF,
RESCTRL_CTRL_NAME_MIN,
RESCTRL_CTRL_NAME_MAX,
- RESCTRL_CTRL_NAME_LAST = RESCTRL_CTRL_NAME_MAX
+ RESCTRL_CTRL_NAME_NODE,
+ RESCTRL_CTRL_NAME_LAST = RESCTRL_CTRL_NAME_NODE
};
/**
@@ -383,6 +385,8 @@ enum resctrl_ctrl_name {
* Specifically, "rdt_resource_final::name"_"resctrl_ctrl::name".
* For example, with resource name "MB" and control name "MAX" the
* schema entry will be "MB_MAX".
+ * @emulated_by: For an emulated control, points at the control that emulates
+ * it; NULL if this control is not emulated.
* @cache: Cache allocation control properties.
* @membw: Bandwidth control properties.
*/
@@ -392,6 +396,7 @@ struct resctrl_ctrl {
struct list_head domains;
enum resctrl_ctrl_type type;
enum resctrl_ctrl_name name;
+ struct resctrl_ctrl *emulated_by;
union {
struct resctrl_cache cache;
struct resctrl_membw membw;
--
2.43.0
next prev parent reply other threads:[~2026-07-16 21:03 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 21:02 [PATCH RFC 00/23] resctrl: MBA control emulation and ARM MPAM MB_NODE support Fenghua Yu
2026-07-16 21:02 ` [PATCH 01/23] resctrl: Fix ownership of resource_schemata control subdirectories Fenghua Yu
2026-07-16 21:02 ` [PATCH 02/23] arm_mpam: Fix NULL address access issue Fenghua Yu
2026-07-16 21:02 ` [PATCH 03/23] resctrl: Expose MBA resource_schemata mode sysfs Fenghua Yu
2026-07-17 8:54 ` Ben Horgan
2026-07-17 10:13 ` Ben Horgan
2026-07-16 21:02 ` [PATCH 04/23] resctrl: Expose per-control status in resource_schemata Fenghua Yu
2026-07-16 21:02 ` Fenghua Yu [this message]
2026-07-16 21:02 ` [PATCH 06/23] resctrl: Mirror schemata for controls without MBW hardware Fenghua Yu
2026-07-16 21:02 ` [PATCH 07/23] resctrl: Rebuild resource_schemata subdirs on MBA mode change Fenghua Yu
2026-07-16 21:02 ` [PATCH 08/23] Documentation: resctrl: document MBA control emulation Fenghua Yu
2026-07-16 21:02 ` [PATCH 09/23] resctrl: De-hardcode L3 monitor infrastructure Fenghua Yu
2026-07-16 21:03 ` [PATCH 10/23] resctrl: Expose MBA MBM counter assignment sysfs Fenghua Yu
2026-07-16 21:03 ` [PATCH 11/23] resctrl: name node-scoped monitor domains mon_NODE_<id> Fenghua Yu
2026-07-16 21:03 ` [PATCH 12/23] resctrl: Add node-scope MBM total event Fenghua Yu
2026-07-16 21:03 ` [PATCH 13/23] resctrl: Make MBM paths resource-aware Fenghua Yu
2026-07-16 21:03 ` [PATCH 14/23] arm_mpam: Support memory-level MSCs and ABMC per class Fenghua Yu
2026-07-16 21:03 ` [PATCH 15/23] arm_mpam: Refine L3 topology and class selection Fenghua Yu
2026-07-17 9:18 ` Ben Horgan
2026-07-16 21:03 ` [PATCH 16/23] arm_mpam: Include all MSC components during domain setup Fenghua Yu
2026-07-16 21:03 ` [PATCH 17/23] arm_mpam: Handle CPU-less numa nodes Fenghua Yu
2026-07-16 21:03 ` [PATCH 18/23] arm_mpam: Emulate MB control with node-scoped MB_NODE control Fenghua Yu
2026-07-16 21:03 ` [PATCH 19/23] Documentation: arm64: mpam: document memory-level MB control and NUMA nodes Fenghua Yu
2026-07-16 21:03 ` [PATCH 20/23] Documentation: resctrl: document NODE-scoped MBA domains and mon_NODE monitoring Fenghua Yu
2026-07-16 21:03 ` [PATCH 21/23] Documentation: resctrl: document MB_NODE emulation example on ARM MPAM Fenghua Yu
2026-07-16 21:03 ` [PATCH 22/23] arm_mpam: Add KUnit test for CPU-less NUMA node affinity Fenghua Yu
2026-07-16 21:03 ` [PATCH 23/23] selftests/resctrl: Add MB emulation test for ARM MPAM Fenghua Yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260716210329.2914625-5-fenghuay@nvidia.com \
--to=fenghuay@nvidia.com \
--cc=Dave.Martin@arm.com \
--cc=babu.moger@amd.com \
--cc=ben.horgan@arm.com \
--cc=fustini@kernel.org \
--cc=gshan@redhat.com \
--cc=james.morse@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=newtonl@nvidia.com \
--cc=reinette.chatre@intel.com \
--cc=sdonthineni@nvidia.com \
--cc=tan.shaopeng@fujitsu.com \
--cc=tony.luck@intel.com \
--cc=vsethi@nvidia.com \
--cc=yu.c.chen@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.