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