aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2017-07-25 12:05:50 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-07-25 15:05:07 +1000
commit024bbfd036bed080a21e30f5a62d287c7e3a42c2 (patch)
treea76fb4b1dfb52d7645763a8e9a534291e4c642fa /core
parent72aa080d0970f7757ccf4f3b00096f2f8bbcafde (diff)
downloadskiboot-024bbfd036bed080a21e30f5a62d287c7e3a42c2.zip
skiboot-024bbfd036bed080a21e30f5a62d287c7e3a42c2.tar.gz
skiboot-024bbfd036bed080a21e30f5a62d287c7e3a42c2.tar.bz2
core/backtrace: Serialise printing backtraces
Add a lock so that only one thread can print a backtrace at a time. This should prevent multiple threads from garbaling each other's backtraces. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/stack.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/core/stack.c b/core/stack.c
index 17a4ca4..bb7fa62 100644
--- a/core/stack.c
+++ b/core/stack.c
@@ -104,12 +104,24 @@ void __print_backtrace(unsigned int pir,
*len = l;
}
+/*
+ * To ensure that we always get backtrace output we bypass the usual console
+ * locking paths. The downside is that when multiple threads need to print
+ * a backtrace they garble each other. To prevent this we use a seperate
+ * lock to serialise printing of the dumps.
+ */
+struct lock bt_lock = LOCK_UNLOCKED;
+
void backtrace(void)
{
unsigned int ents = STACK_BUF_ENTRIES;
+ lock(&bt_lock);
+
__backtrace(bt_buf, &ents);
__print_backtrace(mfspr(SPR_PIR), bt_buf, ents, NULL, NULL, true);
+
+ unlock(&bt_lock);
}
void __nomcount __stack_chk_fail(void);