aboutsummaryrefslogtreecommitdiff
path: root/sys/i386
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2015-09-11 03:54:37 +0000
committerMark Johnston <markj@FreeBSD.org>2015-09-11 03:54:37 +0000
commit610141cebb67f24c49c698b8828067db5acc1b55 (patch)
tree28426773e296f84e10d3d95e2a1489974f368b93 /sys/i386
parent1e954a7c639b52ed66042795c7445f16c4fc4dc9 (diff)
downloadsrc-610141cebb67f24c49c698b8828067db5acc1b55.tar.gz
src-610141cebb67f24c49c698b8828067db5acc1b55.zip
Add stack_save_td_running(), a function to trace the kernel stack of a
running thread. It is currently implemented only on amd64 and i386; on these architectures, it is implemented by raising an NMI on the CPU on which the target thread is currently running. Unlike stack_save_td(), it may fail, for example if the thread is running in user mode. This change also modifies the kern.proc.kstack sysctl to use this function, so that stacks of running threads are shown in the output of "procstat -kk". This is handy for debugging threads that are stuck in a busy loop. Reviewed by: bdrewery, jhb, kib Sponsored by: EMC / Isilon Storage Division Differential Revision: https://reviews.freebsd.org/D3256
Notes
Notes: svn path=/head/; revision=287645
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/trap.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index a3b1b0d2e9ec..40f72042d27f 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include "opt_isa.h"
#include "opt_kdb.h"
#include "opt_npx.h"
+#include "opt_stack.h"
#include "opt_trap.h"
#include <sys/param.h>
@@ -94,6 +95,7 @@ PMC_SOFT_DEFINE( , , page_fault, write);
#ifdef SMP
#include <machine/smp.h>
#endif
+#include <machine/stack.h>
#include <machine/tss.h>
#include <machine/vm86.h>
@@ -219,19 +221,26 @@ trap(struct trapframe *frame)
goto out;
}
-#ifdef HWPMC_HOOKS
- /*
- * CPU PMCs interrupt using an NMI so we check for that first.
- * If the HWPMC module is active, 'pmc_hook' will point to
- * the function to be called. A return value of '1' from the
- * hook means that the NMI was handled by it and that we can
- * return immediately.
- */
- if (type == T_NMI && pmc_intr &&
- (*pmc_intr)(PCPU_GET(cpuid), frame))
- goto out;
+ if (type == T_NMI) {
+#ifdef HWPMC_HOOKS
+ /*
+ * CPU PMCs interrupt using an NMI so we check for that first.
+ * If the HWPMC module is active, 'pmc_hook' will point to
+ * the function to be called. A non-zero return value from the
+ * hook means that the NMI was consumed by it and that we can
+ * return immediately.
+ */
+ if (pmc_intr != NULL &&
+ (*pmc_intr)(PCPU_GET(cpuid), frame) != 0)
+ goto out;
#endif
+#ifdef STACK
+ if (stack_nmi_handler(frame) != 0)
+ goto out;
+#endif
+ }
+
if (type == T_MCHK) {
mca_intr();
goto out;