Hi Tony, On 8/29/23 18:44, Tony Luck wrote: > There isn't a simple h/w bit that indicates whether a CPU is > running in Sub NUMA Cluster mode. Infer the state by comparing > the ratio of NUMA nodes to L3 cache instances. > > When SNC mode is detected, reconfigure the RMID counters by updating > the MSR_RMID_SNC_CONFIG MSR on each socket as CPUs are seen. > > Signed-off-by: Tony Luck <tony.luck@xxxxxxxxx> > --- > arch/x86/include/asm/msr-index.h | 1 + > arch/x86/kernel/cpu/resctrl/core.c | 68 ++++++++++++++++++++++++++++++ > 2 files changed, 69 insertions(+) > > diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h > index 1d111350197f..393d1b047617 100644 > --- a/arch/x86/include/asm/msr-index.h > +++ b/arch/x86/include/asm/msr-index.h > @@ -1100,6 +1100,7 @@ > #define MSR_IA32_QM_CTR 0xc8e > #define MSR_IA32_PQR_ASSOC 0xc8f > #define MSR_IA32_L3_CBM_BASE 0xc90 > +#define MSR_RMID_SNC_CONFIG 0xca0 > #define MSR_IA32_L2_CBM_BASE 0xd10 > #define MSR_IA32_MBA_THRTL_BASE 0xd50 > > diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c > index ed4f55b3e5e4..9f0ac9721fab 100644 > --- a/arch/x86/kernel/cpu/resctrl/core.c > +++ b/arch/x86/kernel/cpu/resctrl/core.c > @@ -16,11 +16,14 @@ > > #define pr_fmt(fmt) "resctrl: " fmt > > +#include <linux/cpu.h> > #include <linux/slab.h> > #include <linux/err.h> > #include <linux/cacheinfo.h> > #include <linux/cpuhotplug.h> > +#include <linux/mod_devicetable.h> I didnt see the need for this include. > > +#include <asm/cpu_device_id.h> > #include <asm/intel-family.h> > #include <asm/resctrl.h> > #include "internal.h" > @@ -724,11 +727,34 @@ static void clear_closid_rmid(int cpu) > wrmsr(MSR_IA32_PQR_ASSOC, 0, 0); > } > > +/* > + * The power-on reset value of MSR_RMID_SNC_CONFIG is 0x1 > + * which indicates that RMIDs are configured in legacy mode. > + * Clearing bit 0 reconfigures the RMID counters for use > + * in Sub NUMA Cluster mode. > + */ > +static void snc_remap_rmids(int cpu) While adding the new functions, i see that new function names start with resctrl_ prefix. However, we are all not very consistent. Can ypu rename this function to resctrl_snc_remap_rmids? > +{ > + u64 val; > + > + /* Only need to enable once per package */ > + if (cpumask_first(topology_core_cpumask(cpu)) != cpu) > + return; > + > + rdmsrl(MSR_RMID_SNC_CONFIG, val); > + val &= ~BIT_ULL(0); > + wrmsrl(MSR_RMID_SNC_CONFIG, val); > +} > + > static int resctrl_online_cpu(unsigned int cpu) > { > struct rdt_resource *r; > > mutex_lock(&rdtgroup_mutex); > + > + if (snc_nodes_per_l3_cache > 1) > + snc_remap_rmids(cpu); > + > for_each_capable_rdt_resource(r) > domain_add_cpu(cpu, r); > /* The cpu is set in default rdtgroup after online. */ > @@ -983,11 +1009,53 @@ static __init bool get_rdt_resources(void) > return (rdt_mon_capable || rdt_alloc_capable); > } > > +/* CPU models that support MSR_RMID_SNC_CONFIG */ > +static const struct x86_cpu_id snc_cpu_ids[] __initconst = { > + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, 0), > + X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 0), > + X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, 0), > + {} > +}; > + > +static __init int get_snc_config(void) Same comment as above. > +{ > + unsigned long *node_caches; > + int mem_only_nodes = 0; > + int cpu, node, ret; > + > + if (!x86_match_cpu(snc_cpu_ids)) > + return 1; > + > + node_caches = kcalloc(BITS_TO_LONGS(nr_node_ids), sizeof(*node_caches), GFP_KERNEL); > + if (!node_caches) > + return 1; > + > + cpus_read_lock(); > + for_each_node(node) { > + cpu = cpumask_first(cpumask_of_node(node)); > + if (cpu < nr_cpu_ids) > + set_bit(get_cpu_cacheinfo_id(cpu, 3), node_caches); > + else > + mem_only_nodes++; > + } > + cpus_read_unlock(); > + > + ret = (nr_node_ids - mem_only_nodes) / bitmap_weight(node_caches, nr_node_ids); > + kfree(node_caches); > + > + if (ret > 1) > + rdt_resources_all[RDT_RESOURCE_L3].r_resctrl.mon_scope = RESCTRL_NODE; > + > + return ret; > +} > + > static __init void rdt_init_res_defs_intel(void) > { > struct rdt_hw_resource *hw_res; > struct rdt_resource *r; > > + snc_nodes_per_l3_cache = get_snc_config(); > + > for_each_rdt_resource(r) { > hw_res = resctrl_to_arch_res(r); > -- Thanks Babu Moger