Skip to content

Commit 2fa0fbe

Browse files
committed
sched_ext: Implement auto local dispatching of migration disabled tasks
Migration disabled tasks are special and pinned to their previous CPUs. They tripped up some unsuspecting BPF schedulers as their ->nr_cpus_allowed may not agree with the bits set in ->cpus_ptr. Make it easier for BPF schedulers by automatically dispatching them to the pinned local DSQs by default. If a BPF scheduler wants to handle migration disabled tasks explicitly, it can set SCX_OPS_ENQ_MIGRATION_DISABLED. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Andrea Righi <arighi@nvidia.com>
1 parent 029b6ce commit 2fa0fbe

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

kernel/sched/ext.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ enum scx_ops_flags {
122122
*/
123123
SCX_OPS_SWITCH_PARTIAL = 1LLU << 3,
124124

125+
/*
126+
* A migration disabled task can only execute on its current CPU. By
127+
* default, such tasks are automatically put on the CPU's local DSQ with
128+
* the default slice on enqueue. If this ops flag is set, they also go
129+
* through ops.enqueue().
130+
*
131+
* A migration disabled task never invokes ops.select_cpu() as it can
132+
* only select the current CPU. Also, p->cpus_ptr will only contain its
133+
* current CPU while p->nr_cpus_allowed keeps tracking p->user_cpus_ptr
134+
* and thus may disagree with cpumask_weight(p->cpus_ptr).
135+
*/
136+
SCX_OPS_ENQ_MIGRATION_DISABLED = 1LLU << 4,
137+
125138
/*
126139
* CPU cgroup support flags
127140
*/
@@ -130,6 +143,7 @@ enum scx_ops_flags {
130143
SCX_OPS_ALL_FLAGS = SCX_OPS_KEEP_BUILTIN_IDLE |
131144
SCX_OPS_ENQ_LAST |
132145
SCX_OPS_ENQ_EXITING |
146+
SCX_OPS_ENQ_MIGRATION_DISABLED |
133147
SCX_OPS_SWITCH_PARTIAL |
134148
SCX_OPS_HAS_CGROUP_WEIGHT,
135149
};
@@ -882,6 +896,7 @@ static bool scx_warned_zero_slice;
882896

883897
static DEFINE_STATIC_KEY_FALSE(scx_ops_enq_last);
884898
static DEFINE_STATIC_KEY_FALSE(scx_ops_enq_exiting);
899+
static DEFINE_STATIC_KEY_FALSE(scx_ops_enq_migration_disabled);
885900
static DEFINE_STATIC_KEY_FALSE(scx_ops_cpu_preempt);
886901
static DEFINE_STATIC_KEY_FALSE(scx_builtin_idle_enabled);
887902

@@ -2014,6 +2029,11 @@ static void do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags,
20142029
unlikely(p->flags & PF_EXITING))
20152030
goto local;
20162031

2032+
/* see %SCX_OPS_ENQ_MIGRATION_DISABLED */
2033+
if (!static_branch_unlikely(&scx_ops_enq_migration_disabled) &&
2034+
is_migration_disabled(p))
2035+
goto local;
2036+
20172037
if (!SCX_HAS_OP(enqueue))
20182038
goto global;
20192039

@@ -5052,6 +5072,7 @@ static void scx_ops_disable_workfn(struct kthread_work *work)
50525072
static_branch_disable(&scx_has_op[i]);
50535073
static_branch_disable(&scx_ops_enq_last);
50545074
static_branch_disable(&scx_ops_enq_exiting);
5075+
static_branch_disable(&scx_ops_enq_migration_disabled);
50555076
static_branch_disable(&scx_ops_cpu_preempt);
50565077
static_branch_disable(&scx_builtin_idle_enabled);
50575078
synchronize_rcu();
@@ -5661,6 +5682,8 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
56615682

56625683
if (ops->flags & SCX_OPS_ENQ_EXITING)
56635684
static_branch_enable(&scx_ops_enq_exiting);
5685+
if (ops->flags & SCX_OPS_ENQ_MIGRATION_DISABLED)
5686+
static_branch_enable(&scx_ops_enq_migration_disabled);
56645687
if (scx_ops.cpu_acquire || scx_ops.cpu_release)
56655688
static_branch_enable(&scx_ops_cpu_preempt);
56665689

0 commit comments

Comments
 (0)