Skip to content

Commit 3559ea8

Browse files
Patryk Wlazlynlenb
authored andcommitted
tools/power turbostat: Avoid possible memory corruption due to sparse topology IDs
Save the highest core and package id when parsing topology to allocate enough memory when get_rapl_counters() is called with a core or a package id as a domain. Note that RAPL domains are per-package on Intel, but per-core on AMD. Thus, the RAPL code effectively runs in different modes on those two product lines. Signed-off-by: Patryk Wlazlyn <[email protected]> Signed-off-by: Len Brown <[email protected]>
1 parent 78464d7 commit 3559ea8

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

tools/power/x86/turbostat/turbostat.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,7 @@ struct rapl_counter_info_t {
10521052

10531053
/* struct rapl_counter_info_t for each RAPL domain */
10541054
struct rapl_counter_info_t *rapl_counter_info_perdomain;
1055+
unsigned int rapl_counter_info_perdomain_size;
10551056

10561057
#define RAPL_COUNTER_FLAG_USE_MSR_SUM (1u << 1)
10571058

@@ -1451,6 +1452,8 @@ struct topo_params {
14511452
int allowed_cpus;
14521453
int allowed_cores;
14531454
int max_cpu_num;
1455+
int max_core_id;
1456+
int max_package_id;
14541457
int max_die_id;
14551458
int max_node_num;
14561459
int nodes_per_pkg;
@@ -3425,15 +3428,18 @@ void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci
34253428
rc->scale = rci->scale[idx];
34263429
}
34273430

3428-
int get_rapl_counters(int cpu, int domain, struct core_data *c, struct pkg_data *p)
3431+
int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct pkg_data *p)
34293432
{
34303433
unsigned long long perf_data[NUM_RAPL_COUNTERS + 1];
3431-
struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[domain];
3434+
struct rapl_counter_info_t *rci;
34323435

34333436
if (debug)
34343437
fprintf(stderr, "%s: cpu%d domain%d\n", __func__, cpu, domain);
34353438

34363439
assert(rapl_counter_info_perdomain);
3440+
assert(domain < rapl_counter_info_perdomain_size);
3441+
3442+
rci = &rapl_counter_info_perdomain[domain];
34373443

34383444
/*
34393445
* If we have any perf counters to read, read them all now, in bulk
@@ -4257,14 +4263,16 @@ void free_fd_rapl_percpu(void)
42574263
if (!rapl_counter_info_perdomain)
42584264
return;
42594265

4260-
const int num_domains = platform->has_per_core_rapl ? topo.num_cores : topo.num_packages;
4266+
const int num_domains = rapl_counter_info_perdomain_size;
42614267

42624268
for (int domain_id = 0; domain_id < num_domains; ++domain_id) {
42634269
if (rapl_counter_info_perdomain[domain_id].fd_perf != -1)
42644270
close(rapl_counter_info_perdomain[domain_id].fd_perf);
42654271
}
42664272

42674273
free(rapl_counter_info_perdomain);
4274+
rapl_counter_info_perdomain = NULL;
4275+
rapl_counter_info_perdomain_size = 0;
42684276
}
42694277

42704278
void free_all_buffers(void)
@@ -6582,17 +6590,18 @@ void linux_perf_init(void)
65826590

65836591
void rapl_perf_init(void)
65846592
{
6585-
const int num_domains = platform->has_per_core_rapl ? topo.num_cores : topo.num_packages;
6593+
const unsigned int num_domains = (platform->has_per_core_rapl ? topo.max_core_id : topo.max_package_id) + 1;
65866594
bool *domain_visited = calloc(num_domains, sizeof(bool));
65876595

65886596
rapl_counter_info_perdomain = calloc(num_domains, sizeof(*rapl_counter_info_perdomain));
65896597
if (rapl_counter_info_perdomain == NULL)
65906598
err(-1, "calloc rapl_counter_info_percpu");
6599+
rapl_counter_info_perdomain_size = num_domains;
65916600

65926601
/*
65936602
* Initialize rapl_counter_info_percpu
65946603
*/
6595-
for (int domain_id = 0; domain_id < num_domains; ++domain_id) {
6604+
for (unsigned int domain_id = 0; domain_id < num_domains; ++domain_id) {
65966605
struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[domain_id];
65976606

65986607
rci->fd_perf = -1;
@@ -6612,7 +6621,7 @@ void rapl_perf_init(void)
66126621
bool has_counter = 0;
66136622
double scale;
66146623
enum rapl_unit unit;
6615-
int next_domain;
6624+
unsigned int next_domain;
66166625

66176626
memset(domain_visited, 0, num_domains * sizeof(*domain_visited));
66186627

@@ -6625,6 +6634,8 @@ void rapl_perf_init(void)
66256634
next_domain =
66266635
platform->has_per_core_rapl ? cpus[cpu].physical_core_id : cpus[cpu].physical_package_id;
66276636

6637+
assert(next_domain < num_domains);
6638+
66286639
if (domain_visited[next_domain])
66296640
continue;
66306641

@@ -7207,6 +7218,8 @@ void topology_probe(bool startup)
72077218
if (cpus[i].thread_id == 0)
72087219
topo.num_cores++;
72097220
}
7221+
topo.max_core_id = max_core_id;
7222+
topo.max_package_id = max_package_id;
72107223

72117224
topo.cores_per_node = max_core_id + 1;
72127225
if (debug > 1)

0 commit comments

Comments
 (0)