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

Commit 29297750 authored by Pavankumar Kondeti's avatar Pavankumar Kondeti
Browse files

sched/walt: Fix stale window start marker passed to the schedutil



With commit d8c5bfcc07ee ("sched: Make sure window start passed to
schedutil is consistent"), the rq->load_reported_window is presented
to the governor as the window_start marker. The rq->load_reported_window
is updated when load is reported to governor only during a window rollover.
So it should be consistent with the current window start mark. But for a
just hotplugged in CPU, the rq->load_reported_window is not updated
until the next window rollover.

If the load is reported for any other reason before the next window
rollover, the window start marker passed to the schedutil would be
stale and leads to a BUG_ON() in schedutil. The recent window start marker
is cached in WALT in walt_irq_work_lastq_ws. Use this instead of
load_reported_window to fix this problem.

The rq->window_start is cached in rq->load_reported_window to filter
the utilization updates in the same window. This is not needed since
utilization updates are not sent when SCHED_CPUFREQ_WALT flag is not
set. So kill the load_reported_window maintenance.

Change-Id: Idaefcb0b9cecb15ea436ac7a66cb6da81e3852a1
Signed-off-by: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
parent ed1e6248
Loading
Loading
Loading
Loading
+3 −16
Original line number Original line Diff line number Diff line
@@ -852,7 +852,6 @@ struct rq {
	int cstate, wakeup_latency, wakeup_energy;
	int cstate, wakeup_latency, wakeup_energy;
	u64 window_start;
	u64 window_start;
	s64 cum_window_start;
	s64 cum_window_start;
	u64 load_reported_window;
	unsigned long walt_flags;
	unsigned long walt_flags;


	u64 cur_irqload;
	u64 cur_irqload;
@@ -1966,6 +1965,8 @@ cpu_util_freq_pelt(int cpu)
}
}


#ifdef CONFIG_SCHED_WALT
#ifdef CONFIG_SCHED_WALT
extern atomic64_t walt_irq_work_lastq_ws;

static inline unsigned long
static inline unsigned long
cpu_util_freq_walt(int cpu, struct sched_walt_cpu_load *walt_load)
cpu_util_freq_walt(int cpu, struct sched_walt_cpu_load *walt_load)
{
{
@@ -2002,7 +2003,7 @@ cpu_util_freq_walt(int cpu, struct sched_walt_cpu_load *walt_load)
		walt_load->prev_window_util = util;
		walt_load->prev_window_util = util;
		walt_load->nl = nl;
		walt_load->nl = nl;
		walt_load->pl = pl;
		walt_load->pl = pl;
		walt_load->ws = rq->load_reported_window;
		walt_load->ws = atomic64_read(&walt_irq_work_lastq_ws);
	}
	}


	return (util >= capacity) ? capacity : util;
	return (util >= capacity) ? capacity : util;
@@ -2453,22 +2454,8 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
	struct update_util_data *data;
	struct update_util_data *data;


#ifdef CONFIG_SCHED_WALT
#ifdef CONFIG_SCHED_WALT
	unsigned int exception_flags = SCHED_CPUFREQ_INTERCLUSTER_MIG |
				SCHED_CPUFREQ_PL | SCHED_CPUFREQ_EARLY_DET |
				SCHED_CPUFREQ_FORCE_UPDATE;

	/*
	 * Skip if we've already reported, but not if this is an inter-cluster
	 * migration. Also only allow WALT update sites.
	 */
	if (!(flags & SCHED_CPUFREQ_WALT))
	if (!(flags & SCHED_CPUFREQ_WALT))
		return;
		return;
	if (!sched_disable_window_stats &&
		(rq->load_reported_window == rq->window_start) &&
		!(flags & exception_flags))
		return;
	if (!(flags & exception_flags))
		rq->load_reported_window = rq->window_start;
#endif
#endif


	data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
	data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
+1 −1
Original line number Original line Diff line number Diff line
@@ -45,7 +45,7 @@ const char *migrate_type_names[] = {"GROUP_TO_RQ", "RQ_TO_GROUP",
static struct cpu_cycle_counter_cb cpu_cycle_counter_cb;
static struct cpu_cycle_counter_cb cpu_cycle_counter_cb;
static bool use_cycle_counter;
static bool use_cycle_counter;
DEFINE_MUTEX(cluster_lock);
DEFINE_MUTEX(cluster_lock);
static atomic64_t walt_irq_work_lastq_ws;
atomic64_t walt_irq_work_lastq_ws;


static struct irq_work walt_cpufreq_irq_work;
static struct irq_work walt_cpufreq_irq_work;
static struct irq_work walt_migration_irq_work;
static struct irq_work walt_migration_irq_work;