sched: Make the idle task quack like a per-CPU kthread
For all intents and purposes, the idle task is a per-CPU kthread. It isn't created via the same route as other pcpu kthreads however, and as a result it is missing a few bells and whistles: it fails kthread_is_per_cpu() and it doesn't have PF_NO_SETAFFINITY set. Fix the former by giving the idle task a kthread struct along with the KTHREAD_IS_PER_CPU flag. This requires some extra iffery as init_idle() call be called more than once on the same idle task. Signed-off-by: Valentin Schneider <valentin.schneider@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20210510151024.2448573-2-valentin.schneider@arm.com
This commit is contained in:
committed by
Peter Zijlstra
parent
fcb5017045
commit
00b89fe019
+18
-12
@@ -68,16 +68,6 @@ enum KTHREAD_BITS {
|
||||
KTHREAD_SHOULD_PARK,
|
||||
};
|
||||
|
||||
static inline void set_kthread_struct(void *kthread)
|
||||
{
|
||||
/*
|
||||
* We abuse ->set_child_tid to avoid the new member and because it
|
||||
* can't be wrongly copied by copy_process(). We also rely on fact
|
||||
* that the caller can't exec, so PF_KTHREAD can't be cleared.
|
||||
*/
|
||||
current->set_child_tid = (__force void __user *)kthread;
|
||||
}
|
||||
|
||||
static inline struct kthread *to_kthread(struct task_struct *k)
|
||||
{
|
||||
WARN_ON(!(k->flags & PF_KTHREAD));
|
||||
@@ -103,6 +93,22 @@ static inline struct kthread *__to_kthread(struct task_struct *p)
|
||||
return kthread;
|
||||
}
|
||||
|
||||
void set_kthread_struct(struct task_struct *p)
|
||||
{
|
||||
struct kthread *kthread;
|
||||
|
||||
if (__to_kthread(p))
|
||||
return;
|
||||
|
||||
kthread = kzalloc(sizeof(*kthread), GFP_KERNEL);
|
||||
/*
|
||||
* We abuse ->set_child_tid to avoid the new member and because it
|
||||
* can't be wrongly copied by copy_process(). We also rely on fact
|
||||
* that the caller can't exec, so PF_KTHREAD can't be cleared.
|
||||
*/
|
||||
p->set_child_tid = (__force void __user *)kthread;
|
||||
}
|
||||
|
||||
void free_kthread_struct(struct task_struct *k)
|
||||
{
|
||||
struct kthread *kthread;
|
||||
@@ -272,8 +278,8 @@ static int kthread(void *_create)
|
||||
struct kthread *self;
|
||||
int ret;
|
||||
|
||||
self = kzalloc(sizeof(*self), GFP_KERNEL);
|
||||
set_kthread_struct(self);
|
||||
set_kthread_struct(current);
|
||||
self = to_kthread(current);
|
||||
|
||||
/* If user was SIGKILLed, I release the structure. */
|
||||
done = xchg(&create->done, NULL);
|
||||
|
||||
Reference in New Issue
Block a user