diff options
Diffstat (limited to 'debian/patches-rt/0004-sched-Provide-rt_mutex-specific-scheduler-helpers.patch')
-rw-r--r-- | debian/patches-rt/0004-sched-Provide-rt_mutex-specific-scheduler-helpers.patch | 128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/debian/patches-rt/0004-sched-Provide-rt_mutex-specific-scheduler-helpers.patch b/debian/patches-rt/0004-sched-Provide-rt_mutex-specific-scheduler-helpers.patch deleted file mode 100644 index f61a67ea3f..0000000000 --- a/debian/patches-rt/0004-sched-Provide-rt_mutex-specific-scheduler-helpers.patch +++ /dev/null @@ -1,128 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Fri, 8 Sep 2023 18:22:51 +0200 -Subject: [PATCH 4/7] sched: Provide rt_mutex specific scheduler helpers -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patches-6.6.7-rt18.tar.xz - -With PREEMPT_RT there is a rt_mutex recursion problem where -sched_submit_work() can use an rtlock (aka spinlock_t). More -specifically what happens is: - - mutex_lock() /* really rt_mutex */ - ... - __rt_mutex_slowlock_locked() - task_blocks_on_rt_mutex() - // enqueue current task as waiter - // do PI chain walk - rt_mutex_slowlock_block() - schedule() - sched_submit_work() - ... - spin_lock() /* really rtlock */ - ... - __rt_mutex_slowlock_locked() - task_blocks_on_rt_mutex() - // enqueue current task as waiter *AGAIN* - // *CONFUSION* - -Fix this by making rt_mutex do the sched_submit_work() early, before -it enqueues itself as a waiter -- before it even knows *if* it will -wait. - -[[ basically Thomas' patch but with different naming and a few asserts - added ]] - -Originally-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Link: https://lkml.kernel.org/r/20230908162254.999499-5-bigeasy@linutronix.de ---- - include/linux/sched.h | 3 +++ - include/linux/sched/rt.h | 4 ++++ - kernel/sched/core.c | 36 ++++++++++++++++++++++++++++++++---- - 3 files changed, 39 insertions(+), 4 deletions(-) - ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -911,6 +911,9 @@ struct task_struct { - * ->sched_remote_wakeup gets used, so it can be in this word. - */ - unsigned sched_remote_wakeup:1; -+#ifdef CONFIG_RT_MUTEXES -+ unsigned sched_rt_mutex:1; -+#endif - - /* Bit to tell LSMs we're in execve(): */ - unsigned in_execve:1; ---- a/include/linux/sched/rt.h -+++ b/include/linux/sched/rt.h -@@ -30,6 +30,10 @@ static inline bool task_is_realtime(stru - } - - #ifdef CONFIG_RT_MUTEXES -+extern void rt_mutex_pre_schedule(void); -+extern void rt_mutex_schedule(void); -+extern void rt_mutex_post_schedule(void); -+ - /* - * Must hold either p->pi_lock or task_rq(p)->lock. - */ ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -6724,9 +6724,6 @@ static inline void sched_submit_work(str - static DEFINE_WAIT_OVERRIDE_MAP(sched_map, LD_WAIT_CONFIG); - unsigned int task_flags; - -- if (task_is_running(tsk)) -- return; -- - /* - * Establish LD_WAIT_CONFIG context to ensure none of the code called - * will use a blocking primitive -- which would lead to recursion. -@@ -6784,7 +6781,12 @@ asmlinkage __visible void __sched schedu - { - struct task_struct *tsk = current; - -- sched_submit_work(tsk); -+#ifdef CONFIG_RT_MUTEXES -+ lockdep_assert(!tsk->sched_rt_mutex); -+#endif -+ -+ if (!task_is_running(tsk)) -+ sched_submit_work(tsk); - __schedule_loop(SM_NONE); - sched_update_worker(tsk); - } -@@ -7045,6 +7047,32 @@ static void __setscheduler_prio(struct t - - #ifdef CONFIG_RT_MUTEXES - -+/* -+ * Would be more useful with typeof()/auto_type but they don't mix with -+ * bit-fields. Since it's a local thing, use int. Keep the generic sounding -+ * name such that if someone were to implement this function we get to compare -+ * notes. -+ */ -+#define fetch_and_set(x, v) ({ int _x = (x); (x) = (v); _x; }) -+ -+void rt_mutex_pre_schedule(void) -+{ -+ lockdep_assert(!fetch_and_set(current->sched_rt_mutex, 1)); -+ sched_submit_work(current); -+} -+ -+void rt_mutex_schedule(void) -+{ -+ lockdep_assert(current->sched_rt_mutex); -+ __schedule_loop(SM_NONE); -+} -+ -+void rt_mutex_post_schedule(void) -+{ -+ sched_update_worker(current); -+ lockdep_assert(fetch_and_set(current->sched_rt_mutex, 0)); -+} -+ - static inline int __rt_effective_prio(struct task_struct *pi_task, int prio) - { - if (pi_task) |