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