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

Commit

Permalink
scx: Fix ops.cgroup_move() not being called on a task which went thro…
Browse files Browse the repository at this point in the history
…ugh ops.cgroup_prep_move()

sched_move_task() takes an early exit if the source and destination are
identical. This triggers the warning in scx_cgroup_can_attach() as it leaves
p->scx.cgrp_moving_from uncleared.

Update the cgroup migration path so that ops.cgroup_prep_move() is skipped
for identity migrations so that its invocations always match
ops.cgroup_move() one-to-one.
  • Loading branch information
htejun committed Mar 19, 2024
1 parent 6d5da8c commit d439866
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions kernel/sched/ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -2713,6 +2713,17 @@ int scx_cgroup_can_attach(struct cgroup_taskset *tset)

cgroup_taskset_for_each(p, css, tset) {
struct cgroup *from = tg_cgrp(task_group(p));
struct cgroup *to = tg_cgrp(css_tg(css));

WARN_ON_ONCE(p->scx.cgrp_moving_from);

/*
* sched_move_task() omits identity migrations. Let's match the
* behavior so that ops.cgroup_prep_move() and ops.cgroup_move()
* always match one-to-one.
*/
if (from == to)
continue;

if (SCX_HAS_OP(cgroup_prep_move)) {
ret = SCX_CALL_OP_RET(SCX_KF_SLEEPABLE, cgroup_prep_move,
Expand All @@ -2721,17 +2732,14 @@ int scx_cgroup_can_attach(struct cgroup_taskset *tset)
goto err;
}

WARN_ON_ONCE(p->scx.cgrp_moving_from);
p->scx.cgrp_moving_from = from;
}

return 0;

err:
cgroup_taskset_for_each(p, css, tset) {
if (!p->scx.cgrp_moving_from)
break;
if (SCX_HAS_OP(cgroup_cancel_move))
if (SCX_HAS_OP(cgroup_cancel_move) && p->scx.cgrp_moving_from)
SCX_CALL_OP(SCX_KF_SLEEPABLE, cgroup_cancel_move, p,
p->scx.cgrp_moving_from, css->cgroup);
p->scx.cgrp_moving_from = NULL;
Expand Down Expand Up @@ -2759,6 +2767,10 @@ void scx_move_task(struct task_struct *p)
if (!scx_enabled())
return;

/*
* @p must have ops.cgroup_prep_move() called on it and thus
* cgrp_moving_from set.
*/
if (SCX_HAS_OP(cgroup_move) && !WARN_ON_ONCE(!p->scx.cgrp_moving_from))
SCX_CALL_OP_TASK(SCX_KF_UNLOCKED, cgroup_move, p,
p->scx.cgrp_moving_from, tg_cgrp(task_group(p)));
Expand All @@ -2779,8 +2791,7 @@ void scx_cgroup_cancel_attach(struct cgroup_taskset *tset)
goto out_unlock;

cgroup_taskset_for_each(p, css, tset) {
if (SCX_HAS_OP(cgroup_cancel_move) &&
!WARN_ON_ONCE(!p->scx.cgrp_moving_from))
if (SCX_HAS_OP(cgroup_cancel_move) && p->scx.cgrp_moving_from)
SCX_CALL_OP(SCX_KF_SLEEPABLE, cgroup_cancel_move, p,
p->scx.cgrp_moving_from, css->cgroup);
p->scx.cgrp_moving_from = NULL;
Expand Down

0 comments on commit d439866

Please sign in to comment.