Skip to content

Commit b32c369

Browse files
committed
tools/power turbostat: Fix forked child affinity regression
In "one-shot" mode, turbostat 1. takes a counter snapshot 2. forks and waits for a child 3. takes the end counter snapshot and prints the result. But turbostat counter snapshots currently use affinity to travel around the system so that counter reads are "local", and this affinity must be cleared between #1 and #2 above. The offending commit removed that reset that allowed the child to run on cpu_present_set. Fix that issue, and improve upon the original by using cpu_possible_set for the child. This allows the child to also run on CPUs that hotplug online during its runtime. Reported-by: Zhang Rui <[email protected]> Fixes: 7bb3fe2 ("tools/power/turbostat: Obey allowed CPUs during startup") Signed-off-by: Len Brown <[email protected]>
1 parent 1a202af commit b32c369

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

tools/power/x86/turbostat/turbostat.c

+52-2
Original file line numberDiff line numberDiff line change
@@ -1120,8 +1120,8 @@ int backwards_count;
11201120
char *progname;
11211121

11221122
#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
1123-
cpu_set_t *cpu_present_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
1124-
size_t cpu_present_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
1123+
cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
1124+
size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
11251125
#define MAX_ADDED_THREAD_COUNTERS 24
11261126
#define MAX_ADDED_CORE_COUNTERS 8
11271127
#define MAX_ADDED_PACKAGE_COUNTERS 16
@@ -8488,6 +8488,33 @@ int dir_filter(const struct dirent *dirp)
84888488
return 0;
84898489
}
84908490

8491+
char *possible_file = "/sys/devices/system/cpu/possible";
8492+
char possible_buf[1024];
8493+
8494+
int initialize_cpu_possible_set(void)
8495+
{
8496+
FILE *fp;
8497+
8498+
fp = fopen(possible_file, "r");
8499+
if (!fp) {
8500+
warn("open %s", possible_file);
8501+
return -1;
8502+
}
8503+
if (fread(possible_buf, sizeof(char), 1024, fp) == 0) {
8504+
warn("read %s", possible_file);
8505+
goto err;
8506+
}
8507+
if (parse_cpu_str(possible_buf, cpu_possible_set, cpu_possible_setsize)) {
8508+
warnx("%s: cpu str malformat %s\n", possible_file, cpu_effective_str);
8509+
goto err;
8510+
}
8511+
return 0;
8512+
8513+
err:
8514+
fclose(fp);
8515+
return -1;
8516+
}
8517+
84918518
void topology_probe(bool startup)
84928519
{
84938520
int i;
@@ -8519,6 +8546,16 @@ void topology_probe(bool startup)
85198546
CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
85208547
for_all_proc_cpus(mark_cpu_present);
85218548

8549+
/*
8550+
* Allocate and initialize cpu_possible_set
8551+
*/
8552+
cpu_possible_set = CPU_ALLOC((topo.max_cpu_num + 1));
8553+
if (cpu_possible_set == NULL)
8554+
err(3, "CPU_ALLOC");
8555+
cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
8556+
CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set);
8557+
initialize_cpu_possible_set();
8558+
85228559
/*
85238560
* Allocate and initialize cpu_effective_set
85248561
*/
@@ -9371,6 +9408,18 @@ void turbostat_init()
93719408
}
93729409
}
93739410

9411+
void affinitize_child(void)
9412+
{
9413+
/* Prefer cpu_possible_set, if available */
9414+
if (sched_setaffinity(0, cpu_possible_setsize, cpu_possible_set)) {
9415+
warn("sched_setaffinity cpu_possible_set");
9416+
9417+
/* Otherwise, allow child to run on same cpu set as turbostat */
9418+
if (sched_setaffinity(0, cpu_allowed_setsize, cpu_allowed_set))
9419+
warn("sched_setaffinity cpu_allowed_set");
9420+
}
9421+
}
9422+
93749423
int fork_it(char **argv)
93759424
{
93769425
pid_t child_pid;
@@ -9386,6 +9435,7 @@ int fork_it(char **argv)
93869435
child_pid = fork();
93879436
if (!child_pid) {
93889437
/* child */
9438+
affinitize_child();
93899439
execvp(argv[0], argv);
93909440
err(errno, "exec %s", argv[0]);
93919441
} else {

0 commit comments

Comments
 (0)