aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Smythies <doug.smythies@gmail.com>2018-05-14 11:35:49 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-05-14 17:34:25 -0400
commit50e9ffaba5ccaac01c5deb17f32b501ba3ed72f0 (patch)
treea5ec6be168e51cc659e101c3119498ab7c284377
parent20b5324d8353d66e68e8c40031e438c247cf2d65 (diff)
cpufreq: intel_pstate: allow trace in passive mode
Allow use of the trace_pstate_sample trace function when the intel_pstate driver is in passive mode. Since the core_busy and scaled_busy fields are not used, and it might be desirable to know which path through the driver was used, either intel_cpufreq_target or intel_cpufreq_fast_switch, re-task the core_busy field as a flag indicator. The user can then use the intel_pstate_tracer.py utility to summarize and plot the trace. Note: The core_busy feild still goes by that name in include/trace/events/power.h and within the intel_pstate_tracer.py script and csv file headers, but it is graphed as "performance", and called core_avg_perf now in the intel_pstate driver. Sometimes, in passive mode, the driver is not called for many tens or even hundreds of seconds. The user needs to understand, and not be confused by, this limitation. Signed-off-by: Doug Smythies <dsmythies@telus.net> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/intel_pstate.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 17e566afbb41..08960a55eb27 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1939,13 +1939,51 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
1939 return 0; 1939 return 0;
1940} 1940}
1941 1941
1942/* Use of trace in passive mode:
1943 *
1944 * In passive mode the trace core_busy field (also known as the
1945 * performance field, and lablelled as such on the graphs; also known as
1946 * core_avg_perf) is not needed and so is re-assigned to indicate if the
1947 * driver call was via the normal or fast switch path. Various graphs
1948 * output from the intel_pstate_tracer.py utility that include core_busy
1949 * (or performance or core_avg_perf) have a fixed y-axis from 0 to 100%,
1950 * so we use 10 to indicate the the normal path through the driver, and
1951 * 90 to indicate the fast switch path through the driver.
1952 * The scaled_busy field is not used, and is set to 0.
1953 */
1954
1955#define INTEL_PSTATE_TRACE_TARGET 10
1956#define INTEL_PSTATE_TRACE_FAST_SWITCH 90
1957
1958static void intel_cpufreq_trace(struct cpudata *cpu, unsigned int trace_type, int old_pstate)
1959{
1960 struct sample *sample;
1961
1962 if (!trace_pstate_sample_enabled())
1963 return;
1964
1965 if (!intel_pstate_sample(cpu, ktime_get()))
1966 return;
1967
1968 sample = &cpu->sample;
1969 trace_pstate_sample(trace_type,
1970 0,
1971 old_pstate,
1972 cpu->pstate.current_pstate,
1973 sample->mperf,
1974 sample->aperf,
1975 sample->tsc,
1976 get_avg_frequency(cpu),
1977 fp_toint(cpu->iowait_boost * 100));
1978}
1979
1942static int intel_cpufreq_target(struct cpufreq_policy *policy, 1980static int intel_cpufreq_target(struct cpufreq_policy *policy,
1943 unsigned int target_freq, 1981 unsigned int target_freq,
1944 unsigned int relation) 1982 unsigned int relation)
1945{ 1983{
1946 struct cpudata *cpu = all_cpu_data[policy->cpu]; 1984 struct cpudata *cpu = all_cpu_data[policy->cpu];
1947 struct cpufreq_freqs freqs; 1985 struct cpufreq_freqs freqs;
1948 int target_pstate; 1986 int target_pstate, old_pstate;
1949 1987
1950 update_turbo_state(); 1988 update_turbo_state();
1951 1989
@@ -1965,12 +2003,14 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
1965 break; 2003 break;
1966 } 2004 }
1967 target_pstate = intel_pstate_prepare_request(cpu, target_pstate); 2005 target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
2006 old_pstate = cpu->pstate.current_pstate;
1968 if (target_pstate != cpu->pstate.current_pstate) { 2007 if (target_pstate != cpu->pstate.current_pstate) {
1969 cpu->pstate.current_pstate = target_pstate; 2008 cpu->pstate.current_pstate = target_pstate;
1970 wrmsrl_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, 2009 wrmsrl_on_cpu(policy->cpu, MSR_IA32_PERF_CTL,
1971 pstate_funcs.get_val(cpu, target_pstate)); 2010 pstate_funcs.get_val(cpu, target_pstate));
1972 } 2011 }
1973 freqs.new = target_pstate * cpu->pstate.scaling; 2012 freqs.new = target_pstate * cpu->pstate.scaling;
2013 intel_cpufreq_trace(cpu, INTEL_PSTATE_TRACE_TARGET, old_pstate);
1974 cpufreq_freq_transition_end(policy, &freqs, false); 2014 cpufreq_freq_transition_end(policy, &freqs, false);
1975 2015
1976 return 0; 2016 return 0;
@@ -1980,13 +2020,15 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy,
1980 unsigned int target_freq) 2020 unsigned int target_freq)
1981{ 2021{
1982 struct cpudata *cpu = all_cpu_data[policy->cpu]; 2022 struct cpudata *cpu = all_cpu_data[policy->cpu];
1983 int target_pstate; 2023 int target_pstate, old_pstate;
1984 2024
1985 update_turbo_state(); 2025 update_turbo_state();
1986 2026
1987 target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling); 2027 target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling);
1988 target_pstate = intel_pstate_prepare_request(cpu, target_pstate); 2028 target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
2029 old_pstate = cpu->pstate.current_pstate;
1989 intel_pstate_update_pstate(cpu, target_pstate); 2030 intel_pstate_update_pstate(cpu, target_pstate);
2031 intel_cpufreq_trace(cpu, INTEL_PSTATE_TRACE_FAST_SWITCH, old_pstate);
1990 return target_pstate * cpu->pstate.scaling; 2032 return target_pstate * cpu->pstate.scaling;
1991} 2033}
1992 2034