linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations
@ 2017-03-12 17:11 Rafael J. Wysocki
  2017-03-12 17:12 ` [PATCH 01/14] cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set() Rafael J. Wysocki
                   ` (15 more replies)
  0 siblings, 16 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:11 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

Hi,

This patch series fixes a couple of bugs in intel_pstate, cleans up the code in
it somewhat and makes some changes targeted at overhead reductions.

Patch [1/14] is a regression fix, patch [2/14] can be regarded as a fix too,

Patches [3-9/14] are cleanups mostly getting rid of unnecessary stuff.

Patches [10-11/14] make changes to reduce the overhead of utilization update
callbacks used in the active mode.

Patches [12-14/14] make more cleanups on top of that.

Refer to the changelogs for details.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/14] cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set()
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
@ 2017-03-12 17:12 ` Rafael J. Wysocki
  2017-03-13  4:00   ` Viresh Kumar
  2017-03-12 17:13 ` [PATCH 02/14] cpufreq: intel_pstate: Drop pointless initialization of PID parameters Rafael J. Wysocki
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:12 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Fix the debugfs interface for PID tuning to actually update
pid_params.sample_rate_ns on PID parameters updates, as changing
pid_params.sample_rate_ms via debugfs has no effect now.

Fixes: a4675fbc4a7a (cpufreq: intel_pstate: Replace timers with utilization update callbacks)
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |    1 +
 1 file changed, 1 insertion(+)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -983,6 +983,7 @@ static void intel_pstate_update_policies
 static int pid_param_set(void *data, u64 val)
 {
 	*(u32 *)data = val;
+	pid_params.sample_rate_ns = pid_params.sample_rate_ms * NSEC_PER_MSEC;
 	intel_pstate_reset_all_pid();
 	return 0;
 }

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 02/14] cpufreq: intel_pstate: Drop pointless initialization of PID parameters
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
  2017-03-12 17:12 ` [PATCH 01/14] cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set() Rafael J. Wysocki
