diff options
author | Prarit Bhargava <prarit@redhat.com> | 2018-07-26 09:08:54 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2018-07-26 14:20:59 -0400 |
commit | 2ffbb22406079fec2c3a6ad6ee1dc99fede740ac (patch) | |
tree | 02ee8ea8b1fcaff212175dfdaf87fd81490a801a | |
parent | cfce494db3bfccd2a0774652b95f286639acef36 (diff) |
tools/power turbostat: Fix logical node enumeration to allow for non-sequential physical nodes
turbostat fails on some multi-package topologies because the logical node
enumeration assumes that the nodes are sequentially numbered,
which causes the logical numa nodes to not be enumerated, or enumerated incorrectly.
Use a more robust enumeration algorithm which allows for non-seqential physical nodes.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 106 |
1 files changed, 50 insertions, 56 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 02e71accad16..2b0135599f37 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -2471,55 +2471,43 @@ int get_core_id(int cpu) | |||
2471 | 2471 | ||
2472 | void set_node_data(void) | 2472 | void set_node_data(void) |
2473 | { | 2473 | { |
2474 | char path[80]; | 2474 | int pkg, node, lnode, cpu, cpux; |
2475 | FILE *filep; | 2475 | int cpu_count; |
2476 | int pkg, node, cpu; | 2476 | |
2477 | 2477 | /* initialize logical_node_id */ | |
2478 | struct pkg_node_info { | 2478 | for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) |
2479 | int count; | 2479 | cpus[cpu].logical_node_id = -1; |
2480 | int min; | 2480 | |
2481 | } *pni; | 2481 | cpu_count = 0; |
2482 | 2482 | for (pkg = 0; pkg < topo.num_packages; pkg++) { | |
2483 | pni = calloc(topo.num_packages, sizeof(struct pkg_node_info)); | 2483 | lnode = 0; |
2484 | if (!pni) | 2484 | for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) { |
2485 | err(1, "calloc pkg_node_count"); | 2485 | if (cpus[cpu].physical_package_id != pkg) |
2486 | 2486 | continue; | |
2487 | for (pkg = 0; pkg < topo.num_packages; pkg++) | 2487 | /* find a cpu with an unset logical_node_id */ |
2488 | pni[pkg].min = topo.num_cpus; | 2488 | if (cpus[cpu].logical_node_id != -1) |
2489 | 2489 | continue; | |
2490 | for (node = 0; node <= topo.max_node_num; node++) { | 2490 | cpus[cpu].logical_node_id = lnode; |
2491 | /* find the "first" cpu in the node */ | 2491 | node = cpus[cpu].physical_node_id; |
2492 | sprintf(path, "/sys/bus/node/devices/node%d/cpulist", node); | 2492 | cpu_count++; |
2493 | filep = fopen(path, "r"); | 2493 | /* |
2494 | if (!filep) | 2494 | * find all matching cpus on this pkg and set |
2495 | continue; | 2495 | * the logical_node_id |
2496 | fscanf(filep, "%d", &cpu); | 2496 | */ |
2497 | fclose(filep); | 2497 | for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) { |
2498 | 2498 | if ((cpus[cpux].physical_package_id == pkg) && | |
2499 | pkg = cpus[cpu].physical_package_id; | 2499 | (cpus[cpux].physical_node_id == node)) { |
2500 | pni[pkg].count++; | 2500 | cpus[cpux].logical_node_id = lnode; |
2501 | 2501 | cpu_count++; | |
2502 | if (node < pni[pkg].min) | 2502 | } |
2503 | pni[pkg].min = node; | 2503 | } |
2504 | } | 2504 | lnode++; |
2505 | 2505 | if (lnode > topo.nodes_per_pkg) | |
2506 | for (pkg = 0; pkg < topo.num_packages; pkg++) | 2506 | topo.nodes_per_pkg = lnode; |
2507 | if (pni[pkg].count > topo.nodes_per_pkg) | 2507 | } |
2508 | topo.nodes_per_pkg = pni[0].count; | 2508 | if (cpu_count >= topo.max_cpu_num) |
2509 | 2509 | break; | |
2510 | /* Fake 1 node per pkg for machines that don't | ||
2511 | * expose nodes and thus avoid -nan results | ||
2512 | */ | ||
2513 | if (topo.nodes_per_pkg == 0) | ||
2514 | topo.nodes_per_pkg = 1; | ||
2515 | |||
2516 | for (cpu = 0; cpu < topo.num_cpus; cpu++) { | ||
2517 | pkg = cpus[cpu].physical_package_id; | ||
2518 | node = cpus[cpu].physical_node_id; | ||
2519 | cpus[cpu].logical_node_id = node - pni[pkg].min; | ||
2520 | } | 2510 | } |
2521 | free(pni); | ||
2522 | |||
2523 | } | 2511 | } |
2524 | 2512 | ||
2525 | int get_physical_node_id(struct cpu_topology *thiscpu) | 2513 | int get_physical_node_id(struct cpu_topology *thiscpu) |
@@ -4840,14 +4828,6 @@ void topology_probe() | |||
4840 | max_siblings = siblings; | 4828 | max_siblings = siblings; |
4841 | if (cpus[i].thread_id == 0) | 4829 | if (cpus[i].thread_id == 0) |
4842 | topo.num_cores++; | 4830 | topo.num_cores++; |
4843 | |||
4844 | if (debug > 1) | ||
4845 | fprintf(outf, | ||
4846 | "cpu %d pkg %d node %d core %d thread %d\n", | ||
4847 | i, cpus[i].physical_package_id, | ||
4848 | cpus[i].physical_node_id, | ||
4849 | cpus[i].physical_core_id, | ||
4850 | cpus[i].thread_id); | ||
4851 | } | 4831 | } |
4852 | 4832 | ||
4853 | topo.cores_per_node = max_core_id + 1; | 4833 | topo.cores_per_node = max_core_id + 1; |
@@ -4873,6 +4853,20 @@ void topology_probe() | |||
4873 | topo.threads_per_core = max_siblings; | 4853 | topo.threads_per_core = max_siblings; |
4874 | if (debug > 1) | 4854 | if (debug > 1) |
4875 | fprintf(outf, "max_siblings %d\n", max_siblings); | 4855 | fprintf(outf, "max_siblings %d\n", max_siblings); |
4856 | |||
4857 | if (debug < 1) | ||
4858 | return; | ||
4859 | |||
4860 | for (i = 0; i <= topo.max_cpu_num; ++i) { | ||
4861 | fprintf(outf, | ||
4862 | "cpu %d pkg %d node %d lnode %d core %d thread %d\n", | ||
4863 | i, cpus[i].physical_package_id, | ||
4864 | cpus[i].physical_node_id, | ||
4865 | cpus[i].logical_node_id, | ||
4866 | cpus[i].physical_core_id, | ||
4867 | cpus[i].thread_id); | ||
4868 | } | ||
4869 | |||
4876 | } | 4870 | } |
4877 | 4871 | ||
4878 | void | 4872 | void |