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--