Skip to content

Commit

Permalink
Merge branch 'pm-cpufreq-sched' into pm-cpufreq
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaeljw committed Oct 1, 2016
2 parents 9ad0a1b + 3ba7bca commit b6e2511
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 119 deletions.
2 changes: 1 addition & 1 deletion arch/arm/configs/exynos_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_EXYNOS_CPUIDLE=y
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/configs/multi_v7_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_QORIQ_CPUFREQ=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
Expand Down
5 changes: 1 addition & 4 deletions drivers/cpufreq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ config CPU_FREQ_GOV_CONSERVATIVE
If in doubt, say N.

config CPU_FREQ_GOV_SCHEDUTIL
tristate "'schedutil' cpufreq policy governor"
bool "'schedutil' cpufreq policy governor"
depends on CPU_FREQ && SMP
select CPU_FREQ_GOV_ATTR_SET
select IRQ_WORK
Expand All @@ -208,9 +208,6 @@ config CPU_FREQ_GOV_SCHEDUTIL
frequency tipping point is at utilization/capacity equal to 80% in
both cases.

To compile this driver as a module, choose M here: the module will
be called cpufreq_schedutil.

If in doubt, say N.

comment "CPU frequency scaling drivers"
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/cpufreq_governor.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ static void dbs_irq_work(struct irq_work *irq_work)
}

static void dbs_update_util_handler(struct update_util_data *data, u64 time,
unsigned long util, unsigned long max)
unsigned int flags)
{
struct cpu_dbs_info *cdbs = container_of(data, struct cpu_dbs_info, update_util);
struct policy_dbs_info *policy_dbs = cdbs->policy_dbs;
Expand Down
63 changes: 34 additions & 29 deletions drivers/cpufreq/intel_pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ struct _pid {
* @cpu: CPU number for this instance data
* @update_util: CPUFreq utility callback information
* @update_util_set: CPUFreq utility callback is set
* @iowait_boost: iowait-related boost fraction
* @last_update: Time of the last update.
* @pstate: Stores P state limits for this CPU
* @vid: Stores VID limits for this CPU
* @pid: Stores PID parameters for this CPU
Expand All @@ -206,6 +208,7 @@ struct cpudata {
struct vid_data vid;
struct _pid pid;

u64 last_update;
u64 last_sample_time;
u64 prev_aperf;
u64 prev_mperf;
Expand All @@ -216,6 +219,7 @@ struct cpudata {
struct acpi_processor_performance acpi_perf_data;
bool valid_pss_table;
#endif
unsigned int iowait_boost;
};

static struct cpudata **all_cpu_data;
Expand All @@ -229,6 +233,7 @@ static struct cpudata **all_cpu_data;
* @p_gain_pct: PID proportional gain
* @i_gain_pct: PID integral gain
* @d_gain_pct: PID derivative gain
* @boost_iowait: Whether or not to use iowait boosting.
*
* Stores per CPU model static PID configuration data.
*/
Expand All @@ -240,6 +245,7 @@ struct pstate_adjust_policy {
int p_gain_pct;
int d_gain_pct;
int i_gain_pct;
bool boost_iowait;
};

/**
Expand Down Expand Up @@ -1037,6 +1043,7 @@ static const struct cpu_defaults silvermont_params = {
.p_gain_pct = 14,
.d_gain_pct = 0,
.i_gain_pct = 4,
.boost_iowait = true,
},
.funcs = {
.get_max = atom_get_max_pstate,
Expand All @@ -1058,6 +1065,7 @@ static const struct cpu_defaults airmont_params = {
.p_gain_pct = 14,
.d_gain_pct = 0,
.i_gain_pct = 4,
.boost_iowait = true,
},
.funcs = {
.get_max = atom_get_max_pstate,
Expand Down Expand Up @@ -1099,6 +1107,7 @@ static const struct cpu_defaults bxt_params = {
.p_gain_pct = 14,
.d_gain_pct = 0,
.i_gain_pct = 4,
.boost_iowait = true,
},
.funcs = {
.get_max = core_get_max_pstate,
Expand Down Expand Up @@ -1222,36 +1231,18 @@ static inline int32_t get_avg_pstate(struct cpudata *cpu)
static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
{
struct sample *sample = &cpu->sample;
u64 cummulative_iowait, delta_iowait_us;
u64 delta_iowait_mperf;
u64 mperf, now;
int32_t cpu_load;
int32_t busy_frac, boost;

cummulative_iowait = get_cpu_iowait_time_us(cpu->cpu, &now);
busy_frac = div_fp(sample->mperf, sample->tsc);

/*
* Convert iowait time into number of IO cycles spent at max_freq.
* IO is considered as busy only for the cpu_load algorithm. For
* performance this is not needed since we always try to reach the
* maximum P-State, so we are already boosting the IOs.
*/
delta_iowait_us = cummulative_iowait - cpu->prev_cummulative_iowait;
delta_iowait_mperf = div64_u64(delta_iowait_us * cpu->pstate.scaling *
cpu->pstate.max_pstate, MSEC_PER_SEC);
boost = cpu->iowait_boost;
cpu->iowait_boost >>= 1;

mperf = cpu->sample.mperf + delta_iowait_mperf;
cpu->prev_cummulative_iowait = cummulative_iowait;
if (busy_frac < boost)
busy_frac = boost;

/*
* The load can be estimated as the ratio of the mperf counter
* running at a constant frequency during active periods
* (C0) and the time stamp counter running at the same frequency
* also during C-states.
*/
cpu_load = div64_u64(int_tofp(100) * mperf, sample->tsc);
cpu->sample.busy_scaled = cpu_load;

return get_avg_pstate(cpu) - pid_calc(&cpu->pid, cpu_load);
sample->busy_scaled = busy_frac * 100;
return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);
}

static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
Expand Down Expand Up @@ -1325,15 +1316,29 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
sample->mperf,
sample->aperf,
sample->tsc,
get_avg_frequency(cpu));
get_avg_frequency(cpu),
fp_toint(cpu->iowait_boost * 100));
}

static void intel_pstate_update_util(struct update_util_data *data, u64 time,
unsigned long util, unsigned long max)
unsigned int flags)
{
struct cpudata *cpu = container_of(data, struct cpudata, update_util);
u64 delta_ns = time - cpu->sample.time;
u64 delta_ns;

if (pid_params.boost_iowait) {
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);

Expand Down
13 changes: 9 additions & 4 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -3469,15 +3469,20 @@ static inline unsigned long rlimit_max(unsigned int limit)
return task_rlimit_max(current, limit);
}

#define SCHED_CPUFREQ_RT (1U << 0)
#define SCHED_CPUFREQ_DL (1U << 1)
#define SCHED_CPUFREQ_IOWAIT (1U << 2)

#define SCHED_CPUFREQ_RT_DL (SCHED_CPUFREQ_RT | SCHED_CPUFREQ_DL)

#ifdef CONFIG_CPU_FREQ
struct update_util_data {
void (*func)(struct update_util_data *data,
u64 time, unsigned long util, unsigned long max);
void (*func)(struct update_util_data *data, u64 time, unsigned int flags);
};

void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
void (*func)(struct update_util_data *data, u64 time,
unsigned long util, unsigned long max));
void (*func)(struct update_util_data *data, u64 time,
unsigned int flags));
void cpufreq_remove_update_util_hook(int cpu);
#endif /* CONFIG_CPU_FREQ */

Expand Down
13 changes: 9 additions & 4 deletions include/trace/events/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ TRACE_EVENT(pstate_sample,
u64 mperf,
u64 aperf,
u64 tsc,
u32 freq
u32 freq,
u32 io_boost
),

TP_ARGS(core_busy,
Expand All @@ -79,7 +80,8 @@ TRACE_EVENT(pstate_sample,
mperf,
aperf,
tsc,
freq
freq,
io_boost
),

TP_STRUCT__entry(
Expand All @@ -91,6 +93,7 @@ TRACE_EVENT(pstate_sample,
__field(u64, aperf)
__field(u64, tsc)
__field(u32, freq)
__field(u32, io_boost)
),

TP_fast_assign(
Expand All @@ -102,17 +105,19 @@ TRACE_EVENT(pstate_sample,
__entry->aperf = aperf;
__entry->tsc = tsc;
__entry->freq = freq;
__entry->io_boost = io_boost;
),

TP_printk("core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu ",
TP_printk("core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu io_boost=%lu",
(unsigned long)__entry->core_busy,
(unsigned long)__entry->scaled_busy,
(unsigned long)__entry->from,
(unsigned long)__entry->to,
(unsigned long long)__entry->mperf,
(unsigned long long)__entry->aperf,
(unsigned long long)__entry->tsc,
(unsigned long)__entry->freq
(unsigned long)__entry->freq,
(unsigned long)__entry->io_boost
)

);
Expand Down
2 changes: 1 addition & 1 deletion kernel/sched/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct update_util_data *, cpufreq_update_util_data);
*/
void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
void (*func)(struct update_util_data *data, u64 time,
unsigned long util, unsigned long max))
unsigned int flags))
{
if (WARN_ON(!data || !func))
return;
Expand Down
Loading

0 comments on commit b6e2511

Please sign in to comment.