From: Willy Tarreau Date: Thu, 27 Feb 2025 18:22:34 +0000 (+0100) Subject: MINOR: cpu-topo: assign an L3 cache if more than 2 L2 instances X-Git-Tag: v3.2-dev8~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b633b9d42271fc507f5a669ae1a038f9623ecf45;p=thirdparty%2Fhaproxy.git MINOR: cpu-topo: assign an L3 cache if more than 2 L2 instances On some machines, L3 is not always reported (e.g. on some lx2 or some armada8040). But some also don't have L3 (core 2 quad). However, no L3 when there are more than 2 L2 is quite unheard of, and while we don't really care about firing 2 thread groups for 2 L2, we'd rather avoid doing this if there are 8! In this case we'll declare an L3 instance to fix the situation. This allows small machines to continue to start with two groups while not derivating on large ones. --- diff --git a/src/cpu_topo.c b/src/cpu_topo.c index 374efe923..ffca19ea2 100644 --- a/src/cpu_topo.c +++ b/src/cpu_topo.c @@ -422,7 +422,8 @@ static int cpu_topo_get_maxcpus(void) void cpu_fixup_topology(void) { struct hap_cpuset cpuset; - int cpu; + int cpu, cpu2; + int curr_id, prev_id; int min_id, neg; /* fill the package id, node id and thread_id. First we'll build a bitmap @@ -504,6 +505,49 @@ void cpu_fixup_topology(void) if (ha_cpu_topo[cpu].capa < 0) ha_cpu_topo[cpu].capa = (ha_cpu_topo[cpu].th_cnt > 1) ? 100 : 50; } + + /* First, on some machines, L3 is not reported. But some also don't + * have L3. However, no L3 when there are more than 2 L2 is quite + * unheard of, and while we don't really care about firing 2 groups for + * 2 L2, we'd rather avoid this if there are 8! In this case we'll add + * an L3 instance to fix the situation. + */ + cpu_reorder_by_locality(ha_cpu_topo, cpu_topo_maxcpus); + + prev_id = -2; // make sure it cannot match even unassigned ones + curr_id = -1; + for (cpu = cpu2 = 0; cpu <= cpu_topo_lastcpu; cpu++) { + if (ha_cpu_topo[cpu].ca_id[3] >= 0) + continue; + + /* L3 not assigned, count L2 instances */ + if (!cpu || + (ha_cpu_topo[cpu].pk_id != ha_cpu_topo[cpu-1].pk_id) || + (ha_cpu_topo[cpu].no_id != ha_cpu_topo[cpu-1].no_id) || + (ha_cpu_topo[cpu].ca_id[4] != ha_cpu_topo[cpu-1].ca_id[4])) { + curr_id = 0; + prev_id = -2; + cpu2 = cpu; + } + else if (ha_cpu_topo[cpu].ca_id[2] != prev_id) { + curr_id++; + if (curr_id >= 2) { + /* let's assign L3 id to zero for all those. + * We can go till the end since we'll just skip + * them on next passes above. + */ + for (; cpu2 <= cpu_topo_lastcpu; cpu2++) { + if (ha_cpu_topo[cpu2].ca_id[3] < 0 && + ha_cpu_topo[cpu2].pk_id == ha_cpu_topo[cpu].pk_id && + ha_cpu_topo[cpu2].no_id == ha_cpu_topo[cpu].no_id && + ha_cpu_topo[cpu2].ca_id[4] == ha_cpu_topo[cpu].ca_id[4]) + ha_cpu_topo[cpu2].ca_id[3] = 0; + } + } + } + } + + cpu_reorder_by_index(ha_cpu_topo, cpu_topo_maxcpus); } /* This function is responsible for composing clusters based on existing info