diff options
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.patch | 135 |
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); + } + + /** |