Subject: inlining spl*()
To: None <port-mips@netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: port-mips
Date: 03/28/2001 00:26:02
--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

hi folks,

attached are some diffs which convert the mips platforms to inline
versions of the spl* functions.  I'm not sure whether it would be
best to use inlining all the time, but I'd like to at least make
it an option so I can turn on inlining when profiling.

here's why I think this is interesting.  the first run below was
vanilla -current, while the second run is with the inlined spls.
notice that while preempt() shows no time in the first run,
it shows a lot of time in the second run.  preempt() isn't really
taking that long, rather it's being charged for the time of all
of its children since it's blocking clock interrupts.  but in the
first run we can't see that the entire preempt() path is taking
any time at all, since the time with interrupts blocked is charged
to _splset() instead of preempt().  (well, really it could be some
combination of preempt() and ltsleep(), but you get the idea.)
does anyone have a different interpretation of this?

so assuming I'm not way off base here, the question I have is,
do we want spl*() inlined all the time or only optionally?

-Chuck


  %   cumulative   self              self     total           
 time   seconds   seconds    calls  us/call  us/call  name    
 26.15     89.73    89.73                             memcpy
 21.82    164.61    74.88                             _splset_noprof
  5.60    183.81    19.20                             __mcount
  5.53    202.79    18.98                             _mcount
  5.33    221.08    18.30   481581    37.99    37.99  memset
  4.73    237.32    16.23   255215    63.61    63.61  mips1_FlushDCache
  2.31    245.26     7.94   208315    38.12   212.97  genfs_getpages
  2.20    252.80     7.55   384757    19.61    62.52  pmap_enter
  1.75    258.80     5.99                             _splraise_noprof
  1.38    263.53     4.73   128066    36.97    61.54  ffs_blkpref
  1.28    267.91     4.38   804991     5.44     5.44  lockmgr
...
  0.46    298.28     1.57      136 11517.69 11517.69  mips_idle
  0.45    299.83     1.55  4143842     0.38     0.38  _splraise
  0.45    301.39     1.55    64000    24.29   820.17  ufs_balloc_range
  0.44    302.91     1.52   192345     7.90    21.43  uvn_findpages
  0.44    304.42     1.52  4559329     0.33     0.33  _splset
...
  0.00    343.14     0.00     2038     0.00     3.76  preempt
...



  %   cumulative   self              self     total           
 time   seconds   seconds    calls  us/call  us/call  name    
 29.99     90.52    90.52                             memmove
 15.60    137.59    47.08                             __mcount
  5.88    155.35    17.76   482044    36.84    36.84  memset
  5.17    170.96    15.61   255107    61.19    61.19  mips1_FlushDCache
  4.86    185.64    14.68                             _mcount
  2.22    192.32     6.69   128066    52.22    86.84  ffs_blkpref
  2.21    198.99     6.66   208494    31.96   210.81  genfs_getpages
  2.08    205.26     6.27   385131    16.28    52.98  pmap_enter
  1.86    210.87     5.61     1837  3055.68  3080.01  preempt
  1.46    215.28     4.41   806300     5.46     5.46  lockmgr
...

--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.mips-spl"

Index: arch/arc/include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/arc/include/intr.h,v
retrieving revision 1.7
diff -u -r1.7 intr.h
--- arch/arc/include/intr.h	2001/01/14 02:00:38	1.7
+++ arch/arc/include/intr.h	2001/03/28 07:15:29
@@ -64,14 +64,7 @@
 #ifndef _LOCORE
 
 #include <mips/cpuregs.h>
-
-extern int _splraise __P((int));
-extern int _spllower __P((int));
-extern int _splset __P((int));
-extern int _splget __P((void));
-extern void _splnone __P((void));
-extern void _setsoftintr __P((int));
-extern void _clrsoftintr __P((int));
+#include <mips/psl.h>
 
 #define setsoftclock()	_setsoftintr(MIPS_SOFT_INT_MASK_0)
 #define setsoftnet()	_setsoftintr(MIPS_SOFT_INT_MASK_1)
Index: arch/cobalt/include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/cobalt/include/intr.h,v
retrieving revision 1.9
diff -u -r1.9 intr.h
--- arch/cobalt/include/intr.h	2001/01/14 02:00:39	1.9
+++ arch/cobalt/include/intr.h	2001/03/28 07:15:33
@@ -52,14 +52,7 @@
 #ifndef _LOCORE
 
 #include <mips/cpuregs.h>
-
-extern int		_splraise(int);
-extern int		_spllower(int);      
-extern int		_splset(int);
-extern int		_splget(void);
-extern void		_splnone(void);
-extern void		_setsoftintr(int);
-extern void		_clrsoftintr(int);
+#include <mips/psl.h>
 
 #define setsoftclock()	_setsoftintr(MIPS_SOFT_INT_MASK_0)
 #define setsoftnet()	_setsoftintr(MIPS_SOFT_INT_MASK_1)
