xref: /freebsd/sys/kern/kern_intr.c (revision 35e0e5b31144763b2053a8a033be4407987e7e69)
1425f9fdaSStefan Eßer /*
2425f9fdaSStefan Eßer  * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3425f9fdaSStefan Eßer  * All rights reserved.
4425f9fdaSStefan Eßer  *
5425f9fdaSStefan Eßer  * Redistribution and use in source and binary forms, with or without
6425f9fdaSStefan Eßer  * modification, are permitted provided that the following conditions
7425f9fdaSStefan Eßer  * are met:
8425f9fdaSStefan Eßer  * 1. Redistributions of source code must retain the above copyright
9425f9fdaSStefan Eßer  *    notice unmodified, this list of conditions, and the following
10425f9fdaSStefan Eßer  *    disclaimer.
11425f9fdaSStefan Eßer  * 2. Redistributions in binary form must reproduce the above copyright
12425f9fdaSStefan Eßer  *    notice, this list of conditions and the following disclaimer in the
13425f9fdaSStefan Eßer  *    documentation and/or other materials provided with the distribution.
14425f9fdaSStefan Eßer  *
15425f9fdaSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16425f9fdaSStefan Eßer  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17425f9fdaSStefan Eßer  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18425f9fdaSStefan Eßer  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19425f9fdaSStefan Eßer  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20425f9fdaSStefan Eßer  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21425f9fdaSStefan Eßer  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22425f9fdaSStefan Eßer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23425f9fdaSStefan Eßer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24425f9fdaSStefan Eßer  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25425f9fdaSStefan Eßer  *
26c3aac50fSPeter Wemm  * $FreeBSD$
27425f9fdaSStefan Eßer  *
28425f9fdaSStefan Eßer  */
29425f9fdaSStefan Eßer 
303900ddb2SDoug Rabson 
311c5bb3eaSPeter Wemm #include <sys/param.h>
329a94c9c5SJohn Baldwin #include <sys/bus.h>
339a94c9c5SJohn Baldwin #include <sys/rtprio.h>
34425f9fdaSStefan Eßer #include <sys/systm.h>
351931cf94SJohn Baldwin #include <sys/ipl.h>
3668352337SDoug Rabson #include <sys/interrupt.h>
371931cf94SJohn Baldwin #include <sys/kernel.h>
381931cf94SJohn Baldwin #include <sys/kthread.h>
391931cf94SJohn Baldwin #include <sys/ktr.h>
401931cf94SJohn Baldwin #include <sys/malloc.h>
4135e0e5b3SJohn Baldwin #include <sys/mutex.h>
421931cf94SJohn Baldwin #include <sys/proc.h>
431931cf94SJohn Baldwin #include <sys/unistd.h>
441931cf94SJohn Baldwin #include <sys/vmmeter.h>
451931cf94SJohn Baldwin #include <machine/atomic.h>
461931cf94SJohn Baldwin #include <machine/cpu.h>
47425f9fdaSStefan Eßer 
4818c5a6c4SBruce Evans struct swilist {
4918c5a6c4SBruce Evans 	swihand_t	*sl_handler;
5018c5a6c4SBruce Evans 	struct swilist	*sl_next;
5118c5a6c4SBruce Evans };
5218c5a6c4SBruce Evans 
5318c5a6c4SBruce Evans static struct swilist swilists[NSWI];
541931cf94SJohn Baldwin u_long softintr_count[NSWI];
551931cf94SJohn Baldwin static struct proc *softithd;
561931cf94SJohn Baldwin volatile u_int sdelayed;
571931cf94SJohn Baldwin volatile u_int spending;
581931cf94SJohn Baldwin 
591931cf94SJohn Baldwin static void start_softintr(void *);
601931cf94SJohn Baldwin static void intr_soft(void *);
6118c5a6c4SBruce Evans 
6218c5a6c4SBruce Evans void
6318c5a6c4SBruce Evans register_swi(intr, handler)
6418c5a6c4SBruce Evans 	int intr;
6518c5a6c4SBruce Evans 	swihand_t *handler;
6618c5a6c4SBruce Evans {
6718c5a6c4SBruce Evans 	struct swilist *slp, *slq;
6818c5a6c4SBruce Evans 	int s;
6918c5a6c4SBruce Evans 
701931cf94SJohn Baldwin 	if (intr < 0 || intr >= NSWI)
7118c5a6c4SBruce Evans 		panic("register_swi: bad intr %d", intr);
7218c5a6c4SBruce Evans 	if (handler == swi_generic || handler == swi_null)
7318c5a6c4SBruce Evans 		panic("register_swi: bad handler %p", (void *)handler);
741931cf94SJohn Baldwin 	slp = &swilists[intr];
7518c5a6c4SBruce Evans 	s = splhigh();
761931cf94SJohn Baldwin 	if (shandlers[intr] == swi_null)
771931cf94SJohn Baldwin 		shandlers[intr] = handler;
7818c5a6c4SBruce Evans 	else {
7918c5a6c4SBruce Evans 		if (slp->sl_next == NULL) {
801931cf94SJohn Baldwin 			slp->sl_handler = shandlers[intr];
811931cf94SJohn Baldwin 			shandlers[intr] = swi_generic;
8218c5a6c4SBruce Evans 		}
8318c5a6c4SBruce Evans 		slq = malloc(sizeof(*slq), M_DEVBUF, M_NOWAIT);
8418c5a6c4SBruce Evans 		if (slq == NULL)
8518c5a6c4SBruce Evans 			panic("register_swi: malloc failed");
8618c5a6c4SBruce Evans 		slq->sl_handler = handler;
8718c5a6c4SBruce Evans 		slq->sl_next = NULL;
8818c5a6c4SBruce Evans 		while (slp->sl_next != NULL)
8918c5a6c4SBruce Evans 			slp = slp->sl_next;
9018c5a6c4SBruce Evans 		slp->sl_next = slq;
9118c5a6c4SBruce Evans 	}
9218c5a6c4SBruce Evans 	splx(s);
9318c5a6c4SBruce Evans }
9418c5a6c4SBruce Evans 
9518c5a6c4SBruce Evans void
9618c5a6c4SBruce Evans swi_dispatcher(intr)
9718c5a6c4SBruce Evans 	int intr;
9818c5a6c4SBruce Evans {
9918c5a6c4SBruce Evans 	struct swilist *slp;
10018c5a6c4SBruce Evans 
1011931cf94SJohn Baldwin 	slp = &swilists[intr];
10218c5a6c4SBruce Evans 	do {
10318c5a6c4SBruce Evans 		(*slp->sl_handler)();
10418c5a6c4SBruce Evans 		slp = slp->sl_next;
10518c5a6c4SBruce Evans 	} while (slp != NULL);
10618c5a6c4SBruce Evans }
10718c5a6c4SBruce Evans 
10818c5a6c4SBruce Evans void
10918c5a6c4SBruce Evans unregister_swi(intr, handler)
11018c5a6c4SBruce Evans 	int intr;
11118c5a6c4SBruce Evans 	swihand_t *handler;
11218c5a6c4SBruce Evans {
11318c5a6c4SBruce Evans 	struct swilist *slfoundpred, *slp, *slq;
11418c5a6c4SBruce Evans 	int s;
11518c5a6c4SBruce Evans 
1161931cf94SJohn Baldwin 	if (intr < 0 || intr >= NSWI)
11718c5a6c4SBruce Evans 		panic("unregister_swi: bad intr %d", intr);
11818c5a6c4SBruce Evans 	if (handler == swi_generic || handler == swi_null)
11918c5a6c4SBruce Evans 		panic("unregister_swi: bad handler %p", (void *)handler);
1201931cf94SJohn Baldwin 	slp = &swilists[intr];
12118c5a6c4SBruce Evans 	s = splhigh();
1221931cf94SJohn Baldwin 	if (shandlers[intr] == handler)
1231931cf94SJohn Baldwin 		shandlers[intr] = swi_null;
12418c5a6c4SBruce Evans 	else if (slp->sl_next != NULL) {
12518c5a6c4SBruce Evans 		slfoundpred = NULL;
12618c5a6c4SBruce Evans 		for (slq = slp->sl_next; slq != NULL;
12718c5a6c4SBruce Evans 		    slp = slq, slq = slp->sl_next)
12818c5a6c4SBruce Evans 			if (slq->sl_handler == handler)
12918c5a6c4SBruce Evans 				slfoundpred = slp;
1301931cf94SJohn Baldwin 		slp = &swilists[intr];
13118c5a6c4SBruce Evans 		if (slfoundpred != NULL) {
13218c5a6c4SBruce Evans 			slq = slfoundpred->sl_next;
13318c5a6c4SBruce Evans 			slfoundpred->sl_next = slq->sl_next;
13418c5a6c4SBruce Evans 			free(slq, M_DEVBUF);
13518c5a6c4SBruce Evans 		} else if (slp->sl_handler == handler) {
13618c5a6c4SBruce Evans 			slq = slp->sl_next;
13718c5a6c4SBruce Evans 			slp->sl_next = slq->sl_next;
13818c5a6c4SBruce Evans 			slp->sl_handler = slq->sl_handler;
13918c5a6c4SBruce Evans 			free(slq, M_DEVBUF);
14018c5a6c4SBruce Evans 		}
14118c5a6c4SBruce Evans 		if (slp->sl_next == NULL)
1421931cf94SJohn Baldwin 			shandlers[intr] = slp->sl_handler;
14318c5a6c4SBruce Evans 	}
14418c5a6c4SBruce Evans 	splx(s);
14518c5a6c4SBruce Evans }
14618c5a6c4SBruce Evans 
1479a94c9c5SJohn Baldwin int
1489a94c9c5SJohn Baldwin ithread_priority(flags)
1499a94c9c5SJohn Baldwin 	int flags;
1509a94c9c5SJohn Baldwin {
1519a94c9c5SJohn Baldwin 	int pri;
1529a94c9c5SJohn Baldwin 
1539a94c9c5SJohn Baldwin 	switch (flags) {
1549a94c9c5SJohn Baldwin 	case INTR_TYPE_TTY:             /* keyboard or parallel port */
1559a94c9c5SJohn Baldwin 		pri = PI_TTYLOW;
1569a94c9c5SJohn Baldwin 		break;
1579a94c9c5SJohn Baldwin 	case (INTR_TYPE_TTY | INTR_FAST): /* sio */
1589a94c9c5SJohn Baldwin 		pri = PI_TTYHIGH;
1599a94c9c5SJohn Baldwin 		break;
1609a94c9c5SJohn Baldwin 	case INTR_TYPE_BIO:
1619a94c9c5SJohn Baldwin 		/*
1629a94c9c5SJohn Baldwin 		 * XXX We need to refine this.  BSD/OS distinguishes
1639a94c9c5SJohn Baldwin 		 * between tape and disk priorities.
1649a94c9c5SJohn Baldwin 		 */
1659a94c9c5SJohn Baldwin 		pri = PI_DISK;
1669a94c9c5SJohn Baldwin 		break;
1679a94c9c5SJohn Baldwin 	case INTR_TYPE_NET:
1689a94c9c5SJohn Baldwin 		pri = PI_NET;
1699a94c9c5SJohn Baldwin 		break;
1709a94c9c5SJohn Baldwin 	case INTR_TYPE_CAM:
1719a94c9c5SJohn Baldwin 		pri = PI_DISK;          /* XXX or PI_CAM? */
1729a94c9c5SJohn Baldwin 		break;
1739a94c9c5SJohn Baldwin 	case INTR_TYPE_MISC:
1749a94c9c5SJohn Baldwin 		pri = PI_DULL;          /* don't care */
1759a94c9c5SJohn Baldwin 		break;
1769a94c9c5SJohn Baldwin 	/* We didn't specify an interrupt level. */
1779a94c9c5SJohn Baldwin 	default:
1789a94c9c5SJohn Baldwin 		panic("ithread_priority: no interrupt type in flags");
1799a94c9c5SJohn Baldwin 	}
1809a94c9c5SJohn Baldwin 
1819a94c9c5SJohn Baldwin 	return pri;
1829a94c9c5SJohn Baldwin }
1839a94c9c5SJohn Baldwin 
1841931cf94SJohn Baldwin /*
1851931cf94SJohn Baldwin  * Schedule the soft interrupt handler thread.
1861931cf94SJohn Baldwin  */
1871931cf94SJohn Baldwin void
1881931cf94SJohn Baldwin sched_softintr(void)
1891931cf94SJohn Baldwin {
1901931cf94SJohn Baldwin 	atomic_add_int(&cnt.v_intr, 1); /* one more global interrupt */
1911931cf94SJohn Baldwin 
1921931cf94SJohn Baldwin 	/*
1931931cf94SJohn Baldwin 	 * If we don't have an interrupt resource or an interrupt thread for
1941931cf94SJohn Baldwin 	 * this IRQ, log it as a stray interrupt.
1951931cf94SJohn Baldwin 	 */
1961931cf94SJohn Baldwin 	if (softithd == NULL)
1971931cf94SJohn Baldwin 		panic("soft interrupt scheduled too early");
1981931cf94SJohn Baldwin 
1991931cf94SJohn Baldwin 	CTR3(KTR_INTR, "sched_softintr pid %d(%s) spending=0x%x",
2001931cf94SJohn Baldwin 		softithd->p_pid, softithd->p_comm, spending);
2011931cf94SJohn Baldwin 
2021931cf94SJohn Baldwin 	/*
2031931cf94SJohn Baldwin 	 * Get the sched lock and see if the thread is on whichkqs yet.
2041931cf94SJohn Baldwin 	 * If not, put it on there.  In any case, kick everyone so that if
2051931cf94SJohn Baldwin 	 * the new thread is higher priority than their current thread, it
2061931cf94SJohn Baldwin 	 * gets run now.
2071931cf94SJohn Baldwin 	 */
2081931cf94SJohn Baldwin 	mtx_enter(&sched_lock, MTX_SPIN);
2091931cf94SJohn Baldwin 	if (softithd->p_stat == SWAIT) { /* not on run queue */
2101931cf94SJohn Baldwin 		CTR1(KTR_INTR, "sched_softintr: setrunqueue %d",
2111931cf94SJohn Baldwin 		    softithd->p_pid);
2121931cf94SJohn Baldwin /*		membar_lock(); */
2131931cf94SJohn Baldwin 		softithd->p_stat = SRUN;
2141931cf94SJohn Baldwin 		setrunqueue(softithd);
2151931cf94SJohn Baldwin 		aston();
2161931cf94SJohn Baldwin 	}
2171931cf94SJohn Baldwin 	mtx_exit(&sched_lock, MTX_SPIN);
2181931cf94SJohn Baldwin #if 0
2191931cf94SJohn Baldwin 	aston();			/* ??? check priorities first? */
2201931cf94SJohn Baldwin #else
2211931cf94SJohn Baldwin 	need_resched();
2221931cf94SJohn Baldwin #endif
2231931cf94SJohn Baldwin }
2241931cf94SJohn Baldwin 
2251931cf94SJohn Baldwin SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr, NULL)
2261931cf94SJohn Baldwin 
2271931cf94SJohn Baldwin /*
2281931cf94SJohn Baldwin  * Start soft interrupt thread.
2291931cf94SJohn Baldwin  */
2301931cf94SJohn Baldwin static void
2311931cf94SJohn Baldwin start_softintr(dummy)
2321931cf94SJohn Baldwin 	void *dummy;
2331931cf94SJohn Baldwin {
2341931cf94SJohn Baldwin 	int error;
2351931cf94SJohn Baldwin 
2361931cf94SJohn Baldwin 	if (softithd != NULL) {		/* we already have a thread */
2371931cf94SJohn Baldwin 		printf("start_softintr: already running");
2381931cf94SJohn Baldwin 		return;
2391931cf94SJohn Baldwin 	}
2401931cf94SJohn Baldwin 
2411931cf94SJohn Baldwin 	error = kthread_create(intr_soft, NULL, &softithd,
2421931cf94SJohn Baldwin 		RFSTOPPED | RFHIGHPID, "softinterrupt");
2431931cf94SJohn Baldwin 	if (error)
2441931cf94SJohn Baldwin 		panic("start_softintr: kthread_create error %d\n", error);
2451931cf94SJohn Baldwin 
2461931cf94SJohn Baldwin 	softithd->p_rtprio.type = RTP_PRIO_ITHREAD;
2471931cf94SJohn Baldwin 	softithd->p_rtprio.prio = PI_SOFT;	/* soft interrupt */
2481931cf94SJohn Baldwin 	softithd->p_stat = SWAIT;		/* we're idle */
2491931cf94SJohn Baldwin 	softithd->p_flag |= P_NOLOAD;
2501931cf94SJohn Baldwin }
2511931cf94SJohn Baldwin 
2521931cf94SJohn Baldwin /*
2531931cf94SJohn Baldwin  * Software interrupt process code.
2541931cf94SJohn Baldwin  */
2551931cf94SJohn Baldwin static void
2561931cf94SJohn Baldwin intr_soft(dummy)
2571931cf94SJohn Baldwin 	void *dummy;
2581931cf94SJohn Baldwin {
2591931cf94SJohn Baldwin 	int i;
2601931cf94SJohn Baldwin 	u_int pend;
2611931cf94SJohn Baldwin 
2621931cf94SJohn Baldwin 	/* Main loop */
2631931cf94SJohn Baldwin 	for (;;) {
2641931cf94SJohn Baldwin 		CTR3(KTR_INTR, "intr_soft pid %d(%s) spending=0x%x",
2651931cf94SJohn Baldwin 		    curproc->p_pid, curproc->p_comm, spending);
2661931cf94SJohn Baldwin 
2671931cf94SJohn Baldwin 		/*
2681931cf94SJohn Baldwin 		 * Service interrupts.  If another interrupt arrives
2691931cf94SJohn Baldwin 		 * while we are running, they will set spending to
2701931cf94SJohn Baldwin 		 * denote that we should make another pass.
2711931cf94SJohn Baldwin 		 */
2721931cf94SJohn Baldwin 		pend = atomic_readandclear_int(&spending);
2731931cf94SJohn Baldwin 		while ((i = ffs(pend))) {
2741931cf94SJohn Baldwin 			i--;
2751931cf94SJohn Baldwin 			atomic_add_long(&softintr_count[i], 1);
2761931cf94SJohn Baldwin 			pend &= ~ (1 << i);
2771931cf94SJohn Baldwin 			mtx_enter(&Giant, MTX_DEF);
2781931cf94SJohn Baldwin 			if (shandlers[i] == swi_generic)
2791931cf94SJohn Baldwin 				swi_dispatcher(i);
2801931cf94SJohn Baldwin 			else
2811931cf94SJohn Baldwin 				(shandlers[i])();
2821931cf94SJohn Baldwin 			mtx_exit(&Giant, MTX_DEF);
2831931cf94SJohn Baldwin 		}
2841931cf94SJohn Baldwin 		/*
2851931cf94SJohn Baldwin 		 * Processed all our interrupts.  Now get the sched
2861931cf94SJohn Baldwin 		 * lock.  This may take a while and spending may get
2871931cf94SJohn Baldwin 		 * set again, so we have to check it again.
2881931cf94SJohn Baldwin 		 */
2891931cf94SJohn Baldwin 		mtx_enter(&sched_lock, MTX_SPIN);
2901931cf94SJohn Baldwin 		if (spending == 0) {
2911931cf94SJohn Baldwin 			CTR1(KTR_INTR, "intr_soft pid %d: done",
2921931cf94SJohn Baldwin 			    curproc->p_pid);
2931931cf94SJohn Baldwin 			curproc->p_stat = SWAIT; /* we're idle */
2941931cf94SJohn Baldwin 			mi_switch();
2951931cf94SJohn Baldwin 			CTR1(KTR_INTR, "intr_soft pid %d: resumed",
2961931cf94SJohn Baldwin 			    curproc->p_pid);
2971931cf94SJohn Baldwin 		}
2981931cf94SJohn Baldwin 		mtx_exit(&sched_lock, MTX_SPIN);
2991931cf94SJohn Baldwin 	}
3001931cf94SJohn Baldwin }
3011931cf94SJohn Baldwin 
3021931cf94SJohn Baldwin /*
3031931cf94SJohn Baldwin  * Bits in the spending bitmap variable must be set atomically because
3041931cf94SJohn Baldwin  * spending may be manipulated by interrupts or other cpu's without holding
3051931cf94SJohn Baldwin  * any locks.
3061931cf94SJohn Baldwin  *
3071931cf94SJohn Baldwin  * Note: setbits uses a locked or, making simple cases MP safe.
3081931cf94SJohn Baldwin  */
3091931cf94SJohn Baldwin #define DO_SETBITS(name, var, bits) \
3101931cf94SJohn Baldwin void name(void)					\
3111931cf94SJohn Baldwin {						\
3121931cf94SJohn Baldwin 	atomic_set_int(var, bits);		\
3131931cf94SJohn Baldwin 	sched_softintr();			\
3141931cf94SJohn Baldwin }
3151931cf94SJohn Baldwin 
3161931cf94SJohn Baldwin #define DO_SETBITS_AND_NO_MORE(name, var, bits)	\
3171931cf94SJohn Baldwin void name(void)					\
3181931cf94SJohn Baldwin {						\
3191931cf94SJohn Baldwin 	atomic_set_int(var, bits);		\
3201931cf94SJohn Baldwin }
3211931cf94SJohn Baldwin 
3221931cf94SJohn Baldwin DO_SETBITS(setsoftcamnet,&spending, SWI_CAMNET_PENDING)
3231931cf94SJohn Baldwin DO_SETBITS(setsoftcambio,&spending, SWI_CAMBIO_PENDING)
3241931cf94SJohn Baldwin DO_SETBITS(setsoftclock, &spending, SWI_CLOCK_PENDING)
3251931cf94SJohn Baldwin DO_SETBITS(setsoftnet,   &spending, SWI_NET_PENDING)
3261931cf94SJohn Baldwin DO_SETBITS(setsofttty,   &spending, SWI_TTY_PENDING)
3271931cf94SJohn Baldwin DO_SETBITS(setsoftvm,	 &spending, SWI_VM_PENDING)
3281931cf94SJohn Baldwin DO_SETBITS(setsofttq,	 &spending, SWI_TQ_PENDING)
3291931cf94SJohn Baldwin 
3301931cf94SJohn Baldwin DO_SETBITS_AND_NO_MORE(schedsoftcamnet, &sdelayed, SWI_CAMNET_PENDING)
3311931cf94SJohn Baldwin DO_SETBITS_AND_NO_MORE(schedsoftcambio, &sdelayed, SWI_CAMBIO_PENDING)
3321931cf94SJohn Baldwin DO_SETBITS_AND_NO_MORE(schedsoftnet, &sdelayed, SWI_NET_PENDING)
3331931cf94SJohn Baldwin DO_SETBITS_AND_NO_MORE(schedsofttty, &sdelayed, SWI_TTY_PENDING)
3341931cf94SJohn Baldwin DO_SETBITS_AND_NO_MORE(schedsoftvm, &sdelayed, SWI_VM_PENDING)
3351931cf94SJohn Baldwin DO_SETBITS_AND_NO_MORE(schedsofttq, &sdelayed, SWI_TQ_PENDING)
3361931cf94SJohn Baldwin 
3371931cf94SJohn Baldwin void
3381931cf94SJohn Baldwin setdelayed(void)
3391931cf94SJohn Baldwin {
3401931cf94SJohn Baldwin 	int pend;
3411931cf94SJohn Baldwin 
3421931cf94SJohn Baldwin 	pend = atomic_readandclear_int(&sdelayed);
3431931cf94SJohn Baldwin 	if (pend != 0) {
3441931cf94SJohn Baldwin 		atomic_set_int(&spending, pend);
3451931cf94SJohn Baldwin 		sched_softintr();
3461931cf94SJohn Baldwin 	}
3471931cf94SJohn Baldwin }
3481931cf94SJohn Baldwin 
3491931cf94SJohn Baldwin intrmask_t
3501931cf94SJohn Baldwin softclockpending(void)
3511931cf94SJohn Baldwin {
3521931cf94SJohn Baldwin 	return (spending & SWI_CLOCK_PENDING);
3531931cf94SJohn Baldwin }
3541931cf94SJohn Baldwin 
3551931cf94SJohn Baldwin /*
3561931cf94SJohn Baldwin  * Dummy spl calls.  The only reason for these is to not break
3571931cf94SJohn Baldwin  * all the code which expects to call them.
3581931cf94SJohn Baldwin  */
3591931cf94SJohn Baldwin void spl0 (void) {}
3601931cf94SJohn Baldwin void splx (intrmask_t x) {}
3611931cf94SJohn Baldwin intrmask_t  splq(intrmask_t mask) { return 0; }
3621931cf94SJohn Baldwin intrmask_t  splbio(void) { return 0; }
3631931cf94SJohn Baldwin intrmask_t  splcam(void) { return 0; }
3641931cf94SJohn Baldwin intrmask_t  splclock(void) { return 0; }
3651931cf94SJohn Baldwin intrmask_t  splhigh(void) { return 0; }
3661931cf94SJohn Baldwin intrmask_t  splimp(void) { return 0; }
3671931cf94SJohn Baldwin intrmask_t  splnet(void) { return 0; }
3681931cf94SJohn Baldwin intrmask_t  splsoftcam(void) { return 0; }
3691931cf94SJohn Baldwin intrmask_t  splsoftcambio(void) { return 0; }
3701931cf94SJohn Baldwin intrmask_t  splsoftcamnet(void) { return 0; }
3711931cf94SJohn Baldwin intrmask_t  splsoftclock(void) { return 0; }
3721931cf94SJohn Baldwin intrmask_t  splsofttty(void) { return 0; }
3731931cf94SJohn Baldwin intrmask_t  splsoftvm(void) { return 0; }
3741931cf94SJohn Baldwin intrmask_t  splsofttq(void) { return 0; }
3751931cf94SJohn Baldwin intrmask_t  splstatclock(void) { return 0; }
3761931cf94SJohn Baldwin intrmask_t  spltty(void) { return 0; }
3771931cf94SJohn Baldwin intrmask_t  splvm(void) { return 0; }
378