@ 2017-03-12 17:13 ` Rafael J. Wysocki
  2017-03-12 17:14 ` [PATCH 03/14] cpufreq: intel_pstate: Initialize pid_params statically Rafael J. Wysocki
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:13 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The P-state selection algorithm used by intel_pstate for Atom
processors is not based on the PID controller and the initialization
of PID parametrs for those processors is pointless and confusing, so
drop it.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   28 ++--------------------------
 1 file changed, 2 insertions(+), 26 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1592,14 +1592,6 @@ static struct cpu_defaults core_params =
 };
 
 static const struct cpu_defaults silvermont_params = {
-	.pid_policy = {
-		.sample_rate_ms = 10,
-		.deadband = 0,
-		.setpoint = 60,
-		.p_gain_pct = 14,
-		.d_gain_pct = 0,
-		.i_gain_pct = 4,
-	},
 	.funcs = {
 		.get_max = atom_get_max_pstate,
 		.get_max_physical = atom_get_max_pstate,
@@ -1613,14 +1605,6 @@ static const struct cpu_defaults silverm
 };
 
 static const struct cpu_defaults airmont_params = {
-	.pid_policy = {
-		.sample_rate_ms = 10,
-		.deadband = 0,
-		.setpoint = 60,
-		.p_gain_pct = 14,
-		.d_gain_pct = 0,
-		.i_gain_pct = 4,
-	},
 	.funcs = {
 		.get_max = atom_get_max_pstate,
 		.get_max_physical = atom_get_max_pstate,
@@ -1654,14 +1638,6 @@ static const struct cpu_defaults knl_par
 };
 
 static const struct cpu_defaults bxt_params = {
-	.pid_policy = {
-		.sample_rate_ms = 10,
-		.deadband = 0,
-		.setpoint = 60,
-		.p_gain_pct = 14,
-		.d_gain_pct = 0,
-		.i_gain_pct = 4,
-	},
 	.funcs = {
 		.get_max = core_get_max_pstate,
 		.get_max_physical = core_get_max_pstate_physical,
@@ -2721,9 +2697,9 @@ static int __init intel_pstate_init(void
 		return -ENODEV;
 
 	cpu_def = (struct cpu_defaults *)id->driver_data;
-
-	copy_pid_params(&cpu_def->pid_policy);
 	copy_cpu_funcs(&cpu_def->funcs);
+	if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance)
+		copy_pid_params(&cpu_def->pid_policy);
 
 	if (intel_pstate_msrs_not_valid())
 		return -ENODEV;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 03/14] cpufreq: intel_pstate: Initialize pid_params statically
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
  2017-03-12 17:12 ` [PATCH 01/14] cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set() Rafael J. Wysocki
  2017-03-12 17:13 ` [PATCH 02/14] cpufreq: intel_pstate: Drop pointless initialization of PID parameters Rafael J. Wysocki
@ 2017-03-12 17:14 ` Rafael J. Wysocki
  2017-03-12 17:15 ` [PATCH 04/14] cpufreq: intel_pstate: Fold intel_pstate_reset_all_pid() into the caller Rafael J. Wysocki
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:14 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Notice that both the existing struct cpu_defaults instances in which
PID parameters are actually initialized use the same values of those
parameters, so it is not really necessary to copy them over to
pid_params dynamically.

Instead, initialize pid_params statically with those values and
drop the unused pid_policy member from struct cpu_defaults along
with copy_pid_params() used for initializing it.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   42 +++++++++--------------------------------
 1 file changed, 10 insertions(+), 32 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -342,19 +342,26 @@ struct pstate_funcs {
 
 /**
  * struct cpu_defaults- Per CPU model default config data
- * @pid_policy:	PID config data
  * @funcs:		Callback function data
  */
 struct cpu_defaults {
-	struct pstate_adjust_policy pid_policy;
 	struct pstate_funcs funcs;
 };
 
 static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu);
 static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu);
 
-static struct pstate_adjust_policy pid_params __read_mostly;
 static struct pstate_funcs pstate_funcs __read_mostly;
+static struct pstate_adjust_policy pid_params __read_mostly = {
+	.sample_rate_ms = 10,
+	.sample_rate_ns = 10 * NSEC_PER_MSEC,
+	.deadband = 0,
+	.setpoint = 97,
+	.p_gain_pct = 20,
+	.d_gain_pct = 0,
+	.i_gain_pct = 0,
+};
+
 static int hwp_active __read_mostly;
 static bool per_cpu_limits __read_mostly;
 
@@ -1572,14 +1579,6 @@ static int knl_get_turbo_pstate(void)
 }
 
 static struct cpu_defaults core_params = {
-	.pid_policy = {
-		.sample_rate_ms = 10,
-		.deadband = 0,
-		.setpoint = 97,
-		.p_gain_pct = 20,
-		.d_gain_pct = 0,
-		.i_gain_pct = 0,
-	},
 	.funcs = {
 		.get_max = core_get_max_pstate,
 		.get_max_physical = core_get_max_pstate_physical,
@@ -1618,14 +1617,6 @@ static const struct cpu_defaults airmont
 };
 
 static const struct cpu_defaults knl_params = {
-	.pid_policy = {
-		.sample_rate_ms = 10,
-		.deadband = 0,
-		.setpoint = 97,
-		.p_gain_pct = 20,
-		.d_gain_pct = 0,
-		.i_gain_pct = 0,
-	},
 	.funcs = {
 		.get_max = core_get_max_pstate,
 		.get_max_physical = core_get_max_pstate_physical,
@@ -2506,17 +2497,6 @@ static int __init intel_pstate_msrs_not_
 	return 0;
 }
 
-static void __init copy_pid_params(struct pstate_adjust_policy *policy)
-{
-	pid_params.sample_rate_ms = policy->sample_rate_ms;
-	pid_params.sample_rate_ns = pid_params.sample_rate_ms * NSEC_PER_MSEC;
-	pid_params.p_gain_pct = policy->p_gain_pct;
-	pid_params.i_gain_pct = policy->i_gain_pct;
-	pid_params.d_gain_pct = policy->d_gain_pct;
-	pid_params.deadband = policy->deadband;
-	pid_params.setpoint = policy->setpoint;
-}
-
 #ifdef CONFIG_ACPI
 static void intel_pstate_use_acpi_profile(void)
 {
@@ -2698,8 +2678,6 @@ static int __init intel_pstate_init(void
 
 	cpu_def = (struct cpu_defaults *)id->driver_data;
 	copy_cpu_funcs(&cpu_def->funcs);
-	if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance)
-		copy_pid_params(&cpu_def->pid_policy);
 
 	if (intel_pstate_msrs_not_valid())
 		return -ENODEV;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 04/14] cpufreq: intel_pstate: Fold intel_pstate_reset_all_pid() into the caller
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (2 preceding siblings ...)
  2017-03-12 17:14 ` [PATCH 03/14] cpufreq: intel_pstate: Initialize pid_params statically Rafael J. Wysocki
@ 2017-03-12 17:15 ` Rafael J. Wysocki
  2017-03-12 17:16 ` [PATCH 05/14] cpufreq: intel_pstate: Clean up intel_pstate_busy_pid_reset() Rafael J. Wysocki
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:15 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

There is only one caller of intel_pstate_reset_all_pid(), which is
pid_param_set() used in the debugfs interface only, and having that
code split does not make it particularly convenient to follow.

For this reason, move the body of intel_pstate_reset_all_pid() into
its caller and drop that function.

Also change the loop from for_each_online_cpu() (which is obviously
racy with respect to CPU offline/online) to for_each_possible_cpu(),
so that all PID parameters are reset for all CPUs regardless of their
online/offline status (to prevent, for example, a previously offline
CPU from going online with a stale set of PID parameters).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -616,16 +616,6 @@ static inline void intel_pstate_busy_pid
 	pid_reset(&cpu->pid, pid_params.setpoint, 100, pid_params.deadband, 0);
 }
 
-static inline void intel_pstate_reset_all_pid(void)
-{
-	unsigned int cpu;
-
-	for_each_online_cpu(cpu) {
-		if (all_cpu_data[cpu])
-			intel_pstate_busy_pid_reset(all_cpu_data[cpu]);
-	}
-}
-
 static inline void update_turbo_state(void)
 {
 	u64 misc_en;
@@ -989,9 +979,14 @@ static void intel_pstate_update_policies
 /************************** debugfs begin ************************/
 static int pid_param_set(void *data, u64 val)
 {
+	unsigned int cpu;
+
 	*(u32 *)data = val;
 	pid_params.sample_rate_ns = pid_params.sample_rate_ms * NSEC_PER_MSEC;
-	intel_pstate_reset_all_pid();
+	for_each_possible_cpu(cpu)
+		if (all_cpu_data[cpu])
+			intel_pstate_busy_pid_reset(all_cpu_data[cpu]);
+
 	return 0;
 }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 05/14] cpufreq: intel_pstate: Clean up intel_pstate_busy_pid_reset()
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (3 preceding siblings ...)
  2017-03-12 17:15 ` [PATCH 04/14] cpufreq: intel_pstate: Fold intel_pstate_reset_all_pid() into the caller Rafael J. Wysocki
@ 2017-03-12 17:16 ` Rafael J. Wysocki
  2017-03-12 17:17 ` [PATCH 06/14] cpufreq: intel_pstate: Set HWP sampling interval once Rafael J. Wysocki
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:16 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

intel_pstate_busy_pid_reset() is the only caller of pid_reset(),
pid_p_gain_set(), pid_i_gain_set(), and pid_d_gain_set().  Moreover,
it passes constatns as two parameters of pid_reset() and all of
the other routines above essentially contain the same code, so
fold all of them into the caller and drop unnecessary computations.

Introduce percent_fp() for converting integer values in percent
to fixed-point fractions and use it in the above code cleanup.

Finally, rename intel_pstate_busy_pid_reset() to
intel_pstate_pid_reset() as it also is used for the
initialization of PID parameters for every CPU and the
meaning of the "busy" part of the name is not particularly
clear.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   46 ++++++++++++++---------------------------
 1 file changed, 16 insertions(+), 30 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -79,6 +79,11 @@ static inline int ceiling_fp(int32_t x)
 	return ret;
 }
 
+static inline int32_t percent_fp(int percent)
+{
+	return div_fp(percent, 100);
+}
+
 static inline u64 mul_ext_fp(u64 x, u64 y)
 {
 	return (x * y) >> EXT_FRAC_BITS;
@@ -547,29 +552,6 @@ static inline void intel_pstate_exit_per
 }
 #endif
 
-static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
-			     int deadband, int integral) {
-	pid->setpoint = int_tofp(setpoint);
-	pid->deadband  = int_tofp(deadband);
-	pid->integral  = int_tofp(integral);
-	pid->last_err  = int_tofp(setpoint) - int_tofp(busy);
-}
-
-static inline void pid_p_gain_set(struct _pid *pid, int percent)
-{
-	pid->p_gain = div_fp(percent, 100);
-}
-
-static inline void pid_i_gain_set(struct _pid *pid, int percent)
-{
-	pid->i_gain = div_fp(percent, 100);
-}
-
-static inline void pid_d_gain_set(struct _pid *pid, int percent)
-{
-	pid->d_gain = div_fp(percent, 100);
-}
-
 static signed int pid_calc(struct _pid *pid, int32_t busy)
 {
 	signed int result;
@@ -607,13 +589,17 @@ static signed int pid_calc(struct _pid *
 	return (signed int)fp_toint(result);
 }
 
-static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu)
+static inline void intel_pstate_pid_reset(struct cpudata *cpu)
 {
-	pid_p_gain_set(&cpu->pid, pid_params.p_gain_pct);
-	pid_d_gain_set(&cpu->pid, pid_params.d_gain_pct);
-	pid_i_gain_set(&cpu->pid, pid_params.i_gain_pct);
+	struct _pid *pid = &cpu->pid;
 
-	pid_reset(&cpu->pid, pid_params.setpoint, 100, pid_params.deadband, 0);
+	pid->p_gain = percent_fp(pid_params.p_gain_pct);
+	pid->d_gain = percent_fp(pid_params.d_gain_pct);
+	pid->i_gain = percent_fp(pid_params.i_gain_pct);
+	pid->setpoint = int_tofp(pid_params.setpoint);
+	pid->last_err  = pid->setpoint - int_tofp(100);
+	pid->deadband  = int_tofp(pid_params.deadband);
+	pid->integral  = 0;
 }
 
 static inline void update_turbo_state(void)
@@ -985,7 +971,7 @@ static int pid_param_set(void *data, u64
 	pid_params.sample_rate_ns = pid_params.sample_rate_ms * NSEC_PER_MSEC;
 	for_each_possible_cpu(cpu)
 		if (all_cpu_data[cpu])
-			intel_pstate_busy_pid_reset(all_cpu_data[cpu]);
+			intel_pstate_pid_reset(all_cpu_data[cpu]);
 
 	return 0;
 }
@@ -1994,7 +1980,7 @@ static int intel_pstate_init_cpu(unsigne
 
 	intel_pstate_get_cpu_pstates(cpu);
 
-	intel_pstate_busy_pid_reset(cpu);
+	intel_pstate_pid_reset(cpu);
 
 	pr_debug("controlling: cpu %d\n", cpunum);
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 06/14] cpufreq: intel_pstate: Set HWP sampling interval once
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (4 preceding siblings ...)
  2017-03-12 17:16 ` [PATCH 05/14] cpufreq: intel_pstate: Clean up intel_pstate_busy_pid_reset() Rafael J. Wysocki
@ 2017-03-12 17:17 ` Rafael J. Wysocki
  2017-03-12 17:18 ` [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init Rafael J. Wysocki
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:17 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

In the HWP enabled case pid_params.sample_rate_ns only needs to be
updated once, because it is global, so do that when setting hwp_active
instead of doing it during the initialization of every CPU.

Moreover, pid_params.sample_rate_ms is never used if HWP is enabled,
so do not update it at all then.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1974,8 +1974,6 @@ static int intel_pstate_init_cpu(unsigne
 			intel_pstate_disable_ee(cpunum);
 
 		intel_pstate_hwp_enable(cpu);
-		pid_params.sample_rate_ms = 50;
-		pid_params.sample_rate_ns = 50 * NSEC_PER_MSEC;
 	}
 
 	intel_pstate_get_cpu_pstates(cpu);
@@ -2650,6 +2648,7 @@ static int __init intel_pstate_init(void
 		copy_cpu_funcs(&core_params.funcs);
 		hwp_active++;
 		intel_pstate.attr = hwp_cpufreq_attrs;
+		pid_params.sample_rate_ns = 50 * NSEC_PER_MSEC;
 		goto hwp_cpu_matched;
 	}
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (5 preceding siblings ...)
  2017-03-12 17:17 ` [PATCH 06/14] cpufreq: intel_pstate: Set HWP sampling interval once Rafael J. Wysocki
@ 2017-03-12 17:18 ` Rafael J. Wysocki
  2017-03-12 17:19 ` [PATCH 08/14] cpufreq: intel_pstate: Drop driver_registered variable Rafael J. Wysocki
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:18 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

PID controller parameters only need to be initialized if the
get_target_pstate_use_performance() P-state selection routine
is going to be used.  It is not necessary to initialize them
otherwise, so don't do that.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1974,12 +1974,12 @@ static int intel_pstate_init_cpu(unsigne
 			intel_pstate_disable_ee(cpunum);
 
 		intel_pstate_hwp_enable(cpu);
+	} else if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance) {
+		intel_pstate_pid_reset(cpu);
 	}
 
 	intel_pstate_get_cpu_pstates(cpu);
 
