Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ffbb224 authored by Prarit Bhargava's avatar Prarit Bhargava Committed by Len Brown
Browse files

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: default avatarPrarit Bhargava <prarit@redhat.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent cfce494d
Loading
Loading
Loading
Loading
+50 −56
Original line number Diff line number Diff line
@@ -2471,55 +2471,43 @@ int get_core_id(int cpu)

void set_node_data(void)
{
	char path[80];
	FILE *filep;
	int pkg, node, cpu;

	struct pkg_node_info {
		int count;
		int min;
	} *pni;

	pni = calloc(topo.num_packages, sizeof(struct pkg_node_info));
	if (!pni)
		err(1, "calloc pkg_node_count");

	for (pkg = 0; pkg < topo.num_packages; pkg++)
		pni[pkg].min = topo.num_cpus;

	for (node = 0; node <= topo.max_node_num; node++) {
		/* find the "first" cpu in the node */
		sprintf(path, "/sys/bus/node/devices/node%d/cpulist", node);
		filep = fopen(path, "r");
		if (!filep)
	int pkg, node, lnode, cpu, cpux;
	int cpu_count;

	/* initialize logical_node_id */
	for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu)
		cpus[cpu].logical_node_id = -1;

	cpu_count = 0;
	for (pkg = 0; pkg < topo.num_packages; pkg++) {
		lnode = 0;
		for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) {
			if (cpus[cpu].physical_package_id != pkg)
				continue;
		fscanf(filep, "%d", &cpu);
		fclose(filep);

		pkg = cpus[cpu].physical_package_id;
		pni[pkg].count++;

		if (node < pni[pkg].min)
			pni[pkg].min = node;
	}

	for (pkg = 0; pkg < topo.num_packages; pkg++)
		if (pni[pkg].count > topo.nodes_per_pkg)
			topo.nodes_per_pkg = pni[0].count;

	/* Fake 1 node per pkg for machines that don't
	 * expose nodes and thus avoid -nan results
	 */
	if (topo.nodes_per_pkg == 0)
		topo.nodes_per_pkg = 1;

	for (cpu = 0; cpu < topo.num_cpus; cpu++) {
		pkg = cpus[cpu].physical_package_id;
			/* find a cpu with an unset logical_node_id */
			if (cpus[cpu].logical_node_id != -1)
				continue;
			cpus[cpu].logical_node_id = lnode;
			node = cpus[cpu].physical_node_id;
		cpus[cpu].logical_node_id = node - pni[pkg].min;
			cpu_count++;
			/*
			 * find all matching cpus on this pkg and set
			 * the logical_node_id
			 */
			for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) {
				if ((cpus[cpux].physical_package_id == pkg) &&
				   (cpus[cpux].physical_node_id == node)) {
					cpus[cpux].logical_node_id = lnode;
					cpu_count++;
				}
			}
			lnode++;
			if (lnode > topo.nodes_per_pkg)
				topo.nodes_per_pkg = lnode;
		}
		if (cpu_count >= topo.max_cpu_num)
			break;
	}
	free(pni);

}

int get_physical_node_id(struct cpu_topology *thiscpu)
@@ -4840,14 +4828,6 @@ void topology_probe()
			max_siblings = siblings;
		if (cpus[i].thread_id == 0)
			topo.num_cores++;

		if (debug > 1)
			fprintf(outf,
				"cpu %d pkg %d node %d core %d thread %d\n",
				i, cpus[i].physical_package_id,
				cpus[i].physical_node_id,
				cpus[i].physical_core_id,
				cpus[i].thread_id);
	}

	topo.cores_per_node = max_core_id + 1;
@@ -4873,6 +4853,20 @@ void topology_probe()
	topo.threads_per_core = max_siblings;
	if (debug > 1)
		fprintf(outf, "max_siblings %d\n", max_siblings);

	if (debug < 1)
		return;

	for (i = 0; i <= topo.max_cpu_num; ++i) {
		fprintf(outf,
			"cpu %d pkg %d node %d lnode %d core %d thread %d\n",
			i, cpus[i].physical_package_id,
			cpus[i].physical_node_id,
			cpus[i].logical_node_id,
			cpus[i].physical_core_id,
			cpus[i].thread_id);
	}

}

void