Skip to content
This repository has been archived by the owner on Jun 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #140 from sched-ext/htejun
Browse files Browse the repository at this point in the history
Fix invalid state transition while scheduler is loaded
  • Loading branch information
Byte-Lab authored Feb 8, 2024
2 parents 28325e3 + c0fb0e5 commit 6f5bf31
Showing 1 changed file with 18 additions and 24 deletions.
42 changes: 18 additions & 24 deletions kernel/sched/ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,26 +2353,30 @@ static enum scx_task_state scx_get_task_state(const struct task_struct *p)
static void scx_set_task_state(struct task_struct *p, enum scx_task_state state)
{
enum scx_task_state prev_state = scx_get_task_state(p);
bool warn = false;

BUILD_BUG_ON(SCX_TASK_NR_STATES > (1 << SCX_TASK_STATE_BITS));

switch (state) {
case SCX_TASK_NONE:
break;
case SCX_TASK_INIT:
WARN_ON_ONCE(prev_state != SCX_TASK_NONE);
warn = prev_state != SCX_TASK_NONE;
break;
case SCX_TASK_READY:
WARN_ON_ONCE(prev_state == SCX_TASK_NONE);
warn = prev_state == SCX_TASK_NONE;
break;
case SCX_TASK_ENABLED:
WARN_ON_ONCE(prev_state != SCX_TASK_READY);
warn = prev_state != SCX_TASK_READY;
break;
default:
WARN_ON_ONCE(true);
warn = true;
return;
}

WARN_ONCE(warn, "sched_ext: Invalid task state transition %d -> %d for %s[%d]",
prev_state, state, p->comm, p->pid);

p->scx.flags &= ~SCX_TASK_STATE_MASK;
p->scx.flags |= state << SCX_TASK_STATE_SHIFT;
}
Expand Down Expand Up @@ -3347,21 +3351,16 @@ static void scx_ops_disable_workfn(struct kthread_work *work)
while ((p = scx_task_iter_next_filtered_locked(&sti))) {
const struct sched_class *old_class = p->sched_class;
struct sched_enq_and_set_ctx ctx;
bool alive = READ_ONCE(p->__state) != TASK_DEAD;

sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE, &ctx);

p->scx.slice = min_t(u64, p->scx.slice, SCX_SLICE_DFL);

__setscheduler_prio(p, p->prio);
if (alive)
check_class_changing(task_rq(p), p, old_class);
check_class_changing(task_rq(p), p, old_class);

sched_enq_and_set_task(&ctx);

if (alive)
check_class_changed(task_rq(p), p, old_class, p->prio);

check_class_changed(task_rq(p), p, old_class, p->prio);
scx_ops_exit_task(p);
}
scx_task_iter_exit(&sti);
Expand Down Expand Up @@ -3830,23 +3829,18 @@ static int scx_ops_enable(struct sched_ext_ops *ops)

scx_task_iter_init(&sti);
while ((p = scx_task_iter_next_filtered_locked(&sti))) {
if (READ_ONCE(p->__state) != TASK_DEAD) {
const struct sched_class *old_class = p->sched_class;
struct sched_enq_and_set_ctx ctx;
const struct sched_class *old_class = p->sched_class;
struct sched_enq_and_set_ctx ctx;

sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE,
&ctx);
sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE, &ctx);

scx_set_task_state(p, SCX_TASK_READY);
__setscheduler_prio(p, p->prio);
check_class_changing(task_rq(p), p, old_class);
scx_set_task_state(p, SCX_TASK_READY);
__setscheduler_prio(p, p->prio);
check_class_changing(task_rq(p), p, old_class);

sched_enq_and_set_task(&ctx);
sched_enq_and_set_task(&ctx);

check_class_changed(task_rq(p), p, old_class, p->prio);
} else {
scx_ops_exit_task(p);
}
check_class_changed(task_rq(p), p, old_class, p->prio);
}
scx_task_iter_exit(&sti);

Expand Down

0 comments on commit 6f5bf31

Please sign in to comment.