@@ -2508,6 +2508,7 @@ static int balance_one(struct rq *rq, struct task_struct *prev, bool local)
25082508
25092509 lockdep_assert_rq_held (rq );
25102510 rq -> scx .flags |= SCX_RQ_IN_BALANCE ;
2511+ rq -> scx .flags &= ~SCX_RQ_BAL_KEEP ;
25112512
25122513 if (static_branch_unlikely (& scx_ops_cpu_preempt ) &&
25132514 unlikely (rq -> scx .cpu_released )) {
@@ -2523,7 +2524,6 @@ static int balance_one(struct rq *rq, struct task_struct *prev, bool local)
25232524 }
25242525
25252526 if (prev_on_scx ) {
2526- WARN_ON_ONCE (local && (prev -> scx .flags & SCX_TASK_BAL_KEEP ));
25272527 update_curr_scx (rq );
25282528
25292529 /*
@@ -2538,13 +2538,13 @@ static int balance_one(struct rq *rq, struct task_struct *prev, bool local)
25382538 *
25392539 * When balancing a remote CPU for core-sched, there won't be a
25402540 * following put_prev_task_scx() call and we don't own
2541- * %SCX_TASK_BAL_KEEP . Instead, pick_task_scx() will test the
2542- * same conditions later and pick @rq->curr accordingly.
2541+ * %SCX_RQ_BAL_KEEP . Instead, pick_task_scx() will test the same
2542+ * conditions later and pick @rq->curr accordingly.
25432543 */
25442544 if ((prev -> scx .flags & SCX_TASK_QUEUED ) &&
25452545 prev -> scx .slice && !scx_ops_bypassing ()) {
25462546 if (local )
2547- prev -> scx .flags |= SCX_TASK_BAL_KEEP ;
2547+ rq -> scx .flags |= SCX_RQ_BAL_KEEP ;
25482548 goto has_tasks ;
25492549 }
25502550 }
@@ -2604,7 +2604,7 @@ static int balance_one(struct rq *rq, struct task_struct *prev, bool local)
26042604 if ((prev -> scx .flags & SCX_TASK_QUEUED ) &&
26052605 (!static_branch_unlikely (& scx_ops_enq_last ) || scx_ops_bypassing ())) {
26062606 if (local )
2607- prev -> scx .flags |= SCX_TASK_BAL_KEEP ;
2607+ rq -> scx .flags |= SCX_RQ_BAL_KEEP ;
26082608 goto has_tasks ;
26092609 }
26102610 rq -> scx .flags &= ~SCX_RQ_IN_BALANCE ;
@@ -2726,8 +2726,6 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,
27262726 SCX_CALL_OP_TASK (SCX_KF_REST , stopping , p , true);
27272727
27282728 if (p -> scx .flags & SCX_TASK_QUEUED ) {
2729- p -> scx .flags &= ~SCX_TASK_BAL_KEEP ;
2730-
27312729 set_task_runnable (rq , p );
27322730
27332731 /*
@@ -2772,8 +2770,8 @@ static struct task_struct *pick_next_task_scx(struct rq *rq,
27722770 * if necessary and keep running @prev. Otherwise, pop the first one
27732771 * from the local DSQ.
27742772 */
2775- if (prev -> scx .flags & SCX_TASK_BAL_KEEP ) {
2776- prev -> scx . flags &= ~ SCX_TASK_BAL_KEEP ;
2773+ if (( rq -> scx .flags & SCX_RQ_BAL_KEEP ) &&
2774+ ! WARN_ON_ONCE ( prev -> sched_class != & ext_sched_class )) {
27772775 p = prev ;
27782776 if (!p -> scx .slice )
27792777 p -> scx .slice = SCX_SLICE_DFL ;
@@ -2841,7 +2839,7 @@ bool scx_prio_less(const struct task_struct *a, const struct task_struct *b,
28412839 *
28422840 * As put_prev_task_scx() hasn't been called on remote CPUs, we can't just look
28432841 * at the first task in the local dsq. @rq->curr has to be considered explicitly
2844- * to mimic %SCX_TASK_BAL_KEEP .
2842+ * to mimic %SCX_RQ_BAL_KEEP .
28452843 */
28462844static struct task_struct * pick_task_scx (struct rq * rq )
28472845{
@@ -3872,7 +3870,7 @@ bool task_should_scx(struct task_struct *p)
38723870 *
38733871 * b. ops.dispatch() is ignored.
38743872 *
3875- * c. balance_scx() does not set %SCX_TASK_BAL_KEEP on non-zero slice as slice
3873+ * c. balance_scx() does not set %SCX_RQ_BAL_KEEP on non-zero slice as slice
38763874 * can't be trusted. Whenever a tick triggers, the running task is rotated to
38773875 * the tail of the queue with core_sched_at touched.
38783876 *
0 commit comments