summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/ext/ext.c2
-rw-r--r--kernel/sched/ext/internal.h11
-rw-r--r--kernel/sched/ext/sub.c8
-rw-r--r--kernel/sched/ext/sub.h4
4 files changed, 19 insertions, 6 deletions
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 2da3a5f44b4a..151befdc9602 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -4792,7 +4792,7 @@ SCX_ATTR(events);
#ifdef CONFIG_EXT_SUB_SCHED
static const char *scx_cap_names[__SCX_NR_CAPS] = {
- [__SCX_CAP_DUMMY] = "dummy",
+ [__SCX_CAP_ENQ_IMMED] = "enq_immed",
};
static ssize_t scx_attr_caps_show(struct kobject *kobj,
diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
index 079ee941b343..e735812e77a5 100644
--- a/kernel/sched/ext/internal.h
+++ b/kernel/sched/ext/internal.h
@@ -1270,17 +1270,22 @@ struct scx_sched_pnode {
* topology-aligned and likely to serve as the locality unit when cids are
* allocated to schedulers, so per-shard lock granularity scales naturally with
* the allocation pattern.
+ *
+ * ENQ_IMMED insert an IMMED task onto the cid's local DSQ
*/
enum scx_cap_flags {
- __SCX_CAP_DUMMY = 0,
+ __SCX_CAP_ENQ_IMMED = 0,
__SCX_NR_CAPS,
__SCX_CAP_ALL = BIT_U64(__SCX_NR_CAPS) - 1,
- SCX_CAP_DUMMY = BIT_U64(__SCX_CAP_DUMMY),
+ SCX_CAP_ENQ_IMMED = BIT_U64(__SCX_CAP_ENQ_IMMED),
+
+ /* alias for minimal cap to make any use of a cpu */
+ SCX_CAP_BASE = SCX_CAP_ENQ_IMMED,
/* caps whose loss strands queued tasks, see scx_process_sync_ecaps() */
- SCX_CAPS_REENQ_ON_LOSS = 0,
+ SCX_CAPS_REENQ_ON_LOSS = SCX_CAP_ENQ_IMMED,
};
#ifdef CONFIG_EXT_SUB_SCHED
diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c
index bbd068bfd86c..11fda1d3828d 100644
--- a/kernel/sched/ext/sub.c
+++ b/kernel/sched/ext/sub.c
@@ -1279,6 +1279,14 @@ __bpf_kfunc bool scx_bpf_sub_dispatch(u64 cgroup_id, const struct bpf_prog_aux *
return false;
}
+ /*
+ * Skip a child that does not effectively hold the base cap on this cpu:
+ * its inserts would only be rejected. ecaps are synced at the top of
+ * balance_one() before dispatch, so this reflects the in-effect state.
+ */
+ if (scx_missing_caps(child, cpu_of(this_rq), SCX_CAP_BASE))
+ return false;
+
return scx_dispatch_sched(child, this_rq, this_rq->scx.sub_dispatch_prev,
true);
}
diff --git a/kernel/sched/ext/sub.h b/kernel/sched/ext/sub.h
index 3c22ae40349d..13e9dec56a6a 100644
--- a/kernel/sched/ext/sub.h
+++ b/kernel/sched/ext/sub.h
@@ -115,13 +115,13 @@ static inline u64 scx_caps_for_enq(u64 enq_flags)
/* a restored task must be put into the local DSQ regardless of caps */
if (enq_flags & SCX_ENQ_IGNORE_CAPS)
return 0;
- return 0;
+ return SCX_CAP_ENQ_IMMED;
}
/* map queued @p to the SCX_CAP_* bit required to stay on its local DSQ */
static inline u64 scx_caps_for_task(struct task_struct *p)
{
- return 0;
+ return SCX_CAP_ENQ_IMMED;
}
/* caps implied by holding @cap */