diff options
Diffstat (limited to 'features/rt/kthread-Move-prio-affinite-change-into-the-newly-cre.patch')
-rw-r--r-- | features/rt/kthread-Move-prio-affinite-change-into-the-newly-cre.patch | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/features/rt/kthread-Move-prio-affinite-change-into-the-newly-cre.patch b/features/rt/kthread-Move-prio-affinite-change-into-the-newly-cre.patch new file mode 100644 index 00000000..ee7fef7e --- /dev/null +++ b/features/rt/kthread-Move-prio-affinite-change-into-the-newly-cre.patch @@ -0,0 +1,85 @@ +From 278ed17d1f399724a529b1b7c3730b364f136e16 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Mon, 9 Nov 2020 21:30:41 +0100 +Subject: [PATCH 003/191] kthread: Move prio/affinite change into the newly + created thread + +With enabled threaded interrupts the nouveau driver reported the +following: +| Chain exists of: +| &mm->mmap_lock#2 --> &device->mutex --> &cpuset_rwsem +| +| Possible unsafe locking scenario: +| +| CPU0 CPU1 +| ---- ---- +| lock(&cpuset_rwsem); +| lock(&device->mutex); +| lock(&cpuset_rwsem); +| lock(&mm->mmap_lock#2); + +The device->mutex is nvkm_device::mutex. + +Unblocking the lockchain at `cpuset_rwsem' is probably the easiest thing +to do. +Move the priority reset to the start of the newly created thread. + +Fixes: 710da3c8ea7df ("sched/core: Prevent race condition between cpuset and __sched_setscheduler()") +Reported-by: Mike Galbraith <efault@gmx.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Link: https://lkml.kernel.org/r/a23a826af7c108ea5651e73b8fbae5e653f16e86.camel@gmx.de +--- + kernel/kthread.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/kernel/kthread.c b/kernel/kthread.c +index 1578973c5740..bb0602597ffd 100644 +--- a/kernel/kthread.c ++++ b/kernel/kthread.c +@@ -243,6 +243,7 @@ EXPORT_SYMBOL_GPL(kthread_parkme); + + static int kthread(void *_create) + { ++ static const struct sched_param param = { .sched_priority = 0 }; + /* Copy data: it's on kthread's stack */ + struct kthread_create_info *create = _create; + int (*threadfn)(void *data) = create->threadfn; +@@ -273,6 +274,13 @@ static int kthread(void *_create) + init_completion(&self->parked); + current->vfork_done = &self->exited; + ++ /* ++ * The new thread inherited kthreadd's priority and CPU mask. Reset ++ * back to default in case they have been changed. ++ */ ++ sched_setscheduler_nocheck(current, SCHED_NORMAL, ¶m); ++ set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_FLAG_KTHREAD)); ++ + /* OK, tell user we're spawned, wait for stop or wakeup */ + __set_current_state(TASK_UNINTERRUPTIBLE); + create->result = current; +@@ -370,7 +378,6 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), + } + task = create->result; + if (!IS_ERR(task)) { +- static const struct sched_param param = { .sched_priority = 0 }; + char name[TASK_COMM_LEN]; + + /* +@@ -379,13 +386,6 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), + */ + vsnprintf(name, sizeof(name), namefmt, args); + set_task_comm(task, name); +- /* +- * root may have changed our (kthreadd's) priority or CPU mask. +- * The kernel thread should not inherit these properties. +- */ +- sched_setscheduler_nocheck(task, SCHED_NORMAL, ¶m); +- set_cpus_allowed_ptr(task, +- housekeeping_cpumask(HK_FLAG_KTHREAD)); + } + kfree(create); + return task; +-- +2.19.1 + |