Skip to content

Commit 10e7071

Browse files
author
Peter Zijlstra
committed
sched: Rework CPU hotplug task selection
The CPU hotplug task selection is the only place where we used put_prev_task() on a task that is not current. While looking at that, it occured to me that we can simplify all that by by using a custom pick loop. Since we don't need to put current, we can do away with the fake task too. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Aaron Lu <[email protected]> Cc: Valentin Schneider <[email protected]> Cc: [email protected] Cc: Phil Auld <[email protected]> Cc: Julien Desfossez <[email protected]> Cc: Nishanth Aravamudan <[email protected]>
1 parent f95d4ea commit 10e7071

File tree

2 files changed

+15
-18
lines changed

2 files changed

+15
-18
lines changed

kernel/sched/core.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6082,21 +6082,22 @@ static void calc_load_migrate(struct rq *rq)
60826082
atomic_long_add(delta, &calc_load_tasks);
60836083
}
60846084

6085-
static void put_prev_task_fake(struct rq *rq, struct task_struct *prev)
6085+
static struct task_struct *__pick_migrate_task(struct rq *rq)
60866086
{
6087-
}
6087+
const struct sched_class *class;
6088+
struct task_struct *next;
60886089

6089-
static const struct sched_class fake_sched_class = {
6090-
.put_prev_task = put_prev_task_fake,
6091-
};
6090+
for_each_class(class) {
6091+
next = class->pick_next_task(rq, NULL, NULL);
6092+
if (next) {
6093+
next->sched_class->put_prev_task(rq, next);
6094+
return next;
6095+
}
6096+
}
60926097

6093-
static struct task_struct fake_task = {
6094-
/*
6095-
* Avoid pull_{rt,dl}_task()
6096-
*/
6097-
.prio = MAX_PRIO + 1,
6098-
.sched_class = &fake_sched_class,
6099-
};
6098+
/* The idle class should always have a runnable task */
6099+
BUG();
6100+
}
61006101

61016102
/*
61026103
* Migrate all tasks from the rq, sleeping tasks will be migrated by
@@ -6139,12 +6140,7 @@ static void migrate_tasks(struct rq *dead_rq, struct rq_flags *rf)
61396140
if (rq->nr_running == 1)
61406141
break;
61416142

6142-
/*
6143-
* pick_next_task() assumes pinned rq->lock:
6144-
*/
6145-
next = pick_next_task(rq, &fake_task, rf);
6146-
BUG_ON(!next);
6147-
put_prev_task(rq, next);
6143+
next = __pick_migrate_task(rq);
61486144

61496145
/*
61506146
* Rules for changing task_struct::cpus_mask are holding

kernel/sched/sched.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,7 @@ struct sched_class {
17511751

17521752
static inline void put_prev_task(struct rq *rq, struct task_struct *prev)
17531753
{
1754+
WARN_ON_ONCE(rq->curr != prev);
17541755
prev->sched_class->put_prev_task(rq, prev);
17551756
}
17561757

0 commit comments

Comments
 (0)