ANDROID: sched: Avoid re-evaluating proxy_needs_return when sched_proxy_exec() is disabled
With proxy-execution, we add an extra check such that should the task
have already been woken up, but it is still in the BO_WAKING state,
thus potentially needed return-migration, we avoid breaking out of
try_to_wakeup() in order so that the proxy_needs_return() logic in
ttwu_runnable() can dequeue the task and allow it to be woken on its
wake_cpu (effecively doing the return migration).
As reported kuyo chang, this check is not conditionalized by
sched_proxy_exec(), so when proxy-execution is disabled its possible
for us to hit this case, and continue to ttwu_runnable(), however
we won't do the proxy_needs_return() logic as it is conditionalized,
resulting in the enqueued task being enqueued again, triggering
warnings.
WARNING: CPU: 5 PID: 20337 at kernel/sched/rt.c:1136 dequeue_rt_stack+0x1a0/0x26c
Call trace:
dequeue_rt_stack+0x1a0/0x26c
enqueue_task_rt+0xa0/0x39c
enqueue_task+0x7c/0x340
do_activate_task+0xcc/0x178
ttwu_do_activate+0xac/0x2a8
try_to_wake_up+0x748/0xb84
wake_up_q+0x70/0xd8
...
or
WARNING: CPU: 6 PID: 0 at kernel/sched/rt.c:1823 pick_task_rt+0x98/0xb0
Call trace:
pick_task_rt+0x98/0xb0
__schedule+0x494/0xc8c
schedule_idle+0x24/0x48
do_idle+0x248/0x290
...
Thus, pull the check out to a separate function and include the
check on sched_proxy_exec() so that it is properly conditionalized.
Bug: 388983726
Fixes: e4239ea599 ("ANDROID: sched: Handle blocked-waiter migration (and return migration)")
Change-Id: Id21c810b240d54aafc63bd0c34255eabdbefe94a
Reported-by: kuyo chang <kuyo.chang@mediatek.com>
Suggested-by: kuyo chang <kuyo.chang@mediatek.com>
Signed-off-by: John Stultz <jstultz@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
9384a0909f
commit
d9f67873f8
+14
-2
@@ -3812,6 +3812,14 @@ static void do_activate_task(struct rq *rq, struct task_struct *p, int en_flags)
|
||||
raw_spin_unlock(&p->blocked_lock);
|
||||
}
|
||||
|
||||
static bool proxy_task_runnable_but_waking(struct task_struct *p)
|
||||
{
|
||||
if (!sched_proxy_exec())
|
||||
return false;
|
||||
return (READ_ONCE(p->__state) == TASK_RUNNING &&
|
||||
READ_ONCE(p->blocked_on_state) == BO_WAKING);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static inline void proxy_set_task_cpu(struct task_struct *p, int cpu)
|
||||
{
|
||||
@@ -4081,6 +4089,11 @@ static inline void do_activate_task(struct rq *rq, struct task_struct *p,
|
||||
activate_task(rq, p, en_flags);
|
||||
}
|
||||
|
||||
static bool proxy_task_runnable_but_waking(struct task_struct *p)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void activate_blocked_waiters(struct rq *target_rq,
|
||||
struct task_struct *owner,
|
||||
int wake_flags)
|
||||
@@ -4667,8 +4680,7 @@ int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
|
||||
* continue on to ttwu_runnable check to force
|
||||
* proxy_needs_return evaluation
|
||||
*/
|
||||
if (!(READ_ONCE(p->__state) == TASK_RUNNING &&
|
||||
READ_ONCE(p->blocked_on_state) == BO_WAKING))
|
||||
if (!proxy_task_runnable_but_waking(p))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user