mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 14:43:16 +00:00
tools/power/turbostat: Handle cgroup v2 cpu limitation
CPUs can be isolated via cgroup settings and turbostat should avoid migrating to these CPUs, just like it does for the '-c' cpus. Introduce cpu_effective_set to save the cgroup cpu limitation info from /sys/fs/cgroup/cpuset.cpus.effective. And use cpu_allowed_set as the intersection of cpu_present_set, cpu_effective_set and cpu_subset. Signed-off-by: Zhang Rui <rui.zhang@intel.com>
This commit is contained in:
parent
8c3dd2c9e5
commit
f638858da0
@ -904,8 +904,8 @@ int backwards_count;
|
||||
char *progname;
|
||||
|
||||
#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
|
||||
cpu_set_t *cpu_present_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
|
||||
size_t cpu_present_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
|
||||
cpu_set_t *cpu_present_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
|
||||
size_t cpu_present_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
|
||||
#define MAX_ADDED_COUNTERS 8
|
||||
#define MAX_ADDED_THREAD_COUNTERS 24
|
||||
#define BITMASK_SIZE 32
|
||||
@ -3419,6 +3419,10 @@ void free_all_buffers(void)
|
||||
cpu_present_set = NULL;
|
||||
cpu_present_setsize = 0;
|
||||
|
||||
CPU_FREE(cpu_effective_set);
|
||||
cpu_effective_set = NULL;
|
||||
cpu_effective_setsize = 0;
|
||||
|
||||
CPU_FREE(cpu_allowed_set);
|
||||
cpu_allowed_set = NULL;
|
||||
cpu_allowed_setsize = 0;
|
||||
@ -3741,6 +3745,46 @@ int for_all_proc_cpus(int (func) (int))
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PATH_EFFECTIVE_CPUS "/sys/fs/cgroup/cpuset.cpus.effective"
|
||||
|
||||
static char cpu_effective_str[1024];
|
||||
|
||||
static int update_effective_str(bool startup)
|
||||
{
|
||||
FILE *fp;
|
||||
char *pos;
|
||||
char buf[1024];
|
||||
int ret;
|
||||
|
||||
if (cpu_effective_str[0] == '\0' && !startup)
|
||||
return 0;
|
||||
|
||||
fp = fopen(PATH_EFFECTIVE_CPUS, "r");
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
pos = fgets(buf, 1024, fp);
|
||||
if (!pos)
|
||||
err(1, "%s: file read failed\n", PATH_EFFECTIVE_CPUS);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
ret = strncmp(cpu_effective_str, buf, 1024);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
strncpy(cpu_effective_str, buf, 1024);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void update_effective_set(bool startup)
|
||||
{
|
||||
update_effective_str(startup);
|
||||
|
||||
if (parse_cpu_str(cpu_effective_str, cpu_effective_set, cpu_effective_setsize))
|
||||
err(1, "%s: cpu str malformat %s\n", PATH_EFFECTIVE_CPUS, cpu_effective_str);
|
||||
}
|
||||
|
||||
void re_initialize(void)
|
||||
{
|
||||
free_all_buffers();
|
||||
@ -4257,6 +4301,10 @@ restart:
|
||||
re_initialize();
|
||||
goto restart;
|
||||
}
|
||||
if (update_effective_str(false)) {
|
||||
re_initialize();
|
||||
goto restart;
|
||||
}
|
||||
do_sleep();
|
||||
if (snapshot_proc_sysfs_files())
|
||||
goto restart;
|
||||
@ -5777,6 +5825,16 @@ void topology_probe(bool startup)
|
||||
CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
|
||||
for_all_proc_cpus(mark_cpu_present);
|
||||
|
||||
/*
|
||||
* Allocate and initialize cpu_effective_set
|
||||
*/
|
||||
cpu_effective_set = CPU_ALLOC((topo.max_cpu_num + 1));
|
||||
if (cpu_effective_set == NULL)
|
||||
err(3, "CPU_ALLOC");
|
||||
cpu_effective_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
|
||||
CPU_ZERO_S(cpu_effective_setsize, cpu_effective_set);
|
||||
update_effective_set(startup);
|
||||
|
||||
/*
|
||||
* Allocate and initialize cpu_allowed_set
|
||||
*/
|
||||
@ -5787,30 +5845,37 @@ void topology_probe(bool startup)
|
||||
CPU_ZERO_S(cpu_allowed_setsize, cpu_allowed_set);
|
||||
|
||||
/*
|
||||
* Validate cpu_subset and update cpu_allowed_set.
|
||||
* Validate and update cpu_allowed_set.
|
||||
*
|
||||
* Make sure all cpus in cpu_subset are also in cpu_present_set during startup,
|
||||
* and give a warning when cpus in cpu_subset become unavailable at runtime.
|
||||
* Make sure all cpus in cpu_subset are also in cpu_present_set during startup.
|
||||
* Give a warning when cpus in cpu_subset become unavailable at runtime.
|
||||
* Give a warning when cpus are not effective because of cgroup setting.
|
||||
*
|
||||
* cpu_allowed_set is the intersection of cpu_present_set and cpu_subset.
|
||||
* cpu_allowed_set is the intersection of cpu_present_set/cpu_effective_set/cpu_subset.
|
||||
*/
|
||||
for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
|
||||
if (!cpu_subset) {
|
||||
if (CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set))
|
||||
CPU_SET_S(i, cpu_allowed_setsize, cpu_allowed_set);
|
||||
if (cpu_subset && !CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
|
||||
continue;
|
||||
}
|
||||
if (CPU_ISSET_S(i, cpu_subset_size, cpu_subset)) {
|
||||
if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set)) {
|
||||
/* all cpus in cpu_subset must be in cpu_present_set during startup */
|
||||
|
||||
if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set)) {
|
||||
if (cpu_subset) {
|
||||
/* cpus in cpu_subset must be in cpu_present_set during startup */
|
||||
if (startup)
|
||||
err(1, "cpu%d not present", i);
|
||||
else
|
||||
fprintf(stderr, "cpu%d not present\n", i);
|
||||
} else {
|
||||
CPU_SET_S(i, cpu_allowed_setsize, cpu_allowed_set);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CPU_COUNT_S(cpu_effective_setsize, cpu_effective_set)) {
|
||||
if (!CPU_ISSET_S(i, cpu_effective_setsize, cpu_effective_set)) {
|
||||
fprintf(stderr, "cpu%d not effective\n", i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
CPU_SET_S(i, cpu_allowed_setsize, cpu_allowed_set);
|
||||
}
|
||||
|
||||
if (!CPU_COUNT_S(cpu_allowed_setsize, cpu_allowed_set))
|
||||
|
Loading…
x
Reference in New Issue
Block a user