it would be nice to have splraise as an MI api within the kernel
so it could be used in some per cpu data structures. at the moment
the only way to use the ipl passed to such things is to use mutexes,
but then whats the point of having a per cpu data structure if
you're guaranteed to not content with other cpus (or be preempted)?
this is the first in a series of diffs i have to make splraise an
MI api, starting with sparc64.
most archs already have splraise in their MD code, or have it with
a weird name like _splraise or raiseipl or _cpu_intr_raise, but
sparc and sparc64 are special.
instead of aliasing splfoo() to splraise(IPL_FOO), sparc64 has
macros that create static inline functions for each spl function.
sparc64 mutexes are hand crafted in assembler so its never needed
an splraise function to call.
this refactors the sparc64 code so theres a single _splraise macro.
it is a macro because the code sequence is short, and so it can
take advantage of gcc constant detection which provides different
asm for immediate/constant ipl levels. the splfoo() things are then
defined to _splraise(IPL_FOO).
splraise itself is provided as a function that wraps the _splraise
macro, which gets the ipl level in register form of the asm.
this also removes the spl debug goo. spls have been solid for a
while, im pretty sure theyre ok.
ok?
Index: include/intr.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/intr.h,v
retrieving revision 1.18
diff -u -p -r1.18 intr.h
--- include/intr.h 27 Sep 2015 11:29:20 -0000 1.18
+++ include/intr.h 7 Jun 2016 06:40:29 -0000
@@ -83,8 +83,29 @@ void intr_establish(int, struct intrh
#define IPL_STATCLOCK PIL_STATCLOCK /* statclock */
#define IPL_HIGH PIL_HIGH /* everything */
+#define spl0() _spl(IPL_NONE)
+#define splsoftint() _splraise(IPL_SOFTINT)
+#define splsoftclock() _splraise(IPL_SOFTCLOCK)
+#define splsoftnet() _splraise(IPL_SOFTNET)
+#define splbio() _splraise(IPL_BIO)
+#define splnet() _splraise(IPL_NET)
+#define splsofttty() _splraise(IPL_SOFTTTY)
+#define spltty() _splraise(IPL_TTY)
+#define splvm() _splraise(IPL_VM)
+#define splaudio() _splraise(IPL_AUDIO)
+#define splclock() _splraise(IPL_CLOCK)
+#define splserial() _splraise(IPL_SERIAL)
+#define splsched() _splraise(IPL_SCHED)
+#define spllock() _splraise(IPL_LOCK)
+#define splstatclock() _splraise(IPL_STATCLOCK)
+#define splhigh() _splraise(IPL_HIGH)
+#define splx(_oldipl) _splx(_oldipl)
+
+#define splzs() splserial()
+
#define IPL_MPSAFE 0x100
+int splraise(int);
void intr_barrier(void *);
void *softintr_establish(int, void (*)(void *), void *);
Index: include/psl.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/psl.h,v
retrieving revision 1.30
diff -u -p -r1.30 psl.h
--- include/psl.h 7 Jun 2016 06:37:33 -0000 1.30
+++ include/psl.h 7 Jun 2016 06:40:29 -0000
@@ -317,156 +317,39 @@ stxa_sync(u_int64_t va, u_int64_t asi, u
intr_restore(s);
}
-/*
- * GCC pseudo-functions for manipulating PIL
- */
+static inline int
+_spl(int newipl)
+{
+ int oldpil;
-#ifdef SPLDEBUG
-void prom_printf(const char *fmt, ...);
-extern int printspl;
-#define SPLPRINT(x) if(printspl) { int i=10000000; prom_printf x ;
while(i--); }
-#define SPL(name, newpil)
\
-extern __inline int name##X(const char *, int);
\
-extern __inline int name##X(const char *file, int line)
\
-{ \
- u_int64_t oldpil = sparc_rdpr(pil); \
- SPLPRINT(("{%s:%d %d=>%d}", file, line, oldpil, newpil)); \
- sparc_wrpr(pil, newpil, 0); \
- return (oldpil); \
-}
-/* A non-priority-decreasing version of SPL */
-#define SPLHOLD(name, newpil) \
-extern __inline int name##X(const char *, int);
\
-extern __inline int name##X(const char * file, int line) \
-{ \
- int oldpil = sparc_rdpr(pil); \
- if (__predict_false((u_int64_t)newpil <= oldpil)) \
- return (oldpil); \
- SPLPRINT(("{%s:%d %d->!d}", file, line, oldpil, newpil)); \
- sparc_wrpr(pil, newpil, 0); \
- return (oldpil); \
-}
+ __asm volatile( " rdpr %%pil, %0 \n"
+ " wrpr %%g0, %1, %%pil \n"
+ : "=&r" (oldpil)
+ : "I" (newipl)
+ : "%g0");
+ __asm volatile("" : : : "memory");
-#else
-#define SPLPRINT(x)
-#define SPL(name, newpil)
\
-extern __inline int name(void);
\
-extern __inline int name() \
-{ \
- int oldpil; \
- __asm volatile(" rdpr %%pil, %0 \n" \
- " wrpr %%g0, %1, %%pil \n" \
- : "=&r" (oldpil) \
- : "n" (newpil) \
- : "%g0"); \
- __asm volatile("" : : : "memory"); \
- return (oldpil); \
+ return (oldpil);
}
-/* A non-priority-decreasing version of SPL */
-#define SPLHOLD(name, newpil)
\
-extern __inline int name(void);
\
-extern __inline int name() \
-{ \
- int oldpil; \
- \
- if (newpil <= 1) { \
- __asm volatile(" rdpr %%pil, %0 \n" \
- " brnz,pn %0, 1f \n" \
- " nop \n" \
- " wrpr %%g0, %1, %%pil \n" \
- "1: \n" \
- : "=&r" (oldpil) \
- : "I" (newpil) \
- : "%g0"); \
- } else { \
- __asm volatile(" rdpr %%pil, %0 \n" \
- " cmp %0, %1 - 1 \n" \
- " bgu,pn %%xcc, 1f \n" \
- " nop \n" \
- " wrpr %%g0, %1, %%pil \n" \
- "1: \n" \
- : "=&r" (oldpil) \
- : "I" (newpil) \
- : "cc"); \
- } \
- __asm volatile("" : : : "memory"); \
- return (oldpil); \
-}
-#endif
-
-SPL(spl0, 0)
-
-SPLHOLD(splsoftint, 1)
-#define splsoftclock splsoftint
-#define splsoftnet splsoftint
-
-/* Block devices */
-SPLHOLD(splbio, PIL_BIO)
-
-/* network hardware interrupts are at level 6 */
-SPLHOLD(splnet, PIL_NET)
-/* tty input runs at software level 6 */
-SPLHOLD(spltty, PIL_TTY)
-
-/*
- * Memory allocation (must be as high as highest network, tty, or disk device)
- */
-SPLHOLD(splvm, PIL_VM)
-
-SPLHOLD(splclock, PIL_CLOCK)
-
-/* fd hardware interrupts are at level 11 */
-SPLHOLD(splfd, PIL_FD)
+/* A non-priority-decreasing version of SPL */
+static inline int
+_splraise(int newpil)
+{
+ int oldpil;
-/* zs hardware interrupts are at level 12 */
-SPLHOLD(splzs, PIL_SER)
-SPLHOLD(splserial, PIL_SER)
-
-/* audio hardware interrupts are at level 13 */
-SPLHOLD(splaudio, PIL_AUD)
-
-/* second sparc timer interrupts at level 14 */
-SPLHOLD(splstatclock, PIL_STATCLOCK)
-
-SPLHOLD(splsched, PIL_SCHED)
-SPLHOLD(spllock, PIL_LOCK)
-
-SPLHOLD(splhigh, PIL_HIGH)
-
-/* splx does not have a return value */
-#ifdef SPLDEBUG
-
-#define spl0() spl0X(__FILE__, __LINE__)
-#define splsoftint() splsoftintX(__FILE__, __LINE__)
-#define splbio() splbioX(__FILE__, __LINE__)
-#define splnet() splnetX(__FILE__, __LINE__)
-#define spltty() splttyX(__FILE__, __LINE__)
-#define splvm() splvmX(__FILE__, __LINE__)
-#define splclock() splclockX(__FILE__, __LINE__)
-#define splfd() splfdX(__FILE__, __LINE__)
-#define splzs() splzsX(__FILE__, __LINE__)
-#define splserial() splzerialX(__FILE__, __LINE__)
-#define splaudio() splaudioX(__FILE__, __LINE__)
-#define splstatclock() splstatclockX(__FILE__, __LINE__)
-#define splsched() splschedX(__FILE__, __LINE__)
-#define spllock() spllockX(__FILE__, __LINE__)
-#define splhigh() splhighX(__FILE__, __LINE__)
-#define splx(x) splxX((x),__FILE__, __LINE__)
+ oldpil = sparc_rdpr(pil);
+ if (newpil > oldpil)
+ sparc_wrpr(pil, newpil, 0);
+ return (oldpil);
+}
-extern __inline void splxX(u_int64_t, const char *, int);
-extern __inline void
-splxX(u_int64_t newpil, const char *file, int line)
-#else
-extern __inline void splx(int newpil)
-#endif
+static inline void
+_splx(int newpil)
{
-#ifdef SPLDEBUG
- u_int64_t oldpil = sparc_rdpr(pil);
- SPLPRINT(("{%d->%d}", oldpil, newpil));
-#endif
sparc_wrpr(pil, newpil, 0);
}
+
#endif /* KERNEL && !_LOCORE */
#endif /* _SPARC64_PSL_ */
Index: sparc64/intr.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/intr.c,v
retrieving revision 1.54
diff -u -p -r1.54 intr.c
--- sparc64/intr.c 27 Sep 2015 11:29:20 -0000 1.54
+++ sparc64/intr.c 7 Jun 2016 06:40:29 -0000
@@ -313,6 +313,12 @@ intr_establish(int level, struct intrhan
splx(s);
}
+int
+splraise(int ipl)
+{
+ return (_splraise(ipl));
+}
+
void
intr_barrier(void *cookie)
{