Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 1348815

Browse files
aeglbp3tk0v
authored andcommitted
x86/resctrl: Detect Sub-NUMA Cluster (SNC) mode
There isn't a simple hardware bit that indicates whether a CPU is running in Sub-NUMA Cluster (SNC) mode. Infer the state by comparing the number of CPUs sharing the L3 cache with CPU0 to the number of CPUs in the same NUMA node as CPU0. Add the missing definition of pr_fmt() to monitor.c. This wasn't noticed before as there are only "can't happen" console messages from this file. [ bp: Massage commit message. ] Signed-off-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Tested-by: Babu Moger <babu.moger@amd.com> Link: https://lore.kernel.org/r/20240628215619.76401-19-tony.luck@intel.com
1 parent 21b362c commit 1348815

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

arch/x86/kernel/cpu/resctrl/monitor.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* Software Developer Manual June 2016, volume 3, section 17.17.
1616
*/
1717

18+
#define pr_fmt(fmt) "resctrl: " fmt
19+
1820
#include <linux/cpu.h>
1921
#include <linux/module.h>
2022
#include <linux/sizes.h>
@@ -1110,13 +1112,77 @@ void arch_mon_domain_online(struct rdt_resource *r, struct rdt_mon_domain *d)
11101112
msr_clear_bit(MSR_RMID_SNC_CONFIG, 0);
11111113
}
11121114

1115+
/* CPU models that support MSR_RMID_SNC_CONFIG */
1116+
static const struct x86_cpu_id snc_cpu_ids[] __initconst = {
1117+
X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
1118+
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0),
1119+
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, 0),
1120+
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, 0),
1121+
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, 0),
1122+
{}
1123+
};
1124+
1125+
/*
1126+
* There isn't a simple hardware bit that indicates whether a CPU is running
1127+
* in Sub-NUMA Cluster (SNC) mode. Infer the state by comparing the
1128+
* number of CPUs sharing the L3 cache with CPU0 to the number of CPUs in
1129+
* the same NUMA node as CPU0.
1130+
* It is not possible to accurately determine SNC state if the system is
1131+
* booted with a maxcpus=N parameter. That distorts the ratio of SNC nodes
1132+
* to L3 caches. It will be OK if system is booted with hyperthreading
1133+
* disabled (since this doesn't affect the ratio).
1134+
*/
1135+
static __init int snc_get_config(void)
1136+
{
1137+
struct cacheinfo *ci = get_cpu_cacheinfo_level(0, RESCTRL_L3_CACHE);
1138+
const cpumask_t *node0_cpumask;
1139+
int cpus_per_node, cpus_per_l3;
1140+
int ret;
1141+
1142+
if (!x86_match_cpu(snc_cpu_ids) || !ci)
1143+
return 1;
1144+
1145+
cpus_read_lock();
1146+
if (num_online_cpus() != num_present_cpus())
1147+
pr_warn("Some CPUs offline, SNC detection may be incorrect\n");
1148+
cpus_read_unlock();
1149+
1150+
node0_cpumask = cpumask_of_node(cpu_to_node(0));
1151+
1152+
cpus_per_node = cpumask_weight(node0_cpumask);
1153+
cpus_per_l3 = cpumask_weight(&ci->shared_cpu_map);
1154+
1155+
if (!cpus_per_node || !cpus_per_l3)
1156+
return 1;
1157+
1158+
ret = cpus_per_l3 / cpus_per_node;
1159+
1160+
/* sanity check: Only valid results are 1, 2, 3, 4 */
1161+
switch (ret) {
1162+
case 1:
1163+
break;
1164+
case 2 ... 4:
1165+
pr_info("Sub-NUMA Cluster mode detected with %d nodes per L3 cache\n", ret);
1166+
rdt_resources_all[RDT_RESOURCE_L3].r_resctrl.mon_scope = RESCTRL_L3_NODE;
1167+
break;
1168+
default:
1169+
pr_warn("Ignore improbable SNC node count %d\n", ret);
1170+
ret = 1;
1171+
break;
1172+
}
1173+
1174+
return ret;
1175+
}
1176+
11131177
int __init rdt_get_mon_l3_config(struct rdt_resource *r)
11141178
{
11151179
unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset;
11161180
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
11171181
unsigned int threshold;
11181182
int ret;
11191183

1184+
snc_nodes_per_l3_cache = snc_get_config();
1185+
11201186
resctrl_rmid_realloc_limit = boot_cpu_data.x86_cache_size * 1024;
11211187
hw_res->mon_scale = boot_cpu_data.x86_cache_occ_scale / snc_nodes_per_l3_cache;
11221188
r->num_rmid = (boot_cpu_data.x86_cache_max_rmid + 1) / snc_nodes_per_l3_cache;

0 commit comments

Comments
 (0)