mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-07 02:19:54 +00:00
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 <patryk.wlazlyn@linux.intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
committed by
Len Brown
parent
78464d7681
commit
3559ea813a
@@ -1052,6 +1052,7 @@ struct rapl_counter_info_t {
|
|||||||
|
|
||||||
/* struct rapl_counter_info_t for each RAPL domain */
|
/* struct rapl_counter_info_t for each RAPL domain */
|
||||||
struct rapl_counter_info_t *rapl_counter_info_perdomain;
|
struct rapl_counter_info_t *rapl_counter_info_perdomain;
|
||||||
|
unsigned int rapl_counter_info_perdomain_size;
|
||||||
|
|
||||||
#define RAPL_COUNTER_FLAG_USE_MSR_SUM (1u << 1)
|
#define RAPL_COUNTER_FLAG_USE_MSR_SUM (1u << 1)
|
||||||
|
|
||||||
@@ -1451,6 +1452,8 @@ struct topo_params {
|
|||||||
int allowed_cpus;
|
int allowed_cpus;
|
||||||
int allowed_cores;
|
int allowed_cores;
|
||||||
int max_cpu_num;
|
int max_cpu_num;
|
||||||
|
int max_core_id;
|
||||||
|
int max_package_id;
|
||||||
int max_die_id;
|
int max_die_id;
|
||||||
int max_node_num;
|
int max_node_num;
|
||||||
int nodes_per_pkg;
|
int nodes_per_pkg;
|
||||||
@@ -3425,15 +3428,18 @@ void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci
|
|||||||
rc->scale = rci->scale[idx];
|
rc->scale = rci->scale[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_rapl_counters(int cpu, int domain, struct core_data *c, struct pkg_data *p)
|
int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct pkg_data *p)
|
||||||
{
|
{
|
||||||
unsigned long long perf_data[NUM_RAPL_COUNTERS + 1];
|
unsigned long long perf_data[NUM_RAPL_COUNTERS + 1];
|
||||||
struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[domain];
|
struct rapl_counter_info_t *rci;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf(stderr, "%s: cpu%d domain%d\n", __func__, cpu, domain);
|
fprintf(stderr, "%s: cpu%d domain%d\n", __func__, cpu, domain);
|
||||||
|
|
||||||
assert(rapl_counter_info_perdomain);
|
assert(rapl_counter_info_perdomain);
|
||||||
|
assert(domain < rapl_counter_info_perdomain_size);
|
||||||
|
|
||||||
|
rci = &rapl_counter_info_perdomain[domain];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have any perf counters to read, read them all now, in bulk
|
* If we have any perf counters to read, read them all now, in bulk
|
||||||
@@ -4257,7 +4263,7 @@ void free_fd_rapl_percpu(void)
|
|||||||
if (!rapl_counter_info_perdomain)
|
if (!rapl_counter_info_perdomain)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int num_domains = platform->has_per_core_rapl ? topo.num_cores : topo.num_packages;
|
const int num_domains = rapl_counter_info_perdomain_size;
|
||||||
|
|
||||||
for (int domain_id = 0; domain_id < num_domains; ++domain_id) {
|
for (int domain_id = 0; domain_id < num_domains; ++domain_id) {
|
||||||
if (rapl_counter_info_perdomain[domain_id].fd_perf != -1)
|
if (rapl_counter_info_perdomain[domain_id].fd_perf != -1)
|
||||||
@@ -4265,6 +4271,8 @@ void free_fd_rapl_percpu(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(rapl_counter_info_perdomain);
|
free(rapl_counter_info_perdomain);
|
||||||
|
rapl_counter_info_perdomain = NULL;
|
||||||
|
rapl_counter_info_perdomain_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_all_buffers(void)
|
void free_all_buffers(void)
|
||||||
@@ -6582,17 +6590,18 @@ void linux_perf_init(void)
|
|||||||
|
|
||||||
void rapl_perf_init(void)
|
void rapl_perf_init(void)
|
||||||
{
|
{
|
||||||
const int num_domains = platform->has_per_core_rapl ? topo.num_cores : topo.num_packages;
|
const unsigned int num_domains = (platform->has_per_core_rapl ? topo.max_core_id : topo.max_package_id) + 1;
|
||||||
bool *domain_visited = calloc(num_domains, sizeof(bool));
|
bool *domain_visited = calloc(num_domains, sizeof(bool));
|
||||||
|
|
||||||
rapl_counter_info_perdomain = calloc(num_domains, sizeof(*rapl_counter_info_perdomain));
|
rapl_counter_info_perdomain = calloc(num_domains, sizeof(*rapl_counter_info_perdomain));
|
||||||
if (rapl_counter_info_perdomain == NULL)
|
if (rapl_counter_info_perdomain == NULL)
|
||||||
err(-1, "calloc rapl_counter_info_percpu");
|
err(-1, "calloc rapl_counter_info_percpu");
|
||||||
|
rapl_counter_info_perdomain_size = num_domains;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize rapl_counter_info_percpu
|
* Initialize rapl_counter_info_percpu
|
||||||
*/
|
*/
|
||||||
for (int domain_id = 0; domain_id < num_domains; ++domain_id) {
|
for (unsigned int domain_id = 0; domain_id < num_domains; ++domain_id) {
|
||||||
struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[domain_id];
|
struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[domain_id];
|
||||||
|
|
||||||
rci->fd_perf = -1;
|
rci->fd_perf = -1;
|
||||||
@@ -6612,7 +6621,7 @@ void rapl_perf_init(void)
|
|||||||
bool has_counter = 0;
|
bool has_counter = 0;
|
||||||
double scale;
|
double scale;
|
||||||
enum rapl_unit unit;
|
enum rapl_unit unit;
|
||||||
int next_domain;
|
unsigned int next_domain;
|
||||||
|
|
||||||
memset(domain_visited, 0, num_domains * sizeof(*domain_visited));
|
memset(domain_visited, 0, num_domains * sizeof(*domain_visited));
|
||||||
|
|
||||||
@@ -6625,6 +6634,8 @@ void rapl_perf_init(void)
|
|||||||
next_domain =
|
next_domain =
|
||||||
platform->has_per_core_rapl ? cpus[cpu].physical_core_id : cpus[cpu].physical_package_id;
|
platform->has_per_core_rapl ? cpus[cpu].physical_core_id : cpus[cpu].physical_package_id;
|
||||||
|
|
||||||
|
assert(next_domain < num_domains);
|
||||||
|
|
||||||
if (domain_visited[next_domain])
|
if (domain_visited[next_domain])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -7207,6 +7218,8 @@ void topology_probe(bool startup)
|
|||||||
if (cpus[i].thread_id == 0)
|
if (cpus[i].thread_id == 0)
|
||||||
topo.num_cores++;
|
topo.num_cores++;
|
||||||
}
|
}
|
||||||
|
topo.max_core_id = max_core_id;
|
||||||
|
topo.max_package_id = max_package_id;
|
||||||
|
|
||||||
topo.cores_per_node = max_core_id + 1;
|
topo.cores_per_node = max_core_id + 1;
|
||||||
if (debug > 1)
|
if (debug > 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user