Skip to content

Commit b76a8e5

Browse files
lenbmehmetb0
authored andcommitted
tools/power turbostat: Fix forked child affinity regression
BugLink: https://bugs.launchpad.net/bugs/2103829 [ Upstream commit b32c36975da48afc9089f8b61f7b2dcc40e479d2 ] 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]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Noah Wager <[email protected]> Signed-off-by: Mehmet Basaran <[email protected]>
1 parent 0136f11 commit b76a8e5

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

tools/power/x86/turbostat/turbostat.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,8 @@ int backwards_count;
10871087
char *progname;
10881088

10891089
#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
1090-
cpu_set_t *cpu_present_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
1091-
size_t cpu_present_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
1090+
cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
1091+
size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
10921092
#define MAX_ADDED_THREAD_COUNTERS 24
10931093
#define MAX_ADDED_CORE_COUNTERS 8
10941094
#define MAX_ADDED_PACKAGE_COUNTERS 16
@@ -8223,6 +8223,33 @@ int dir_filter(const struct dirent *dirp)
82238223
return 0;
82248224
}
82258225

8226+
char *possible_file = "/sys/devices/system/cpu/possible";
8227+
char possible_buf[1024];
8228+
8229+
int initialize_cpu_possible_set(void)
8230+
{
8231+
FILE *fp;
8232+
8233+
fp = fopen(possible_file, "r");
8234+
if (!fp) {
8235+
warn("open %s", possible_file);
8236+
return -1;
8237+
}
8238+
if (fread(possible_buf, sizeof(char), 1024, fp) == 0) {
8239+
warn("read %s", possible_file);
8240+
goto err;
8241+
}
8242+
if (parse_cpu_str(possible_buf, cpu_possible_set, cpu_possible_setsize)) {
8243+
warnx("%s: cpu str malformat %s\n", possible_file, cpu_effective_str);
8244+
goto err;
8245+
}
8246+
return 0;
8247+
8248+
err:
8249+
fclose(fp);
8250+
return -1;
8251+
}
8252+
82268253
void topology_probe(bool startup)
82278254
{
82288255
int i;
@@ -8254,6 +8281,16 @@ void topology_probe(bool startup)
82548281
CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
82558282
for_all_proc_cpus(mark_cpu_present);
82568283

8284+
/*
8285+
* Allocate and initialize cpu_possible_set
8286+
*/
8287+
cpu_possible_set = CPU_ALLOC((topo.max_cpu_num + 1));
8288+
if (cpu_possible_set == NULL)
8289+
err(3, "CPU_ALLOC");
8290+
cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
8291+
CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set);
8292+
initialize_cpu_possible_set();
8293+
82578294
/*
82588295
* Allocate and initialize cpu_effective_set
82598296
*/
@@ -9094,6 +9131,18 @@ void turbostat_init()
90949131
}
90959132
}
90969133

9134+
void affinitize_child(void)
9135+
{
9136+
/* Prefer cpu_possible_set, if available */
9137+
if (sched_setaffinity(0, cpu_possible_setsize, cpu_possible_set)) {
9138+
warn("sched_setaffinity cpu_possible_set");
9139+
9140+
/* Otherwise, allow child to run on same cpu set as turbostat */
9141+
if (sched_setaffinity(0, cpu_allowed_setsize, cpu_allowed_set))
9142+
warn("sched_setaffinity cpu_allowed_set");
9143+
}
9144+
}
9145+
90979146
int fork_it(char **argv)
90989147
{
90999148
pid_t child_pid;
@@ -9109,6 +9158,7 @@ int fork_it(char **argv)
91099158
child_pid = fork();
91109159
if (!child_pid) {
91119160
/* child */
9161+
affinitize_child();
91129162
execvp(argv[0], argv);
91139163
err(errno, "exec %s", argv[0]);
91149164
} else {

0 commit comments

Comments
 (0)