[PATCH RFC v2 13/19] resctrl: Add mbm_assign_scope_mode for native assignment file names
flat view
COLD31d
From: Fenghua Yu <fenghuay@nvidia.com>
Date: 2026-08-31 17:23:45
Also in:
lkml
Subsystem:
filesystems (vfs and infrastructure), rdt - resource allocation, the rest · Maintainers:
Alexander Viro, Christian Brauner, Tony Luck, Reinette Chatre, Linus Torvalds
On platforms whose MBM counters are backed by NUMA node MSCs, mbm_NODE_assignments is the native assignment file. User space that already programs mbm_L3_assignments needs a compatible default. Add info/MB_MON/mbm_assign_scope_mode. Legacy (default) always exposes mbm_L3_assignments; that file still programs node-scoped counters when node MSCs provide MBM. Native mode replaces it with mbm_NODE_assignments on those platforms. Signed-off-by: Fenghua Yu <fenghuay@nvidia.com> --- fs/resctrl/internal.h | 9 +++ fs/resctrl/monitor.c | 147 +++++++++++++++++++++++++++++++++++++--- fs/resctrl/rdtgroup.c | 9 +++ include/linux/resctrl.h | 6 ++ 4 files changed, 162 insertions(+), 9 deletions(-)
diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h
index 32c7d53790ec..f46d4fb7c624 100644
--- a/fs/resctrl/internal.h
+++ b/fs/resctrl/internal.h@@ -457,6 +457,15 @@ int mbm_L3_assignments_show(struct kernfs_open_file *of, struct seq_file *s, voi ssize_t mbm_L3_assignments_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off); + +int resctrl_mbm_assign_scope_mode_show(struct kernfs_open_file *of, struct seq_file *s, + void *v); + +ssize_t resctrl_mbm_assign_scope_mode_write(struct kernfs_open_file *of, char *buf, + size_t nbytes, loff_t off); + +void resctrl_mbm_assign_files_apply(struct kernfs_node *kn); + int resctrl_io_alloc_show(struct kernfs_open_file *of, struct seq_file *seq, void *v); int rdtgroup_init_cat(struct rdt_resource_final *f, struct resctrl_ctrl *ctrl,
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index d555f2d19164..074dc2a040dc 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c@@ -18,6 +18,7 @@ #define pr_fmt(fmt) "resctrl: " fmt #include <linux/cpu.h> +#include <linux/kernfs.h> #include <linux/resctrl.h> #include <linux/sizes.h> #include <linux/slab.h>
@@ -1704,6 +1705,130 @@ int resctrl_available_mbm_cntrs_show(struct kernfs_open_file *of, return ret; } +static bool resctrl_mbm_has_node_mscs(void) +{ + struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_MBA); + + return r->mon_capable && r->mon_scope == RESCTRL_NODE; +} + +static bool resctrl_mbm_show_l3_assignments(void) +{ + return !resctrl_arch_get_resource(RDT_RESOURCE_MBA)->mon.mbm_assign_scope_native || + !resctrl_mbm_has_node_mscs(); +} + +static bool resctrl_mbm_show_node_assignments(void) +{ + return resctrl_arch_get_resource(RDT_RESOURCE_MBA)->mon.mbm_assign_scope_native && + resctrl_mbm_has_node_mscs(); +} + +static struct rdt_resource *mbm_l3_assignments_resource(void) +{ + if (resctrl_mbm_has_node_mscs()) + return resctrl_arch_get_resource(RDT_RESOURCE_MBA); + + return resctrl_arch_get_resource(RDT_RESOURCE_L3); +} + +static void resctrl_mbm_assign_file_show(struct kernfs_node *parent, const char *name, + bool show) +{ + struct kernfs_node *kn; + + kn = kernfs_find_and_get(parent, name); + if (!kn) + return; + + kernfs_show(kn, show); + kernfs_put(kn); +} + +void resctrl_mbm_assign_files_apply(struct kernfs_node *kn) +{ + if (!kn) + return; + + resctrl_mbm_assign_file_show(kn, "mbm_L3_assignments", + resctrl_mbm_show_l3_assignments()); + resctrl_mbm_assign_file_show(kn, "mbm_NODE_assignments", + resctrl_mbm_show_node_assignments()); +} + +static void resctrl_mbm_assign_files_apply_all(void) +{ + struct rdtgroup *prgrp, *crgrp; + + lockdep_assert_held(&rdtgroup_mutex); + + list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { + resctrl_mbm_assign_files_apply(prgrp->kn); + list_for_each_entry(crgrp, &prgrp->mon.crdtgrp_list, mon.crdtgrp_list) + resctrl_mbm_assign_files_apply(crgrp->kn); + } +} + +int resctrl_mbm_assign_scope_mode_show(struct kernfs_open_file *of, + struct seq_file *s, void *v) +{ + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); + + if (!info_kn_lock(of->kn)) + return -ENOENT; + + if (r->mon.mbm_assign_scope_native) + seq_puts(s, "legacy [native]\n"); + else + seq_puts(s, "[legacy] native\n"); + + info_kn_unlock(of->kn); + + return 0; +} + +ssize_t resctrl_mbm_assign_scope_mode_write(struct kernfs_open_file *of, char *buf, + size_t nbytes, loff_t off) +{ + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); + bool native; + int ret = 0; + + if (!info_kn_lock(of->kn)) + return -ENOENT; + + rdt_last_cmd_clear(); + + /* Valid input requires a trailing newline */ + if (nbytes == 0 || buf[nbytes - 1] != '\n') { + rdt_last_cmd_puts("mbm_assign_scope_mode: Invalid input\n"); + ret = -EINVAL; + goto out_unlock; + } + + buf[nbytes - 1] = '\0'; + + if (!strcmp(buf, "legacy")) { + native = false; + } else if (!strcmp(buf, "native")) { + native = true; + } else { + rdt_last_cmd_puts("Unsupported assign scope mode\n"); + ret = -EINVAL; + goto out_unlock; + } + + if (r->mon.mbm_assign_scope_native != native) { + r->mon.mbm_assign_scope_native = native; + resctrl_mbm_assign_files_apply_all(); + } + +out_unlock: + info_kn_unlock(of->kn); + + return ret ?: nbytes; +} + static int mbm_assignments_show(struct kernfs_open_file *of, struct seq_file *s, void *v, struct rdt_resource *r) {
@@ -1753,8 +1878,7 @@ static int mbm_assignments_show(struct kernfs_open_file *of, struct seq_file *s, int mbm_L3_assignments_show(struct kernfs_open_file *of, struct seq_file *s, void *v) { - return mbm_assignments_show(of, s, v, - resctrl_arch_get_resource(RDT_RESOURCE_L3)); + return mbm_assignments_show(of, s, v, mbm_l3_assignments_resource()); } int mbm_NODE_assignments_show(struct kernfs_open_file *of, struct seq_file *s, void *v)
@@ -1873,7 +1997,7 @@ static ssize_t mbm_assignments_write(struct kernfs_open_file *of, char *buf, /* Valid input requires a trailing newline */ if (nbytes == 0 || buf[nbytes - 1] != '\n') { - rdt_last_cmd_puts("mbm_L3_assignments: Invalid input\n"); + rdt_last_cmd_puts("mbm assignments: Invalid input\n"); ret = -EINVAL; goto out_unlock; }
@@ -1909,14 +2033,14 @@ ssize_t mbm_L3_assignments_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { return mbm_assignments_write(of, buf, nbytes, off, - resctrl_arch_get_resource(RDT_RESOURCE_L3)); + mbm_l3_assignments_resource()); } ssize_t mbm_NODE_assignments_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { return mbm_assignments_write(of, buf, nbytes, off, - resctrl_arch_get_resource(RDT_RESOURCE_MBA)); + resctrl_arch_get_resource(RDT_RESOURCE_MBA)); } static int closid_num_dirty_rmid_alloc(struct rdt_resource *r)
@@ -2012,10 +2136,15 @@ static void resctrl_mon_resource_init(struct rdt_resource *r) resctrl_file_mode_init("event_filter", 0644); resctrl_file_fflags_init("mbm_assign_on_mkdir", RFTYPE_MON_INFO | fflags); - if (r->rid == RDT_RESOURCE_MBA) - resctrl_file_fflags_init("mbm_NODE_assignments", RFTYPE_MON_BASE); - else - resctrl_file_fflags_init("mbm_L3_assignments", RFTYPE_MON_BASE); + resctrl_file_fflags_init("mbm_L3_assignments", RFTYPE_MON_BASE); + if (r->rid == RDT_RESOURCE_MBA) { + r->mon.mbm_assign_scope_native = false; + resctrl_file_fflags_init("mbm_assign_scope_mode", + RFTYPE_MON_INFO | RFTYPE_RES_MB); + if (r->mon_scope == RESCTRL_NODE) + resctrl_file_fflags_init("mbm_NODE_assignments", + RFTYPE_MON_BASE); + } resctrl_file_fflags_init("mbm_assign_mode", RFTYPE_MON_INFO | fflags); }
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index a16e35b587c4..1547306dc8d6 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c@@ -2316,6 +2316,13 @@ static struct rftype res_common_files[] = { .seq_show = mbm_NODE_assignments_show, .write = mbm_NODE_assignments_write, }, + { + .name = "mbm_assign_scope_mode", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = resctrl_mbm_assign_scope_mode_show, + .write = resctrl_mbm_assign_scope_mode_write, + }, { .name = "mbm_assign_mode", .mode = 0644,
@@ -2653,6 +2660,8 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags) } } + resctrl_mbm_assign_files_apply(kn); + return 0; error: pr_warn("Failed to add %s, err=%d\n", rft->name, ret);
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index b8df7489539f..141e2ff594f9 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h@@ -380,6 +380,11 @@ enum resctrl_ctrl_type { * events of monitor groups created via mkdir. * @mbm_cntr_configurable: True if assignable counters are configurable. * @mbm_cntr_assign_fixed: True if the counter assignment mode is fixed. + * @mbm_assign_scope_native: True if assignment files use native names. + * Legacy mode always exposes "mbm_L3_assignments". + * Native mode exposes "mbm_NODE_assignments" when + * NUMA node MSCs are present, otherwise + * "mbm_L3_assignments". */ struct resctrl_mon { u32 num_rmid;
@@ -389,6 +394,7 @@ struct resctrl_mon { bool mbm_assign_on_mkdir; bool mbm_cntr_configurable; bool mbm_cntr_assign_fixed; + bool mbm_assign_scope_native; }; /**
--
2.53.0