MINOR: cpu-topo: add "only-cluster" and "drop-cluster" to cpu-set

These are processed after the topology is detected, and they allow to
restrict binding to or evict CPUs matching the indicated hardware
cluster number(s). It can be used to bind to only some clusters, such
as CCX or different energy efficiency cores. For this reason, here we
use the cluster's local ID (local to the node).
This commit is contained in:
Willy Tarreau 2025-02-27 11:54:06 +01:00
parent a946cfa8b5
commit 9a8e8af11a
2 changed files with 32 additions and 1 deletions

View File

@ -1957,6 +1957,8 @@ cpu-set <directive>...
- only-cpu <set> do not bind to CPUs not in this set - only-cpu <set> do not bind to CPUs not in this set
- drop-node <set> do not bind to CPUs belonging to this NUMA node - drop-node <set> do not bind to CPUs belonging to this NUMA node
- only-node <set> do not bind to CPUs not belonging to this NUMA node - only-node <set> do not bind to CPUs not belonging to this NUMA node
- drop-cluster <set> do not bind to CPUs on this hardware cluster number
- only-cluster <set> do not bind to CPUs on other hardware cluster number
- drop-core <set> do not bind to CPUs on this hardware core number - drop-core <set> do not bind to CPUs on this hardware core number
- only-core <set> do not bind to CPUs on other hardware core number - only-core <set> do not bind to CPUs on other hardware core number
- drop-thread <set> do not bind to CPUs on this hardware thread number - drop-thread <set> do not bind to CPUs on this hardware thread number

View File

@ -35,6 +35,9 @@ struct cpu_set_cfg {
/* node numbers to accept / reject */ /* node numbers to accept / reject */
struct hap_cpuset only_nodes; struct hap_cpuset only_nodes;
struct hap_cpuset drop_nodes; struct hap_cpuset drop_nodes;
/* cluster numbers to accept / reject */
struct hap_cpuset only_clusters;
struct hap_cpuset drop_clusters;
/* core numbers to accept / reject */ /* core numbers to accept / reject */
struct hap_cpuset only_cores; struct hap_cpuset only_cores;
struct hap_cpuset drop_cores; struct hap_cpuset drop_cores;
@ -847,6 +850,13 @@ void cpu_refine_cpusets(void)
ha_cpu_topo[cpu].st |= HA_CPU_F_DONT_USE; ha_cpu_topo[cpu].st |= HA_CPU_F_DONT_USE;
} }
/* remove CPUs in the drop-cluster set or not in the only-cluster set */
for (cpu = 0; cpu <= cpu_topo_lastcpu; cpu++) {
if ( ha_cpuset_isset(&cpu_set_cfg.drop_clusters, ha_cpu_topo[cpu].cl_lid) ||
!ha_cpuset_isset(&cpu_set_cfg.only_clusters, ha_cpu_topo[cpu].cl_lid))
ha_cpu_topo[cpu].st |= HA_CPU_F_DONT_USE;
}
/* remove CPUs in the drop-core set or not in the only-core set */ /* remove CPUs in the drop-core set or not in the only-core set */
for (cpu = 0; cpu <= cpu_topo_lastcpu; cpu++) { for (cpu = 0; cpu <= cpu_topo_lastcpu; cpu++) {
if ( ha_cpuset_isset(&cpu_set_cfg.drop_cores, ha_cpu_topo[cpu].ts_id) || if ( ha_cpuset_isset(&cpu_set_cfg.drop_cores, ha_cpu_topo[cpu].ts_id) ||
@ -1243,6 +1253,22 @@ static int cfg_parse_cpu_set(char **args, int section_type, struct proxy *curpx,
ha_cpuset_and(&cpu_set_cfg.only_nodes, &tmp_cpuset); ha_cpuset_and(&cpu_set_cfg.only_nodes, &tmp_cpuset);
arg++; arg++;
} }
else if (strcmp(args[arg], "drop-cluster") == 0 || strcmp(args[arg], "only-cluster") == 0) {
if (!*args[arg + 1]) {
memprintf(err, "missing cluster set");
goto parse_err;
}
cpu_set_str[0] = args[arg + 1];
if (parse_cpu_set(cpu_set_str, &tmp_cpuset, err) != 0)
goto parse_err;
if (*args[arg] == 'd') // clusters to drop
ha_cpuset_or(&cpu_set_cfg.drop_clusters, &tmp_cpuset);
else // clusters to keep
ha_cpuset_and(&cpu_set_cfg.only_clusters, &tmp_cpuset);
arg++;
}
else if (strcmp(args[arg], "drop-core") == 0 || strcmp(args[arg], "only-core") == 0) { else if (strcmp(args[arg], "drop-core") == 0 || strcmp(args[arg], "only-core") == 0) {
if (!*args[arg + 1]) { if (!*args[arg + 1]) {
memprintf(err, "missing core set"); memprintf(err, "missing core set");
@ -1299,7 +1325,7 @@ static int cfg_parse_cpu_set(char **args, int section_type, struct proxy *curpx,
leave_with_err: leave_with_err:
/* complete with supported directives */ /* complete with supported directives */
memprintf(err, "%s (only 'reset', 'only-cpu', 'drop-cpu', 'only-node', 'drop-node', 'only-core', 'drop-core', 'only-thread', 'drop-thread' supported).", *err); memprintf(err, "%s (only 'reset', 'only-cpu', 'drop-cpu', 'only-node', 'drop-node', 'only-cluster', 'drop-cluster', 'only-core', 'drop-core', 'only-thread', 'drop-thread' supported).", *err);
leave: leave:
return -1; return -1;
} }
@ -1346,6 +1372,8 @@ static int cpu_topo_alloc(void)
ha_cpuset_zero(&cpu_set_cfg.only_cpus); ha_cpuset_zero(&cpu_set_cfg.only_cpus);
ha_cpuset_zero(&cpu_set_cfg.drop_nodes); ha_cpuset_zero(&cpu_set_cfg.drop_nodes);
ha_cpuset_zero(&cpu_set_cfg.only_nodes); ha_cpuset_zero(&cpu_set_cfg.only_nodes);
ha_cpuset_zero(&cpu_set_cfg.drop_clusters);
ha_cpuset_zero(&cpu_set_cfg.only_clusters);
ha_cpuset_zero(&cpu_set_cfg.drop_cores); ha_cpuset_zero(&cpu_set_cfg.drop_cores);
ha_cpuset_zero(&cpu_set_cfg.only_cores); ha_cpuset_zero(&cpu_set_cfg.only_cores);
ha_cpuset_zero(&cpu_set_cfg.drop_threads); ha_cpuset_zero(&cpu_set_cfg.drop_threads);
@ -1355,6 +1383,7 @@ static int cpu_topo_alloc(void)
for (cpu = 0; cpu < cpu_topo_maxcpus; cpu++) { for (cpu = 0; cpu < cpu_topo_maxcpus; cpu++) {
ha_cpuset_set(&cpu_set_cfg.only_cpus, cpu); ha_cpuset_set(&cpu_set_cfg.only_cpus, cpu);
ha_cpuset_set(&cpu_set_cfg.only_nodes, cpu); ha_cpuset_set(&cpu_set_cfg.only_nodes, cpu);
ha_cpuset_set(&cpu_set_cfg.only_clusters, cpu);
ha_cpuset_set(&cpu_set_cfg.only_cores, cpu); ha_cpuset_set(&cpu_set_cfg.only_cores, cpu);
ha_cpuset_set(&cpu_set_cfg.only_threads, cpu); ha_cpuset_set(&cpu_set_cfg.only_threads, cpu);
} }