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

Commit b1bfa78b authored by Syed Rameez Mustafa's avatar Syed Rameez Mustafa Committed by Gerrit - the friendly Code Review server
Browse files

sched: Fix load tracking bug to avoid adding phantom task demand



When update_task_ravg() is called with the TASK_UPDATE event on a task
that is not on the runqueue, task demand accounting incorrectly treats
the time delta as execution time. This can happen when a sleeping
task is moved to/from colocation groups. This phantom execution time can
cause unpredictable changes to demand that in turn can result in
incorrect task placement. Fix the issue by adding special handling of
TASK_UPDATE in task demand accounting. CPU busy time accounting already
has all the necessary checks.

Change-Id: Ibb42d83ac353bf2e849055fa3cb5c22e7acd56de
Signed-off-by: default avatarSyed Rameez Mustafa <rameezmustafa@codeaurora.org>
parent 28f2df62
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -2572,7 +2572,8 @@ update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event,
	trace_sched_get_task_cpu_cycles(cpu, event, rq->cc.cycles, rq->cc.time);
}

static int account_busy_for_task_demand(struct task_struct *p, int event)
static int
account_busy_for_task_demand(struct rq *rq, struct task_struct *p, int event)
{
	/*
	 * No need to bother updating task demand for exiting tasks
@@ -2591,6 +2592,17 @@ static int account_busy_for_task_demand(struct task_struct *p, int event)
			 (event == PICK_NEXT_TASK || event == TASK_MIGRATE)))
		return 0;

	/*
	 * TASK_UPDATE can be called on sleeping task, when its moved between
	 * related groups
	 */
	if (event == TASK_UPDATE) {
		if (rq->curr == p)
			return 1;

		return p->on_rq ? SCHED_ACCOUNT_WAIT_TIME : 0;
	}

	return 1;
}

@@ -2731,7 +2743,7 @@ static u64 update_task_demand(struct task_struct *p, struct rq *rq,
	u64 runtime;

	new_window = mark_start < window_start;
	if (!account_busy_for_task_demand(p, event)) {
	if (!account_busy_for_task_demand(rq, p, event)) {
		if (new_window)
			/*
			 * If the time accounted isn't being accounted as