All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM <linux-pm@vger.kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>,
	Doug Smythies <dsmythies@telus.net>
Subject: [PATCH 11/16] cpufreq: intel_pstate: Add update_util callback to pstate_funcs
Date: Tue, 28 Mar 2017 00:17:10 +0200	[thread overview]
Message-ID: <2934524.ZKsJBBBObz@aspire.rjw.lan> (raw)
In-Reply-To: <6409323.DYHvh3CYlO@aspire.rjw.lan>

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 |   81 +++++++++++++++++++++--------------------
 1 file changed, 43 insertions(+), 38 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -311,7 +311,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.
@@ -324,7 +324,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);
 };
 
 /**
@@ -335,9 +336,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,
@@ -1510,6 +1508,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,
@@ -1518,7 +1521,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,
 	},
 };
 
@@ -1531,7 +1534,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,
 	},
 };
 
@@ -1544,7 +1547,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,
 	},
 };
 
@@ -1556,7 +1559,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,
 	},
 };
 
@@ -1568,7 +1571,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,
 	},
 };
 
@@ -1704,6 +1707,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;
@@ -1740,6 +1746,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).
@@ -1790,16 +1799,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);
@@ -1837,8 +1841,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,
@@ -1860,13 +1868,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,\
@@ -1938,7 +1946,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);
 	}
 
@@ -1965,7 +1973,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;
 }
 
@@ -2318,7 +2327,7 @@ static int intel_pstate_register_driver(
 	global.min_perf_pct = min_perf_pct_min();
 
 	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;
@@ -2329,8 +2338,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);
@@ -2409,8 +2418,7 @@ static void intel_pstate_use_acpi_profil
 	case PM_APPLIANCE_PC:
 	case PM_DESKTOP:
 	case PM_WORKSTATION:
-		pstate_funcs.get_target_pstate =
-				get_target_pstate_use_cpu_load;
+		pstate_funcs.update_util = intel_pstate_update_util;
 	}
 }
 #else
@@ -2428,12 +2436,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
@@ -2578,11 +2583,11 @@ static int __init intel_pstate_init(void
 	if (x86_match_cpu(hwp_support_ids)) {
 		copy_cpu_funcs(&core_params.funcs);
 		if (no_hwp) {
-			update_util_cb = intel_pstate_update_util;
+			pstate_funcs.update_util = intel_pstate_update_util;
 		} else {
 			hwp_active++;
 			intel_pstate.attr = hwp_cpufreq_attrs;
-			update_util_cb = intel_pstate_update_util_hwp;
+			pstate_funcs.update_util = intel_pstate_update_util_hwp;
 			goto hwp_cpu_matched;
 		}
 	} else {

  parent reply	other threads:[~2017-03-27 22:46 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-27 22:01 [PATCH 00/16] cpufreq: intel_pstate: Cleanups and optimizations Rafael J. Wysocki
2017-03-27 22:03 ` [PATCH 01/16] cpufreq: intel_pstate: Eliminate struct perf_limits Rafael J. Wysocki
2017-03-27 22:04 ` [PATCH 02/16] cpufreq: intel_pstate: Drop pointless initialization of PID parameters Rafael J. Wysocki
2017-03-27 22:05 ` [PATCH 03/16] cpufreq: intel_pstate: Initialize pid_params statically Rafael J. Wysocki
2017-03-27 22:07 ` [PATCH 04/16] cpufreq: intel_pstate: Fold intel_pstate_reset_all_pid() into the caller Rafael J. Wysocki
2017-03-27 22:09 ` [PATCH 05/16] cpufreq: intel_pstate: Clean up intel_pstate_busy_pid_reset() Rafael J. Wysocki
2017-03-27 22:10 ` [PATCH 06/16] cpufreq: intel_pstate: Set HWP sampling interval once Rafael J. Wysocki
2017-03-27 22:11 ` [PATCH 07/16] cpufreq: intel_pstate: Skip unnecessary PID resets on init Rafael J. Wysocki
2017-03-27 22:13 ` [PATCH 08/16] cpufreq: intel_pstate: Drop driver_registered variable Rafael J. Wysocki
2017-03-27 22:14 ` [PATCH 09/16] cpufreq: intel_pstate: Modify check in intel_pstate_update_status() Rafael J. Wysocki
2017-03-27 22:15 ` [PATCH 10/16] cpufreq: intel_pstate: Use different utilization update callbacks Rafael J. Wysocki
2017-03-27 22:17 ` Rafael J. Wysocki [this message]
2017-03-27 22:18 ` [PATCH 12/16] cpufreq: intel_pstate: Move cpu_defaults definitions Rafael J. Wysocki
2017-03-27 22:19 ` [PATCH 13/16] cpufreq: intel_pstate: Drop struct cpu_defaults Rafael J. Wysocki
2017-03-27 22:20 ` [PATCH 14/16] cpufreq: intel_pstate: Introduce pid_in_use() Rafael J. Wysocki
2017-03-27 22:22 ` [PATCH 15/16] cpufreq: intel_pstate: Do not walk policy->cpus Rafael J. Wysocki
2017-03-27 22:24 ` [PATCH 16/16] cpufreq: intel_pstate: Eliminate intel_pstate_get_min_max() Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2934524.ZKsJBBBObz@aspire.rjw.lan \
    --to=rjw@rjwysocki.net \
    --cc=dsmythies@telus.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=srinivas.pandruvada@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.