Commit ec3d8b83 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'pm-tools'

Merge power management utilities changes for 5.18-rc1:

 - Add tracer tool for the amd-pstate driver (Jinzhou Su).

 - Fix PC6 displaying in turbostat on some systems (Artem Bityutskiy).

 - Add AMD P-State support to the cpupower utility (Huang Rui).

* pm-tools:
  Documentation: amd-pstate: add tracer tool introduction
  tools/power/x86/amd_pstate_tracer: Add tracer tool for AMD P-state
  tools/power/x86/intel_pstate_tracer: make tracer as a module
  cpufreq: amd-pstate: Add more tracepoint for AMD P-State module
  turbostat: fix PC6 displaying on some systems
  cpupower: Add "perf" option to print AMD P-State information
  cpupower: Add function to print AMD P-State performance capabilities
  cpupower: Move print_speed function into misc helper
  cpupower: Enable boost state support for AMD P-State module
  cpupower: Add AMD P-State sysfs definition and access helper
  cpupower: Introduce ACPI CPPC library
  cpupower: Add the function to get the sysfs value from specific table
  cpupower: Initial AMD P-State capability
  cpupower: Add the function to check AMD P-State enabled
  cpupower: Add AMD P-State capability flag
  tools/power/cpupower/{ToDo => TODO}: Rename the todo file
  tools: cpupower: fix typo in cpupower-idle-set(1) manpage
parents ac9f3109 b020771a
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -369,6 +369,32 @@ governor (for the policies it is attached to), or by the ``CPUFreq`` core (for t
policies with other scaling governors).


Tracer Tool
-------------

``amd_pstate_tracer.py`` can record and parse ``amd-pstate`` trace log, then
generate performance plots. This utility can be used to debug and tune the
performance of ``amd-pstate`` driver. The tracer tool needs to import intel
pstate tracer.

Tracer tool located in ``linux/tools/power/x86/amd_pstate_tracer``. It can be
used in two ways. If trace file is available, then directly parse the file
with command ::

 ./amd_pstate_trace.py [-c cpus] -t <trace_file> -n <test_name>

Or generate trace file with root privilege, then parse and plot with command ::

 sudo ./amd_pstate_trace.py [-c cpus] -n <test_name> -i <interval> [-m kbytes]

The test result can be found in ``results/test_name``. Following is the example
about part of the output. ::

 common_cpu  common_secs  common_usecs  min_perf  des_perf  max_perf  freq    mperf   apef    tsc       load   duration_ms  sample_num  elapsed_time  common_comm
 CPU_005     712          116384        39        49        166       0.7565  9645075 2214891 38431470  25.1   11.646       469         2.496         kworker/5:0-40
 CPU_006     712          116408        39        49        166       0.6769  8950227 1839034 37192089  24.06  11.272       470         2.496         kworker/6:0-1264


Reference
===========

