Skip to content

Commit fd03c5b

Browse files
author
Peter Zijlstra
committed
sched: Rework pick_next_task()
The current rule is that: pick_next_task() := pick_task() + set_next_task(.first = true) And many classes implement it directly as such. Change things around to make pick_next_task() optional while also changing the definition to: pick_next_task(prev) := pick_task() + put_prev_task() + set_next_task(.first = true) The reason is that sched_ext would like to have a 'final' call that knows the next task. By placing put_prev_task() right next to set_next_task() (as it already is for sched_core) this becomes trivial. As a bonus, this is a nice cleanup on its own. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 260598f commit fd03c5b

File tree

7 files changed

+37
-74
lines changed

7 files changed

+37
-74
lines changed

kernel/sched/core.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5893,8 +5893,9 @@ __pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
58935893

58945894
/* Assume the next prioritized class is idle_sched_class */
58955895
if (!p) {
5896+
p = pick_task_idle(rq);
58965897
put_prev_task(rq, prev);
5897-
p = pick_next_task_idle(rq);
5898+
set_next_task_first(rq, p);
58985899
}
58995900

59005901
/*
@@ -5916,12 +5917,20 @@ __pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
59165917

59175918
restart:
59185919
prev_balance(rq, prev, rf);
5919-
put_prev_task(rq, prev);
59205920

59215921
for_each_class(class) {
5922-
p = class->pick_next_task(rq);
5923-
if (p)
5924-
return p;
5922+
if (class->pick_next_task) {
5923+
p = class->pick_next_task(rq, prev);
5924+
if (p)
5925+
return p;
5926+
} else {
5927+
p = class->pick_task(rq);
5928+
if (p) {
5929+
put_prev_task(rq, prev);
5930+
set_next_task_first(rq, p);
5931+
return p;
5932+
}
5933+
}
59255934
}
59265935

59275936
BUG(); /* The idle class should always have a runnable task. */
@@ -6017,7 +6026,6 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
60176026
}
60186027

60196028
prev_balance(rq, prev, rf);
6020-
put_prev_task(rq, prev);
60216029

60226030
smt_mask = cpu_smt_mask(cpu);
60236031
need_sync = !!rq->core->core_cookie;
@@ -6184,6 +6192,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
61846192
}
61856193

61866194
out_set_next:
6195+
put_prev_task(rq, prev);
61876196
set_next_task_first(rq, next);
61886197
out:
61896198
if (rq->core->core_forceidle_count && next == rq->idle)

kernel/sched/deadline.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,28 +2431,10 @@ static struct task_struct *__pick_task_dl(struct rq *rq)
24312431
return p;
24322432
}
24332433

2434-
#ifdef CONFIG_SMP
24352434
static struct task_struct *pick_task_dl(struct rq *rq)
24362435
{
24372436
return __pick_task_dl(rq);
24382437
}
2439-
#endif
2440-
2441-
static struct task_struct *pick_next_task_dl(struct rq *rq)
2442-
{
2443-
struct task_struct *p;
2444-
2445-
p = __pick_task_dl(rq);
2446-
if (!p)
2447-
return p;
2448-
2449-
if (p->dl_server)
2450-
p->sched_class->set_next_task(rq, p, true);
2451-
else
2452-
set_next_task_dl(rq, p, true);
2453-
2454-
return p;
2455-
}
24562438

