summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0002-stop_machine-Add-function-and-caller-debug-info.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0002-stop_machine-Add-function-and-caller-debug-info.patch')
-rw-r--r--debian/patches-rt/0002-stop_machine-Add-function-and-caller-debug-info.patch135
1 files changed, 135 insertions, 0 deletions
diff --git a/debian/patches-rt/0002-stop_machine-Add-function-and-caller-debug-info.patch b/debian/patches-rt/0002-stop_machine-Add-function-and-caller-debug-info.patch
new file mode 100644
index 000000000..f68789cd5
--- /dev/null
+++ b/debian/patches-rt/0002-stop_machine-Add-function-and-caller-debug-info.patch
@@ -0,0 +1,135 @@
+From 863bc087d69814dc4113ca9ec91ce1895b53480e Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Fri, 23 Oct 2020 12:11:59 +0200
+Subject: [PATCH 002/323] stop_machine: Add function and caller debug info
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.10/older/patches-5.10.204-rt100.tar.xz
+
+Crashes in stop-machine are hard to connect to the calling code, add a
+little something to help with that.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ include/linux/stop_machine.h | 5 +++++
+ kernel/stop_machine.c | 23 ++++++++++++++++++++---
+ lib/dump_stack.c | 2 ++
+ 3 files changed, 27 insertions(+), 3 deletions(-)
+
+--- a/include/linux/stop_machine.h
++++ b/include/linux/stop_machine.h
+@@ -24,6 +24,7 @@
+ struct cpu_stop_work {
+ struct list_head list; /* cpu_stopper->works */
+ cpu_stop_fn_t fn;
++ unsigned long caller;
+ void *arg;
+ struct cpu_stop_done *done;
+ };
+@@ -36,6 +37,8 @@
+ void stop_machine_unpark(int cpu);
+ void stop_machine_yield(const struct cpumask *cpumask);
+
++extern void print_stop_info(const char *log_lvl, struct task_struct *task);
++
+ #else /* CONFIG_SMP */
+
+ #include <linux/workqueue.h>
+@@ -80,6 +83,8 @@
+ return false;
+ }
+
++static inline void print_stop_info(const char *log_lvl, struct task_struct *task) { }
++
+ #endif /* CONFIG_SMP */
+
+ /*
+--- a/kernel/stop_machine.c
++++ b/kernel/stop_machine.c
+@@ -42,11 +42,23 @@
+ struct list_head works; /* list of pending works */
+
+ struct cpu_stop_work stop_work; /* for stop_cpus */
++ unsigned long caller;
++ cpu_stop_fn_t fn;
+ };
+
+ static DEFINE_PER_CPU(struct cpu_stopper, cpu_stopper);
+ static bool stop_machine_initialized = false;
+
++void print_stop_info(const char *log_lvl, struct task_struct *task)
++{
++ struct cpu_stopper *stopper = this_cpu_ptr(&cpu_stopper);
++
++ if (task != stopper->thread)
++ return;
++
++ printk("%sStopper: %pS <- %pS\n", log_lvl, stopper->fn, (void *)stopper->caller);
++}
++
+ /* static data for stop_cpus */
+ static DEFINE_MUTEX(stop_cpus_mutex);
+ static bool stop_cpus_in_progress;
+@@ -123,7 +135,7 @@
+ int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg)
+ {
+ struct cpu_stop_done done;
+- struct cpu_stop_work work = { .fn = fn, .arg = arg, .done = &done };
++ struct cpu_stop_work work = { .fn = fn, .arg = arg, .done = &done, .caller = _RET_IP_ };
+
+ cpu_stop_init_done(&done, 1);
+ if (!cpu_stop_queue_work(cpu, &work))
+@@ -331,7 +343,8 @@
+ work1 = work2 = (struct cpu_stop_work){
+ .fn = multi_cpu_stop,
+ .arg = &msdata,
+- .done = &done
++ .done = &done,
++ .caller = _RET_IP_,
+ };
+
+ cpu_stop_init_done(&done, 2);
+@@ -367,7 +380,7 @@
+ bool stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg,
+ struct cpu_stop_work *work_buf)
+ {
+- *work_buf = (struct cpu_stop_work){ .fn = fn, .arg = arg, };
++ *work_buf = (struct cpu_stop_work){ .fn = fn, .arg = arg, .caller = _RET_IP_, };
+ return cpu_stop_queue_work(cpu, work_buf);
+ }
+
+@@ -487,6 +500,8 @@
+ int ret;
+
+ /* cpu stop callbacks must not sleep, make in_atomic() == T */
++ stopper->caller = work->caller;
++ stopper->fn = fn;
+ preempt_count_inc();
+ ret = fn(arg);
+ if (done) {
+@@ -495,6 +510,8 @@
+ cpu_stop_signal_done(done);
+ }
+ preempt_count_dec();
++ stopper->fn = NULL;
++ stopper->caller = 0;
+ WARN_ONCE(preempt_count(),
+ "cpu_stop: %ps(%p) leaked preempt count\n", fn, arg);
+ goto repeat;
+--- a/lib/dump_stack.c
++++ b/lib/dump_stack.c
+@@ -12,6 +12,7 @@
+ #include <linux/atomic.h>
+ #include <linux/kexec.h>
+ #include <linux/utsname.h>
++#include <linux/stop_machine.h>
+ #include <generated/package.h>
+
+ static char dump_stack_arch_desc_str[128];
+@@ -59,6 +60,7 @@
+ log_lvl, dump_stack_arch_desc_str);
+
+ print_worker_info(log_lvl, current);
++ print_stop_info(log_lvl, current);
+ }
+
+ /**