-	intel_pstate_pid_reset(cpu);
-
 	pr_debug("controlling: cpu %d\n", cpunum);
 
 	return 0;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 08/14] cpufreq: intel_pstate: Drop driver_registered variable
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (6 preceding siblings ...)
  2017-03-12 17:18 ` [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init Rafael J. Wysocki
@ 2017-03-12 17:19 ` Rafael J. Wysocki
  2017-03-12 17:20 ` [PATCH 09/14] cpufreq: intel_pstate: Modify check in intel_pstate_update_status() Rafael J. Wysocki
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:19 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The driver_registered variable in intel_pstate is used for checking
whether or not the driver has been registered, but intel_pstate_driver
can be used for that too (with the rule that the driver is not
registered as long as it is NULL).

That is a bit more straightforward and the code may be simplified
a bit this way, so modify the driver accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   46 ++++++++++++++++-------------------------
 1 file changed, 19 insertions(+), 27 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -370,7 +370,7 @@ static struct pstate_adjust_policy pid_p
 static int hwp_active __read_mostly;
 static bool per_cpu_limits __read_mostly;
 
-static bool driver_registered __read_mostly;
+static struct cpufreq_driver *intel_pstate_driver __read_mostly;
 
 #ifdef CONFIG_ACPI
 static bool acpi_ppc;
@@ -1083,7 +1083,7 @@ static ssize_t show_turbo_pct(struct kob
 
 	mutex_lock(&intel_pstate_driver_lock);
 
-	if (!driver_registered) {
+	if (!intel_pstate_driver) {
 		mutex_unlock(&intel_pstate_driver_lock);
 		return -EAGAIN;
 	}
@@ -1108,7 +1108,7 @@ static ssize_t show_num_pstates(struct k
 
 	mutex_lock(&intel_pstate_driver_lock);
 
-	if (!driver_registered) {
+	if (!intel_pstate_driver) {
 		mutex_unlock(&intel_pstate_driver_lock);
 		return -EAGAIN;
 	}
@@ -1128,7 +1128,7 @@ static ssize_t show_no_turbo(struct kobj
 
 	mutex_lock(&intel_pstate_driver_lock);
 
-	if (!driver_registered) {
+	if (!intel_pstate_driver) {
 		mutex_unlock(&intel_pstate_driver_lock);
 		return -EAGAIN;
 	}
@@ -1156,7 +1156,7 @@ static ssize_t store_no_turbo(struct kob
 
 	mutex_lock(&intel_pstate_driver_lock);
 
-	if (!driver_registered) {
+	if (!intel_pstate_driver) {
 		mutex_unlock(&intel_pstate_driver_lock);
 		return -EAGAIN;
 	}
@@ -1194,7 +1194,7 @@ static ssize_t store_max_perf_pct(struct
 
 	mutex_lock(&intel_pstate_driver_lock);
 
-	if (!driver_registered) {
+	if (!intel_pstate_driver) {
 		mutex_unlock(&intel_pstate_driver_lock);
 		return -EAGAIN;
 	}
@@ -1231,7 +1231,7 @@ static ssize_t store_min_perf_pct(struct
 
 	mutex_lock(&intel_pstate_driver_lock);
 
-	if (!driver_registered) {
+	if (!intel_pstate_driver) {
 		mutex_unlock(&intel_pstate_driver_lock);
 		return -EAGAIN;
 	}
@@ -2346,7 +2346,7 @@ static struct cpufreq_driver intel_cpufr
 	.name		= "intel_cpufreq",
 };
 
-static struct cpufreq_driver *intel_pstate_driver = &intel_pstate;
+static struct cpufreq_driver *default_driver = &intel_pstate;
 
 static void intel_pstate_driver_cleanup(void)
 {
@@ -2363,12 +2363,14 @@ static void intel_pstate_driver_cleanup(
 		}
 	}
 	put_online_cpus();
+	intel_pstate_driver = NULL;
 }
 
-static int intel_pstate_register_driver(void)
+static int intel_pstate_register_driver(struct cpufreq_driver *driver)
 {
 	int ret;
 
+	intel_pstate_driver = driver;
 	intel_pstate_init_limits(&powersave_limits);
 	intel_pstate_set_performance_limits(&performance_limits);
 	if (IS_ENABLED(CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE) &&
@@ -2383,10 +2385,6 @@ static int intel_pstate_register_driver(
 		return ret;
 	}
 
-	mutex_lock(&intel_pstate_limits_lock);
-	driver_registered = true;
-	mutex_unlock(&intel_pstate_limits_lock);
-
 	if (intel_pstate_driver == &intel_pstate && !hwp_active &&
 	    pstate_funcs.get_target_pstate != get_target_pstate_use_cpu_load)
 		intel_pstate_debug_expose_params();
@@ -2403,10 +2401,6 @@ static int intel_pstate_unregister_drive
 	    pstate_funcs.get_target_pstate != get_target_pstate_use_cpu_load)
 		intel_pstate_debug_hide_params();
 
-	mutex_lock(&intel_pstate_limits_lock);
-	driver_registered = false;
-	mutex_unlock(&intel_pstate_limits_lock);
-
 	cpufreq_unregister_driver(intel_pstate_driver);
 	intel_pstate_driver_cleanup();
 
@@ -2415,7 +2409,7 @@ static int intel_pstate_unregister_drive
 
 static ssize_t intel_pstate_show_status(char *buf)
 {
-	if (!driver_registered)
+	if (!intel_pstate_driver)
 		return sprintf(buf, "off\n");
 
 	return sprintf(buf, "%s\n", intel_pstate_driver == &intel_pstate ?
@@ -2427,11 +2421,11 @@ static int intel_pstate_update_status(co
 	int ret;
 
 	if (size == 3 && !strncmp(buf, "off", size))
-		return driver_registered ?
+		return intel_pstate_driver ?
 			intel_pstate_unregister_driver() : -EINVAL;
 
 	if (size == 6 && !strncmp(buf, "active", size)) {
-		if (driver_registered) {
+		if (intel_pstate_driver) {
 			if (intel_pstate_driver == &intel_pstate)
 				return 0;
 
@@ -2440,12 +2434,11 @@ static int intel_pstate_update_status(co
 				return ret;
 		}
 
-		intel_pstate_driver = &intel_pstate;
-		return intel_pstate_register_driver();
+		return intel_pstate_register_driver(&intel_pstate);
 	}
 
 	if (size == 7 && !strncmp(buf, "passive", size)) {
-		if (driver_registered) {
+		if (intel_pstate_driver) {
 			if (intel_pstate_driver != &intel_pstate)
 				return 0;
 
@@ -2454,8 +2447,7 @@ static int intel_pstate_update_status(co
 				return ret;
 		}
 
-		intel_pstate_driver = &intel_cpufreq;
-		return intel_pstate_register_driver();
+		return intel_pstate_register_driver(&intel_cpufreq);
 	}
 
 	return -EINVAL;
@@ -2684,7 +2676,7 @@ hwp_cpu_matched:
 	intel_pstate_sysfs_expose_params();
 
 	mutex_lock(&intel_pstate_driver_lock);
-	rc = intel_pstate_register_driver();
+	rc = intel_pstate_register_driver(default_driver);
 	mutex_unlock(&intel_pstate_driver_lock);
 	if (rc)
 		return rc;
@@ -2705,7 +2697,7 @@ static int __init intel_pstate_setup(cha
 		no_load = 1;
 	} else if (!strcmp(str, "passive")) {
 		pr_info("Passive mode enabled\n");
-		intel_pstate_driver = &intel_cpufreq;
+		default_driver = &intel_cpufreq;
 		no_hwp = 1;
 	}
 	if (!strcmp(str, "no_hwp")) {

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 09/14] cpufreq: intel_pstate: Modify check in intel_pstate_update_status()
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (7 preceding siblings ...)
  2017-03-12 17:19 ` [PATCH 08/14] cpufreq: intel_pstate: Drop driver_registered variable Rafael J. Wysocki
