aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/kernel/sched/core.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2024-11-09 10:43:55 -1000
committerTejun Heo <tj@kernel.org>2024-11-09 10:43:55 -1000
commita6250aa251eacaf3ebfcfe152a96a727fd483ecd (patch)
tree763a6d78a04ea2d66f8baa2406d7c704094f7f6f /kernel/sched/core.c
parentsched_ext: Update scx_show_state.py to match scx_ops_bypass_depth's new type (diff)
downloadwireguard-linux-a6250aa251eacaf3ebfcfe152a96a727fd483ecd.tar.xz
wireguard-linux-a6250aa251eacaf3ebfcfe152a96a727fd483ecd.zip
sched_ext: Handle cases where pick_task_scx() is called without preceding balance_scx()
sched_ext dispatches tasks from the BPF scheduler from balance_scx() and thus every pick_task_scx() call must be preceded by balance_scx(). While this usually holds, due to a bug, there are cases where the fair class's balance() returns true indicating that it has tasks to run on the CPU and thus terminating balance() calls but fails to actually find the next task to run when pick_task() is called. In such cases, pick_task_scx() can be called without preceding balance_scx(). Detect this condition using SCX_RQ_BAL_PENDING flags. If detected, keep running the previous task if possible and avoid stalling from entering idle without balancing. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/Ztj_h5c2LYsdXYbA@slm.duckdns.org
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r--kernel/sched/core.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index aeb595514461..a910a5b4c274 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5914,12 +5914,15 @@ static void prev_balance(struct rq *rq, struct task_struct *prev,
#ifdef CONFIG_SCHED_CLASS_EXT
/*
- * SCX requires a balance() call before every pick_next_task() including
- * when waking up from SCHED_IDLE. If @start_class is below SCX, start
- * from SCX instead.
+ * SCX requires a balance() call before every pick_task() including when
+ * waking up from SCHED_IDLE. If @start_class is below SCX, start from
+ * SCX instead. Also, set a flag to detect missing balance() call.
*/
- if (scx_enabled() && sched_class_above(&ext_sched_class, start_class))
- start_class = &ext_sched_class;
+ if (scx_enabled()) {
+ rq->scx.flags |= SCX_RQ_BAL_PENDING;
+ if (sched_class_above(&ext_sched_class, start_class))
+ start_class = &ext_sched_class;
+ }
#endif
/*