+1 −0
Original line number Diff line number Diff line
@@ -1002,6 +1002,7 @@ L: linux-pm@vger.kernel.org
S:	Supported
F:	Documentation/admin-guide/pm/amd-pstate.rst
F:	drivers/cpufreq/amd-pstate*
F:	tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
AMD PTDMA DRIVER
M:	Sanjay R Mehta <sanju.mehta@amd.com>
+21 −1
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@ TRACE_EVENT(amd_pstate_perf,
	TP_PROTO(unsigned long min_perf,
		 unsigned long target_perf,
		 unsigned long capacity,
		 u64 freq,
		 u64 mperf,
		 u64 aperf,
		 u64 tsc,
		 unsigned int cpu_id,
		 bool changed,
		 bool fast_switch
@@ -35,6 +39,10 @@ TRACE_EVENT(amd_pstate_perf,
	TP_ARGS(min_perf,
		target_perf,
		capacity,
		freq,
		mperf,
		aperf,
		tsc,
		cpu_id,
		changed,
		fast_switch
@@ -44,6 +52,10 @@ TRACE_EVENT(amd_pstate_perf,
		__field(unsigned long, min_perf)
		__field(unsigned long, target_perf)
		__field(unsigned long, capacity)
		__field(unsigned long long, freq)
		__field(unsigned long long, mperf)
		__field(unsigned long long, aperf)
		__field(unsigned long long, tsc)
		__field(unsigned int, cpu_id)
		__field(bool, changed)
		__field(bool, fast_switch)
@@ -53,15 +65,23 @@ TRACE_EVENT(amd_pstate_perf,
		__entry->min_perf = min_perf;
		__entry->target_perf = target_perf;
		__entry->capacity = capacity;
		__entry->freq = freq;
		__entry->mperf = mperf;
		__entry->aperf = aperf;
		__entry->tsc = tsc;
		__entry->cpu_id = cpu_id;
		__entry->changed = changed;
		__entry->fast_switch = fast_switch;
		),

	TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu cpu_id=%u changed=%s fast_switch=%s",
	TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u changed=%s fast_switch=%s",
		  (unsigned long)__entry->min_perf,
		  (unsigned long)__entry->target_perf,
		  (unsigned long)__entry->capacity,
		  (unsigned long long)__entry->freq,
		  (unsigned long long)__entry->mperf,
		  (unsigned long long)__entry->aperf,
		  (unsigned long long)__entry->tsc,
		  (unsigned int)__entry->cpu_id,
		  (__entry->changed) ? "true" : "false",
		  (__entry->fast_switch) ? "true" : "false"
+57 −2
Original line number Diff line number Diff line
@@ -65,6 +65,18 @@ MODULE_PARM_DESC(shared_mem,

static struct cpufreq_driver amd_pstate_driver;

/**
 * struct  amd_aperf_mperf
 * @aperf: actual performance frequency clock count
 * @mperf: maximum performance frequency clock count
 * @tsc:   time stamp counter
 */
struct amd_aperf_mperf {
	u64 aperf;
	u64 mperf;
	u64 tsc;
};

/**
 * struct amd_cpudata - private CPU data for AMD P-State
 * @cpu: CPU number
@@ -81,6 +93,9 @@ static struct cpufreq_driver amd_pstate_driver;
 * @min_freq: the frequency that mapped to lowest_perf
 * @nominal_freq: the frequency that mapped to nominal_perf
 * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
 * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
 * @prev: Last Aperf/Mperf/tsc count value read from register
 * @freq: current cpu frequency value
 * @boost_supported: check whether the Processor or SBIOS supports boost mode
 *
 * The amd_cpudata is key private data for each CPU thread in AMD P-State, and
@@ -102,6 +117,10 @@ struct amd_cpudata {
	u32	nominal_freq;
	u32	lowest_nonlinear_freq;

	struct amd_aperf_mperf cur;
	struct amd_aperf_mperf prev;

	u64 freq;
	bool	boost_supported;
};

@@ -211,6 +230,39 @@ static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
					    max_perf, fast_switch);
}

static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
{
	u64 aperf, mperf, tsc;
	unsigned long flags;

	local_irq_save(flags);
	rdmsrl(MSR_IA32_APERF, aperf);
	rdmsrl(MSR_IA32_MPERF, mperf);
	tsc = rdtsc();

	if (cpudata->prev.mperf == mperf || cpudata->prev.tsc == tsc) {
		local_irq_restore(flags);
		return false;
	}

	local_irq_restore(flags);

	cpudata->cur.aperf = aperf;
	cpudata->cur.mperf = mperf;
	cpudata->cur.tsc =  tsc;
	cpudata->cur.aperf -= cpudata->prev.aperf;
	cpudata->cur.mperf -= cpudata->prev.mperf;
	cpudata->cur.tsc -= cpudata->prev.tsc;

	cpudata->prev.aperf = aperf;
	cpudata->prev.mperf = mperf;
	cpudata->prev.tsc = tsc;

	cpudata->freq = div64_u64((cpudata->cur.aperf * cpu_khz), cpudata->cur.mperf);

	return true;
}

static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
			      u32 des_perf, u32 max_perf, bool fast_switch)
{
@@ -226,8 +278,11 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
	value &= ~AMD_CPPC_MAX_PERF(~0L);
	value |= AMD_CPPC_MAX_PERF(max_perf);

	trace_amd_pstate_perf(min_perf, des_perf, max_perf,
	if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
		trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
			cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc,
				cpudata->cpu, (value != prev), fast_switch);
	}

	if (value == prev)
		return;
+3 −3
Original line number Diff line number Diff line
@@ -143,9 +143,9 @@ UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \
	utils/helpers/bitmask.h \
	utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def

LIB_HEADERS = 	lib/cpufreq.h lib/cpupower.h lib/cpuidle.h
LIB_SRC = 	lib/cpufreq.c lib/cpupower.c lib/cpuidle.c
LIB_OBJS = 	lib/cpufreq.o lib/cpupower.o lib/cpuidle.o
LIB_HEADERS = 	lib/cpufreq.h lib/cpupower.h lib/cpuidle.h lib/acpi_cppc.h
LIB_SRC = 	lib/cpufreq.c lib/cpupower.c lib/cpuidle.c lib/acpi_cppc.c
LIB_OBJS = 	lib/cpufreq.o lib/cpupower.o lib/cpuidle.o lib/acpi_cppc.o
LIB_OBJS :=	$(addprefix $(OUTPUT),$(LIB_OBJS))

override CFLAGS +=	-pipe
Loading