Skip to content

Commit 546a3fe

Browse files
author
Peter Zijlstra
committed
sched: Reverse sched_class layout
Because GCC-12 is fully stupid about array bounds and it's just really hard to get a solid array definition from a linker script, flip the array order to avoid needing negative offsets :-/ This makes the whole relational pointer magic a little less obvious, but alas. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Kees Cook <keescook@chromium.org> Link: https://lkml.kernel.org/r/YoOLLmLG7HRTXeEm@hirez.programming.kicks-ass.net
1 parent 734387e commit 546a3fe

File tree

3 files changed

+20
-19
lines changed

3 files changed

+20
-19
lines changed

include/asm-generic/vmlinux.lds.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,13 @@
126126
*/
127127
#define SCHED_DATA \
128128
STRUCT_ALIGN(); \
129-
__begin_sched_classes = .; \
130-
*(__idle_sched_class) \
131-
*(__fair_sched_class) \
132-
*(__rt_sched_class) \
133-
*(__dl_sched_class) \
129+
__sched_class_highest = .; \
134130
*(__stop_sched_class) \
135-
__end_sched_classes = .;
131+
*(__dl_sched_class) \
132+
*(__rt_sched_class) \
133+
*(__fair_sched_class) \
134+
*(__idle_sched_class) \
135+
__sched_class_lowest = .;
136136

137137
/* The actual configuration determine if the init/exit sections
138138
* are handled as text/data or they can be discarded (which

kernel/sched/core.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,7 +2193,7 @@ void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
21932193
{
21942194
if (p->sched_class == rq->curr->sched_class)
21952195
rq->curr->sched_class->check_preempt_curr(rq, p, flags);
2196-
else if (p->sched_class > rq->curr->sched_class)
2196+
else if (sched_class_above(p->sched_class, rq->curr->sched_class))
21972197
resched_curr(rq);
21982198

21992199
/*
@@ -5692,7 +5692,7 @@ __pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
56925692
* higher scheduling class, because otherwise those lose the
56935693
* opportunity to pull in more work from other CPUs.
56945694
*/
5695-
if (likely(prev->sched_class <= &fair_sched_class &&
5695+
if (likely(!sched_class_above(prev->sched_class, &fair_sched_class) &&
56965696
rq->nr_running == rq->cfs.h_nr_running)) {
56975697

56985698
p = pick_next_task_fair(rq, prev, rf);
@@ -9472,11 +9472,11 @@ void __init sched_init(void)
94729472
int i;
94739473

94749474
/* Make sure the linker didn't screw up */
9475-
BUG_ON(&idle_sched_class + 1 != &fair_sched_class ||
9476-
&fair_sched_class + 1 != &rt_sched_class ||
9477-
&rt_sched_class + 1 != &dl_sched_class);
9475+
BUG_ON(&idle_sched_class != &fair_sched_class + 1 ||
9476+
&fair_sched_class != &rt_sched_class + 1 ||
9477+
&rt_sched_class != &dl_sched_class + 1);
94789478
#ifdef CONFIG_SMP
9479-
BUG_ON(&dl_sched_class + 1 != &stop_sched_class);
9479+
BUG_ON(&dl_sched_class != &stop_sched_class + 1);
94809480
#endif
94819481

94829482
wait_bit_init();

kernel/sched/sched.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,6 +2177,8 @@ static inline void set_next_task(struct rq *rq, struct task_struct *next)
21772177
*
21782178
* include/asm-generic/vmlinux.lds.h
21792179
*
2180+
* *CAREFUL* they are laid out in *REVERSE* order!!!
2181+
*
21802182
* Also enforce alignment on the instance, not the type, to guarantee layout.
21812183
*/
21822184
#define DEFINE_SCHED_CLASS(name) \
@@ -2185,17 +2187,16 @@ const struct sched_class name##_sched_class \
21852187
__section("__" #name "_sched_class")
21862188

21872189
/* Defined in include/asm-generic/vmlinux.lds.h */
2188-
extern struct sched_class __begin_sched_classes[];
2189-
extern struct sched_class __end_sched_classes[];
2190-
2191-
#define sched_class_highest (__end_sched_classes - 1)
2192-
#define sched_class_lowest (__begin_sched_classes - 1)
2190+
extern struct sched_class __sched_class_highest[];
2191+
extern struct sched_class __sched_class_lowest[];
21932192

21942193
#define for_class_range(class, _from, _to) \
2195-
for (class = (_from); class != (_to); class--)
2194+
for (class = (_from); class < (_to); class++)
21962195

21972196
#define for_each_class(class) \
2198-
for_class_range(class, sched_class_highest, sched_class_lowest)
2197+
for_class_range(class, __sched_class_highest, __sched_class_lowest)
2198+
2199+
#define sched_class_above(_a, _b) ((_a) < (_b))
21992200

22002201
extern const struct sched_class stop_sched_class;
22012202
extern const struct sched_class dl_sched_class;

0 commit comments

Comments
 (0)