aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2018-07-26 09:08:54 -0400
committerLen Brown <len.brown@intel.com>2018-07-26 14:20:59 -0400
commit2ffbb22406079fec2c3a6ad6ee1dc99fede740ac (patch)
tree02ee8ea8b1fcaff212175dfdaf87fd81490a801a
parentcfce494db3bfccd2a0774652b95f286639acef36 (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.c106
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
2472void set_node_data(void) 2472void 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
2525int get_physical_node_id(struct cpu_topology *thiscpu) 2513int 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
4878void 4872void