* [PATCH sched_ext/for-7.3] sched_ext: Replace open-coded event lists with SCX_EVENTS_LIST
@ 2026-06-29 14:35 Cheng-Yang Chou
2026-06-29 18:17 ` Tejun Heo
0 siblings, 1 reply; 2+ messages in thread
From: Cheng-Yang Chou @ 2026-06-29 14:35 UTC (permalink / raw)
To: sched-ext, Tejun Heo, David Vernet, Andrea Righi, Changwoo Min
Cc: Ching-Chun Huang, Chia-Ping Tsai, chengyang.chou, Cheng-Yang Chou
Three sites enumerate every scx_event_stats field by name:
scx_read_events(), scx_attr_events_show(), and scx_dump_state().
Adding a new SCX_EV_* event requires three separate manual edits.
Missing any one silently drops counts or omits the field from
diagnostic output with no compile-time indication.
SCX_EVENTS_LIST(SCX_EVENT) in internal.h becomes the single
authoritative list of event names, with NR_SCX_EVENTS derived
from the struct size, so all three sites stay in sync with one
edit instead of three.
No functional changes.
Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com>
---
kernel/sched/ext/ext.c | 64 +++++++------------------------------
kernel/sched/ext/internal.h | 17 ++++++++++
2 files changed, 29 insertions(+), 52 deletions(-)
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 9c9cb9d08bca..57acefdd9573 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -1004,16 +1004,6 @@ static struct task_struct *scx_task_iter_next_locked(struct scx_task_iter *iter)
trace_sched_ext_event(#name, cnt); \
} while(0)
-/**
- * scx_agg_event - Aggregate an event counter 'kind' from 'src_e' to 'dst_e'
- * @dst_e: destination event stats
- * @src_e: source event stats
- * @kind: a kind of event to be aggregated
- */
-#define scx_agg_event(dst_e, src_e, kind) do { \
- (dst_e)->kind += READ_ONCE((src_e)->kind); \
-} while(0)
-
/**
* scx_dump_event - Dump an event 'kind' in 'events' to 's'
* @s: output seq_buf
@@ -4989,19 +4979,9 @@ static ssize_t scx_attr_events_show(struct kobject *kobj,
int at = 0;
scx_read_events(sch, &events);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_SELECT_CPU_FALLBACK);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_DISPATCH_KEEP_LAST);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_ENQ_SKIP_EXITING);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_ENQ_SKIP_MIGRATION_DISABLED);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_REENQ_IMMED);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_REENQ_LOCAL_REPEAT);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_REFILL_SLICE_DFL);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_BYPASS_DURATION);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_BYPASS_DISPATCH);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_BYPASS_ACTIVATE);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_INSERT_NOT_OWNED);
- at += scx_attr_event_show(buf, at, &events, SCX_EV_SUB_BYPASS_DISPATCH);
+#define SCX_EVENT(name) at += scx_attr_event_show(buf, at, &events, name)
+ SCX_EVENTS_LIST(SCX_EVENT);
+#undef SCX_EVENT
return at;
}
SCX_ATTR(events);
@@ -6651,19 +6631,9 @@ static void scx_dump_state(struct scx_sched *sch, struct scx_exit_info *ei,
dump_line(&s, "--------------");
scx_read_events(sch, &events);
- scx_dump_event(s, &events, SCX_EV_SELECT_CPU_FALLBACK);
- scx_dump_event(s, &events, SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE);
- scx_dump_event(s, &events, SCX_EV_DISPATCH_KEEP_LAST);
- scx_dump_event(s, &events, SCX_EV_ENQ_SKIP_EXITING);
- scx_dump_event(s, &events, SCX_EV_ENQ_SKIP_MIGRATION_DISABLED);
- scx_dump_event(s, &events, SCX_EV_REENQ_IMMED);
- scx_dump_event(s, &events, SCX_EV_REENQ_LOCAL_REPEAT);
- scx_dump_event(s, &events, SCX_EV_REFILL_SLICE_DFL);
- scx_dump_event(s, &events, SCX_EV_BYPASS_DURATION);
- scx_dump_event(s, &events, SCX_EV_BYPASS_DISPATCH);
- scx_dump_event(s, &events, SCX_EV_BYPASS_ACTIVATE);
- scx_dump_event(s, &events, SCX_EV_INSERT_NOT_OWNED);
- scx_dump_event(s, &events, SCX_EV_SUB_BYPASS_DISPATCH);
+#define SCX_EVENT(name) scx_dump_event(s, &events, name)
+ SCX_EVENTS_LIST(SCX_EVENT);
+#undef SCX_EVENT
if (seq_buf_has_overflowed(&s) && dump_len >= sizeof(trunc_marker))
memcpy(ei->dump + dump_len - sizeof(trunc_marker),
@@ -10333,26 +10303,16 @@ __bpf_kfunc u64 scx_bpf_now(void)
static void scx_read_events(struct scx_sched *sch, struct scx_event_stats *events)
{
- struct scx_event_stats *e_cpu;
- int cpu;
+ int cpu, i;
/* Aggregate per-CPU event counters into @events. */
memset(events, 0, sizeof(*events));
for_each_possible_cpu(cpu) {
- e_cpu = &per_cpu_ptr(sch->pcpu, cpu)->event_stats;
- scx_agg_event(events, e_cpu, SCX_EV_SELECT_CPU_FALLBACK);
- scx_agg_event(events, e_cpu, SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE);
- scx_agg_event(events, e_cpu, SCX_EV_DISPATCH_KEEP_LAST);
- scx_agg_event(events, e_cpu, SCX_EV_ENQ_SKIP_EXITING);
- scx_agg_event(events, e_cpu, SCX_EV_ENQ_SKIP_MIGRATION_DISABLED);
- scx_agg_event(events, e_cpu, SCX_EV_REENQ_IMMED);
- scx_agg_event(events, e_cpu, SCX_EV_REENQ_LOCAL_REPEAT);
- scx_agg_event(events, e_cpu, SCX_EV_REFILL_SLICE_DFL);
- scx_agg_event(events, e_cpu, SCX_EV_BYPASS_DURATION);
- scx_agg_event(events, e_cpu, SCX_EV_BYPASS_DISPATCH);
- scx_agg_event(events, e_cpu, SCX_EV_BYPASS_ACTIVATE);
- scx_agg_event(events, e_cpu, SCX_EV_INSERT_NOT_OWNED);
- scx_agg_event(events, e_cpu, SCX_EV_SUB_BYPASS_DISPATCH);
+ const s64 *src = (const s64 *)&per_cpu_ptr(sch->pcpu, cpu)->event_stats;
+ s64 *dst = (s64 *)events;
+
+ for (i = 0; i < NR_SCX_EVENTS; i++)
+ dst[i] += READ_ONCE(src[i]);
}
}
diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
index 75522a5f28f4..b03fdb382af7 100644
--- a/kernel/sched/ext/internal.h
+++ b/kernel/sched/ext/internal.h
@@ -1051,6 +1051,23 @@ struct scx_event_stats {
s64 SCX_EV_SUB_BYPASS_DISPATCH;
};
+#define SCX_EVENTS_LIST(SCX_EVENT) \
+ SCX_EVENT(SCX_EV_SELECT_CPU_FALLBACK); \
+ SCX_EVENT(SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE); \
+ SCX_EVENT(SCX_EV_DISPATCH_KEEP_LAST); \
+ SCX_EVENT(SCX_EV_ENQ_SKIP_EXITING); \
+ SCX_EVENT(SCX_EV_ENQ_SKIP_MIGRATION_DISABLED); \
+ SCX_EVENT(SCX_EV_REENQ_IMMED); \
+ SCX_EVENT(SCX_EV_REENQ_LOCAL_REPEAT); \
+ SCX_EVENT(SCX_EV_REFILL_SLICE_DFL); \
+ SCX_EVENT(SCX_EV_BYPASS_DURATION); \
+ SCX_EVENT(SCX_EV_BYPASS_DISPATCH); \
+ SCX_EVENT(SCX_EV_BYPASS_ACTIVATE); \
+ SCX_EVENT(SCX_EV_INSERT_NOT_OWNED); \
+ SCX_EVENT(SCX_EV_SUB_BYPASS_DISPATCH)
+
+#define NR_SCX_EVENTS (sizeof(struct scx_event_stats) / sizeof(s64))
+
struct scx_sched;
enum scx_sched_pcpu_flags {
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH sched_ext/for-7.3] sched_ext: Replace open-coded event lists with SCX_EVENTS_LIST
2026-06-29 14:35 [PATCH sched_ext/for-7.3] sched_ext: Replace open-coded event lists with SCX_EVENTS_LIST Cheng-Yang Chou
@ 2026-06-29 18:17 ` Tejun Heo
0 siblings, 0 replies; 2+ messages in thread
From: Tejun Heo @ 2026-06-29 18:17 UTC (permalink / raw)
To: Cheng-Yang Chou
Cc: sched-ext, David Vernet, Andrea Righi, Changwoo Min,
Ching-Chun Huang, Chia-Ping Tsai, chengyang.chou
Hello,
On Mon, Jun 29, 2026 at 10:35:11PM +0800, Cheng-Yang Chou wrote:
> + const s64 *src = (const s64 *)&per_cpu_ptr(sch->pcpu, cpu)->event_stats;
> + s64 *dst = (s64 *)events;
> +
> + for (i = 0; i < NR_SCX_EVENTS; i++)
> + dst[i] += READ_ONCE(src[i]);
scx_read_events() can expand SCX_EVENTS_LIST() too, like the other two
sites:
struct scx_event_stats *e_cpu = &per_cpu_ptr(sch->pcpu, cpu)->event_stats;
#define SCX_EVENT(name) events->name += READ_ONCE(e_cpu->name)
SCX_EVENTS_LIST(SCX_EVENT);
#undef SCX_EVENT
That keeps all three sites consistent and lets you drop NR_SCX_EVENTS and
the s64 casts, which assume the struct stays a packed array of s64.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-06-29 18:24 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-29 14:35 [PATCH sched_ext/for-7.3] sched_ext: Replace open-coded event lists with SCX_EVENTS_LIST Cheng-Yang Chou
2026-06-29 18:17 ` Tejun Heo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox