Skip to content

Commit 6fa6588

Browse files
committed
Merge tag 'sched_ext-for-6.12-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext
Pull sched_ext fixes from Tejun Heo: - Three build fixes - The fix for a stall bug introduced by a recent optimization in sched core (SM_IDLE) - Addition of /sys/kernel/sched_ext/enable_seq. While not a fix, it is a simple addition that distro people want to be able to tell whether an SCX scheduler has ever been loaded on the system * tag 'sched_ext-for-6.12-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext: sched_ext: Provide a sysfs enable_seq counter sched_ext: Fix build when !CONFIG_STACKTRACE sched, sched_ext: Disable SM_IDLE/rq empty path when scx_enabled() sched: Put task_group::idle under CONFIG_GROUP_SCHED_WEIGHT sched: Add dummy version of sched_group_set_idle()
2 parents 3147a06 + 431844b commit 6fa6588

File tree

5 files changed

+40
-8
lines changed

5 files changed

+40
-8
lines changed

Documentation/scheduler/sched-ext.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ The current status of the BPF scheduler can be determined as follows:
8383
# cat /sys/kernel/sched_ext/root/ops
8484
simple
8585
86+
You can check if any BPF scheduler has ever been loaded since boot by examining
87+
this monotonically incrementing counter (a value of zero indicates that no BPF
88+
scheduler has been loaded):
89+
90+
.. code-block:: none
91+
92+
# cat /sys/kernel/sched_ext/enable_seq
93+
1
94+
8695
``tools/sched_ext/scx_show_state.py`` is a drgn script which shows more
8796
detailed information:
8897

@@ -96,6 +105,7 @@ detailed information:
96105
enable_state : enabled (2)
97106
bypass_depth : 0
98107
nr_rejected : 0
108+
enable_seq : 1
99109
100110
If ``CONFIG_SCHED_DEBUG`` is set, whether a given task is on sched_ext can
101111
be determined as follows:

kernel/sched/core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6591,7 +6591,8 @@ static void __sched notrace __schedule(int sched_mode)
65916591
*/
65926592
prev_state = READ_ONCE(prev->__state);
65936593
if (sched_mode == SM_IDLE) {
6594-
if (!rq->nr_running) {
6594+
/* SCX must consult the BPF scheduler to tell if rq is empty */
6595+
if (!rq->nr_running && !scx_enabled()) {
65956596
next = prev;
65966597
goto picked;
65976598
}

kernel/sched/ext.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,13 @@ static struct scx_exit_info *scx_exit_info;
874874
static atomic_long_t scx_nr_rejected = ATOMIC_LONG_INIT(0);
875875
static atomic_long_t scx_hotplug_seq = ATOMIC_LONG_INIT(0);
876876

877+
/*
878+
* A monotically increasing sequence number that is incremented every time a
879+
* scheduler is enabled. This can be used by to check if any custom sched_ext
880+
* scheduler has ever been used in the system.
881+
*/
882+
static atomic_long_t scx_enable_seq = ATOMIC_LONG_INIT(0);
883+
877884
/*
878885
* The maximum amount of time in jiffies that a task may be runnable without
879886
* being scheduled on a CPU. If this timeout is exceeded, it will trigger
@@ -4154,11 +4161,19 @@ static ssize_t scx_attr_hotplug_seq_show(struct kobject *kobj,
41544161
}
41554162
SCX_ATTR(hotplug_seq);
41564163

4164+
static ssize_t scx_attr_enable_seq_show(struct kobject *kobj,
4165+
struct kobj_attribute *ka, char *buf)
4166+
{
4167+
return sysfs_emit(buf, "%ld\n", atomic_long_read(&scx_enable_seq));
4168+
}
4169+
SCX_ATTR(enable_seq);
4170+
41574171
static struct attribute *scx_global_attrs[] = {
41584172
&scx_attr_state.attr,
41594173
&scx_attr_switch_all.attr,
41604174
&scx_attr_nr_rejected.attr,
41614175
&scx_attr_hotplug_seq.attr,
4176+
&scx_attr_enable_seq.attr,
41624177
NULL,
41634178
};
41644179

@@ -4469,8 +4484,9 @@ static void scx_ops_disable_workfn(struct kthread_work *work)
44694484

44704485
if (ei->msg[0] != '\0')
44714486
pr_err("sched_ext: %s: %s\n", scx_ops.name, ei->msg);
4472-
4487+
#ifdef CONFIG_STACKTRACE
44734488
stack_trace_print(ei->bt, ei->bt_len, 2);
4489+
#endif
44744490
} else {
44754491
pr_info("sched_ext: BPF scheduler \"%s\" disabled (%s)\n",
44764492
scx_ops.name, ei->reason);
@@ -4847,10 +4863,10 @@ static __printf(3, 4) void scx_ops_exit_kind(enum scx_exit_kind kind,
48474863
return;
48484864

48494865
ei->exit_code = exit_code;
4850-
4866+
#ifdef CONFIG_STACKTRACE
48514867
if (kind >= SCX_EXIT_ERROR)
48524868
ei->bt_len = stack_trace_save(ei->bt, SCX_EXIT_BT_LEN, 1);
4853-
4869+
#endif
48544870
va_start(args, fmt);
48554871
vscnprintf(ei->msg, SCX_EXIT_MSG_LEN, fmt, args);
48564872
va_end(args);
@@ -5176,6 +5192,8 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
51765192
kobject_uevent(scx_root_kobj, KOBJ_ADD);
51775193
mutex_unlock(&scx_ops_enable_mutex);
51785194

5195+
atomic_long_inc(&scx_enable_seq);
5196+
51795197
return 0;
51805198

51815199
err_del:

kernel/sched/sched.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,16 +432,17 @@ struct cfs_bandwidth {
432432
struct task_group {
433433
struct cgroup_subsys_state css;
434434

435+
#ifdef CONFIG_GROUP_SCHED_WEIGHT
436+
/* A positive value indicates that this is a SCHED_IDLE group. */
437+
int idle;
438+
#endif
439+
435440
#ifdef CONFIG_FAIR_GROUP_SCHED
436441
/* schedulable entities of this group on each CPU */
437442
struct sched_entity **se;
438443
/* runqueue "owned" by this group on each CPU */
439444
struct cfs_rq **cfs_rq;
440445
unsigned long shares;
441-
442-
/* A positive value indicates that this is a SCHED_IDLE group. */
443-
int idle;
444-
445446
#ifdef CONFIG_SMP
446447
/*
447448
* load_avg can be heavily contended at clock tick time, so put
@@ -582,6 +583,7 @@ static inline void set_task_rq_fair(struct sched_entity *se,
582583
#endif /* CONFIG_SMP */
583584
#else /* !CONFIG_FAIR_GROUP_SCHED */
584585
static inline int sched_group_set_shares(struct task_group *tg, unsigned long shares) { return 0; }
586+
static inline int sched_group_set_idle(struct task_group *tg, long idle) { return 0; }
585587
#endif /* CONFIG_FAIR_GROUP_SCHED */
586588

587589
#else /* CONFIG_CGROUP_SCHED */

tools/sched_ext/scx_show_state.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ def ops_state_str(state):
3737
print(f'enable_state : {ops_state_str(enable_state)} ({enable_state})')
3838
print(f'bypass_depth : {read_atomic("scx_ops_bypass_depth")}')
3939
print(f'nr_rejected : {read_atomic("scx_nr_rejected")}')
40+
print(f'enable_seq : {read_atomic("scx_enable_seq")}')

0 commit comments

Comments
 (0)