Commit 227ed18f authored by Chen Yu's avatar Chen Yu Committed by Len Brown
Browse files

tools/power turbostat: Do not print negative LPI residency



turbostat prints the abnormal SYS%LPI across suspend-to-idle:
SYS%LPI = 114479815993277.50

This is reproduced by:
Run a freeze cycle, e.g. "sleepgraph -m freeze -rtcwake 15".
Then do a reboot. After boot up, launch the suspend-idle-idle
and check the SYS%LPI field.

The slp_so residence counter is in LPIT table, and BIOS does not
clears this register across reset. The PMC expects the OS to calculate
the LPI residency based on the delta. However, there is an firmware
issue that the LPIT gets cleared to 0 during the second suspend
to idle after the reboot, which brings negative delta value.

[lenb: updated to print "neg" upon this BIOS failure]

Reported-by: default avatarTodd Brandt <todd.e.brandt@intel.com>
Signed-off-by: default avatarChen Yu <yu.c.chen@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 0b13410b
Loading
Loading
Loading
Loading
+21 −9
Original line number Diff line number Diff line
@@ -991,8 +991,8 @@ struct pkg_data {
	unsigned long long pc8;
	unsigned long long pc9;
	unsigned long long pc10;
	unsigned long long cpu_lpi;
	unsigned long long sys_lpi;
	long long cpu_lpi;
	long long sys_lpi;
	unsigned long long pkg_wtd_core_c0;
	unsigned long long pkg_any_core_c0;
	unsigned long long pkg_any_gfxe_c0;
@@ -1978,12 +1978,22 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
	if (DO_BIC(BIC_Pkgpc10))
		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc10 / tsc);

	if (DO_BIC(BIC_CPU_LPI))
	if (DO_BIC(BIC_CPU_LPI)) {
		if (p->cpu_lpi >= 0)
			outp +=
		    sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->cpu_lpi / 1000000.0 / interval_float);
	if (DO_BIC(BIC_SYS_LPI))
			    sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
				    100.0 * p->cpu_lpi / 1000000.0 / interval_float);
		else
			outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
	}
	if (DO_BIC(BIC_SYS_LPI)) {
		if (p->sys_lpi >= 0)
			outp +=
		    sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float);
			    sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
				    100.0 * p->sys_lpi / 1000000.0 / interval_float);
		else
			outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
	}

	if (DO_BIC(BIC_PkgWatt))
		outp +=
@@ -3832,7 +3842,8 @@ void re_initialize(void)
{
	free_all_buffers();
	setup_all_buffers(false);
	fprintf(outf, "turbostat: re-initialized with num_cpus %d, allowed_cpus %d\n", topo.num_cpus, topo.allowed_cpus);
	fprintf(outf, "turbostat: re-initialized with num_cpus %d, allowed_cpus %d\n", topo.num_cpus,
		topo.allowed_cpus);
}

void set_max_cpu_num(void)
@@ -6145,6 +6156,7 @@ void topology_update(void)
	topo.allowed_packages = 0;
	for_all_cpus(update_topo, ODD_COUNTERS);
}

void setup_all_buffers(bool startup)
{
	topology_probe(startup);