@ 2017-03-12 17:20 ` Rafael J. Wysocki
  2017-03-12 17:21 ` [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks Rafael J. Wysocki
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:20 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

One of the checks in intel_pstate_update_status() implicitly relies
on the information that there are only two struct cpufreq_driver
objects available, but it is better to do it directly against the
value it really is about (to make the code easier to follow if
nothing else).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -2439,7 +2439,7 @@ static int intel_pstate_update_status(co
 
 	if (size == 7 && !strncmp(buf, "passive", size)) {
 		if (intel_pstate_driver) {
-			if (intel_pstate_driver != &intel_pstate)
+			if (intel_pstate_driver == &intel_cpufreq)
 				return 0;
 
 			ret = intel_pstate_unregister_driver();

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (8 preceding siblings ...)
  2017-03-12 17:20 ` [PATCH 09/14] cpufreq: intel_pstate: Modify check in intel_pstate_update_status() Rafael J. Wysocki
@ 2017-03-12 17:21 ` Rafael J. Wysocki
  2017-03-12 17:22 ` [PATCH 11/14] cpufreq: intel_pstate: Add update_util callback to pstate_funcs Rafael J. Wysocki
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:21 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Notice that some overhead in the utilization update callbacks
registered by intel_pstate in the active mode can be avoided if
those callbacks are tailored to specific configurations of the
driver.  For example, the utilization update callback for the HWP
enabled case only needs to update the average CPU performance
periodically whereas the utilization update callback for the
PID-based algorithm does not need to take IO-wait boosting into
account and so on.

With that in mind, define three utilization update callbacks for
three different use cases: HWP enabled, the CPU load "powersave"
P-state selection algorithm and the PID-based "powersave" P-state
selection algorithm and modify the driver initialization to
choose the callback matching its current configuration.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   77 ++++++++++++++++++++++++++++-------------
 1 file changed, 53 insertions(+), 24 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -37,6 +37,9 @@
 #include <asm/cpufeature.h>
 #include <asm/intel-family.h>
 
+#define INTEL_PSTATE_DEFAULT_SAMPLING_INTERVAL	(10 * NSEC_PER_MSEC)
+#define INTEL_PSTATE_HWP_SAMPLING_INTERVAL	(50 * NSEC_PER_MSEC)
+
 #define INTEL_CPUFREQ_TRANSITION_LATENCY	20000
 
 #define ATOM_RATIOS		0x66a
@@ -1732,7 +1735,11 @@ static inline bool intel_pstate_sample(s
 	 * that sample.time will always be reset before setting the utilization
 	 * update hook and make the caller skip the sample then.
 	 */
-	return !!cpu->last_sample_time;
+	if (cpu->last_sample_time) {
+		intel_pstate_calc_avg_perf(cpu);
+		return true;
+	}
+	return false;
 }
 
 static inline int32_t get_avg_frequency(struct cpudata *cpu)
@@ -1839,7 +1846,7 @@ static void intel_pstate_update_pstate(s
 	wrmsrl(MSR_IA32_PERF_CTL, pstate_funcs.get_val(cpu, pstate));
 }
 
-static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
+static void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 {
 	int from, target_pstate;
 	struct sample *sample;
@@ -1867,36 +1874,56 @@ static inline void intel_pstate_adjust_b
 		fp_toint(cpu->iowait_boost * 100));
 }
 
+static void intel_pstate_update_util_hwp(struct update_util_data *data,
+					 u64 time, unsigned int flags)
+{
+	struct cpudata *cpu = container_of(data, struct cpudata, update_util);
+	u64 delta_ns = time - cpu->sample.time;
+
+	if ((s64)delta_ns >= INTEL_PSTATE_HWP_SAMPLING_INTERVAL)
+		intel_pstate_sample(cpu, time);
+}
+
+static void intel_pstate_update_util_pid(struct update_util_data *data,
+					 u64 time, unsigned int flags)
+{
+	struct cpudata *cpu = container_of(data, struct cpudata, update_util);
+	u64 delta_ns = time - cpu->sample.time;
+
+	if ((s64)delta_ns < pid_params.sample_rate_ns)
+		return;
+
+	if (intel_pstate_sample(cpu, time))
+		intel_pstate_adjust_busy_pstate(cpu);
+}
+
 static void intel_pstate_update_util(struct update_util_data *data, u64 time,
 				     unsigned int flags)
 {
 	struct cpudata *cpu = container_of(data, struct cpudata, update_util);
 	u64 delta_ns;
 
-	if (pstate_funcs.get_target_pstate == get_target_pstate_use_cpu_load) {
-		if (flags & SCHED_CPUFREQ_IOWAIT) {
-			cpu->iowait_boost = int_tofp(1);
-		} else if (cpu->iowait_boost) {
-			/* Clear iowait_boost if the CPU may have been idle. */
-			delta_ns = time - cpu->last_update;
-			if (delta_ns > TICK_NSEC)
-				cpu->iowait_boost = 0;
-		}
-		cpu->last_update = time;
+	if (flags & SCHED_CPUFREQ_IOWAIT) {
+		cpu->iowait_boost = int_tofp(1);
+	} else if (cpu->iowait_boost) {
+		/* Clear iowait_boost if the CPU may have been idle. */
+		delta_ns = time - cpu->last_update;
+		if (delta_ns > TICK_NSEC)
+			cpu->iowait_boost = 0;
 	}
-
+	cpu->last_update = time;
 	delta_ns = time - cpu->sample.time;
-	if ((s64)delta_ns >= pid_params.sample_rate_ns) {
-		bool sample_taken = intel_pstate_sample(cpu, time);
+	if ((s64)delta_ns < INTEL_PSTATE_DEFAULT_SAMPLING_INTERVAL)
+		return;
 
-		if (sample_taken) {
-			intel_pstate_calc_avg_perf(cpu);
-			if (!hwp_active)
-				intel_pstate_adjust_busy_pstate(cpu);
-		}
-	}
+	if (intel_pstate_sample(cpu, time))
+		intel_pstate_adjust_busy_pstate(cpu);
 }
 
+/* Utilization update callback to register in the active mode. */
+static void (*update_util_cb)(struct update_util_data *data, u64 time,
+			      unsigned int flags) = intel_pstate_update_util;
+
 #define ICPU(model, policy) \
 	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_APERFMPERF,\
 			(unsigned long)&policy }
@@ -2001,8 +2028,7 @@ static void intel_pstate_set_update_util
 
 	/* Prevent intel_pstate_update_util() from using stale data. */
 	cpu->sample.time = 0;
-	cpufreq_add_update_util_hook(cpu_num, &cpu->update_util,
-				     intel_pstate_update_util);
+	cpufreq_add_update_util_hook(cpu_num, &cpu->update_util, update_util_cb);
 	cpu->update_util_set = true;
 }
 
@@ -2493,6 +2519,9 @@ static void __init copy_cpu_funcs(struct
 	pstate_funcs.get_target_pstate = funcs->get_target_pstate;
 
 	intel_pstate_use_acpi_profile();
+
+	if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance)
+		update_util_cb = intel_pstate_update_util_pid;
 }
 
 #ifdef CONFIG_ACPI
@@ -2640,7 +2669,7 @@ static int __init intel_pstate_init(void
 		copy_cpu_funcs(&core_params.funcs);
 		hwp_active++;
 		intel_pstate.attr = hwp_cpufreq_attrs;
-		pid_params.sample_rate_ns = 50 * NSEC_PER_MSEC;
+		update_util_cb = intel_pstate_update_util_hwp;
 		goto hwp_cpu_matched;
 	}
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 11/14] cpufreq: intel_pstate: Add update_util callback to pstate_funcs
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (9 preceding siblings ...)
  2017-03-12 17:21 ` [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks Rafael J. Wysocki
@ 2017-03-12 17:22 ` Rafael J. Wysocki
  2017-03-12 17:23 ` [PATCH 12/14] cpufreq: intel_pstate: Move cpu_defaults definitions Rafael J. Wysocki
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:22 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Avoid using extra function pointers during P-state selection by
dropping the get_target_pstate member from struct pstate_funcs,
adding a new update_util callback to it (to be registered with
the CPU scheduler as the utilization update callback in the active
mode) and reworking the utilization update callback routines to
invoke specific P-state selection functions directly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   79 +++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 37 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -332,7 +332,7 @@ struct pstate_adjust_policy {
  * @get_scaling:	Callback to get frequency scaling factor
  * @get_val:		Callback to convert P state to actual MSR write value
  * @get_vid:		Callback to get VID data for Atom platforms
- * @get_target_pstate:	Callback to a function to calculate next P state to use
+ * @update_util:	Active mode utilization update callback.
  *
  * Core and Atom CPU models have different way to get P State limits. This
  * structure is used to store those callbacks.
@@ -345,7 +345,8 @@ struct pstate_funcs {
 	int (*get_scaling)(void);
 	u64 (*get_val)(struct cpudata*, int pstate);
 	void (*get_vid)(struct cpudata *);
-	int32_t (*get_target_pstate)(struct cpudata *);
+	void (*update_util)(struct update_util_data *data, u64 time,
+			    unsigned int flags);
 };
 
 /**
@@ -356,9 +357,6 @@ struct cpu_defaults {
 	struct pstate_funcs funcs;
 };
 
-static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu);
-static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu);
-
 static struct pstate_funcs pstate_funcs __read_mostly;
 static struct pstate_adjust_policy pid_params __read_mostly = {
 	.sample_rate_ms = 10,
@@ -1562,6 +1560,11 @@ static int knl_get_turbo_pstate(void)
 	return ret;
 }
 
+static void intel_pstate_update_util_pid(struct update_util_data *data,
+					 u64 time, unsigned int flags);
+static void intel_pstate_update_util(struct update_util_data *data, u64 time,
+				     unsigned int flags);
+
 static struct cpu_defaults core_params = {
 	.funcs = {
 		.get_max = core_get_max_pstate,
@@ -1570,7 +1573,7 @@ static struct cpu_defaults core_params =
 		.get_turbo = core_get_turbo_pstate,
 		.get_scaling = core_get_scaling,
 		.get_val = core_get_val,
-		.get_target_pstate = get_target_pstate_use_performance,
+		.update_util = intel_pstate_update_util_pid,
 	},
 };
 
@@ -1583,7 +1586,7 @@ static const struct cpu_defaults silverm
 		.get_val = atom_get_val,
 		.get_scaling = silvermont_get_scaling,
 		.get_vid = atom_get_vid,
-		.get_target_pstate = get_target_pstate_use_cpu_load,
+		.update_util = intel_pstate_update_util,
 	},
 };
 
@@ -1596,7 +1599,7 @@ static const struct cpu_defaults airmont
 		.get_val = atom_get_val,
 		.get_scaling = airmont_get_scaling,
 		.get_vid = atom_get_vid,
-		.get_target_pstate = get_target_pstate_use_cpu_load,
+		.update_util = intel_pstate_update_util,
 	},
 };
 
@@ -1608,7 +1611,7 @@ static const struct cpu_defaults knl_par
 		.get_turbo = knl_get_turbo_pstate,
 		.get_scaling = core_get_scaling,
 		.get_val = core_get_val,
-		.get_target_pstate = get_target_pstate_use_performance,
+		.update_util = intel_pstate_update_util_pid,
 	},
 };
 
@@ -1620,7 +1623,7 @@ static const struct cpu_defaults bxt_par
 		.get_turbo = core_get_turbo_pstate,
 		.get_scaling = core_get_scaling,
 		.get_val = core_get_val,
-		.get_target_pstate = get_target_pstate_use_cpu_load,
+		.update_util = intel_pstate_update_util,
 	},
 };
 
@@ -1760,6 +1763,9 @@ static inline int32_t get_target_pstate_
 	int32_t busy_frac, boost;
 	int target, avg_pstate;
 
+	if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE)
+		return cpu->pstate.turbo_pstate;
+
 	busy_frac = div_fp(sample->mperf, sample->tsc);
 
 	boost = cpu->iowait_boost;
@@ -1796,6 +1802,9 @@ static inline int32_t get_target_pstate_
 	int32_t perf_scaled, max_pstate, current_pstate, sample_ratio;
 	u64 duration_ns;
 
+	if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE)
+		return cpu->pstate.turbo_pstate;
+
 	/*
 	 * perf_scaled is the ratio of the average P-state during the last
 	 * sampling period to the P-state requested last time (in percent).
@@ -1846,16 +1855,11 @@ static void intel_pstate_update_pstate(s
 	wrmsrl(MSR_IA32_PERF_CTL, pstate_funcs.get_val(cpu, pstate));
 }
 
-static void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
+static void intel_pstate_adjust_pstate(struct cpudata *cpu, int target_pstate)
 {
-	int from, target_pstate;
+	int from = cpu->pstate.current_pstate;
 	struct sample *sample;
 
-	from = cpu->pstate.current_pstate;
-
-	target_pstate = cpu->policy == CPUFREQ_POLICY_PERFORMANCE ?
-		cpu->pstate.turbo_pstate : pstate_funcs.get_target_pstate(cpu);
-
 	update_turbo_state();
 
 	target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
@@ -1893,8 +1897,12 @@ static void intel_pstate_update_util_pid
 	if ((s64)delta_ns < pid_params.sample_rate_ns)
 		return;
 
-	if (intel_pstate_sample(cpu, time))
-		intel_pstate_adjust_busy_pstate(cpu);
+	if (intel_pstate_sample(cpu, time)) {
+		int target_pstate;
+
+		target_pstate = get_target_pstate_use_performance(cpu);
+		intel_pstate_adjust_pstate(cpu, target_pstate);
+	}
 }
 
 static void intel_pstate_update_util(struct update_util_data *data, u64 time,
@@ -1916,13 +1924,13 @@ static void intel_pstate_update_util(str
 	if ((s64)delta_ns < INTEL_PSTATE_DEFAULT_SAMPLING_INTERVAL)
 		return;
 
-	if (intel_pstate_sample(cpu, time))
-		intel_pstate_adjust_busy_pstate(cpu);
-}
+	if (intel_pstate_sample(cpu, time)) {
+		int target_pstate;
 
-/* Utilization update callback to register in the active mode. */
-static void (*update_util_cb)(struct update_util_data *data, u64 time,
-			      unsigned int flags) = intel_pstate_update_util;
+		target_pstate = get_target_pstate_use_cpu_load(cpu);
+		intel_pstate_adjust_pstate(cpu, target_pstate);
+	}
+}
 
 #define ICPU(model, policy) \
 	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_APERFMPERF,\
@@ -2001,7 +2009,7 @@ static int intel_pstate_init_cpu(unsigne
 			intel_pstate_disable_ee(cpunum);
 
 		intel_pstate_hwp_enable(cpu);
-	} else if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance) {
+	} else if (pstate_funcs.update_util == intel_pstate_update_util_pid) {
 		intel_pstate_pid_reset(cpu);
 	}
 
@@ -2028,7 +2036,8 @@ static void intel_pstate_set_update_util
 
 	/* Prevent intel_pstate_update_util() from using stale data. */
 	cpu->sample.time = 0;
-	cpufreq_add_update_util_hook(cpu_num, &cpu->update_util, update_util_cb);
+	cpufreq_add_update_util_hook(cpu_num, &cpu->update_util,
+				     pstate_funcs.update_util);
 	cpu->update_util_set = true;
 }
 
@@ -2412,7 +2421,7 @@ static int intel_pstate_register_driver(
 	}
 
 	if (intel_pstate_driver == &intel_pstate && !hwp_active &&
-	    pstate_funcs.get_target_pstate != get_target_pstate_use_cpu_load)
+	    pstate_funcs.update_util == intel_pstate_update_util_pid)
 		intel_pstate_debug_expose_params();
 
 	return 0;
@@ -2423,8 +2432,8 @@ static int intel_pstate_unregister_drive
 	if (hwp_active)
 		return -EBUSY;
 
-	if (intel_pstate_driver == &intel_pstate && !hwp_active &&
-	    pstate_funcs.get_target_pstate != get_target_pstate_use_cpu_load)
+	if (intel_pstate_driver == &intel_pstate &&
+	    pstate_funcs.update_util == intel_pstate_update_util_pid)
 		intel_pstate_debug_hide_params();
 
 	cpufreq_unregister_driver(intel_pstate_driver);
@@ -2498,8 +2507,7 @@ static int __init intel_pstate_msrs_not_
 static void intel_pstate_use_acpi_profile(void)
 {
 	if (acpi_gbl_FADT.preferred_profile == PM_MOBILE)
-		pstate_funcs.get_target_pstate =
-				get_target_pstate_use_cpu_load;
+		pstate_funcs.update_util = intel_pstate_update_util;
 }
 #else
 static void intel_pstate_use_acpi_profile(void)
@@ -2516,12 +2524,9 @@ static void __init copy_cpu_funcs(struct
 	pstate_funcs.get_scaling = funcs->get_scaling;
 	pstate_funcs.get_val   = funcs->get_val;
 	pstate_funcs.get_vid   = funcs->get_vid;
-	pstate_funcs.get_target_pstate = funcs->get_target_pstate;
+	pstate_funcs.update_util = funcs->update_util;
 
 	intel_pstate_use_acpi_profile();
-
-	if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance)
-		update_util_cb = intel_pstate_update_util_pid;
 }
 
 #ifdef CONFIG_ACPI
