aboutsummaryrefslogtreecommitdiffstats
path: root/features/rt/kthread-Move-prio-affinite-change-into-the-newly-cre.patch
diff options
context:
space:
mode:
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.patch85
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, &param);
++ 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, &param);
+- set_cpus_allowed_ptr(task,
+- housekeeping_cpumask(HK_FLAG_KTHREAD));
+ }
+ kfree(create);
+ return task;
+--
+2.19.1
+