sched: Pass correct scheduling policy to __setscheduler_class
Commit98442f0ccd
("sched: Fix delayed_dequeue vs switched_from_fair()") overlooked that __setscheduler_prio(), now __setscheduler_class() relies on p->policy for task_should_scx(), and moved the call before __setscheduler_params() updates it, causing it to be using the old p->policy value. Resolve this by changing task_should_scx() to take the policy itself instead of a task pointer, such that __sched_setscheduler() can pass in the updated policy. Fixes:98442f0ccd
("sched: Fix delayed_dequeue vs switched_from_fair()") Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
9c70b2a33c
commit
5db91545ef
@ -4711,7 +4711,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p)
|
||||
if (rt_prio(p->prio)) {
|
||||
p->sched_class = &rt_sched_class;
|
||||
#ifdef CONFIG_SCHED_CLASS_EXT
|
||||
} else if (task_should_scx(p)) {
|
||||
} else if (task_should_scx(p->policy)) {
|
||||
p->sched_class = &ext_sched_class;
|
||||
#endif
|
||||
} else {
|
||||
@ -7025,7 +7025,7 @@ int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flag
|
||||
}
|
||||
EXPORT_SYMBOL(default_wake_function);
|
||||
|
||||
const struct sched_class *__setscheduler_class(struct task_struct *p, int prio)
|
||||
const struct sched_class *__setscheduler_class(int policy, int prio)
|
||||
{
|
||||
if (dl_prio(prio))
|
||||
return &dl_sched_class;
|
||||
@ -7034,7 +7034,7 @@ const struct sched_class *__setscheduler_class(struct task_struct *p, int prio)
|
||||
return &rt_sched_class;
|
||||
|
||||
#ifdef CONFIG_SCHED_CLASS_EXT
|
||||
if (task_should_scx(p))
|
||||
if (task_should_scx(policy))
|
||||
return &ext_sched_class;
|
||||
#endif
|
||||
|
||||
@ -7142,7 +7142,7 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
|
||||
queue_flag &= ~DEQUEUE_MOVE;
|
||||
|
||||
prev_class = p->sched_class;
|
||||
next_class = __setscheduler_class(p, prio);
|
||||
next_class = __setscheduler_class(p->policy, prio);
|
||||
|
||||
if (prev_class != next_class && p->se.sched_delayed)
|
||||
dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
|
||||
|
@ -4256,14 +4256,14 @@ static const struct kset_uevent_ops scx_uevent_ops = {
|
||||
* Used by sched_fork() and __setscheduler_prio() to pick the matching
|
||||
* sched_class. dl/rt are already handled.
|
||||
*/
|
||||
bool task_should_scx(struct task_struct *p)
|
||||
bool task_should_scx(int policy)
|
||||
{
|
||||
if (!scx_enabled() ||
|
||||
unlikely(scx_ops_enable_state() == SCX_OPS_DISABLING))
|
||||
return false;
|
||||
if (READ_ONCE(scx_switching_all))
|
||||
return true;
|
||||
return p->policy == SCHED_EXT;
|
||||
return policy == SCHED_EXT;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4493,7 +4493,7 @@ static void scx_ops_disable_workfn(struct kthread_work *work)
|
||||
|
||||
sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE, &ctx);
|
||||
|
||||
p->sched_class = __setscheduler_class(p, p->prio);
|
||||
p->sched_class = __setscheduler_class(p->policy, p->prio);
|
||||
check_class_changing(task_rq(p), p, old_class);
|
||||
|
||||
sched_enq_and_set_task(&ctx);
|
||||
@ -5204,7 +5204,7 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
|
||||
sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE, &ctx);
|
||||
|
||||
p->scx.slice = SCX_SLICE_DFL;
|
||||
p->sched_class = __setscheduler_class(p, p->prio);
|
||||
p->sched_class = __setscheduler_class(p->policy, p->prio);
|
||||
check_class_changing(task_rq(p), p, old_class);
|
||||
|
||||
sched_enq_and_set_task(&ctx);
|
||||
|
@ -18,7 +18,7 @@ bool scx_can_stop_tick(struct rq *rq);
|
||||
void scx_rq_activate(struct rq *rq);
|
||||
void scx_rq_deactivate(struct rq *rq);
|
||||
int scx_check_setscheduler(struct task_struct *p, int policy);
|
||||
bool task_should_scx(struct task_struct *p);
|
||||
bool task_should_scx(int policy);
|
||||
void init_sched_ext_class(void);
|
||||
|
||||
static inline u32 scx_cpuperf_target(s32 cpu)
|
||||
|
@ -3830,7 +3830,7 @@ static inline int rt_effective_prio(struct task_struct *p, int prio)
|
||||
|
||||
extern int __sched_setscheduler(struct task_struct *p, const struct sched_attr *attr, bool user, bool pi);
|
||||
extern int __sched_setaffinity(struct task_struct *p, struct affinity_context *ctx);
|
||||
extern const struct sched_class *__setscheduler_class(struct task_struct *p, int prio);
|
||||
extern const struct sched_class *__setscheduler_class(int policy, int prio);
|
||||
extern void set_load_weight(struct task_struct *p, bool update_load);
|
||||
extern void enqueue_task(struct rq *rq, struct task_struct *p, int flags);
|
||||
extern bool dequeue_task(struct rq *rq, struct task_struct *p, int flags);
|
||||
|
@ -707,7 +707,7 @@ change:
|
||||
}
|
||||
|
||||
prev_class = p->sched_class;
|
||||
next_class = __setscheduler_class(p, newprio);
|
||||
next_class = __setscheduler_class(policy, newprio);
|
||||
|
||||
if (prev_class != next_class && p->se.sched_delayed)
|
||||
dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
|
||||
|
Loading…
Reference in New Issue
Block a user