Index: arch/hpcmips/include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcmips/include/intr.h,v
retrieving revision 1.8
diff -u -r1.8 intr.h
--- arch/hpcmips/include/intr.h	2001/01/14 02:00:40	1.8
+++ arch/hpcmips/include/intr.h	2001/03/28 07:15:33
@@ -55,14 +55,7 @@
 #ifndef _LOCORE
 
 #include <mips/cpuregs.h>
-
-int	_splraise __P((int));
-int	_spllower __P((int));
-int	_splset __P((int));
-int	_splget __P((void));
-void	_splnone __P((void));
-void	_setsoftintr __P((int));
-void	_clrsoftintr __P((int));
+#include <mips/psl.h>
 
 #define splhigh()	_splraise(MIPS_INT_MASK)
 #define spl0()		(void)_spllower(0)
Index: arch/mips/include/profile.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/include/profile.h,v
retrieving revision 1.15
diff -u -r1.15 profile.h
--- arch/mips/include/profile.h	2000/07/18 06:25:32	1.15
+++ arch/mips/include/profile.h	2001/03/28 07:15:34
@@ -42,13 +42,7 @@
 #define _MIPS_PROFILE_H_
 
 #ifdef _KERNEL
- /*
-  *  Declare non-profiled _splhigh() /_splx() entrypoints for _mcount.
-  *  see MCOUNT_ENTER and MCOUNT_EXIT.
-  */
-#define	_KERNEL_MCOUNT_DECL			\
-	int _splraise_noprof __P((int));	\
-	int _splset_noprof __P((int));
+#define	_KERNEL_MCOUNT_DECL
 #else   /* !_KERNEL */
 /* Make __mcount static. */
 #define	_KERNEL_MCOUNT_DECL	static
@@ -95,15 +89,8 @@
 	".set at");
 
 #ifdef _KERNEL
-/*
- * The following two macros do splhigh and splx respectively.
- * We use versions of _splraise() and _splset that don't
- * including profiling support.
- */
-
-#define	MCOUNT_ENTER	s = _splraise_noprof(MIPS_INT_MASK)
-
-#define	MCOUNT_EXIT	(void)_splset_noprof(s)
+#define	MCOUNT_ENTER	s = splhigh()
+#define	MCOUNT_EXIT	splx(s);
 #endif /* _KERNEL */
 
 #endif /* _MIPS_PROFILE_H_ */
