@@ -2013,7 +2013,7 @@ static int balance_one(struct rq *rq, struct task_struct *prev)
20132013
20142014 lockdep_assert_rq_held (rq );
20152015 rq -> scx .flags |= SCX_RQ_IN_BALANCE ;
2016- rq -> scx .flags &= ~( SCX_RQ_BAL_PENDING | SCX_RQ_BAL_KEEP ) ;
2016+ rq -> scx .flags &= ~SCX_RQ_BAL_KEEP ;
20172017
20182018 if ((sch -> ops .flags & SCX_OPS_HAS_CPU_PREEMPT ) &&
20192019 unlikely (rq -> scx .cpu_released )) {
@@ -2119,40 +2119,6 @@ static int balance_one(struct rq *rq, struct task_struct *prev)
21192119 return true;
21202120}
21212121
2122- static int balance_scx (struct rq * rq , struct task_struct * prev ,
2123- struct rq_flags * rf )
2124- {
2125- int ret ;
2126-
2127- rq_unpin_lock (rq , rf );
2128-
2129- ret = balance_one (rq , prev );
2130-
2131- #ifdef CONFIG_SCHED_SMT
2132- /*
2133- * When core-sched is enabled, this ops.balance() call will be followed
2134- * by pick_task_scx() on this CPU and the SMT siblings. Balance the
2135- * siblings too.
2136- */
2137- if (sched_core_enabled (rq )) {
2138- const struct cpumask * smt_mask = cpu_smt_mask (cpu_of (rq ));
2139- int scpu ;
2140-
2141- for_each_cpu_andnot (scpu , smt_mask , cpumask_of (cpu_of (rq ))) {
2142- struct rq * srq = cpu_rq (scpu );
2143- struct task_struct * sprev = srq -> curr ;
2144-
2145- WARN_ON_ONCE (__rq_lockp (rq ) != __rq_lockp (srq ));
2146- update_rq_clock (srq );
2147- balance_one (srq , sprev );
2148- }
2149- }
2150- #endif
2151- rq_repin_lock (rq , rf );
2152-
2153- return ret ;
2154- }
2155-
21562122static void process_ddsp_deferred_locals (struct rq * rq )
21572123{
21582124 struct task_struct * p ;
@@ -2335,38 +2301,19 @@ static struct task_struct *first_local_task(struct rq *rq)
23352301static struct task_struct * pick_task_scx (struct rq * rq , struct rq_flags * rf )
23362302{
23372303 struct task_struct * prev = rq -> curr ;
2304+ bool keep_prev , kick_idle = false;
23382305 struct task_struct * p ;
2339- bool keep_prev = rq -> scx .flags & SCX_RQ_BAL_KEEP ;
2340- bool kick_idle = false;
23412306
2342- /*
2343- * WORKAROUND:
2344- *
2345- * %SCX_RQ_BAL_KEEP should be set iff $prev is on SCX as it must just
2346- * have gone through balance_scx(). Unfortunately, there currently is a
2347- * bug where fair could say yes on balance() but no on pick_task(),
2348- * which then ends up calling pick_task_scx() without preceding
2349- * balance_scx().
2350- *
2351- * Keep running @prev if possible and avoid stalling from entering idle
2352- * without balancing.
2353- *
2354- * Once fair is fixed, remove the workaround and trigger WARN_ON_ONCE()
2355- * if pick_task_scx() is called without preceding balance_scx().
2356- */
2357- if (unlikely (rq -> scx .flags & SCX_RQ_BAL_PENDING )) {
2358- if (prev -> scx .flags & SCX_TASK_QUEUED ) {
2359- keep_prev = true;
2360- } else {
2361- keep_prev = false;
2362- kick_idle = true;
2363- }
2364- } else if (unlikely (keep_prev &&
2365- prev -> sched_class != & ext_sched_class )) {
2366- /*
2367- * Can happen while enabling as SCX_RQ_BAL_PENDING assertion is
2368- * conditional on scx_enabled() and may have been skipped.
2369- */
2307+ rq_modified_clear (rq );
2308+ rq_unpin_lock (rq , rf );
2309+ balance_one (rq , prev );
2310+ rq_repin_lock (rq , rf );
2311+ if (rq_modified_above (rq , & ext_sched_class ))
2312+ return RETRY_TASK ;
2313+
2314+ keep_prev = rq -> scx .flags & SCX_RQ_BAL_KEEP ;
2315+ if (unlikely (keep_prev &&
2316+ prev -> sched_class != & ext_sched_class )) {
23702317 WARN_ON_ONCE (scx_enable_state () == SCX_ENABLED );
23712318 keep_prev = false;
23722319 }
@@ -3243,7 +3190,6 @@ DEFINE_SCHED_CLASS(ext) = {
32433190
32443191 .wakeup_preempt = wakeup_preempt_scx ,
32453192
3246- .balance = balance_scx ,
32473193 .pick_task = pick_task_scx ,
32483194
32493195 .put_prev_task = put_prev_task_scx ,
0 commit comments