Port-i386 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
splraise()/spllower() instrumentation
Instrumentation that I have add to spllower() and to splraise() does
not work as expected, but it causes the kernel to hang very early:
Choose an option; RETURN for default; SPACE to stop countdown.
Option 1 will be chosen in 0 seconds.
10528020+439284+640968 [511472+504041]=0xc0be3c
Loading ffs
<< hangs here >>
Maybe someone can see my mistake?
I'm trying to track down the cause of "panic: cpu_switchto: switching
above IPL_SCHED (8)" in my kernels. To that end, I've patched the
kernel (see attachment), adding splraise_instrument() that records the
top of the call stack on every splraise(IPL_HIGH) call, and adding
spllower_instrument() that, for every spllower(n) call where n <
IPL_HIGH, erases the record of prior splraise(IPL_HIGH) calls.
Note that the even with the bodies of spllower_instrument() and
splraise_instrument() commented out as I have done in the attached
patch, the kernel still hangs.
My kernel configuration is MONOLITHIC with some added options:
no makeoptions DEBUG
makeoptions DEBUG="-g -fno-omit-frame-pointer -fno-optimize-sibling-calls
-O0"
options DEBUG
options LOCKDEBUG
options DIAGNOSTIC
Dave
--
David Young OJC Technologies
dyoung%ojctech.com@localhost Urbana, IL * (217) 278-3933
Index: arch/i386/i386/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.671
diff -p -u -u -p -r1.671 machdep.c
--- arch/i386/i386/machdep.c 18 Aug 2009 16:41:02 -0000 1.671
+++ arch/i386/i386/machdep.c 6 Oct 2009 00:09:12 -0000
@@ -299,6 +299,18 @@ int mem_cluster_cnt = 0;
void init386(paddr_t);
void initgdt(union descriptor *);
+void splraise_instrument(int);
+void spllower_instrument(int);
+void splraise_instrument_stop(void);
+
+#define SPLRAISE_STACKLEN 32
+
+uintptr_t splraise_retaddrs[MAXCPUS][SPLRAISE_STACKLEN][4];
+int splraise_depth[MAXCPUS] = {0};
+int spllowered_to[MAXCPUS] = {0};
+uintptr_t spllowered_from[MAXCPUS][2] = {{0}};
+bool splraise_instrument_stopped = false;
+
extern int time_adjusted;
int *esym;
@@ -1879,6 +1891,91 @@ cpu_setmcontext(struct lwp *l, const mco
}
void
+splraise_instrument_stop(void)
+{
+ splraise_instrument_stopped = true;
+}
+
+void
+spllower_instrument(int ipl)
+{
+#if 1
+ return;
+#else
+ struct cpu_info *ci;
+
+ if (cold || splraise_instrument_stopped)
+ return;
+
+ if (ipl >= IPL_HIGH)
+ return;
+
+ ci = curcpu();
+
+ if (cpu_index(ci) > MAXCPUS)
+ return;
+
+ splraise_depth[cpu_index(ci)] = 0;
+ spllowered_to[cpu_index(ci)] = ipl;
+#if 0
+ spllowered_from[cpu_index(ci)][0] =
+ (uintptr_t)__builtin_return_address(0);
+ spllowered_from[cpu_index(ci)][1] =
+ (uintptr_t)__builtin_return_address(1);
+#endif
+#endif
+}
+
+void
+splraise_instrument(int ipl)
+{
+#if 1
+ return;
+#else
+ uintptr_t *retaddrs;
+ struct cpu_info *ci;
+
+ if (cold || splraise_instrument_stopped)
+ return;
+
+ if (ipl < IPL_HIGH)
+ return;
+
+ ci = curcpu();
+
+ if (cpu_index(ci) > MAXCPUS)
+ return;
+
+ if (splraise_depth[cpu_index(ci)] >= SPLRAISE_STACKLEN)
+ return;
+
+ retaddrs = &splraise_retaddrs[cpu_index(ci)]
+ [splraise_depth[cpu_index(ci)]++][0];
+
+ retaddrs[0] = retaddrs[1] = retaddrs[2] = 0;
+
+#if 0
+ retaddrs[0] = (uintptr_t)__builtin_return_address(0);
+
+ if (retaddrs[0] == 0)
+ return;
+
+ retaddrs[1] = (uintptr_t)__builtin_return_address(1);
+
+ if (retaddrs[1] == 0)
+ return;
+
+ retaddrs[2] = (uintptr_t)__builtin_return_address(2);
+
+ if (retaddrs[2] == 0)
+ return;
+
+ retaddrs[3] = (uintptr_t)__builtin_return_address(3);
+#endif
+#endif
+}
+
+void
cpu_initclocks(void)
{
Index: arch/i386/i386/spl.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/spl.S,v
retrieving revision 1.32
diff -p -u -u -p -r1.32 spl.S
--- arch/i386/i386/spl.S 1 Jul 2008 18:49:21 -0000 1.32
+++ arch/i386/i386/spl.S 6 Oct 2009 00:09:12 -0000
@@ -55,6 +55,11 @@ ENTRY(splraise)
ja 1f
movl %edx,CPUVAR(ILEVEL)
1:
+ push %ebp
+ movl %esp,%ebp
+ pushl %edx
+ call _C_LABEL(splraise_instrument)
+ addl $8, %esp
ret
END(splraise)
@@ -67,6 +72,12 @@ END(splraise)
*/
ENTRY(spllower)
movl 4(%esp), %ecx
+ push %ebp
+ movl %esp,%ebp
+ pushl %ecx
+ call _C_LABEL(spllower_instrument)
+ addl $8, %esp
+ movl 4(%esp), %ecx
cmpl CPUVAR(ILEVEL), %ecx
jae 1f
movl CPUVAR(IUNMASK)(,%ecx,4), %edx
Index: arch/x86/x86/patch.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/patch.c,v
retrieving revision 1.18
diff -p -u -u -p -r1.18 patch.c
--- arch/x86/x86/patch.c 24 Apr 2009 17:45:40 -0000 1.18
+++ arch/x86/x86/patch.c 6 Oct 2009 00:09:12 -0000
@@ -201,12 +201,14 @@ x86_patch(bool early)
#endif /* i386 */
if (!early && (cpu_feature & CPUID_CX8) != 0) {
+#if 0
/* Faster splx(), mutex_spin_exit(). */
patchfunc(
cx8_spllower, cx8_spllower_end,
spllower, spllower_end,
cx8_spllower_patch
);
+#endif
#if defined(i386) && !defined(LOCKDEBUG)
patchfunc(
i686_mutex_spin_exit, i686_mutex_spin_exit_end,
Index: kern/subr_prf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_prf.c,v
retrieving revision 1.136
diff -p -u -u -p -r1.136 subr_prf.c
--- kern/subr_prf.c 28 Jun 2009 15:30:30 -0000 1.136
+++ kern/subr_prf.c 6 Oct 2009 00:09:13 -0000
@@ -197,6 +197,8 @@ twiddle(void)
kprintf_unlock();
}
+extern void splraise_instrument_stop(void);
+
/*
* panic: handle an unresolvable fatal error
*
@@ -213,6 +215,8 @@ panic(const char *fmt, ...)
int bootopt;
va_list ap;
+ splraise_instrument_stop();
+
if (lwp0.l_cpu && curlwp) {
/*
* Disable preemption. If already panicing on another CPU, sit
Home |
Main Index |
Thread Index |
Old Index