Commit 9b7c19e9 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'pm-tools'

Merge turbostat utility fixes for final 4.18:

 - Fix the -S option on 1-CPU systems.
 - Fix computations using incorrect processor core counts.
 - Fix the x2apic debug message.
 - Fix logical node enumeration to allow for non-sequential physical nodes.
 - Fix reported family on modern AMD processors.
 - Clarify the RAPL column information in the man page.

* pm-tools:
  tools/power turbostat: version 18.07.27
  tools/power turbostat: Read extended processor family from CPUID
  tools/power turbostat: Fix logical node enumeration to allow for non-sequential physical nodes
  tools/power turbostat: fix x2apic debug message output file
  tools/power turbostat: fix bogus summary values
  tools/power turbostat: fix -S on UP systems
  tools/power turbostat: Update turbostat(8) RAPL throttling column description
parents 01e61a42 b0cd6035
...@@ -106,7 +106,7 @@ The system configuration dump (if --quiet is not used) is followed by statistics ...@@ -106,7 +106,7 @@ The system configuration dump (if --quiet is not used) is followed by statistics
\fBC1%, C2%, C3%\fP The residency percentage that Linux requested C1, C2, C3.... The system summary is the average of all CPUs in the system. Note that these are software, reflecting what was requested. The hardware counters reflect what was actually achieved. \fBC1%, C2%, C3%\fP The residency percentage that Linux requested C1, C2, C3.... The system summary is the average of all CPUs in the system. Note that these are software, reflecting what was requested. The hardware counters reflect what was actually achieved.
\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. These numbers are from hardware residency counters. \fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. These numbers are from hardware residency counters.
\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor. \fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
\fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor. \fBPkgTmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
\fBGFX%rc6\fP The percentage of time the GPU is in the "render C6" state, rc6, during the measurement interval. From /sys/class/drm/card0/power/rc6_residency_ms. \fBGFX%rc6\fP The percentage of time the GPU is in the "render C6" state, rc6, during the measurement interval. From /sys/class/drm/card0/power/rc6_residency_ms.
\fBGFXMHz\fP Instantaneous snapshot of what sysfs presents at the end of the measurement interval. From /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz. \fBGFXMHz\fP Instantaneous snapshot of what sysfs presents at the end of the measurement interval. From /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz.
\fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. These numbers are from hardware residency counters. \fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. These numbers are from hardware residency counters.
...@@ -114,7 +114,7 @@ The system configuration dump (if --quiet is not used) is followed by statistics ...@@ -114,7 +114,7 @@ The system configuration dump (if --quiet is not used) is followed by statistics
\fBCorWatt\fP Watts consumed by the core part of the package. \fBCorWatt\fP Watts consumed by the core part of the package.
\fBGFXWatt\fP Watts consumed by the Graphics part of the package -- available only on client processors. \fBGFXWatt\fP Watts consumed by the Graphics part of the package -- available only on client processors.
\fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors. \fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors.
\fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. \fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. Note that the system summary is the sum of the package throttling time, and thus may be higher than 100% on a multi-package system. Note that the meaning of this field is model specific. For example, some hardware increments this counter when RAPL responds to thermal limits, but does not increment this counter when RAPL responds to power limits. Comparing PkgWatt and PkgTmp to system limits is necessary.
\fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM. \fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM.
.fi .fi
.SH TOO MUCH INFORMATION EXAMPLE .SH TOO MUCH INFORMATION EXAMPLE
......
...@@ -1163,9 +1163,7 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_ ...@@ -1163,9 +1163,7 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_
if (!printed || !summary_only) if (!printed || !summary_only)
print_header("\t"); print_header("\t");
if (topo.num_cpus > 1) format_counters(&average.threads, &average.cores, &average.packages);
format_counters(&average.threads, &average.cores,
&average.packages);
printed = 1; printed = 1;
...@@ -1692,7 +1690,7 @@ void get_apic_id(struct thread_data *t) ...@@ -1692,7 +1690,7 @@ void get_apic_id(struct thread_data *t)
t->x2apic_id = edx; t->x2apic_id = edx;
if (debug && (t->apic_id != t->x2apic_id)) if (debug && (t->apic_id != t->x2apic_id))
fprintf(stderr, "cpu%d: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id); fprintf(outf, "cpu%d: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id);
} }
/* /*
...@@ -2473,55 +2471,43 @@ int get_core_id(int cpu) ...@@ -2473,55 +2471,43 @@ int get_core_id(int cpu)
void set_node_data(void) void set_node_data(void)
{ {
char path[80]; int pkg, node, lnode, cpu, cpux;
FILE *filep; int cpu_count;
int pkg, node, cpu;
struct pkg_node_info {
int count;
int min;
} *pni;
pni = calloc(topo.num_packages, sizeof(struct pkg_node_info)); /* initialize logical_node_id */
if (!pni) for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu)
err(1, "calloc pkg_node_count"); cpus[cpu].logical_node_id = -1;
for (pkg = 0; pkg < topo.num_packages; pkg++) cpu_count = 0;
pni[pkg].min = topo.num_cpus; for (pkg = 0; pkg < topo.num_packages; pkg++) {
lnode = 0;
for (node = 0; node <= topo.max_node_num; node++) { for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) {
/* find the "first" cpu in the node */ if (cpus[cpu].physical_package_id != pkg)
sprintf(path, "/sys/bus/node/devices/node%d/cpulist", node);
filep = fopen(path, "r");
if (!filep)
continue; continue;
fscanf(filep, "%d", &cpu); /* find a cpu with an unset logical_node_id */
fclose(filep); if (cpus[cpu].logical_node_id != -1)
continue;
pkg = cpus[cpu].physical_package_id; cpus[cpu].logical_node_id = lnode;
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;
node = cpus[cpu].physical_node_id; 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) int get_physical_node_id(struct cpu_topology *thiscpu)
...@@ -4471,7 +4457,9 @@ void process_cpuid() ...@@ -4471,7 +4457,9 @@ void process_cpuid()
family = (fms >> 8) & 0xf; family = (fms >> 8) & 0xf;
model = (fms >> 4) & 0xf; model = (fms >> 4) & 0xf;
stepping = fms & 0xf; stepping = fms & 0xf;
if (family == 6 || family == 0xf) if (family == 0xf)
family += (fms >> 20) & 0xff;
if (family >= 6)
model += ((fms >> 16) & 0xf) << 4; model += ((fms >> 16) & 0xf) << 4;
if (!quiet) { if (!quiet) {
...@@ -4840,16 +4828,8 @@ void topology_probe() ...@@ -4840,16 +4828,8 @@ void topology_probe()
siblings = get_thread_siblings(&cpus[i]); siblings = get_thread_siblings(&cpus[i]);
if (siblings > max_siblings) if (siblings > max_siblings)
max_siblings = siblings; max_siblings = siblings;
if (cpus[i].thread_id != -1) if (cpus[i].thread_id == 0)
topo.num_cores++; 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; topo.cores_per_node = max_core_id + 1;
...@@ -4875,6 +4855,20 @@ void topology_probe() ...@@ -4875,6 +4855,20 @@ void topology_probe()
topo.threads_per_core = max_siblings; topo.threads_per_core = max_siblings;
if (debug > 1) if (debug > 1)
fprintf(outf, "max_siblings %d\n", max_siblings); 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 void
...@@ -5102,7 +5096,7 @@ int get_and_dump_counters(void) ...@@ -5102,7 +5096,7 @@ int get_and_dump_counters(void)
} }
void print_version() { void print_version() {
fprintf(outf, "turbostat version 18.06.20" fprintf(outf, "turbostat version 18.07.27"
" - Len Brown <lenb@kernel.org>\n"); " - Len Brown <lenb@kernel.org>\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment