Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6a4d1b4 authored by Srinivas Rao L's avatar Srinivas Rao L
Browse files

cpuidle: lpm_levels: Wakeup biased cpu



If a biased cpu entered shallowest LPM state and
there are no wakeups for it, can stay in the shallowest
state for long.

Program wakeup for the biased CPU to wakeup after the
expected bias window is completed, so that the cpu can
enter a deeper state.

Change-Id: Ic92c779f0f8b1fa85aa8b3afa68d075f8d5d7dd6
Signed-off-by: default avatarSrinivas Rao L <lsrao@codeaurora.org>
parent db92782e
Loading
Loading
Loading
Loading
+56 −5
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ static DEFINE_PER_CPU(struct lpm_cpu*, cpu_lpm);
static bool suspend_in_progress;
static struct hrtimer lpm_hrtimer;
static DEFINE_PER_CPU(struct hrtimer, histtimer);
static DEFINE_PER_CPU(struct hrtimer, biastimer);
static struct lpm_debug *lpm_debug;
static phys_addr_t lpm_debug_phys;
static const int num_dbg_elements = 0x100;
@@ -428,6 +429,34 @@ static void msm_pm_set_timer(uint32_t modified_time_us)
	hrtimer_start(&lpm_hrtimer, modified_ktime, HRTIMER_MODE_REL_PINNED);
}

static void biastimer_cancel(void)
{
	unsigned int cpu = raw_smp_processor_id();
	struct hrtimer *cpu_biastimer = &per_cpu(biastimer, cpu);
	ktime_t time_rem;

	time_rem = hrtimer_get_remaining(cpu_biastimer);
	if (ktime_to_us(time_rem) <= 0)
		return;

	hrtimer_try_to_cancel(cpu_biastimer);
}

static enum hrtimer_restart biastimer_fn(struct hrtimer *h)
{
	return HRTIMER_NORESTART;
}

static void biastimer_start(uint32_t time_ns)
{
	ktime_t bias_ktime = ns_to_ktime(time_ns);
	unsigned int cpu = raw_smp_processor_id();
	struct hrtimer *cpu_biastimer = &per_cpu(biastimer, cpu);

	cpu_biastimer->function = biastimer_fn;
	hrtimer_start(cpu_biastimer, bias_ktime, HRTIMER_MODE_REL_PINNED);
}

static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev,
		struct lpm_cpu *cpu, int *idx_restrict,
		uint32_t *idx_restrict_time)
@@ -588,22 +617,36 @@ static void clear_predict_history(void)

static void update_history(struct cpuidle_device *dev, int idx);

static inline bool is_cpu_biased(int cpu)
static inline bool is_cpu_biased(int cpu, uint64_t *bias_time)
{
	u64 now = sched_clock();
	u64 last = sched_get_cpu_last_busy_time(cpu);
	u64 diff = 0;

	if (!last)
		return false;

	return (now - last) < BIAS_HYST;
	diff = now - last;
	if (diff < BIAS_HYST) {
		*bias_time = BIAS_HYST - diff;
		return true;
	}

	return false;
}

static inline bool lpm_disallowed(s64 sleep_us, int cpu)
static inline bool lpm_disallowed(s64 sleep_us, int cpu, struct lpm_cpu *pm_cpu)
{
	if ((sleep_disabled && !cpu_isolated(cpu)) || is_cpu_biased(cpu))
	uint64_t bias_time = 0;

	if (sleep_disabled && !cpu_isolated(cpu))
		return true;

	if (is_cpu_biased(cpu, &bias_time) && (!cpu_isolated(cpu))) {
		pm_cpu->bias = bias_time;
		return true;
	}

	if (sleep_us < 0)
		return true;

@@ -628,7 +671,7 @@ static int cpu_power_select(struct cpuidle_device *dev,
	uint32_t min_residency, max_residency;
	struct power_params *pwr_params;

	if (lpm_disallowed(sleep_us, dev->cpu))
	if (lpm_disallowed(sleep_us, dev->cpu, cpu))
		goto done_select;

	idx_restrict = cpu->nlevels + 1;
@@ -1294,6 +1337,8 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle)
	 */

	if (!idx) {
		if (cpu->bias)
			biastimer_start(cpu->bias);
		stop_critical_timings();
		wfi();
		start_critical_timings();
@@ -1404,6 +1449,10 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev,
		histtimer_cancel();
		clusttimer_cancel();
	}
	if (cpu->bias) {
		biastimer_cancel();
		cpu->bias = 0;
	}
	local_irq_enable();
	return idx;
}
@@ -1705,6 +1754,8 @@ static int lpm_probe(struct platform_device *pdev)
	for_each_possible_cpu(cpu) {
		cpu_histtimer = &per_cpu(histtimer, cpu);
		hrtimer_init(cpu_histtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		cpu_histtimer = &per_cpu(biastimer, cpu);
		hrtimer_init(cpu_histtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	}

	cluster_timer_init(lpm_root_node);
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct lpm_cpu {
	uint32_t ref_premature_cnt;
	uint32_t tmr_add;
	bool lpm_prediction;
	uint64_t bias;
	struct cpuidle_driver *drv;
	struct lpm_cluster *parent;
};