Subject: mips kernel profiling?
To: None <port-mips@netbsd.org>
From: Simon Burge <simonb@netbsd.org>
List: port-mips
Date: 03/28/2000 22:08:46
I was going to try profiling the same kernel on a 5000/240 and 5900-260
to try to get a handle on where to start looking for the fork/exec
slowness, but I'm having problems getting a profiled kernel built and
running. With the trailing patches I at least get a kernel built, but
it barely starts and get's an interesting error on the way through:
Starting at 0x80030000
[ preserving 139364 bytes of netbsd ELF symbol table ]
Copyright (c) 1996, 1997, 1998, 1999, 2000
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
...
le0 at ioasic0 offset 0xc0000ioasic0: can't allocate DMA area for LANCE
le0: DMA area not set up
...
Profiling kernel, textsize=1810624 [80030000..801ea0c0]
trap: address error (load or I-fetch) in kernel mode
status=0xff03, cause=0x10, epc=0x8005d91c, vaddr=0xf
pid=0 cmd=swapper usp=0x0 ksp=0x80294e40
Stopped in swapper at fork1+0x5c: lw v1,16(s1)
db> trace
fork1+5c (1,414,14,0) ra 800565c4 sz 64
main+4a0 (1,414,14,0) ra 80030084 sz 88
User-level: pid 0
Note that I didn't do a complete "make clean" - I'll restart a clean
build and head off to sleep and see what happens in the morning.
When was the last time anyone had kernel profiling working? Is
what I have below ok - if so I'll commit it.
Simon.
--
Index: mips/include/profile.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/include/profile.h,v
retrieving revision 1.13
diff -p -u -r1.13 profile.h
--- profile.h 2000/03/28 02:58:46 1.13
+++ profile.h 2000/03/28 12:01:34
@@ -46,9 +46,9 @@
* Declare non-profiled _splhigh() /_splx() entrypoints for _mcount.
* see MCOUNT_ENTER and MCOUNT_EXIT.
*/
-#define _KERNEL_MCOUNT_DECL \
- int _splhigh __P((void)); \
- int _splx __P((int));
+#define _KERNEL_MCOUNT_DECL \
+ int _splraise_noprof __P((int)); \
+ int _splset_noprof __P((int));
#else /* !_KERNEL */
/* Make __mcount static. */
#define _KERNEL_MCOUNT_DECL static
@@ -96,13 +96,13 @@
#ifdef _KERNEL
/*
* The following two macros do splhigh and splx respectively.
- * They have to be defined this way because these are real
- * functions on the MIPS, and we do not want to invoke mcount
- * recursively.
+ * We use versions of _splraise() and _splset that don't
+ * including profiling support.
*/
-#define MCOUNT_ENTER s = _splhigh()
-#define MCOUNT_EXIT _splx(s)
+#define MCOUNT_ENTER s = _splraise_noprof(MIPS_INT_MASK)
+
+#define MCOUNT_EXIT (void)_splset_noprof(s)
#endif /* _KERNEL */
#endif /* _MIPS_PROFILE_H_ */
Index: mips/mips/locore.S
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/mips/locore.S,v
retrieving revision 1.92
diff -p -u -r1.92 locore.S
--- locore.S 2000/03/28 02:58:48 1.92
+++ locore.S 2000/03/28 12:01:34
@@ -493,6 +493,18 @@ LEAF(_splraise)
and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
END(_splraise)
+/* as above, with no profiling support */
+LEAF_NOPROFILE(_splraise_noprof)
+ mfc0 v0, MIPS_COP_0_STATUS # fetch status register
+ and a0, a0, MIPS_INT_MASK # extract INT bits
+ nor a0, zero, a0 # bitwise inverse of A0
+ and a0, a0, v0 # disable retaining other bits
+ mtc0 a0, MIPS_COP_0_STATUS # store back
+ nop
+ j ra
+ and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
+END(_splraise_noprof)
+
LEAF(_spllower)
mfc0 v0, MIPS_COP_0_STATUS # fetch status register
li v1, ~MIPS_INT_MASK
@@ -529,6 +541,19 @@ LEAF(_splset)
j ra
and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
END(_splset)
+
+/* as above, with no profiling support */
+LEAF_NOPROFILE(_splset_noprof)
+ mfc0 v0, MIPS_COP_0_STATUS # fetch status register
+ and a0, a0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
+ li v1, ~(MIPS_INT_MASK | MIPS_SR_INT_IE)
+ and v1, v1, v0 # turn off every INT bit
+ or v1, v1, a0 # set old INT bits
+ mtc0 v1, MIPS_COP_0_STATUS # store back
+ nop
+ j ra
+ and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
+END(_splset_noprof)
LEAF(_splget)
mfc0 v0, MIPS_COP_0_STATUS # fetch status register