diff --git a/doc/configuration.txt b/doc/configuration.txt index c51101389..8eb8db06f 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -2014,6 +2014,17 @@ cpu-policy systems, these can also be used to run auxiliary tools such as load generators and monitoring tools. + - resource this is like group-by-cluster above, except that only + the smallest and most efficient CPU cluster will be + used, while all other ones will be ignored. This can be + used to limit the resource usage to the strict minimum + that still delivers decent performance, for example to + try to further reduce power consumption or minimize the + number of cores needed on some rented systems for a + sidecar setup, in order to scale the system down more + easily. Note that if a single cluster is present, it + will still be fully used. + See also: "cpu-map", "cpu-set", "nbthread" cpu-set ... diff --git a/src/cpu_topo.c b/src/cpu_topo.c index 7611e0ccc..7e07b4781 100644 --- a/src/cpu_topo.c +++ b/src/cpu_topo.c @@ -55,6 +55,7 @@ static int cpu_policy_first_usable_node(int policy, int tmin, int tmax, int gmin static int cpu_policy_group_by_cluster(int policy, int tmin, int tmax, int gmin, int gmax, char **err); static int cpu_policy_performance(int policy, int tmin, int tmax, int gmin, int gmax, char **err); static int cpu_policy_efficiency(int policy, int tmin, int tmax, int gmin, int gmax, char **err); +static int cpu_policy_resource(int policy, int tmin, int tmax, int gmin, int gmax, char **err); static struct ha_cpu_policy ha_cpu_policy[] = { { .name = "none", .desc = "use all available CPUs", .fct = NULL }, @@ -62,6 +63,7 @@ static struct ha_cpu_policy ha_cpu_policy[] = { { .name = "group-by-cluster", .desc = "make one thread group per core cluster", .fct = cpu_policy_group_by_cluster }, { .name = "performance", .desc = "make one thread group per perf. core cluster", .fct = cpu_policy_performance }, { .name = "efficiency", .desc = "make one thread group per eff. core cluster", .fct = cpu_policy_efficiency }, + { .name = "resource", .desc = "make one thread group from the smallest cluster", .fct = cpu_policy_resource }, { 0 } /* end */ }; @@ -1176,6 +1178,43 @@ static int cpu_policy_efficiency(int policy, int tmin, int tmax, int gmin, int g return cpu_policy_group_by_cluster(policy, tmin, tmax, gmin, gmax, err); } + +/* the "resource" cpu-policy: + * - does nothing if nbthread or thread-groups are set + * - only keeps the smallest cluster. + */ +static int cpu_policy_resource(int policy, int tmin, int tmax, int gmin, int gmax, char **err) +{ + int cpu, cluster; + int capa; + + if (global.nbthread || global.nbtgroups) + return 0; + + /* sort clusters by reverse capacity */ + cpu_cluster_reorder_by_capa(ha_cpu_clusters, cpu_topo_maxcpus); + + capa = 0; + for (cluster = cpu_topo_maxcpus - 1; cluster >= 0; cluster--) { + if (capa) { + /* we already have a cluster, let's disable this + * one. + */ + for (cpu = 0; cpu <= cpu_topo_lastcpu; cpu++) { + if (ha_cpu_topo[cpu].cl_gid == ha_cpu_clusters[cluster].idx) + ha_cpu_topo[cpu].st |= HA_CPU_F_IGNORED; + } + } + else + capa = ha_cpu_clusters[cluster].capa; + } + + cpu_cluster_reorder_by_index(ha_cpu_clusters, cpu_topo_maxcpus); + + /* and finish using the group-by-cluster strategy */ + return cpu_policy_group_by_cluster(policy, tmin, tmax, gmin, gmax, err); +} + /* apply the chosen CPU policy if no cpu-map was forced. Returns < 0 on failure * with a message in *err that must be freed by the caller if non-null. */