@@ -2667,9 +2672,9 @@ static int __init intel_pstate_init(void
 
 	if (x86_match_cpu(hwp_support_ids) && !no_hwp) {
 		copy_cpu_funcs(&core_params.funcs);
+		pstate_funcs.update_util = intel_pstate_update_util_hwp;
 		hwp_active++;
 		intel_pstate.attr = hwp_cpufreq_attrs;
-		update_util_cb = intel_pstate_update_util_hwp;
 		goto hwp_cpu_matched;
 	}
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 12/14] cpufreq: intel_pstate: Move cpu_defaults definitions
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (10 preceding siblings ...)
  2017-03-12 17:22 ` [PATCH 11/14] cpufreq: intel_pstate: Add update_util callback to pstate_funcs Rafael J. Wysocki
@ 2017-03-12 17:23 ` Rafael J. Wysocki
  2017-03-12 17:23 ` [PATCH 13/14] cpufreq: intel_pstate: Drop struct cpu_defaults Rafael J. Wysocki
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:23 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Move the definitions of the cpu_defaults structures after the
definitions of utilization update callback routines to avoid
extra declarations of the latter.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |  129 +++++++++++++++++++----------------------
 1 file changed, 62 insertions(+), 67 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1560,73 +1560,6 @@ static int knl_get_turbo_pstate(void)
 	return ret;
 }
 
-static void intel_pstate_update_util_pid(struct update_util_data *data,
-					 u64 time, unsigned int flags);
-static void intel_pstate_update_util(struct update_util_data *data, u64 time,
-				     unsigned int flags);
-
-static struct cpu_defaults core_params = {
-	.funcs = {
-		.get_max = core_get_max_pstate,
-		.get_max_physical = core_get_max_pstate_physical,
-		.get_min = core_get_min_pstate,
-		.get_turbo = core_get_turbo_pstate,
-		.get_scaling = core_get_scaling,
-		.get_val = core_get_val,
-		.update_util = intel_pstate_update_util_pid,
-	},
-};
-
-static const struct cpu_defaults silvermont_params = {
-	.funcs = {
-		.get_max = atom_get_max_pstate,
-		.get_max_physical = atom_get_max_pstate,
-		.get_min = atom_get_min_pstate,
-		.get_turbo = atom_get_turbo_pstate,
-		.get_val = atom_get_val,
-		.get_scaling = silvermont_get_scaling,
-		.get_vid = atom_get_vid,
-		.update_util = intel_pstate_update_util,
-	},
-};
-
-static const struct cpu_defaults airmont_params = {
-	.funcs = {
-		.get_max = atom_get_max_pstate,
-		.get_max_physical = atom_get_max_pstate,
-		.get_min = atom_get_min_pstate,
-		.get_turbo = atom_get_turbo_pstate,
-		.get_val = atom_get_val,
-		.get_scaling = airmont_get_scaling,
-		.get_vid = atom_get_vid,
-		.update_util = intel_pstate_update_util,
-	},
-};
-
-static const struct cpu_defaults knl_params = {
-	.funcs = {
-		.get_max = core_get_max_pstate,
-		.get_max_physical = core_get_max_pstate_physical,
-		.get_min = core_get_min_pstate,
-		.get_turbo = knl_get_turbo_pstate,
-		.get_scaling = core_get_scaling,
-		.get_val = core_get_val,
-		.update_util = intel_pstate_update_util_pid,
-	},
-};
-
-static const struct cpu_defaults bxt_params = {
-	.funcs = {
-		.get_max = core_get_max_pstate,
-		.get_max_physical = core_get_max_pstate_physical,
-		.get_min = core_get_min_pstate,
-		.get_turbo = core_get_turbo_pstate,
-		.get_scaling = core_get_scaling,
-		.get_val = core_get_val,
-		.update_util = intel_pstate_update_util,
-	},
-};
-
 static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
 {
 	int max_perf = cpu->pstate.turbo_pstate;
@@ -1932,6 +1865,68 @@ static void intel_pstate_update_util(str
 	}
 }
 
+static struct cpu_defaults core_params = {
+	.funcs = {
+		.get_max = core_get_max_pstate,
+		.get_max_physical = core_get_max_pstate_physical,
+		.get_min = core_get_min_pstate,
+		.get_turbo = core_get_turbo_pstate,
+		.get_scaling = core_get_scaling,
+		.get_val = core_get_val,
+		.update_util = intel_pstate_update_util_pid,
+	},
+};
+
+static const struct cpu_defaults silvermont_params = {
+	.funcs = {
+		.get_max = atom_get_max_pstate,
+		.get_max_physical = atom_get_max_pstate,
+		.get_min = atom_get_min_pstate,
+		.get_turbo = atom_get_turbo_pstate,
+		.get_val = atom_get_val,
+		.get_scaling = silvermont_get_scaling,
+		.get_vid = atom_get_vid,
+		.update_util = intel_pstate_update_util,
+	},
+};
+
+static const struct cpu_defaults airmont_params = {
+	.funcs = {
+		.get_max = atom_get_max_pstate,
+		.get_max_physical = atom_get_max_pstate,
+		.get_min = atom_get_min_pstate,
+		.get_turbo = atom_get_turbo_pstate,
+		.get_val = atom_get_val,
+		.get_scaling = airmont_get_scaling,
+		.get_vid = atom_get_vid,
+		.update_util = intel_pstate_update_util,
+	},
+};
+
+static const struct cpu_defaults knl_params = {
+	.funcs = {
+		.get_max = core_get_max_pstate,
+		.get_max_physical = core_get_max_pstate_physical,
+		.get_min = core_get_min_pstate,
+		.get_turbo = knl_get_turbo_pstate,
+		.get_scaling = core_get_scaling,
+		.get_val = core_get_val,
+		.update_util = intel_pstate_update_util_pid,
+	},
+};
+
+static const struct cpu_defaults bxt_params = {
+	.funcs = {
+		.get_max = core_get_max_pstate,
+		.get_max_physical = core_get_max_pstate_physical,
+		.get_min = core_get_min_pstate,
+		.get_turbo = core_get_turbo_pstate,
+		.get_scaling = core_get_scaling,
+		.get_val = core_get_val,
+		.update_util = intel_pstate_update_util,
+	},
+};
+
 #define ICPU(model, policy) \
 	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_APERFMPERF,\
 			(unsigned long)&policy }

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 13/14] cpufreq: intel_pstate: Drop struct cpu_defaults
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (11 preceding siblings ...)
  2017-03-12 17:23 ` [PATCH 12/14] cpufreq: intel_pstate: Move cpu_defaults definitions Rafael J. Wysocki
