Skip to content

Commit

Permalink
cpufreq/intel_pstate: Use CPPC to get max performance
Browse files Browse the repository at this point in the history
Use the acpi cppc_lib interface to get CPPC performance limits and update
the per cpu priority for the ITMT scheduler. If the highest performance of
CPUs differs the ITMT feature is enabled.

Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-pm@vger.kernel.org
Cc: peterz@infradead.org
Cc: jolsa@redhat.com
Cc: rjw@rjwysocki.net
Cc: linux-acpi@vger.kernel.org
Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Cc: bp@suse.de
Link: http://lkml.kernel.org/r/0998b98943bcdec7d1ddd4ff27358da555ea8e92.1479844244.git.tim.c.chen@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
rafaeljw authored and Thomas Gleixner committed Nov 24, 2016
1 parent 8b533a0 commit 1766900
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/cpufreq/Kconfig.x86
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
56 changes: 55 additions & 1 deletion drivers/cpufreq/intel_pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

#ifdef CONFIG_ACPI
#include <acpi/processor.h>
#include <acpi/cppc_acpi.h>
#endif

#define FRAC_BITS 8
Expand Down Expand Up @@ -379,14 +380,67 @@ static bool intel_pstate_get_ppc_enable_status(void)
return acpi_ppc;
}

#ifdef CONFIG_ACPI_CPPC_LIB

/* 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();
}

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, &cppc_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(&sched_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;
Expand Down

0 comments on commit 1766900

Please sign in to comment.