Skip to content

Commit 0d4a011

Browse files
lenbgregkh
authored andcommitted
tools/power turbostat: Fix forked child affinity regression
[ Upstream commit b32c369 ] 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]>
1 parent b80ab02 commit 0d4a011

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
@@ -1096,8 +1096,8 @@ int backwards_count;
10961096
char *progname;
10971097

10981098
#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
1099-
cpu_set_t *cpu_present_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
1100-
size_t cpu_present_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
1099+
cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
1100+
size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
11011101
#define MAX_ADDED_THREAD_COUNTERS 24
11021102
#define MAX_ADDED_CORE_COUNTERS 8
11031103
#define MAX_ADDED_PACKAGE_COUNTERS 16
@@ -8294,6 +8294,33 @@ int dir_filter(const struct dirent *dirp)
82948294
return 0;
82958295
}
82968296

8297+
char *possible_file = "/sys/devices/system/cpu/possible";
8298+
char possible_buf[1024];
8299+
8300+
int initialize_cpu_possible_set(void)
8301+
{
8302+
FILE *fp;
8303+
8304+
fp = fopen(possible_file, "r");
8305+
if (!fp) {
8306+
warn("open %s", possible_file);
8307+
return -1;
8308+
}
8309+
if (fread(possible_buf, sizeof(char), 1024, fp) == 0) {
8310+
warn("read %s", possible_file);
8311+
goto err;
8312+
}
8313+
if (parse_cpu_str(possible_buf, cpu_possible_set, cpu_possible_setsize)) {
8314+
warnx("%s: cpu str malformat %s\n", possible_file, cpu_effective_str);
8315+
goto err;
8316+
}
8317+
return 0;
8318+
8319+
err:
8320+
fclose(fp);
8321+
return -1;
8322+
}
8323+
82978324
void topology_probe(bool startup)
82988325
{
82998326
int i;
@@ -8325,6 +8352,16 @@ void topology_probe(bool startup)
83258352
CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
83268353
for_all_proc_cpus(mark_cpu_present);
83278354

8355+
/*
8356+
* Allocate and initialize cpu_possible_set
8357+
*/
8358+
cpu_possible_set = CPU_ALLOC((topo.max_cpu_num + 1));
8359+
if (cpu_possible_set == NULL)
8360+
err(3, "CPU_ALLOC");
8361+
cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
8362+
CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set);
8363+
initialize_cpu_possible_set();
8364+
83288365
/*
83298366
* Allocate and initialize cpu_effective_set
83308367
*/
@@ -9165,6 +9202,18 @@ void turbostat_init()
91659202
}
91669203
}
91679204

9205+
void affinitize_child(void)
9206+
{
9207+
/* Prefer cpu_possible_set, if available */
9208+
if (sched_setaffinity(0, cpu_possible_setsize, cpu_possible_set)) {
9209+
warn("sched_setaffinity cpu_possible_set");
9210+
9211+
/* Otherwise, allow child to run on same cpu set as turbostat */
9212+
if (sched_setaffinity(0, cpu_allowed_setsize, cpu_allowed_set))
9213+
warn("sched_setaffinity cpu_allowed_set");
9214+
}
9215+
}
9216+
91689217
int fork_it(char **argv)
91699218
{
91709219
pid_t child_pid;
@@ -9180,6 +9229,7 @@ int fork_it(char **argv)
91809229
child_pid = fork();
91819230
if (!child_pid) {
91829231
/* child */
9232+
affinitize_child();
91839233
execvp(argv[0], argv);
91849234
err(errno, "exec %s", argv[0]);
91859235
} else {

0 commit comments

Comments
 (0)