diff options
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 117 |
1 files changed, 82 insertions, 35 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 1684f4ec627e..6bf426813797 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -158,6 +158,7 @@ cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_subset; size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size; #define MAX_ADDED_COUNTERS 8 #define MAX_ADDED_THREAD_COUNTERS 24 +#define BITMASK_SIZE 32 struct thread_data { struct timeval tv_begin; @@ -256,6 +257,13 @@ struct system_summary { struct pkg_data packages; } average; +struct cpu_topology { + int physical_package_id; + int logical_cpu_id; + int node_id; + int physical_core_id; + cpu_set_t *put_ids; /* Processing Unit/Thread IDs */ +} *cpus; struct topo_params { int num_packages; @@ -2271,6 +2279,8 @@ void free_fd_percpu(void) void free_all_buffers(void) { + int i; + CPU_FREE(cpu_present_set); cpu_present_set = NULL; cpu_present_setsize = 0; @@ -2303,6 +2313,12 @@ void free_all_buffers(void) free(irq_column_2_cpu); free(irqs_per_cpu); + + for (i = 0; i <= topo.max_cpu_num; ++i) { + if (cpus[i].put_ids) + CPU_FREE(cpus[i].put_ids); + } + free(cpus); } @@ -2383,35 +2399,60 @@ int get_core_id(int cpu) return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); } -int get_num_ht_siblings(int cpu) +int get_node_id(struct cpu_topology *thiscpu) { char path[80]; FILE *filep; - int sib1; - int matches = 0; - char character; - char str[100]; - char *ch; - - sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu); - filep = fopen_or_die(path, "r"); + int i; + int cpu = thiscpu->logical_cpu_id; - /* - * file format: - * A ',' separated or '-' separated set of numbers - * (eg 1-2 or 1,3,4,5) - */ - fscanf(filep, "%d%c\n", &sib1, &character); - fseek(filep, 0, SEEK_SET); - fgets(str, 100, filep); - ch = strchr(str, character); - while (ch != NULL) { - matches++; - ch = strchr(ch+1, character); + for (i = 0; i <= topo.max_cpu_num; i++) { + sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist", + cpu, i); + filep = fopen(path, "r"); + if (!filep) + continue; + fclose(filep); + return i; } + return -1; +} +int get_thread_siblings(struct cpu_topology *thiscpu) +{ + char path[80], character; + FILE *filep; + unsigned long map; + int shift, sib_core; + int cpu = thiscpu->logical_cpu_id; + int offset = topo.max_cpu_num + 1; + size_t size; + + thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1)); + if (!thiscpu->put_ids) + return -1; + + size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); + CPU_ZERO_S(size, thiscpu->put_ids); + + sprintf(path, + "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu); + filep = fopen_or_die(path, "r"); + do { + offset -= BITMASK_SIZE; + fscanf(filep, "%lx%c", &map, &character); + for (shift = 0; shift < BITMASK_SIZE; shift++) { + if ((map >> shift) & 0x1) { + sib_core = get_core_id(shift + offset); + if (sib_core == thiscpu->physical_core_id) + CPU_SET_S(shift + offset, size, + thiscpu->put_ids); + } + } + } while (!strncmp(&character, ",", 1)); fclose(filep); - return matches+1; + + return CPU_COUNT_S(size, thiscpu->put_ids); } /* @@ -2506,7 +2547,7 @@ void set_max_cpu_num(void) "/sys/devices/system/cpu/cpu0/topology/thread_siblings", "r"); while (fscanf(filep, "%lx,", &dummy) == 1) - topo.max_cpu_num += 32; + topo.max_cpu_num += BITMASK_SIZE; fclose(filep); topo.max_cpu_num--; /* 0 based */ } @@ -4569,10 +4610,6 @@ void topology_probe() int max_core_id = 0; int max_package_id = 0; int max_siblings = 0; - struct cpu_topology { - int core_id; - int physical_package_id; - } *cpus; /* Initialize num_cpus, max_cpu_num */ set_max_cpu_num(); @@ -4629,20 +4666,32 @@ void topology_probe() fprintf(outf, "cpu%d NOT PRESENT\n", i); continue; } - cpus[i].core_id = get_core_id(i); - if (cpus[i].core_id > max_core_id) - max_core_id = cpus[i].core_id; + cpus[i].logical_cpu_id = i; + + /* get package information */ cpus[i].physical_package_id = get_physical_package_id(i); if (cpus[i].physical_package_id > max_package_id) max_package_id = cpus[i].physical_package_id; - siblings = get_num_ht_siblings(i); + /* get numa node information */ + cpus[i].node_id = get_node_id(&cpus[i]); + + /* get core information */ + cpus[i].physical_core_id = get_core_id(i); + if (cpus[i].physical_core_id > max_core_id) + max_core_id = cpus[i].physical_core_id; + + /* get thread information */ + siblings = get_thread_siblings(&cpus[i]); if (siblings > max_siblings) max_siblings = siblings; + if (debug > 1) - fprintf(outf, "cpu %d pkg %d core %d\n", - i, cpus[i].physical_package_id, cpus[i].core_id); + fprintf(outf, "cpu %d pkg %d node %d core %d\n", + i, cpus[i].physical_package_id, + cpus[i].node_id, + cpus[i].physical_core_id); } topo.num_cores_per_pkg = max_core_id + 1; if (debug > 1) @@ -4661,8 +4710,6 @@ void topology_probe() topo.num_threads_per_core = max_siblings; if (debug > 1) fprintf(outf, "max_siblings %d\n", max_siblings); - - free(cpus); } void |