@ 2017-03-12 17:23 ` Rafael J. Wysocki
  2017-03-12 17:26 ` [PATCH 14/14] cpufreq: intel_pstate: Introduce pid_in_use() Rafael J. Wysocki
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:23 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The cpu_defaults structure is redundant, because it only contains
one member of type struct pstate_funcs which can be used directly
instead of struct cpu_defaults.

For this reason, drop struct cpu_defaults, use struct pstate_funcs
directly instead of it where applicable and rename all of the
variables of that type accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |  170 ++++++++++++++++++-----------------------
 1 file changed, 75 insertions(+), 95 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -349,14 +349,6 @@ struct pstate_funcs {
 			    unsigned int flags);
 };
 
-/**
- * struct cpu_defaults- Per CPU model default config data
- * @funcs:		Callback function data
- */
-struct cpu_defaults {
-	struct pstate_funcs funcs;
-};
-
 static struct pstate_funcs pstate_funcs __read_mostly;
 static struct pstate_adjust_policy pid_params __read_mostly = {
 	.sample_rate_ms = 10,
@@ -1865,66 +1857,56 @@ static void intel_pstate_update_util(str
 	}
 }
 
-static struct cpu_defaults core_params = {
-	.funcs = {
-		.get_max = core_get_max_pstate,
-		.get_max_physical = core_get_max_pstate_physical,
-		.get_min = core_get_min_pstate,
-		.get_turbo = core_get_turbo_pstate,
-		.get_scaling = core_get_scaling,
-		.get_val = core_get_val,
-		.update_util = intel_pstate_update_util_pid,
-	},
-};
-
-static const struct cpu_defaults silvermont_params = {
-	.funcs = {
-		.get_max = atom_get_max_pstate,
-		.get_max_physical = atom_get_max_pstate,
-		.get_min = atom_get_min_pstate,
-		.get_turbo = atom_get_turbo_pstate,
-		.get_val = atom_get_val,
-		.get_scaling = silvermont_get_scaling,
-		.get_vid = atom_get_vid,
-		.update_util = intel_pstate_update_util,
-	},
-};
-
-static const struct cpu_defaults airmont_params = {
-	.funcs = {
-		.get_max = atom_get_max_pstate,
-		.get_max_physical = atom_get_max_pstate,
-		.get_min = atom_get_min_pstate,
-		.get_turbo = atom_get_turbo_pstate,
-		.get_val = atom_get_val,
-		.get_scaling = airmont_get_scaling,
-		.get_vid = atom_get_vid,
-		.update_util = intel_pstate_update_util,
-	},
-};
-
-static const struct cpu_defaults knl_params = {
-	.funcs = {
-		.get_max = core_get_max_pstate,
-		.get_max_physical = core_get_max_pstate_physical,
-		.get_min = core_get_min_pstate,
-		.get_turbo = knl_get_turbo_pstate,
-		.get_scaling = core_get_scaling,
-		.get_val = core_get_val,
-		.update_util = intel_pstate_update_util_pid,
-	},
-};
-
-static const struct cpu_defaults bxt_params = {
-	.funcs = {
-		.get_max = core_get_max_pstate,
-		.get_max_physical = core_get_max_pstate_physical,
-		.get_min = core_get_min_pstate,
-		.get_turbo = core_get_turbo_pstate,
-		.get_scaling = core_get_scaling,
-		.get_val = core_get_val,
-		.update_util = intel_pstate_update_util,
-	},
+static struct pstate_funcs core_funcs = {
+	.get_max = core_get_max_pstate,
+	.get_max_physical = core_get_max_pstate_physical,
+	.get_min = core_get_min_pstate,
+	.get_turbo = core_get_turbo_pstate,
+	.get_scaling = core_get_scaling,
+	.get_val = core_get_val,
+	.update_util = intel_pstate_update_util_pid,
+};
+
+static const struct pstate_funcs silvermont_funcs = {
+	.get_max = atom_get_max_pstate,
+	.get_max_physical = atom_get_max_pstate,
+	.get_min = atom_get_min_pstate,
+	.get_turbo = atom_get_turbo_pstate,
+	.get_val = atom_get_val,
+	.get_scaling = silvermont_get_scaling,
+	.get_vid = atom_get_vid,
+	.update_util = intel_pstate_update_util,
+};
+
+static const struct pstate_funcs airmont_funcs = {
+	.get_max = atom_get_max_pstate,
+	.get_max_physical = atom_get_max_pstate,
+	.get_min = atom_get_min_pstate,
+	.get_turbo = atom_get_turbo_pstate,
+	.get_val = atom_get_val,
+	.get_scaling = airmont_get_scaling,
+	.get_vid = atom_get_vid,
+	.update_util = intel_pstate_update_util,
+};
+
+static const struct pstate_funcs knl_funcs = {
+	.get_max = core_get_max_pstate,
+	.get_max_physical = core_get_max_pstate_physical,
+	.get_min = core_get_min_pstate,
+	.get_turbo = knl_get_turbo_pstate,
+	.get_scaling = core_get_scaling,
+	.get_val = core_get_val,
+	.update_util = intel_pstate_update_util_pid,
+};
+
+static const struct pstate_funcs bxt_funcs = {
+	.get_max = core_get_max_pstate,
+	.get_max_physical = core_get_max_pstate_physical,
+	.get_min = core_get_min_pstate,
+	.get_turbo = core_get_turbo_pstate,
+	.get_scaling = core_get_scaling,
+	.get_val = core_get_val,
+	.update_util = intel_pstate_update_util,
 };
 
 #define ICPU(model, policy) \
@@ -1932,38 +1914,38 @@ static const struct cpu_defaults bxt_par
 			(unsigned long)&policy }
 
 static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
