Skip to content

Commit

Permalink
tools/power turbostat: Fix forked child affinity regression
Browse files Browse the repository at this point in the history
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 linuxppc#1 and linuxppc#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 <rui.zhang@intel.com>
Fixes: 7bb3fe2 ("tools/power/turbostat: Obey allowed CPUs during startup")
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
lenb committed Jan 27, 2025
1 parent 1a202af commit b32c369
Showing 1 changed file with 52 additions and 2 deletions.
54 changes: 52 additions & 2 deletions tools/power/x86/turbostat/turbostat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,8 +1120,8 @@ int backwards_count;
char *progname;

#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
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;
cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
#define MAX_ADDED_THREAD_COUNTERS 24
#define MAX_ADDED_CORE_COUNTERS 8
#define MAX_ADDED_PACKAGE_COUNTERS 16
Expand Down Expand Up @@ -8488,6 +8488,33 @@ int dir_filter(const struct dirent *dirp)
return 0;
}

char *possible_file = "/sys/devices/system/cpu/possible";
char possible_buf[1024];

int initialize_cpu_possible_set(void)
{
FILE *fp;

fp = fopen(possible_file, "r");
if (!fp) {
warn("open %s", possible_file);
return -1;
}
if (fread(possible_buf, sizeof(char), 1024, fp) == 0) {
warn("read %s", possible_file);
goto err;
}
if (parse_cpu_str(possible_buf, cpu_possible_set, cpu_possible_setsize)) {
warnx("%s: cpu str malformat %s\n", possible_file, cpu_effective_str);
goto err;
}
return 0;

err:
fclose(fp);
return -1;
}

void topology_probe(bool startup)
{
int i;
Expand Down Expand Up @@ -8519,6 +8546,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_possible_set
*/
cpu_possible_set = CPU_ALLOC((topo.max_cpu_num + 1));
if (cpu_possible_set == NULL)
err(3, "CPU_ALLOC");
cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set);
initialize_cpu_possible_set();

/*
* Allocate and initialize cpu_effective_set
*/
Expand Down Expand Up @@ -9371,6 +9408,18 @@ void turbostat_init()
}
}

void affinitize_child(void)
{
/* Prefer cpu_possible_set, if available */
if (sched_setaffinity(0, cpu_possible_setsize, cpu_possible_set)) {
warn("sched_setaffinity cpu_possible_set");

/* Otherwise, allow child to run on same cpu set as turbostat */
if (sched_setaffinity(0, cpu_allowed_setsize, cpu_allowed_set))
warn("sched_setaffinity cpu_allowed_set");
}
}

int fork_it(char **argv)
{
pid_t child_pid;
Expand All @@ -9386,6 +9435,7 @@ int fork_it(char **argv)
child_pid = fork();
if (!child_pid) {
/* child */
affinitize_child();
execvp(argv[0], argv);
err(errno, "exec %s", argv[0]);
} else {
Expand Down

0 comments on commit b32c369

Please sign in to comment.