[PATCH v5 9/9] cpufreq: intel_pstate: Use CPPC to get max performance

2016-10-01 Thread Srinivas Pandruvada
From: "Rafael J. Wysocki" 

This change uses acpi cppc_lib interface to get CPPC performance limits
and calls scheduler interface to update per cpu highest priority. If
there is a difference in highest performance of each CPUs, call scheduler
interface to enable ITMT feature for only one time.

Here sched_set_itmt_core_prio() is called to set priorities and
sched_set_itmt_support() is called to enable ITMT feature.

Original-by: Srinivas Pandruvada 
Signed-off-by: Rafael J. Wysocki 
Signed-off-by: Srinivas Pandruvada 
---
 drivers/cpufreq/Kconfig.x86|  1 +
 drivers/cpufreq/intel_pstate.c | 56 +-
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index adbd1de..c6d273b 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -6,6 +6,7 @@ config X86_INTEL_PSTATE
bool "Intel P state control"
depends on X86
select ACPI_PROCESSOR if ACPI
+   select ACPI_CPPC_LIB if X86_64 && ACPI && SCHED_ITMT
help
   This driver provides a P state for Intel core processors.
  The driver implements an internal governor and will become
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index c877e70..e135cef 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -44,6 +44,7 @@
 
 #ifdef CONFIG_ACPI
 #include 
+#include 
 #endif
 
 #define FRAC_BITS 8
@@ -377,14 +378,67 @@ static bool intel_pstate_get_ppc_enable_status(void)
return acpi_ppc;
 }
 
+#ifdef CONFIG_SCHED_ITMT
+
+/* The work item is needed to avoid CPU hotplug locking issues */
+static void intel_pstste_sched_itmt_work_fn(struct work_struct *work)
+{
+   sched_set_itmt_support(true);
+}
+
+static DECLARE_WORK(sched_itmt_work, intel_pstste_sched_itmt_work_fn);
+
+static void intel_pstate_set_itmt_prio(int cpu)
+{
+   struct cppc_perf_caps cppc_perf;
+   static u32 max_highest_perf = 0, min_highest_perf = U32_MAX;
+   int ret;
+
+   ret = cppc_get_perf_caps(cpu, _perf);
+   if (ret)
+   return;
+
+   /*
+* The priorities can be set regardless of whether or not
+* sched_set_itmt_support(true) has been called and it is valid to
+* update them at any time after it has been called.
+*/
+   sched_set_itmt_core_prio(cppc_perf.highest_perf, cpu);
+
+   if (max_highest_perf <= min_highest_perf) {
+   if (cppc_perf.highest_perf > max_highest_perf)
+   max_highest_perf = cppc_perf.highest_perf;
+
+   if (cppc_perf.highest_perf < min_highest_perf)
+   min_highest_perf = cppc_perf.highest_perf;
+
+   if (max_highest_perf > min_highest_perf) {
+   /*
+* This code can be run during CPU online under the
+* CPU hotplug locks, so sched_set_itmt_support()
+* cannot be called from here.  Queue up a work item
+* to invoke it.
+*/
+   schedule_work(_itmt_work);
+   }
+   }
+}
+#else
+static void intel_pstate_set_itmt_prio(int cpu)
+{
+}
+#endif
+
 static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
 {
struct cpudata *cpu;
int ret;
int i;
 
-   if (hwp_active)
+   if (hwp_active) {
+   intel_pstate_set_itmt_prio(policy->cpu);
return;
+   }
 
if (!intel_pstate_get_ppc_enable_status())
return;
-- 
2.7.4



[PATCH v5 9/9] cpufreq: intel_pstate: Use CPPC to get max performance

2016-10-01 Thread Srinivas Pandruvada
From: "Rafael J. Wysocki" 

This change uses acpi cppc_lib interface to get CPPC performance limits
and calls scheduler interface to update per cpu highest priority. If
there is a difference in highest performance of each CPUs, call scheduler
interface to enable ITMT feature for only one time.

Here sched_set_itmt_core_prio() is called to set priorities and
sched_set_itmt_support() is called to enable ITMT feature.

Original-by: Srinivas Pandruvada 
Signed-off-by: Rafael J. Wysocki 
Signed-off-by: Srinivas Pandruvada 
---
 drivers/cpufreq/Kconfig.x86|  1 +
 drivers/cpufreq/intel_pstate.c | 56 +-
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index adbd1de..c6d273b 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -6,6 +6,7 @@ config X86_INTEL_PSTATE
bool "Intel P state control"
depends on X86
select ACPI_PROCESSOR if ACPI
+   select ACPI_CPPC_LIB if X86_64 && ACPI && SCHED_ITMT
help
   This driver provides a P state for Intel core processors.
  The driver implements an internal governor and will become
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index c877e70..e135cef 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -44,6 +44,7 @@
 
 #ifdef CONFIG_ACPI
 #include 
+#include 
 #endif
 
 #define FRAC_BITS 8
@@ -377,14 +378,67 @@ static bool intel_pstate_get_ppc_enable_status(void)
return acpi_ppc;
 }
 
+#ifdef CONFIG_SCHED_ITMT
+
+/* The work item is needed to avoid CPU hotplug locking issues */
+static void intel_pstste_sched_itmt_work_fn(struct work_struct *work)
+{
+   sched_set_itmt_support(true);
+}
+
+static DECLARE_WORK(sched_itmt_work, intel_pstste_sched_itmt_work_fn);
+
+static void intel_pstate_set_itmt_prio(int cpu)
+{
+   struct cppc_perf_caps cppc_perf;
+   static u32 max_highest_perf = 0, min_highest_perf = U32_MAX;
+   int ret;
+
+   ret = cppc_get_perf_caps(cpu, _perf);
+   if (ret)
+   return;
+
+   /*
+* The priorities can be set regardless of whether or not
+* sched_set_itmt_support(true) has been called and it is valid to
+* update them at any time after it has been called.
+*/
+   sched_set_itmt_core_prio(cppc_perf.highest_perf, cpu);
+
+   if (max_highest_perf <= min_highest_perf) {
+   if (cppc_perf.highest_perf > max_highest_perf)
+   max_highest_perf = cppc_perf.highest_perf;
+
+   if (cppc_perf.highest_perf < min_highest_perf)
+   min_highest_perf = cppc_perf.highest_perf;
+
+   if (max_highest_perf > min_highest_perf) {
+   /*
+* This code can be run during CPU online under the
+* CPU hotplug locks, so sched_set_itmt_support()
+* cannot be called from here.  Queue up a work item
+* to invoke it.
+*/
+   schedule_work(_itmt_work);
+   }
+   }
+}
+#else
+static void intel_pstate_set_itmt_prio(int cpu)
+{
+}
+#endif
+
 static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
 {
struct cpudata *cpu;
int ret;
int i;
 
-   if (hwp_active)
+   if (hwp_active) {
+   intel_pstate_set_itmt_prio(policy->cpu);
return;
+   }
 
if (!intel_pstate_get_ppc_enable_status())
return;
-- 
2.7.4