-	ICPU(INTEL_FAM6_SANDYBRIDGE, 		core_params),
-	ICPU(INTEL_FAM6_SANDYBRIDGE_X,		core_params),
-	ICPU(INTEL_FAM6_ATOM_SILVERMONT1,	silvermont_params),
-	ICPU(INTEL_FAM6_IVYBRIDGE,		core_params),
-	ICPU(INTEL_FAM6_HASWELL_CORE,		core_params),
-	ICPU(INTEL_FAM6_BROADWELL_CORE,		core_params),
-	ICPU(INTEL_FAM6_IVYBRIDGE_X,		core_params),
-	ICPU(INTEL_FAM6_HASWELL_X,		core_params),
-	ICPU(INTEL_FAM6_HASWELL_ULT,		core_params),
-	ICPU(INTEL_FAM6_HASWELL_GT3E,		core_params),
-	ICPU(INTEL_FAM6_BROADWELL_GT3E,		core_params),
-	ICPU(INTEL_FAM6_ATOM_AIRMONT,		airmont_params),
-	ICPU(INTEL_FAM6_SKYLAKE_MOBILE,		core_params),
-	ICPU(INTEL_FAM6_BROADWELL_X,		core_params),
-	ICPU(INTEL_FAM6_SKYLAKE_DESKTOP,	core_params),
-	ICPU(INTEL_FAM6_BROADWELL_XEON_D,	core_params),
-	ICPU(INTEL_FAM6_XEON_PHI_KNL,		knl_params),
-	ICPU(INTEL_FAM6_XEON_PHI_KNM,		knl_params),
-	ICPU(INTEL_FAM6_ATOM_GOLDMONT,		bxt_params),
+	ICPU(INTEL_FAM6_SANDYBRIDGE, 		core_funcs),
+	ICPU(INTEL_FAM6_SANDYBRIDGE_X,		core_funcs),
+	ICPU(INTEL_FAM6_ATOM_SILVERMONT1,	silvermont_funcs),
+	ICPU(INTEL_FAM6_IVYBRIDGE,		core_funcs),
+	ICPU(INTEL_FAM6_HASWELL_CORE,		core_funcs),
+	ICPU(INTEL_FAM6_BROADWELL_CORE,		core_funcs),
+	ICPU(INTEL_FAM6_IVYBRIDGE_X,		core_funcs),
+	ICPU(INTEL_FAM6_HASWELL_X,		core_funcs),
+	ICPU(INTEL_FAM6_HASWELL_ULT,		core_funcs),
+	ICPU(INTEL_FAM6_HASWELL_GT3E,		core_funcs),
+	ICPU(INTEL_FAM6_BROADWELL_GT3E,		core_funcs),
+	ICPU(INTEL_FAM6_ATOM_AIRMONT,		airmont_funcs),
+	ICPU(INTEL_FAM6_SKYLAKE_MOBILE,		core_funcs),
+	ICPU(INTEL_FAM6_BROADWELL_X,		core_funcs),
+	ICPU(INTEL_FAM6_SKYLAKE_DESKTOP,	core_funcs),
+	ICPU(INTEL_FAM6_BROADWELL_XEON_D,	core_funcs),
+	ICPU(INTEL_FAM6_XEON_PHI_KNL,		knl_funcs),
+	ICPU(INTEL_FAM6_XEON_PHI_KNM,		knl_funcs),
+	ICPU(INTEL_FAM6_ATOM_GOLDMONT,		bxt_funcs),
 	{}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
 
 static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = {
-	ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_params),
-	ICPU(INTEL_FAM6_BROADWELL_X, core_params),
-	ICPU(INTEL_FAM6_SKYLAKE_X, core_params),
+	ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs),
+	ICPU(INTEL_FAM6_BROADWELL_X, core_funcs),
+	ICPU(INTEL_FAM6_SKYLAKE_X, core_funcs),
 	{}
 };
 
 static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[] = {
-	ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, core_params),
+	ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, core_funcs),
 	{}
 };
 