24572439
static void put_prev_task_dl(struct rq *rq, struct task_struct *p)
24582440
{
@@ -3146,13 +3128,12 @@ DEFINE_SCHED_CLASS(dl) = {
31463128

31473129
.wakeup_preempt = wakeup_preempt_dl,
31483130

3149-
.pick_next_task = pick_next_task_dl,
3131+
.pick_task = pick_task_dl,
31503132
.put_prev_task = put_prev_task_dl,
31513133
.set_next_task = set_next_task_dl,
31523134

31533135
#ifdef CONFIG_SMP
31543136
.balance = balance_dl,
3155-
.pick_task = pick_task_dl,
31563137
.select_task_rq = select_task_rq_dl,
31573138
.migrate_task_rq = migrate_task_rq_dl,
31583139
.set_cpus_allowed = set_cpus_allowed_dl,

kernel/sched/fair.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8777,7 +8777,7 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
87778777
se = &p->se;
87788778

87798779
#ifdef CONFIG_FAIR_GROUP_SCHED
8780-
if (!prev || prev->sched_class != &fair_sched_class)
8780+
if (prev->sched_class != &fair_sched_class)
87818781
goto simple;
87828782

87838783
/*
@@ -8819,8 +8819,7 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
88198819

88208820
simple:
88218821
#endif
8822-
if (prev)
8823-
put_prev_task(rq, prev);
8822+
put_prev_task(rq, prev);
88248823
set_next_task_fair(rq, p, true);
88258824
return p;
88268825

@@ -8850,9 +8849,9 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
88508849
return NULL;
88518850
}
88528851

8853-
static struct task_struct *__pick_next_task_fair(struct rq *rq)
8852+
static struct task_struct *__pick_next_task_fair(struct rq *rq, struct task_struct *prev)
88548853
{
8855-
return pick_next_task_fair(rq, NULL, NULL);
8854+
return pick_next_task_fair(rq, prev, NULL);
88568855
}
88578856

88588857
static bool fair_server_has_tasks(struct sched_dl_entity *dl_se)
@@ -13490,13 +13489,13 @@ DEFINE_SCHED_CLASS(fair) = {
1349013489

1349113490
.wakeup_preempt = check_preempt_wakeup_fair,
1349213491

13492+
.pick_task = pick_task_fair,
1349313493
.pick_next_task = __pick_next_task_fair,
1349413494
.put_prev_task = put_prev_task_fair,
1349513495
.set_next_task = set_next_task_fair,
1349613496

1349713497
#ifdef CONFIG_SMP
1349813498
.balance = balance_fair,
13499-
.pick_task = pick_task_fair,
1350013499
.select_task_rq = select_task_rq_fair,
1350113500
.migrate_task_rq = migrate_task_rq_fair,
1350213501

kernel/sched/idle.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -462,21 +462,10 @@ static void set_next_task_idle(struct rq *rq, struct task_struct *next, bool fir
462462
next->se.exec_start = rq_clock_task(rq);
463463
}
464464

465-
#ifdef CONFIG_SMP
466-
static struct task_struct *pick_task_idle(struct rq *rq)
465+
struct task_struct *pick_task_idle(struct rq *rq)
467466
{
468467
return rq->idle;
469468
}
470-
#endif
471-
472-
struct task_struct *pick_next_task_idle(struct rq *rq)
473-
{
474-
struct task_struct *next = rq->idle;
475-
476-
set_next_task_idle(rq, next, true);
477-
478-
return next;
479-
}
480469

481470
/*
482471
* It is not legal to sleep in the idle task - print a warning
@@ -531,13 +520,12 @@ DEFINE_SCHED_CLASS(idle) = {
531520

532521
.wakeup_preempt = wakeup_preempt_idle,
533522

534-
.pick_next_task = pick_next_task_idle,
523+
.pick_task = pick_task_idle,
535524
.put_prev_task = put_prev_task_idle,
536525
.set_next_task = set_next_task_idle,
537526

538527
#ifdef CONFIG_SMP
539528
.balance = balance_idle,
540-
.pick_task = pick_task_idle,
541529
.select_task_rq = select_task_rq_idle,
542530
.set_cpus_allowed = set_cpus_allowed_common,
543531
#endif

kernel/sched/rt.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,16 +1748,6 @@ static struct task_struct *pick_task_rt(struct rq *rq)
17481748
return p;
17491749
}
17501750

1751-
static struct task_struct *pick_next_task_rt(struct rq *rq)
1752-
{
1753-
struct task_struct *p = pick_task_rt(rq);
1754-
1755-
if (p)
1756-
set_next_task_rt(rq, p, true);
1757-
1758-
return p;
1759-
}
1760-
17611751
static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
17621752
{
17631753
struct sched_rt_entity *rt_se = &p->rt;
@@ -2645,13 +2635,12 @@ DEFINE_SCHED_CLASS(rt) = {
26452635

26462636
.wakeup_preempt = wakeup_preempt_rt,
26472637

2648-
.pick_next_task = pick_next_task_rt,
2638+
.pick_task = pick_task_rt,
26492639
.put_prev_task = put_prev_task_rt,
26502640
.set_next_task = set_next_task_rt,
26512641

26522642
#ifdef CONFIG_SMP
26532643
.balance = balance_rt,
2654-
.pick_task = pick_task_rt,
26552644
.select_task_rq = select_task_rq_rt,
26562645
.set_cpus_allowed = set_cpus_allowed_common,
26572646
.rq_online = rq_online_rt,

kernel/sched/sched.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2300,7 +2300,17 @@ struct sched_class {
23002300

23012301
void (*wakeup_preempt)(struct rq *rq, struct task_struct *p, int flags);
23022302

2303-
struct task_struct *(*pick_next_task)(struct rq *rq);
2303+
struct task_struct *(*pick_task)(struct rq *rq);
2304+
/*
2305+
* Optional! When implemented pick_next_task() should be equivalent to:
2306+
*
2307+
* next = pick_task();
2308+
* if (next) {
2309+
* put_prev_task(prev);
2310+
* set_next_task_first(next);
2311+
* }
2312+
*/
2313+
struct task_struct *(*pick_next_task)(struct rq *rq, struct task_struct *prev);
23042314

23052315
void (*put_prev_task)(struct rq *rq, struct task_struct *p);
23062316
void (*set_next_task)(struct rq *rq, struct task_struct *p, bool first);
@@ -2309,8 +2319,6 @@ struct sched_class {
23092319
int (*balance)(struct rq *rq, struct task_struct *prev, struct rq_flags *rf);
23102320
int (*select_task_rq)(struct task_struct *p, int task_cpu, int flags);
23112321

2312-
struct task_struct * (*pick_task)(struct rq *rq);
2313-
23142322
void (*migrate_task_rq)(struct task_struct *p, int new_cpu);
23152323

23162324
void (*task_woken)(struct rq *this_rq, struct task_struct *task);
@@ -2421,7 +2429,7 @@ static inline bool sched_fair_runnable(struct rq *rq)
24212429
}
24222430

24232431
extern struct task_struct *pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf);
2424-
extern struct task_struct *pick_next_task_idle(struct rq *rq);
2432+
extern struct task_struct *pick_task_idle(struct rq *rq);
24252433

24262434
#define SCA_CHECK 0x01
24272435
#define SCA_MIGRATE_DISABLE 0x02

kernel/sched/stop_task.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,6 @@ static struct task_struct *pick_task_stop(struct rq *rq)
4141
return rq->stop;
4242
}
4343

44-
static struct task_struct *pick_next_task_stop(struct rq *rq)
45-
{
46-
struct task_struct *p = pick_task_stop(rq);
47-
48-
if (p)
49-
set_next_task_stop(rq, p, true);
50-
51-
return p;
52-
}
53-
5444
static void
5545
enqueue_task_stop(struct rq *rq, struct task_struct *p, int flags)
5646
{
@@ -112,13 +102,12 @@ DEFINE_SCHED_CLASS(stop) = {
112102

113103
.wakeup_preempt = wakeup_preempt_stop,
114104

115-
.pick_next_task = pick_next_task_stop,
105+
.pick_task = pick_task_stop,
116106
.put_prev_task = put_prev_task_stop,
117107
.set_next_task = set_next_task_stop,
118108

119109
#ifdef CONFIG_SMP
120110
.balance = balance_stop,
121-
.pick_task = pick_task_stop,
122111
.select_task_rq = select_task_rq_stop,
123112
.set_cpus_allowed = set_cpus_allowed_common,
124113
#endif

0 commit comments

Comments
 (0)