Index: arch/mips/include/psl.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/include/psl.h,v
retrieving revision 1.14
diff -u -r1.14 psl.h
--- arch/mips/include/psl.h	2000/07/11 06:26:08	1.14
+++ arch/mips/include/psl.h	2001/03/28 07:15:34
@@ -38,6 +38,9 @@
  *	@(#)psl.h	8.1 (Berkeley) 6/10/93
  */
 
+#ifndef	_MIPS_PSL_H_
+#define	_MIPS_PSL_H_ 1
+
 /*
  * Define PSL_LOWIPL, PSL_USERSET, PSL_USERCLR, USERMODE, BASEPRI
  * for MI code, for MIPS1, MIPS3, or both, depending on the
@@ -123,3 +126,95 @@
 # define  BASEPRI(ps)	\
 	(CPUISMIPS3 ? MIPS3_BASEPRI(ps) : MIPS1_BASEPRI(ps))
 #endif
+
+
+static inline int _splmask(int);
+static inline int _splraise(int);
+static inline int _spllower(int);
+static inline void _splset(int);
+static inline void _setsoftintr(int);
+static inline void _clrsoftintr(int);
+static inline void _splnone(void);
+
+static inline int
+_splmask(int streg)
+{
+#ifdef MIPS_DYNAMIC_STATUS_MASK
+	streg &= mips_dynamic_status_mask;
+#endif
+	return streg;
+}
+
+static inline int
+_splraise(int newipl)
+{
+	int streg;
+
+	__asm__("mfc0 %0, $12" : "=r" (streg));
+	newipl &= MIPS_INT_MASK;
+	__asm__("mtc0 %0, $12" : : "r"	(_splmask(streg & ~newipl)));
+	__asm__("nop");
+	return streg & (MIPS_INT_MASK | MIPS_SR_INT_IE);
+}
+
+static inline int
+_spllower(int newipl)
+{
+	int streg;
+
+	__asm__("mfc0 %0, $12" : "=r" (streg));
+	__asm__("mtc0 %0, $12" : : "r" (_splmask((streg & ~MIPS_INT_MASK) |
+						 (~newipl & MIPS_INT_MASK))));
+	__asm__("nop");
+	return streg & (MIPS_INT_MASK | MIPS_SR_INT_IE);
+}
+
+static inline void
+_splset(int newipl)
+{
+	int streg;
+
+	__asm__("mfc0 %0, $12" : "=r" (streg));
+	newipl &= (MIPS_INT_MASK | MIPS_SR_INT_IE);
+	streg &= ~(MIPS_INT_MASK | MIPS_SR_INT_IE);
+	__asm__("mtc0 %0, $12" : : "r" (_splmask(streg | newipl)));
+	__asm__("nop");
+}
+
+static inline void
+_setsoftintr(int setbits)
+{
+	int streg, causereg;
+
+	__asm__("mfc0 %0, $12" : "=r" (streg));
+	__asm__("mtc0 $0, $12");
+	__asm__("nop; nop");
+	__asm__("mfc0 %0, $13" : "=r" (causereg));
+	__asm__("mtc0 %0, $13" : : "r" (causereg | setbits));
+	__asm__("mtc0 %0, $12" : : "r" (streg));
+}
+
+static inline void
+_clrsoftintr(int clrbits)
+{
+	int streg, causereg;
+
+	__asm__("mfc0 %0, $12" : "=r" (streg));
+	__asm__("mtc0 $0, $12");
+	__asm__("nop; nop");
+	__asm__("mfc0 %0, $13" : "=r" (causereg));
+	__asm__("mtc0 %0, $13" : : "r" (causereg & ~clrbits));
+	__asm__("mtc0 %0, $12" : : "r" (streg));
+}
+
+static inline void
+_splnone(void)
+{
+	int streg;
+
+	__asm__("mtc0 $0, $13");
+	streg = MIPS_INT_MASK | MIPS_SR_INT_IE;
+	__asm__("mtc0 %0, $12" : : "r" (_splmask(streg)));
+}
+
+#endif	/* _MIPS_PSL_H_ */
Index: arch/mips/mips/locore.S
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/mips/locore.S,v
retrieving revision 1.120
diff -u -r1.120 locore.S
--- arch/mips/mips/locore.S	2000/12/14 21:29:51	1.120
+++ arch/mips/mips/locore.S	2001/03/28 07:15:35
@@ -552,112 +552,6 @@
 END(longjmp)
 #endif
 
-
-/*
- * MIPS processor interrupt control
- *
- * Used as building blocks for spl(9) kernel interface.
- */
-LEAF(_splraise)
-XLEAF(_splraise_noprof)				# does not get mcount hooks
-	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
-	DYNAMIC_STATUS_MASK(a0,t0)		# machine dependent masking
-	mtc0	a0, MIPS_COP_0_STATUS		# store back
-	nop
-	j	ra
-	and	v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
-END(_splraise)
-
-LEAF(_spllower)
-	mfc0	v0, MIPS_COP_0_STATUS		# fetch status register
-	li	v1, ~MIPS_INT_MASK
-	and	v1, v0, v1			# turn off INT bit
-	nor	a0, zero, a0			# bitwise inverse of A0
-	and	a0, a0, MIPS_INT_MASK		# extract INT bits
-	or	a0, a0, v1			# disable making other bits on
-	DYNAMIC_STATUS_MASK(a0,t0)		# machine dependent masking
-	mtc0	a0, MIPS_COP_0_STATUS		# store back
-	nop
-	j	ra
-	and	v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
-END(_spllower)
-
-LEAF(_splrestore)
-	mfc0	v0, MIPS_COP_0_STATUS		# fetch status register
-	and	a0, a0, MIPS_INT_MASK
-	li	v1, ~MIPS_INT_MASK
-	and	v1, v1, v0			# turn off every INT bit
-	or	v1, v1, a0			# set old INT bits
-	DYNAMIC_STATUS_MASK(v1,t0)		# machine dependent masking
-	mtc0	v1, MIPS_COP_0_STATUS		# store back
-	nop
-	j	ra
-	and	v0, v0, MIPS_INT_MASK
-END(_splrestore)
-
-LEAF(_splset)
-XLEAF(_splset_noprof)				# does not get mcount hooks
-	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
-	DYNAMIC_STATUS_MASK(v1,t0)		# machine dependent masking
-	mtc0	v1, MIPS_COP_0_STATUS		# store back
-	nop
-	j	ra
-	and	v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
-END(_splset)
-
-LEAF(_splget)
-	mfc0	v0, MIPS_COP_0_STATUS		# fetch status register
-	nop
-	j	ra
-	and	v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
-END(_splget)
-
-LEAF(_setsoftintr)
-	mfc0	v1, MIPS_COP_0_STATUS		# save status register
-	mtc0	zero, MIPS_COP_0_STATUS		# disable interrupts (2 cycles)
-	nop
-	nop
-	mfc0	v0, MIPS_COP_0_CAUSE		# fetch cause register
-	nop
-	or	v0, v0, a0			# set soft intr. bits
-	mtc0	v0, MIPS_COP_0_CAUSE		# store back
-	mtc0	v1, MIPS_COP_0_STATUS		# enable interrupts
-	j	ra
-	nop
-END(_setsoftintr)
-
-LEAF(_clrsoftintr)
-	mfc0	v1, MIPS_COP_0_STATUS		# save status register
-	mtc0	zero, MIPS_COP_0_STATUS		# disable interrupts (2 cycles)
-	nop
-	nop
-	mfc0	v0, MIPS_COP_0_CAUSE		# fetch cause register
-	nor	a0, zero, a0			# bitwise inverse of A0
-	and	v0, v0, a0			# clear soft intr. bits
-	mtc0	v0, MIPS_COP_0_CAUSE		# store back
-	mtc0	v1, MIPS_COP_0_STATUS		# enable interrupts
-	j	ra
-	nop
-END(_clrsoftintr)
-
-LEAF(_splnone)
-	mtc0	zero, MIPS_COP_0_CAUSE		# clear SOFT_INT bits
-	li	v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
-	DYNAMIC_STATUS_MASK(v0,t0)		# machine dependent masking
-	mtc0	v0, MIPS_COP_0_STATUS		# enable all sources
-	nop
-	j	ra
-	nop
-END(_splnone)
-
-
 /*
  * int copystr(void *kfaddr, void *kdaddr, size_t maxlen, size_t *lencopied)
  * Copy a NIL-terminated string, at most maxlen characters long.  Return the
Index: arch/mipsco/include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mipsco/include/intr.h,v
retrieving revision 1.5
diff -u -r1.5 intr.h
--- arch/mipsco/include/intr.h	2001/01/14 02:00:40	1.5
+++ arch/mipsco/include/intr.h	2001/03/28 07:15:35
@@ -56,14 +56,7 @@
 #ifdef _KERNEL
 #ifndef _LOCORE
 #include <mips/cpuregs.h>
-
-extern int _splraise __P((int));
-extern int _spllower __P((int));
-extern int _splset __P((int));
-extern int _splget __P((void));
-extern void _splnone __P((void));
-extern void _setsoftintr __P((int));
-extern void _clrsoftintr __P((int));
+#include <mips/psl.h>
 
 /*
  * software simulated interrupt
Index: arch/newsmips/include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/newsmips/include/intr.h,v
retrieving revision 1.10
diff -u -r1.10 intr.h
--- arch/newsmips/include/intr.h	2001/01/14 02:00:41	1.10
+++ arch/newsmips/include/intr.h	2001/03/28 07:15:35
@@ -45,14 +45,7 @@
 #ifdef _KERNEL
 #ifndef _LOCORE
 #include <mips/cpuregs.h>
-
-extern int _splraise __P((int));
-extern int _spllower __P((int));
-extern int _splset __P((int));
-extern int _splget __P((void));
-extern void _splnone __P((void));
-extern void _setsoftintr __P((int));
-extern void _clrsoftintr __P((int));
+#include <mips/psl.h>
 
 /*
  * software simulated interrupt
Index: arch/pmax/include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/pmax/include/intr.h,v
retrieving revision 1.18
diff -u -r1.18 intr.h
--- arch/pmax/include/intr.h	2001/01/14 02:00:41	1.18
+++ arch/pmax/include/intr.h	2001/03/28 07:15:35
@@ -47,14 +47,7 @@
 #ifndef _LOCORE
 
 #include <mips/cpuregs.h>
-
-int	_splraise __P((int));
-int	_spllower __P((int));
-int	_splset __P((int));
-int	_splget __P((void));
-void	_splnone __P((void));
-void	_setsoftintr __P((int));
-void	_clrsoftintr __P((int));
+#include <mips/psl.h>
 
 #define splhigh()	_splraise(MIPS_INT_MASK)
 #define spl0()		(void)_spllower(0)
Index: arch/sgimips/include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sgimips/include/intr.h,v
retrieving revision 1.5
diff -u -r1.5 intr.h
--- arch/sgimips/include/intr.h	2001/01/14 02:00:42	1.5
+++ arch/sgimips/include/intr.h	2001/03/28 07:15:44
@@ -61,14 +61,7 @@
 #ifndef _LOCORE
 
 #include <mips/cpuregs.h>
-
-extern int		_splraise(int);
-extern int		_spllower(int); 
-extern int		_splset(int);
-extern int		_splget(void);
-extern void		_splnone(void); 
-extern void		_setsoftintr(int);
-extern void		_clrsoftintr(int);
+#include <mips/psl.h>
 
 #define setsoftclock()	_setsoftintr(MIPS_SOFT_INT_MASK_0)
 #define setsoftnet()	_setsoftintr(MIPS_SOFT_INT_MASK_1)

--jI8keyz6grp/JLjh--