@@ -2659,14 +2641,13 @@ static const struct x86_cpu_id hwp_suppo
 static int __init intel_pstate_init(void)
 {
 	const struct x86_cpu_id *id;
-	struct cpu_defaults *cpu_def;
 	int rc = 0;
 
 	if (no_load)
 		return -ENODEV;
 
 	if (x86_match_cpu(hwp_support_ids) && !no_hwp) {
-		copy_cpu_funcs(&core_params.funcs);
+		copy_cpu_funcs(&core_funcs);
 		pstate_funcs.update_util = intel_pstate_update_util_hwp;
 		hwp_active++;
 		intel_pstate.attr = hwp_cpufreq_attrs;
@@ -2677,8 +2658,7 @@ static int __init intel_pstate_init(void
 	if (!id)
 		return -ENODEV;
 
-	cpu_def = (struct cpu_defaults *)id->driver_data;
-	copy_cpu_funcs(&cpu_def->funcs);
+	copy_cpu_funcs((struct pstate_funcs *)id->driver_data);
 
 	if (intel_pstate_msrs_not_valid())
 		return -ENODEV;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 14/14] cpufreq: intel_pstate: Introduce pid_in_use()
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (12 preceding siblings ...)
  2017-03-12 17:23 ` [PATCH 13/14] cpufreq: intel_pstate: Drop struct cpu_defaults Rafael J. Wysocki
@ 2017-03-12 17:26 ` Rafael J. Wysocki
  2017-03-14 16:06 ` [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init Doug Smythies
  2017-03-14 16:07 ` [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks Doug Smythies
  15 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-12 17:26 UTC (permalink / raw)
  To: Linux PM; +Cc: LKML, Srinivas Pandruvada

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Add a new function pid_in_use() to return the information on whether
or not the PID-based P-state selection algorithm is in use.

That allows a couple of complicated conditions in the code to be
reduced to simple checks against the new function's return value.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1949,6 +1949,8 @@ static const struct x86_cpu_id intel_pst
 	{}
 };
 
+static bool pid_in_use(void);
+
 static int intel_pstate_init_cpu(unsigned int cpunum)
 {
 	struct cpudata *cpu;
@@ -1986,7 +1988,7 @@ static int intel_pstate_init_cpu(unsigne
 			intel_pstate_disable_ee(cpunum);
 
 		intel_pstate_hwp_enable(cpu);
-	} else if (pstate_funcs.update_util == intel_pstate_update_util_pid) {
+	} else if (pid_in_use()) {
 		intel_pstate_pid_reset(cpu);
 	}
 
@@ -2360,6 +2362,12 @@ static struct cpufreq_driver intel_cpufr
 
 static struct cpufreq_driver *default_driver = &intel_pstate;
 
+static bool pid_in_use(void)
+{
+	return intel_pstate_driver == &intel_pstate &&
+		pstate_funcs.update_util == intel_pstate_update_util_pid;
+}
+
 static void intel_pstate_driver_cleanup(void)
 {
 	unsigned int cpu;
@@ -2397,8 +2405,7 @@ static int intel_pstate_register_driver(
 		return ret;
 	}
 
-	if (intel_pstate_driver == &intel_pstate && !hwp_active &&
-	    pstate_funcs.update_util == intel_pstate_update_util_pid)
+	if (pid_in_use())
 		intel_pstate_debug_expose_params();
 
 	return 0;
@@ -2409,8 +2416,7 @@ static int intel_pstate_unregister_drive
 	if (hwp_active)
 		return -EBUSY;
 
-	if (intel_pstate_driver == &intel_pstate &&
-	    pstate_funcs.update_util == intel_pstate_update_util_pid)
+	if (pid_in_use())
 		intel_pstate_debug_hide_params();
 
 	cpufreq_unregister_driver(intel_pstate_driver);

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/14] cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set()
  2017-03-12 17:12 ` [PATCH 01/14] cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set() Rafael J. Wysocki
@ 2017-03-13  4:00   ` Viresh Kumar
  0 siblings, 0 replies; 20+ messages in thread
From: Viresh Kumar @ 2017-03-13  4:00 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Linux PM, LKML, Srinivas Pandruvada

On Sun, Mar 12, 2017 at 10:42 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Fix the debugfs interface for PID tuning to actually update
> pid_params.sample_rate_ns on PID parameters updates, as changing
> pid_params.sample_rate_ms via debugfs has no effect now.
>
> Fixes: a4675fbc4a7a (cpufreq: intel_pstate: Replace timers with utilization update callbacks)
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/cpufreq/intel_pstate.c |    1 +
>  1 file changed, 1 insertion(+)
>
> Index: linux-pm/drivers/cpufreq/intel_pstate.c
> ===================================================================
> --- linux-pm.orig/drivers/cpufreq/intel_pstate.c
> +++ linux-pm/drivers/cpufreq/intel_pstate.c
> @@ -983,6 +983,7 @@ static void intel_pstate_update_policies
>  static int pid_param_set(void *data, u64 val)
>  {
>         *(u32 *)data = val;
> +       pid_params.sample_rate_ns = pid_params.sample_rate_ms * NSEC_PER_MSEC;
>         intel_pstate_reset_all_pid();
>         return 0;
>  }
>

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (13 preceding siblings ...)
  2017-03-12 17:26 ` [PATCH 14/14] cpufreq: intel_pstate: Introduce pid_in_use() Rafael J. Wysocki
@ 2017-03-14 16:06 ` Doug Smythies
  2017-03-14 16:40   ` Rafael J. Wysocki
  2017-03-14 16:07 ` [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks Doug Smythies
  15 siblings, 1 reply; 20+ messages in thread
From: Doug Smythies @ 2017-03-14 16:06 UTC (permalink / raw)
  To: 'Rafael J. Wysocki'
  Cc: 'LKML', 'Srinivas Pandruvada', 'Linux PM'

On 2017.03.12 10:19 Rafael J. Wysocki wrote:

> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> PID controller parameters only need to be initialized if the
> get_target_pstate_use_performance() P-state selection routine
> is going to be used.  It is not necessary to initialize them
> otherwise, so don't do that.
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> drivers/cpufreq/intel_pstate.c |    4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> Index: linux-pm/drivers/cpufreq/intel_pstate.c
> ===================================================================
> --- linux-pm.orig/drivers/cpufreq/intel_pstate.c
> +++ linux-pm/drivers/cpufreq/intel_pstate.c
> @@ -1974,12 +1974,12 @@ static int intel_pstate_init_cpu(unsigne
> 			intel_pstate_disable_ee(cpunum);
> 
>  		intel_pstate_hwp_enable(cpu);
> +	} else if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance) {
> +		intel_pstate_pid_reset(cpu);
>  	}
> 
>  	intel_pstate_get_cpu_pstates(cpu);
> 
> -	intel_pstate_pid_reset(cpu);
> -
>  	pr_debug("controlling: cpu %d\n", cpunum);
> 
> 	return 0;

Hi Rafael,

The patch has a long line and scripts/checkpatch.pl complains.

$ scripts/checkpatch.pl rjw_7_14.txt
WARNING: line over 80 characters
#27: FILE: drivers/cpufreq/intel_pstate.c:1977:
+       } else if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance) {

total: 0 errors, 1 warnings, 14 lines checked

Myself, I don't care, and only found this by accident. I am just passing along
the information.

... Doug

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks
  2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
                   ` (14 preceding siblings ...)
  2017-03-14 16:06 ` [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init Doug Smythies
@ 2017-03-14 16:07 ` Doug Smythies
  2017-03-14 16:41   ` Rafael J. Wysocki
  15 siblings, 1 reply; 20+ messages in thread
From: Doug Smythies @ 2017-03-14 16:07 UTC (permalink / raw)
  To: 'Rafael J. Wysocki'
  Cc: 'LKML', 'Srinivas Pandruvada', 'Linux PM'

Hi Rafael,

I can not get this patch to apply.
My start point is kernel 4.11-rc2, so maybe (probably) it is my problem.

On 2017.03.12 10:22 Rafael J. Wysocki wrote:

... [cut] ...

> drivers/cpufreq/intel_pstate.c |   77 ++++++++++++++++++++++++++++-------------
> 1 file changed, 53 insertions(+), 24 deletions(-)
>
> Index: linux-pm/drivers/cpufreq/intel_pstate.c
> ===================================================================
> --- linux-pm.orig/drivers/cpufreq/intel_pstate.c
> +++ linux-pm/drivers/cpufreq/intel_pstate.c
> @@ -37,6 +37,9 @@
> #include <asm/cpufeature.h>
> #include <asm/intel-family.h>
> 
> +#define INTEL_PSTATE_DEFAULT_SAMPLING_INTERVAL	(10 * NSEC_PER_MSEC)
> +#define INTEL_PSTATE_HWP_SAMPLING_INTERVAL	(50 * NSEC_PER_MSEC)
> +
> #define INTEL_CPUFREQ_TRANSITION_LATENCY	20000
> 
> #define ATOM_RATIOS		0x66a

"git am" is getting upset because the above line is still there.
However it was removed in Len Brown's patch turbostat stuff
patch 15 of 44, which is in kernel 4.11-rc1.
(92134bdbc6272da6e98e9242cc6f1576cedc0735)

... [cut] ...

By the way, scripts/checkpatch.pl also complains about a line
length in the patch.

$ scripts/checkpatch.pl rjw_10_14.txt
WARNING: line over 80 characters
#148: FILE: drivers/cpufreq/intel_pstate.c:2031:
+       cpufreq_add_update_util_hook(cpu_num, &cpu->update_util, update_util_cb);

total: 0 errors, 1 warnings, 130 lines checked
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init
  2017-03-14 16:06 ` [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init Doug Smythies
@ 2017-03-14 16:40   ` Rafael J. Wysocki
  0 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-14 16:40 UTC (permalink / raw)
  To: Doug Smythies
  Cc: 'LKML', 'Srinivas Pandruvada', 'Linux PM'

On Tuesday, March 14, 2017 09:06:52 AM Doug Smythies wrote:
> On 2017.03.12 10:19 Rafael J. Wysocki wrote:
> 
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > PID controller parameters only need to be initialized if the
> > get_target_pstate_use_performance() P-state selection routine
> > is going to be used.  It is not necessary to initialize them
> > otherwise, so don't do that.
> >
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> > drivers/cpufreq/intel_pstate.c |    4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > Index: linux-pm/drivers/cpufreq/intel_pstate.c
> > ===================================================================
> > --- linux-pm.orig/drivers/cpufreq/intel_pstate.c
> > +++ linux-pm/drivers/cpufreq/intel_pstate.c
> > @@ -1974,12 +1974,12 @@ static int intel_pstate_init_cpu(unsigne
> > 			intel_pstate_disable_ee(cpunum);
> > 
> >  		intel_pstate_hwp_enable(cpu);
> > +	} else if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance) {
> > +		intel_pstate_pid_reset(cpu);
> >  	}
> > 
> >  	intel_pstate_get_cpu_pstates(cpu);
> > 
> > -	intel_pstate_pid_reset(cpu);
> > -
> >  	pr_debug("controlling: cpu %d\n", cpunum);
> > 
> > 	return 0;
> 
> Hi Rafael,
> 
> The patch has a long line and scripts/checkpatch.pl complains.
> 
> $ scripts/checkpatch.pl rjw_7_14.txt
> WARNING: line over 80 characters

I just ignore these.  I disagree with checkpatch.pl about this particular item. :-)

> #27: FILE: drivers/cpufreq/intel_pstate.c:1977:
> +       } else if (pstate_funcs.get_target_pstate == get_target_pstate_use_performance) {
> 
> total: 0 errors, 1 warnings, 14 lines checked
> 
> Myself, I don't care, and only found this by accident. I am just passing along
> the information.

OK

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks
  2017-03-14 16:07 ` [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks Doug Smythies
@ 2017-03-14 16:41   ` Rafael J. Wysocki
  0 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2017-03-14 16:41 UTC (permalink / raw)
  To: Doug Smythies
  Cc: 'LKML', 'Srinivas Pandruvada', 'Linux PM'

On Tuesday, March 14, 2017 09:07:48 AM Doug Smythies wrote:
> Hi Rafael,
> 
> I can not get this patch to apply.
> My start point is kernel 4.11-rc2, so maybe (probably) it is my problem.

I need to rebase the series.

There are fixes in flight that will need to go in first anyway.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-03-14 16:48 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-12 17:11 [PATCH 00/14] cpufreq: intel_pstate: Fixes, cleanups and optimizations Rafael J. Wysocki
2017-03-12 17:12 ` [PATCH 01/14] cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set() Rafael J. Wysocki
2017-03-13  4:00   ` Viresh Kumar
2017-03-12 17:13 ` [PATCH 02/14] cpufreq: intel_pstate: Drop pointless initialization of PID parameters Rafael J. Wysocki
2017-03-12 17:14 ` [PATCH 03/14] cpufreq: intel_pstate: Initialize pid_params statically Rafael J. Wysocki
2017-03-12 17:15 ` [PATCH 04/14] cpufreq: intel_pstate: Fold intel_pstate_reset_all_pid() into the caller Rafael J. Wysocki
2017-03-12 17:16 ` [PATCH 05/14] cpufreq: intel_pstate: Clean up intel_pstate_busy_pid_reset() Rafael J. Wysocki
2017-03-12 17:17 ` [PATCH 06/14] cpufreq: intel_pstate: Set HWP sampling interval once Rafael J. Wysocki
2017-03-12 17:18 ` [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init Rafael J. Wysocki
2017-03-12 17:19 ` [PATCH 08/14] cpufreq: intel_pstate: Drop driver_registered variable Rafael J. Wysocki
2017-03-12 17:20 ` [PATCH 09/14] cpufreq: intel_pstate: Modify check in intel_pstate_update_status() Rafael J. Wysocki
2017-03-12 17:21 ` [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks Rafael J. Wysocki
2017-03-12 17:22 ` [PATCH 11/14] cpufreq: intel_pstate: Add update_util callback to pstate_funcs Rafael J. Wysocki
2017-03-12 17:23 ` [PATCH 12/14] cpufreq: intel_pstate: Move cpu_defaults definitions Rafael J. Wysocki
2017-03-12 17:23 ` [PATCH 13/14] cpufreq: intel_pstate: Drop struct cpu_defaults Rafael J. Wysocki
2017-03-12 17:26 ` [PATCH 14/14] cpufreq: intel_pstate: Introduce pid_in_use() Rafael J. Wysocki
2017-03-14 16:06 ` [PATCH 07/14] cpufreq: intel_pstate: Skip unnecessary PID resets on init Doug Smythies
2017-03-14 16:40   ` Rafael J. Wysocki
2017-03-14 16:07 ` [PATCH 10/14] cpufreq: intel_pstate: Use different utilization update callbacks Doug Smythies
2017-03-14 16:41   ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).