Skip to content

Commit 4c95380

Browse files
author
Peter Zijlstra
committed
sched/ext: Fold balance_scx() into pick_task_scx()
With pick_task() having an rf argument, it is possible to do the lock-break there, get rid of the weird balance/pick_task hack. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Tejun Heo <tj@kernel.org>
1 parent 5065321 commit 4c95380

3 files changed

Lines changed: 12 additions & 80 deletions

File tree

kernel/sched/core.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5845,19 +5845,6 @@ static void prev_balance(struct rq *rq, struct task_struct *prev,
58455845
const struct sched_class *start_class = prev->sched_class;
58465846
const struct sched_class *class;
58475847

5848-
#ifdef CONFIG_SCHED_CLASS_EXT
5849-
/*
5850-
* SCX requires a balance() call before every pick_task() including when
5851-
* waking up from SCHED_IDLE. If @start_class is below SCX, start from
5852-
* SCX instead. Also, set a flag to detect missing balance() call.
5853-
*/
5854-
if (scx_enabled()) {
5855-
rq->scx.flags |= SCX_RQ_BAL_PENDING;
5856-
if (sched_class_above(&ext_sched_class, start_class))
5857-
start_class = &ext_sched_class;
5858-
}
5859-
#endif
5860-
58615848
/*
58625849
* We must do the balancing pass before put_prev_task(), such
58635850
* that when we release the rq->lock the task is in the same

kernel/sched/ext.c

Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
21562122
static 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)
23352301
static 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,

kernel/sched/sched.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,6 @@ enum scx_rq_flags {
779779
*/
780780
SCX_RQ_ONLINE = 1 << 0,
781781
SCX_RQ_CAN_STOP_TICK = 1 << 1,
782-
SCX_RQ_BAL_PENDING = 1 << 2, /* balance hasn't run yet */
783782
SCX_RQ_BAL_KEEP = 1 << 3, /* balance decided to keep current */
784783
SCX_RQ_BYPASSING = 1 << 4,
785784
SCX_RQ_CLK_VALID = 1 << 5, /* RQ clock is fresh and valid */

0 commit comments

Comments
 (0)