Change the meaning of safepri from a cpl mask to a thread priority.
Make a minor adjustment to tests within one of the buffer cache's
critical sections.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $FreeBSD: src/sys/i386/i386/autoconf.c,v 1.146.2.2 2001/06/07 06:05:58 dd Exp $
- * $DragonFly: src/sys/i386/i386/Attic/autoconf.c,v 1.15 2004/10/14 18:31:02 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/autoconf.c,v 1.16 2005/06/06 15:02:26 dillon Exp $
*/
/*
* completely safe (since a panic may occur in a critical region
* at splhigh()), but we want at least bio interrupts to work.
*/
- safepri = curthread->td_cpl;
+ safepri = TDPRI_KERN_USER;
}
static void
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
- * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.72 2005/03/17 08:22:38 swildner Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.73 2005/06/06 15:02:26 dillon Exp $
*/
#include "use_apm.h"
thread0.td_flags |= TDF_RUNNING;
thread0.td_proc = &proc0;
thread0.td_switch = cpu_heavy_switch; /* YYY eventually LWKT */
- safepri = thread0.td_cpl = SWI_MASK | HWI_MASK;
+ thread0.td_cpl = 0; /* crit section protects us */
+ safepri = TDPRI_MAX;
/* make ldt memory segments */
/*
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/init_main.c,v 1.134.2.8 2003/06/06 20:21:32 tegge Exp $
- * $DragonFly: src/sys/kern/init_main.c,v 1.41 2005/04/19 17:54:42 dillon Exp $
+ * $DragonFly: src/sys/kern/init_main.c,v 1.42 2005/06/06 15:02:27 dillon Exp $
*/
#include "opt_init_path.h"
create_init(const void *udata __unused)
{
int error;
- int s;
- s = splhigh();
+ crit_enter();
error = fork1(&proc0, RFFDG | RFPROC, &initproc);
if (error)
panic("cannot fork init: %d", error);
initproc->p_flag |= P_INMEM | P_SYSTEM;
cpu_set_fork_handler(initproc, start_init, NULL);
- splx(s);
+ crit_exit();
}
SYSINIT(init,SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/kern_clock.c,v 1.105.2.10 2002/10/17 13:19:40 maxim Exp $
- * $DragonFly: src/sys/kern/kern_clock.c,v 1.42 2005/06/03 23:57:32 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_clock.c,v 1.43 2005/06/06 15:02:27 dillon Exp $
*/
#include "opt_ntp.h"
* in ``non-process'' (i.e., interrupt) work.
*
* XXX assume system if frame is NULL. A NULL frame
- * can occur if ipi processing is done from an splx().
+ * can occur if ipi processing is done from a crit_exit().
*/
if (frame && CLKF_INTR(frame))
td->td_iticks += bump;
p->p_flag |= P_PROFIL;
#if 0 /* XXX */
if (++profprocs == 1 && stathz != 0) {
- s = splstatclock();
+ crit_enter();
psdiv = psratio;
setstatclockrate(profhz);
- splx(s);
+ crit_exit();
}
#endif
}
p->p_flag &= ~P_PROFIL;
#if 0 /* XXX */
if (--profprocs == 0 && stathz != 0) {
- s = splstatclock();
+ crit_enter();
psdiv = 1;
setstatclockrate(stathz);
- splx(s);
+ crit_exit();
}
#endif
}
*
* @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
* $FreeBSD: src/sys/kern/kern_descrip.c,v 1.81.2.19 2004/02/28 00:43:31 tegge Exp $
- * $DragonFly: src/sys/kern/kern_descrip.c,v 1.41 2005/04/08 17:39:31 joerg Exp $
+ * $DragonFly: src/sys/kern/kern_descrip.c,v 1.42 2005/06/06 15:02:27 dillon Exp $
*/
#include "opt_compat.h"
#include <vm/vm.h>
#include <vm/vm_extern.h>
+#include <sys/thread2.h>
#include <sys/file2.h>
static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
void
funsetown(struct sigio *sigio)
{
- int s;
-
if (sigio == NULL)
return;
- s = splhigh();
+ crit_enter();
*(sigio->sio_myref) = NULL;
- splx(s);
+ crit_exit();
if (sigio->sio_pgid < 0) {
SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio,
sigio, sio_pgsigio);
struct proc *proc;
struct pgrp *pgrp;
struct sigio *sigio;
- int s;
if (pgid == 0) {
funsetown(*sigiop);
/* It would be convenient if p_ruid was in ucred. */
sigio->sio_ruid = curproc->p_ucred->cr_ruid;
sigio->sio_myref = sigiop;
- s = splhigh();
+ crit_enter();
*sigiop = sigio;
- splx(s);
+ crit_exit();
return (0);
}
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/kern_event.c,v 1.2.2.10 2004/04/04 07:03:14 cperciva Exp $
- * $DragonFly: src/sys/kern/kern_event.c,v 1.13 2004/11/12 00:09:23 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_event.c,v 1.14 2005/06/06 15:02:27 dillon Exp $
*/
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/sysproto.h>
#include <sys/uio.h>
+#include <sys/thread2.h>
#include <sys/file2.h>
#include <vm/vm_zone.h>
struct filterops *fops;
struct file *fp = NULL;
struct knote *kn = NULL;
- int s, error = 0;
+ int error = 0;
if (kev->filter < 0) {
if (kev->filter + EVFILT_SYSCOUNT < 0)
kn->kn_kevent.udata = kev->udata;
}
- s = splhigh();
+ crit_enter();
if (kn->kn_fop->f_event(kn, 0))
KNOTE_ACTIVATE(kn);
- splx(s);
-
+ crit_exit();
} else if (kev->flags & EV_DELETE) {
kn->kn_fop->f_detach(kn);
knote_drop(kn, td);
if ((kev->flags & EV_DISABLE) &&
((kn->kn_status & KN_DISABLED) == 0)) {
- s = splhigh();
+ crit_enter();
kn->kn_status |= KN_DISABLED;
- splx(s);
+ crit_exit();
}
if ((kev->flags & EV_ENABLE) && (kn->kn_status & KN_DISABLED)) {
- s = splhigh();
+ crit_enter();
kn->kn_status &= ~KN_DISABLED;
if ((kn->kn_status & KN_ACTIVE) &&
((kn->kn_status & KN_QUEUED) == 0))
knote_enqueue(kn);
- splx(s);
+ crit_exit();
}
done:
struct kevent *kevp;
struct timeval atv, rtv, ttv;
struct knote *kn, marker;
- int s, count, timeout, nkev = 0, error = 0;
+ int count, timeout, nkev = 0, error = 0;
count = maxevents;
if (count == 0)
start:
kevp = kq->kq_kev;
- s = splhigh();
+ crit_enter();
if (kq->kq_count == 0) {
if (timeout < 0) {
error = EWOULDBLOCK;
kq->kq_state |= KQ_SLEEP;
error = tsleep(kq, PCATCH, "kqread", timeout);
}
- splx(s);
+ crit_exit();
if (error == 0)
goto retry;
/* don't restart after signals... */
kn = TAILQ_FIRST(&kq->kq_head);
TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
if (kn == &marker) {
- splx(s);
+ crit_exit();
if (count == maxevents)
goto retry;
goto done;
if (kn->kn_flags & EV_ONESHOT) {
kn->kn_status &= ~KN_QUEUED;
kq->kq_count--;
- splx(s);
+ crit_exit();
kn->kn_fop->f_detach(kn);
knote_drop(kn, td);
- s = splhigh();
+ crit_enter();
} else if (kn->kn_flags & EV_CLEAR) {
kn->kn_data = 0;
kn->kn_fflags = 0;
}
count--;
if (nkev == KQ_NEVENTS) {
- splx(s);
+ crit_exit();
error = copyout((caddr_t)&kq->kq_kev, (caddr_t)ulistp,
sizeof(struct kevent) * nkev);
ulistp += nkev;
nkev = 0;
kevp = kq->kq_kev;
- s = splhigh();
+ crit_enter();
if (error)
break;
}
}
TAILQ_REMOVE(&kq->kq_head, &marker, kn_tqe);
- splx(s);
+ crit_exit();
done:
if (nkev != 0)
error = copyout((caddr_t)&kq->kq_kev, (caddr_t)ulistp,
{
struct kqueue *kq = (struct kqueue *)fp->f_data;
int revents = 0;
- int s = splnet();
+ crit_enter();
if (events & (POLLIN | POLLRDNORM)) {
if (kq->kq_count) {
revents |= events & (POLLIN | POLLRDNORM);
kq->kq_state |= KQ_SEL;
}
}
- splx(s);
+ crit_exit();
return (revents);
}
}
/*
- * should be called at spl == 0, since we don't want to hold spl
- * while calling fdrop and free.
+ * should be called outside of a critical section, since we don't want to
+ * hold a critical section while calling fdrop and free.
*/
static void
knote_drop(struct knote *kn, struct thread *td)
knote_enqueue(struct knote *kn)
{
struct kqueue *kq = kn->kn_kq;
- int s = splhigh();
+ crit_enter();
KASSERT((kn->kn_status & KN_QUEUED) == 0, ("knote already queued"));
TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
kn->kn_status |= KN_QUEUED;
kq->kq_count++;
- splx(s);
+ crit_exit();
kqueue_wakeup(kq);
}
knote_dequeue(struct knote *kn)
{
struct kqueue *kq = kn->kn_kq;
- int s = splhigh();
KASSERT(kn->kn_status & KN_QUEUED, ("knote not queued"));
+ crit_enter();
TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
kn->kn_status &= ~KN_QUEUED;
kq->kq_count--;
- splx(s);
+ crit_exit();
}
static void
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
* $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $
- * $DragonFly: src/sys/kern/kern_exit.c,v 1.40 2005/04/20 16:37:09 cpressey Exp $
+ * $DragonFly: src/sys/kern/kern_exit.c,v 1.41 2005/06/06 15:02:27 dillon Exp $
*/
#include "opt_compat.h"
#include <vm/vm_extern.h>
#include <sys/user.h>
+#include <sys/thread2.h>
+
/* Required to be non-static for SysVR4 emulator */
MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
{
struct proc *p = curproc;
struct sigacts *pss;
- int s;
if (p->p_procsig->ps_refcnt == 1 &&
p->p_sigacts != &p->p_addr->u_sigacts) {
pss = p->p_sigacts;
- s = splhigh();
+ crit_enter();
p->p_addr->u_sigacts = *pss;
p->p_sigacts = &p->p_addr->u_sigacts;
- splx(s);
+ crit_exit();
FREE(pss, M_SUBPROC);
}
}
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
* $FreeBSD: src/sys/kern/kern_fork.c,v 1.72.2.14 2003/06/26 04:15:10 silby Exp $
- * $DragonFly: src/sys/kern/kern_fork.c,v 1.32 2005/01/31 22:29:59 joerg Exp $
+ * $DragonFly: src/sys/kern/kern_fork.c,v 1.33 2005/06/06 15:02:27 dillon Exp $
*/
#include "opt_ktrace.h"
#include <sys/vmmeter.h>
#include <sys/user.h>
+#include <sys/thread2.h>
static MALLOC_DEFINE(M_ATFORK, "atfork", "atfork callback");
p2->p_procsig->ps_refcnt++;
if (p1->p_sigacts == &p1->p_addr->u_sigacts) {
struct sigacts *newsigacts;
- int s;
/* Create the shared sigacts structure */
MALLOC(newsigacts, struct sigacts *,
sizeof(struct sigacts), M_SUBPROC, M_WAITOK);
- s = splhigh();
+ crit_enter();
/*
* Set p_sigacts to the new shared structure.
* Note that this is updating p1->p_sigacts at the
bcopy(&p1->p_addr->u_sigacts, p2->p_sigacts,
sizeof(*p2->p_sigacts));
*p2->p_sigacts = p1->p_addr->u_sigacts;
- splx(s);
+ crit_exit();
}
} else {
MALLOC(p2->p_procsig, struct procsig *, sizeof(struct procsig),
KASSERT(p2 && p2->p_stat == SIDL,
("cannot start forked process, bad status: %p", p2));
resetpriority(p2);
- (void) splhigh();
+ crit_enter();
p2->p_stat = SRUN;
setrunqueue(p2);
- (void) spl0();
+ crit_exit();
/*
* Now can be swapped.
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/kern_intr.c,v 1.24.2.1 2001/10/14 20:05:50 luigi Exp $
- * $DragonFly: src/sys/kern/kern_intr.c,v 1.20 2005/06/01 17:43:42 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_intr.c,v 1.21 2005/06/06 15:02:27 dillon Exp $
*
*/
SYSCTL_INT(_kern, OID_AUTO, livelock_fallback,
CTLFLAG_RW, &livelock_fallback, 0, "Livelock interrupt fallback rate");
-/*
- * TEMPORARY sysctl to allow interrupt handlers to run without the critical
- * section (if set to 0).
- *
- * SEQUENCE OF EVENTS: default to prior operation, testing, change default
- * to 0, lots more testing, then make operation without a critical section
- * mandatory and remove the sysctl code and variable.
- */
-static int int_use_crit_section = 1;
-SYSCTL_INT(_kern, OID_AUTO, int_use_crit_section,
- CTLFLAG_RW, &int_use_crit_section, 0, "Run interrupts entirely within a critical section");
-
static void ithread_handler(void *arg);
/*
intrec_t *nrec;
struct random_softc *sc = &irandom_ary[intr];
globaldata_t gd = mycpu;
- int in_crit_section; /* REMOVE WHEN TESTING COMPLETE */
- intrmask_t s;
/*
* The loop must be entered with one critical section held.
for (;;) {
/*
- * Deal with the sysctl variable allowing the interrupt thread to run
- * without a critical section. Once this is proven out it will
- * become the default. Note that a critical section is always
- * held as of the top of the loop.
- */
- in_crit_section = int_use_crit_section;
- if (in_crit_section == 0)
- crit_exit_gd(gd);
-
- /*
* We can get woken up by the livelock periodic code too, run the
* handlers only if there is a real interrupt pending. XXX
*
* Clear irunning[] prior to running the handlers to interlock
* again new events occuring during processing of existing events.
+ *
+ * For now run each handler in a critical section.
*/
irunning[intr] = 0;
for (rec = *list; rec; rec = nrec) {
nrec = rec->next;
- s = splq(*rec->maskptr);
rec->handler(rec->argument);
- splx(s);
}
/*
+ * Do a quick exit/enter to catch any higher-priority
+ * interrupt sources and so user/system/interrupt statistics
+ * work for interrupt threads.
+ */
+ crit_exit_gd(gd);
+ crit_enter_gd(gd);
+
+ /*
* This is our interrupt hook to add rate randomness to the random
* number generator.
*/
* section safe and must be handled by the platform specific
* ithread_done() routine.
*/
- if (in_crit_section) {
- if (irunning[intr] == 0)
- ithread_done(intr);
- } else {
- crit_enter_gd(gd);
- if (irunning[intr] == 0)
- ithread_done(intr);
- }
+ if (irunning[intr] == 0)
+ ithread_done(intr);
/* must be in critical section on loop */
}
+ /* not reached */
}
/*
*
* @(#)kern_lock.c 8.18 (Berkeley) 5/21/95
* $FreeBSD: src/sys/kern/kern_lock.c,v 1.31.2.3 2001/12/25 01:44:44 dillon Exp $
- * $DragonFly: src/sys/kern/kern_lock.c,v 1.13 2005/01/19 18:00:39 drhodus Exp $
+ * $DragonFly: src/sys/kern/kern_lock.c,v 1.14 2005/06/06 15:02:27 dillon Exp $
*/
#include "opt_lint.h"
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/sysctl.h>
+#include <sys/thread2.h>
/*
* 0: no warnings, 1: warnings, 2: panic
static int
acquire(struct lock *lkp, int extflags, int wanted)
{
- int s, error;
+ int error;
if ((extflags & LK_NOWAIT) && (lkp->lk_flags & wanted)) {
return EBUSY;
return 0;
}
- s = splhigh();
+ crit_enter();
while ((lkp->lk_flags & wanted) != 0) {
lkp->lk_flags |= LK_WAIT_NONZERO;
lkp->lk_waitcount++;
lkp->lk_waitcount--;
}
if (error) {
- splx(s);
+ crit_exit();
return error;
}
if (extflags & LK_SLEEPFAIL) {
- splx(s);
+ crit_exit();
return ENOLCK;
}
}
- splx(s);
+ crit_exit();
return 0;
}
* Copyright (c) 1998 David Greenman. All rights reserved.
* src/sys/kern/kern_sfbuf.c,v 1.7 2004/05/13 19:46:18 dillon
*
- * $DragonFly: src/sys/kern/kern_msfbuf.c,v 1.13 2005/04/20 10:24:48 hmp Exp $
+ * $DragonFly: src/sys/kern/kern_msfbuf.c,v 1.14 2005/06/06 15:02:27 dillon Exp $
*/
/*
* MSFBUFs cache linear multi-page ephermal mappings and operate similar
* and release resources back to the system. Note that the sfbuf's
* removal from the freelist is delayed, so it may in fact already be
* on the free list. This is the optimal (and most likely) scenario.
- *
- * Must be called at splimp.
*/
void
msf_buf_free(struct msf_buf *msf)
* are met.
*
* $FreeBSD: src/sys/kern/kern_physio.c,v 1.46.2.4 2003/11/14 09:51:47 simokawa Exp $
- * $DragonFly: src/sys/kern/kern_physio.c,v 1.9 2004/12/31 22:30:19 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_physio.c,v 1.10 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
{
int i;
int error;
- int spl;
int chk_blockno;
caddr_t sa;
off_t blockno;
}
BUF_STRATEGY(bp, 0);
- spl = splbio();
+ crit_enter();
while ((bp->b_flags & B_DONE) == 0)
tsleep((caddr_t)bp, 0, "physstr", 0);
- splx(spl);
+ crit_exit();
if (uio->uio_segflg == UIO_USERSPACE)
vunmapbuf(bp);
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/kern_poll.c,v 1.2.2.4 2002/06/27 23:26:33 luigi Exp $
- * $DragonFly: src/sys/kern/kern_poll.c,v 1.17 2005/06/01 20:47:14 joerg Exp $
+ * $DragonFly: src/sys/kern/kern_poll.c,v 1.18 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
{
struct timeval t;
int kern_load;
- int s = splhigh();
+ crit_enter();
lwkt_replymsg(&msg->nm_lmsg, 0);
phase = 5;
if (residual_burst > 0) {
phase = 6;
}
out:
- splx(s);
+ crit_exit();
return(EASYNC);
}
/*
* netisr_poll is scheduled by schednetisr when appropriate, typically once
- * per tick. It is called at splnet() so first thing to do is to upgrade to
- * splimp(), and call all registered handlers.
+ * per tick.
*
* Note that the message is replied immediately in order to allow a new
* ISR to be scheduled in the handler.
+ *
+ * XXX each registration should indicate whether it needs a critical
+ * section to operate.
*/
/* ARGSUSED */
static int
static int reg_frac_count;
int i, cycles;
enum poll_cmd arg = POLL_ONLY;
- int s;
lwkt_replymsg(&msg->nm_lmsg, 0);
- s = splimp();
+ crit_enter();
phase = 3;
if (residual_burst == 0) { /* first call in this tick */
microuptime(&poll_start_t);
}
schednetisr(NETISR_POLLMORE);
phase = 4;
- splx(s);
+ crit_exit();
return(EASYNC);
}
* kern_random.c -- A strong random number generator
*
* $FreeBSD: src/sys/kern/kern_random.c,v 1.36.2.4 2002/09/17 17:11:57 sam Exp $
- * $DragonFly: src/sys/kern/Attic/kern_random.c,v 1.8 2005/06/01 17:43:42 dillon Exp $
+ * $DragonFly: src/sys/kern/Attic/kern_random.c,v 1.9 2005/06/06 15:02:28 dillon Exp $
*
* Version 0.95, last modified 18-Oct-95
*
#include <sys/select.h>
#include <sys/systm.h>
#include <sys/systimer.h>
+#include <sys/thread2.h>
#ifdef __i386__
#include <i386/isa/icu.h>
int
random_poll(dev_t dev, int events, struct thread *td)
{
- int s;
int revents = 0;
- s = splhigh();
+ crit_enter();
if (events & (POLLIN | POLLRDNORM)) {
if (random_state.entropy_count >= 8)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(td, &random_state.rsel);
}
- splx(s);
+ crit_exit();
if (events & (POLLOUT | POLLWRNORM))
revents |= events & (POLLOUT | POLLWRNORM); /* heh */
*
* @(#)kern_resource.c 8.5 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/kern_resource.c,v 1.55.2.5 2001/11/03 01:41:08 ps Exp $
- * $DragonFly: src/sys/kern/kern_resource.c,v 1.20 2004/05/03 16:06:26 joerg Exp $
+ * $DragonFly: src/sys/kern/kern_resource.c,v 1.21 2005/06/06 15:02:28 dillon Exp $
*/
#include "opt_compat.h"
chgsbsize(struct uidinfo *uip, u_long *hiwat, u_long to, rlim_t max)
{
rlim_t new;
- int s;
- s = splnet();
+ crit_enter();
new = uip->ui_sbsize + to - *hiwat;
/* don't allow them to exceed max, but allow subtraction */
if (to > *hiwat && new > max) {
- splx(s);
+ crit_exit();
return (0);
}
uip->ui_sbsize = new;
*hiwat = to;
if (uip->ui_sbsize < 0)
printf("negative sbsize for uid = %d\n", uip->ui_uid);
- splx(s);
+ crit_exit();
return (1);
}
*
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
* $FreeBSD: src/sys/kern/kern_sig.c,v 1.72.2.17 2003/05/16 16:34:34 obrien Exp $
- * $DragonFly: src/sys/kern/kern_sig.c,v 1.36 2005/03/02 06:17:17 davidxu Exp $
+ * $DragonFly: src/sys/kern/kern_sig.c,v 1.37 2005/06/06 15:02:28 dillon Exp $
*/
#include "opt_ktrace.h"
#include <sys/malloc.h>
#include <sys/unistd.h>
#include <sys/kern_syscall.h>
+#include <sys/thread2.h>
#include <machine/ipl.h>
/*
* Change setting atomically.
*/
- splhigh();
+ crit_enter();
ps->ps_catchmask[_SIG_IDX(sig)] = act->sa_mask;
SIG_CANTMASK(ps->ps_catchmask[_SIG_IDX(sig)]);
SIGADDSET(p->p_sigcatch, sig);
}
- spl0();
+ crit_exit();
}
return (0);
}
* kern_sigprocmask() - MP SAFE ONLY IF p == curproc
*
* Manipulate signal mask. This routine is MP SAFE *ONLY* if
- * p == curproc. Also remember that in order to remain MP SAFE
- * no spl*() calls may be made.
+ * p == curproc.
*/
int
kern_sigprocmask(int how, sigset_t *set, sigset_t *oset)
void
psignal(struct proc *p, int sig)
{
- int s, prop;
+ int prop;
sig_t action;
if (sig > _SIG_MAXSIG || sig <= 0) {
panic("psignal signal number");
}
- s = splhigh();
+ crit_enter();
KNOTE(&p->p_klist, NOTE_SIGNAL | sig);
- splx(s);
+ crit_exit();
prop = sigprop(sig);
*/
if (action == SIG_HOLD && (!(prop & SA_CONT) || p->p_stat != SSTOP))
return;
- s = splhigh();
+
+ crit_enter();
+
switch (p->p_stat) {
case SSLEEP:
/*
run:
setrunnable(p);
out:
- splx(s);
+ crit_exit();
}
#ifdef SMP
* mask from before the sigsuspend is what we want
* restored after the signal processing is completed.
*/
- splhigh();
+ crit_enter();
if (p->p_flag & P_OLDMASK) {
returnmask = p->p_oldsigmask;
p->p_flag &= ~P_OLDMASK;
SIGADDSET(p->p_sigignore, sig);
ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
}
- spl0();
+ crit_exit();
p->p_stats->p_ru.ru_nsignals++;
if (p->p_sig != sig) {
code = 0;
*
* @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
* $FreeBSD: src/sys/kern/kern_synch.c,v 1.87.2.6 2002/10/13 07:29:53 kbyanc Exp $
- * $DragonFly: src/sys/kern/kern_synch.c,v 1.41 2005/01/14 02:20:22 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_synch.c,v 1.42 2005/06/06 15:02:28 dillon Exp $
*/
#include "opt_ktrace.h"
int sched_quantum; /* Roundrobin scheduling quantum in ticks. */
int ncpus;
int ncpus2, ncpus2_shift, ncpus2_mask;
+int safepri;
static struct callout loadav_callout;
static struct callout roundrobin_callout;
static void roundrobin (void *arg);
static void schedcpu (void *arg);
static void updatepri (struct proc *p);
-static void crit_panicints(void);
static int
sysctl_kern_quantum(SYSCTL_HANDLER_ARGS)
{
fixpt_t loadfac = averunnable.ldavg[0];
struct proc *p;
- int s;
unsigned int ndecay;
FOREACH_PROC_IN_SYSTEM(p) {
if (p->p_slptime > 1)
continue;
/* prevent state changes and protect run queue */
- s = splhigh();
+ crit_enter();
/*
* p_cpticks runs at ESTCPUFREQ but must be divided by the
* load average for par-100% use. Higher p_interactive
else
p->p_estcpu = 0;
resetpriority(p);
- splx(s);
+ crit_exit();
}
wakeup((caddr_t)&lbolt);
callout_reset(&schedcpu_callout, hz, schedcpu, NULL);
/*
* During autoconfiguration or after a panic, a sleep will simply
* lower the priority briefly to allow interrupts, then return.
- * The priority to be used (safepri) is machine-dependent, thus this
- * value is initialized and maintained in the machine-dependent layers.
- * This priority will typically be 0, or the lowest priority
- * that is safe for use on the interrupt stack; it can be made
- * higher to block network software interrupts after panics.
*/
-int safepri;
void
sleepinit(void)
struct proc *p = td->td_proc; /* may be NULL */
int sig = 0, catch = flags & PCATCH;
int id = LOOKUP(ident);
+ int oldpri;
struct callout thandle;
/*
* don't run any other procs or panic below,
* in case this is the idle process and already asleep.
*/
- crit_panicints();
+ splz();
+ oldpri = td->td_pri & TDPRI_MASK;
+ lwkt_setpri_self(safepri);
+ lwkt_switch();
+ lwkt_setpri_self(oldpri);
return (0);
}
KKASSERT(td != &mycpu->gd_idlethread); /* you must be kidding! */
void
setrunnable(struct proc *p)
{
- int s;
+ crit_enter();
- s = splhigh();
switch (p->p_stat) {
case 0:
case SRUN:
#endif
if (p->p_flag & P_INMEM)
lwkt_schedule(p->p_thread);
- splx(s);
+ crit_exit();
if (p->p_slptime > 1)
updatepri(p);
p->p_slptime = 0;
}
}
-static
-void
-crit_panicints(void)
-{
- int s;
- int cpri;
-
- s = splhigh();
- cpri = crit_panic_save();
- splx(safepri);
- crit_panic_restore(cpri);
- splx(s);
-}
-
*
* From: @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/kern_timeout.c,v 1.59.2.1 2001/11/13 18:24:52 archie Exp $
- * $DragonFly: src/sys/kern/kern_timeout.c,v 1.15 2005/06/03 23:57:32 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_timeout.c,v 1.16 2005/06/06 15:02:28 dillon Exp $
*/
/*
* DRAGONFLY BGL STATUS
{
struct callout *p;
unsigned long delta_ticks;
- int s;
/*
* How many ticks were we asleep?
*/
/* don't collide with softclock() */
- s = splhigh();
+ crit_enter();
for (p = calltodo.c_next; p != NULL; p = p->c_next) {
p->c_time -= delta_ticks;
/* take back the ticks the timer didn't use (p->c_time <= 0) */
delta_ticks = -p->c_time;
}
- splx(s);
+ crit_exit();
return;
}
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $DragonFly: src/sys/kern/kern_xio.c,v 1.9 2005/03/02 18:42:08 hmp Exp $
+ * $DragonFly: src/sys/kern/kern_xio.c,v 1.10 2005/06/06 15:02:28 dillon Exp $
*/
/*
* Kernel XIO interface. An initialized XIO is basically a collection of
vm_page_t m;
int i;
int n;
- int s;
int vmprot;
addr = trunc_page((vm_offset_t)ubase);
break;
if ((paddr = pmap_kextract(addr)) == 0)
break;
- s = splvm();
+ crit_enter();
m = PHYS_TO_VM_PAGE(paddr);
vm_page_hold(m);
- splx(s);
+ crit_exit();
xio->xio_pages[i] = m;
ubytes -= n;
xio->xio_bytes += n;
vm_page_t m;
int i;
int n;
- int s;
addr = trunc_page((vm_offset_t)kbase);
xio->xio_flags = 0;
for (i = 0; n && i < XIO_INTERNAL_PAGES; ++i) {
if ((paddr = pmap_kextract(addr)) == 0)
break;
- s = splvm();
+ crit_enter();
m = PHYS_TO_VM_PAGE(paddr);
vm_page_hold(m);
- splx(s);
+ crit_exit();
xio->xio_pages[i] = m;
kbytes -= n;
xio->xio_bytes += n;
xio_release(xio_t xio)
{
int i;
- int s;
vm_page_t m;
- s = splvm();
+ crit_enter();
for (i = 0; i < xio->xio_npages; ++i) {
m = xio->xio_pages[i];
vm_page_unhold(m);
}
- splx(s);
+ crit_exit();
xio->xio_offset = 0;
xio->xio_npages = 0;
xio->xio_bytes = 0;
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
* $FreeBSD: src/sys/kern/subr_diskslice.c,v 1.82.2.6 2001/07/24 09:49:41 dd Exp $
- * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.9 2005/04/30 23:04:21 swildner Exp $
+ * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.10 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
#include <sys/syslog.h>
#include <sys/vnode.h>
#include <sys/device.h>
+#include <sys/thread2.h>
#include <vfs/ufs/fs.h>
daddr_t secno;
daddr_t slicerel_secno;
struct diskslice *sp;
- int s;
blkno = bp->b_blkno;
if (blkno < 0) {
* temporarily corrupting the in-core copy.
*/
if (bp->b_vp != NULL) {
- s = splbio();
+ crit_enter();
bp->b_vp->v_numoutput++;
- splx(s);
+ crit_exit();
}
/* XXX need name here. */
msg = fixlabel((char *)NULL, sp,
*
* @(#)subr_log.c 8.1 (Berkeley) 6/10/93
* $FreeBSD: src/sys/kern/subr_log.c,v 1.39.2.2 2001/06/02 08:11:25 phk Exp $
- * $DragonFly: src/sys/kern/subr_log.c,v 1.7 2004/05/19 22:52:58 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_log.c,v 1.8 2005/06/06 15:02:28 dillon Exp $
*/
/*
#include <sys/poll.h>
#include <sys/filedesc.h>
#include <sys/sysctl.h>
+#include <sys/thread2.h>
#define LOG_ASYNC 0x04
#define LOG_RDWAIT 0x08
{
struct msgbuf *mbp = msgbufp;
long l;
- int s;
int error = 0;
- s = splhigh();
+ crit_enter();
while (mbp->msg_bufr == mbp->msg_bufx) {
if (flag & IO_NDELAY) {
- splx(s);
+ crit_exit();
return (EWOULDBLOCK);
}
logsoftc.sc_state |= LOG_RDWAIT;
if ((error = tsleep((caddr_t)mbp, PCATCH, "klog", 0))) {
- splx(s);
+ crit_exit();
return (error);
}
}
- splx(s);
+ crit_exit();
logsoftc.sc_state &= ~LOG_RDWAIT;
while (uio->uio_resid > 0) {
static int
logpoll(dev_t dev, int events, struct thread *td)
{
- int s;
int revents = 0;
- s = splhigh();
-
+ crit_enter();
if (events & (POLLIN | POLLRDNORM)) {
if (msgbufp->msg_bufr != msgbufp->msg_bufx)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(td, &logsoftc.sc_selp);
}
- splx(s);
+ crit_exit();
return (revents);
}
logioctl(dev_t dev, u_long com, caddr_t data, int flag, struct thread *td)
{
long l;
- int s;
switch (com) {
/* return number of characters immediately available */
case FIONREAD:
- s = splhigh();
+ crit_enter();
l = msgbufp->msg_bufx - msgbufp->msg_bufr;
- splx(s);
+ crit_exit();
if (l < 0)
l += msgbufp->msg_size;
*(int *)data = l;
*
* @(#)subr_prof.c 8.3 (Berkeley) 9/23/93
* $FreeBSD: src/sys/kern/subr_prof.c,v 1.32.2.2 2000/08/03 00:09:32 ps Exp $
- * $DragonFly: src/sys/kern/subr_prof.c,v 1.9 2004/06/01 22:19:30 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_prof.c,v 1.10 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/sysctl.h>
+#include <sys/thread2.h>
#include <machine/ipl.h>
#include <machine/cpu.h>
{
struct proc *p = curproc;
struct uprof *upp;
- int s;
if (uap->scale > (1 << 16))
return (EINVAL);
upp = &p->p_stats->p_prof;
/* Block profile interrupts while changing state. */
- s = splstatclock();
+ crit_enter();
upp->pr_off = uap->offset;
upp->pr_scale = uap->scale;
upp->pr_base = uap->samples;
upp->pr_size = uap->size;
startprofclock(p);
- splx(s);
+ crit_exit();
return (0);
}
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/subr_rman.c,v 1.10.2.1 2001/06/05 08:06:08 imp Exp $
- * $DragonFly: src/sys/kern/subr_rman.c,v 1.6 2004/03/01 06:33:17 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_rman.c,v 1.7 2005/06/06 15:02:28 dillon Exp $
*/
/*
int
rman_await_resource(struct resource *r, lwkt_tokref_t ilock, int slpflags, int timo)
{
- int rv, s;
+ int rv;
struct resource *whohas;
struct rman *rm;
if (r->r_sharehead == 0)
panic("rman_await_resource");
/*
- * splhigh hopefully will prevent a race between
- * lwkt_reltoken and tsleep where a process
+ * A critical section will hopefully will prevent a race
+ * between lwkt_reltoken and tsleep where a process
* could conceivably get in and release the resource
* before we have a chance to sleep on it. YYY
*/
- s = splhigh();
+ crit_enter();
whohas->r_flags |= RF_WANTED;
rv = tsleep(r->r_sharehead, slpflags, "rmwait", timo);
if (rv) {
lwkt_reltoken(ilock);
- splx(s);
+ crit_exit();
return rv;
}
- splx(s);
+ crit_exit();
}
}
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/subr_taskqueue.c,v 1.1.2.3 2003/09/10 00:40:39 ken Exp $
- * $DragonFly: src/sys/kern/subr_taskqueue.c,v 1.5 2005/02/01 22:41:26 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_taskqueue.c,v 1.6 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
#include <sys/interrupt.h>
#include <sys/malloc.h>
#include <sys/kthread.h>
+#include <sys/thread2.h>
#include <machine/ipl.h>
{
struct taskqueue *queue;
static int once = 1;
- int s;
queue = malloc(sizeof(struct taskqueue), M_TASKQUEUE, mflags);
if (!queue)
queue->tq_context = context;
queue->tq_draining = 0;
- s = splhigh();
+ crit_enter();
if (once) {
STAILQ_INIT(&taskqueue_queues);
once = 0;
}
STAILQ_INSERT_TAIL(&taskqueue_queues, queue, tq_link);
- splx(s);
+ crit_exit();
return queue;
}
void
taskqueue_free(struct taskqueue *queue)
{
- int s = splhigh();
+ crit_enter();
queue->tq_draining = 1;
- splx(s);
+ crit_exit();
taskqueue_run(queue);
- s = splhigh();
+ crit_enter();
STAILQ_REMOVE(&taskqueue_queues, queue, taskqueue, tq_link);
- splx(s);
+ crit_exit();
free(queue, M_TASKQUEUE);
}
taskqueue_find(const char *name)
{
struct taskqueue *queue;
- int s;
- s = splhigh();
- STAILQ_FOREACH(queue, &taskqueue_queues, tq_link)
+ crit_enter();
+ STAILQ_FOREACH(queue, &taskqueue_queues, tq_link) {
if (!strcmp(queue->tq_name, name)) {
- splx(s);
+ crit_exit();
return queue;
}
- splx(s);
+ }
+ crit_exit();
return 0;
}
struct task *ins;
struct task *prev;
- int s = splhigh();
+ crit_enter();
/*
* Don't allow new tasks on a queue which is being freed.
*/
if (queue->tq_draining) {
- splx(s);
+ crit_exit();
return EPIPE;
}
*/
if (task->ta_pending) {
task->ta_pending++;
- splx(s);
+ crit_exit();
return 0;
}
if (queue->tq_enqueue)
queue->tq_enqueue(queue->tq_context);
- splx(s);
+ crit_exit();
return 0;
}
void
taskqueue_run(struct taskqueue *queue)
{
- int s;
struct task *task;
int pending;
- s = splhigh();
+ crit_enter();
while (STAILQ_FIRST(&queue->tq_queue)) {
/*
* Carefully remove the first task from the queue and
STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link);
pending = task->ta_pending;
task->ta_pending = 0;
- splx(s);
+ crit_exit();
task->ta_func(task->ta_context, pending);
- s = splhigh();
+ crit_enter();
}
- splx(s);
+ crit_exit();
}
static void
static void
taskqueue_kthread(void *arg)
{
- int s;
-
for (;;) {
taskqueue_run(taskqueue_thread);
- s = splhigh();
+ crit_enter();
if (STAILQ_EMPTY(&taskqueue_thread->tq_queue))
tsleep(&taskqueue_thread, 0, "tqthr", 0);
- splx(s);
+ crit_exit();
}
}
*
* @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/sys_generic.c,v 1.55.2.10 2001/03/17 10:39:32 peter Exp $
- * $DragonFly: src/sys/kern/sys_generic.c,v 1.20 2005/03/29 00:35:55 drhodus Exp $
+ * $DragonFly: src/sys/kern/sys_generic.c,v 1.21 2005/06/06 15:02:28 dillon Exp $
*/
#include "opt_ktrace.h"
fd_mask s_selbits[howmany(2048, NFDBITS)];
fd_mask *ibits[3], *obits[3], *selbits, *sbp;
struct timeval atv, rtv, ttv;
- int s, ncoll, error, timo;
+ int ncoll, error, timo;
u_int nbufbytes, ncpbytes, nfdbits;
if (uap->nd < 0)
timo = ttv.tv_sec > 24 * 60 * 60 ?
24 * 60 * 60 * hz : tvtohz_high(&ttv);
}
- s = splhigh();
+ crit_enter();
if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
- splx(s);
+ crit_exit();
goto retry;
}
p->p_flag &= ~P_SELECT;
error = tsleep((caddr_t)&selwait, PCATCH, "select", timo);
- splx(s);
+ crit_exit();
if (error == 0)
goto retry;
done:
struct pollfd *bits;
struct pollfd smallbits[32];
struct timeval atv, rtv, ttv;
- int s, ncoll, error = 0, timo;
+ int ncoll, error = 0, timo;
u_int nfds;
size_t ni;
struct proc *p = curproc;
timo = ttv.tv_sec > 24 * 60 * 60 ?
24 * 60 * 60 * hz : tvtohz_high(&ttv);
}
- s = splhigh();
+ crit_enter();
if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
- splx(s);
+ crit_exit();
goto retry;
}
p->p_flag &= ~P_SELECT;
error = tsleep((caddr_t)&selwait, PCATCH, "poll", timo);
- splx(s);
+ crit_exit();
if (error == 0)
goto retry;
done:
selwakeup(struct selinfo *sip)
{
struct proc *p;
- int s;
if (sip->si_pid == 0)
return;
p = pfind(sip->si_pid);
sip->si_pid = 0;
if (p != NULL) {
- s = splhigh();
+ crit_enter();
if (p->p_wchan == (caddr_t)&selwait) {
if (p->p_stat == SSLEEP)
setrunnable(p);
unsleep(p->p_thread);
} else if (p->p_flag & P_SELECT)
p->p_flag &= ~P_SELECT;
- splx(s);
+ crit_exit();
}
}
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/sys_process.c,v 1.51.2.6 2003/01/08 03:06:45 kan Exp $
- * $DragonFly: src/sys/kern/sys_process.c,v 1.14 2003/10/15 21:52:38 dillon Exp $
+ * $DragonFly: src/sys/kern/sys_process.c,v 1.15 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
sendsig:
/* deliver or queue signal */
- s = splhigh();
+ crit_enter();
if (p->p_stat == SSTOP) {
p->p_xstat = data;
setrunnable(p);
} else if (data) {
psignal(p, data);
}
- splx(s);
+ crit_exit();
return 0;
case PT_WRITE_I:
*
* @(#)tty.c 8.8 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/tty.c,v 1.129.2.5 2002/03/11 01:32:31 dd Exp $
- * $DragonFly: src/sys/kern/tty.c,v 1.16 2004/12/29 02:40:52 dillon Exp $
+ * $DragonFly: src/sys/kern/tty.c,v 1.17 2005/06/06 15:02:28 dillon Exp $
*/
/*-
dev_t device;
struct tty *tp;
{
- int s;
-
- s = spltty();
+ crit_enter();
tp->t_dev = device;
if (!ISSET(tp->t_state, TS_ISOPEN)) {
SET(tp->t_state, TS_ISOPEN);
bzero(&tp->t_winsize, sizeof(tp->t_winsize));
}
ttsetwater(tp);
- splx(s);
+ crit_exit();
return (0);
}
ttyclose(tp)
struct tty *tp;
{
- int s;
-
funsetown(tp->t_sigio);
- s = spltty();
+ crit_enter();
if (constty == tp)
constty = NULL;
tp->t_line = TTYDISC;
ttyclearsession(tp);
tp->t_state = 0;
- splx(s);
+ crit_exit();
return (0);
}
struct tty *tp;
{
tcflag_t oflag;
- int col, s;
+ int col;
oflag = tp->t_oflag;
if (!ISSET(oflag, OPOST)) {
ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
c = 8 - (tp->t_column & 7);
if (!ISSET(tp->t_lflag, FLUSHO)) {
- s = spltty(); /* Don't interrupt tabs. */
+ crit_enter(); /* Don't interrupt tabs. */
c -= b_to_q(" ", c, &tp->t_outq);
tk_nout += c;
tp->t_outcc += c;
- splx(s);
+ crit_exit();
}
tp->t_column += c;
return (c ? -1 : '\t');
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
- int s, error;
+ int error;
KKASSERT(p);
switch (cmd) { /* Process the ioctl. */
case FIOASYNC: /* set/clear async i/o */
- s = spltty();
+ crit_enter();
if (*(int *)data)
SET(tp->t_state, TS_ASYNC);
else
CLR(tp->t_state, TS_ASYNC);
- splx(s);
+ crit_exit();
break;
case FIONBIO: /* set/clear non-blocking i/o */
break; /* XXX: delete. */
case FIONREAD: /* get # bytes to read */
- s = spltty();
+ crit_enter();
*(int *)data = ttnread(tp);
- splx(s);
+ crit_exit();
break;
case FIOSETOWN:
break;
case TIOCEXCL: /* set exclusive use of tty */
- s = spltty();
+ crit_enter();
SET(tp->t_state, TS_XCLUDE);
- splx(s);
+ crit_exit();
break;
case TIOCFLUSH: { /* flush buffers */
int flags = *(int *)data;
break;
#ifdef TIOCHPCL
case TIOCHPCL: /* hang up on last close */
- s = spltty();
+ crit_enter();
SET(tp->t_cflag, HUPCL);
- splx(s);
+ crit_exit();
break;
#endif
case TIOCNXCL: /* reset exclusive use of tty */
- s = spltty();
+ crit_enter();
CLR(tp->t_state, TS_XCLUDE);
- splx(s);
+ crit_exit();
break;
case TIOCOUTQ: /* output queue size */
*(int *)data = tp->t_outq.c_cc;
t->c_ispeed = tp->t_ospeed;
if (t->c_ispeed == 0)
return (EINVAL);
- s = spltty();
+ crit_enter();
if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
error = ttywait(tp);
if (error) {
- splx(s);
+ crit_exit();
return (error);
}
if (cmd == TIOCSETAF)
* Set device hardware.
*/
if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
- splx(s);
+ crit_exit();
return (error);
}
if (ISSET(t->c_cflag, CLOCAL) &&
t->c_cc[VTIME] != tp->t_cc[VTIME])
ttwakeup(tp);
bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
- splx(s);
+ crit_exit();
break;
}
case TIOCSETD: { /* set line discipline */
if ((u_int)t >= nlinesw)
return (ENXIO);
if (t != tp->t_line) {
- s = spltty();
+ crit_enter();
(*linesw[tp->t_line].l_close)(tp, flag);
error = (*linesw[t].l_open)(device, tp);
if (error) {
(void)(*linesw[tp->t_line].l_open)(device, tp);
- splx(s);
+ crit_exit();
return (error);
}
tp->t_line = t;
- splx(s);
+ crit_exit();
}
break;
}
case TIOCSTART: /* start output, like ^Q */
- s = spltty();
+ crit_enter();
if (ISSET(tp->t_state, TS_TTSTOP) ||
ISSET(tp->t_lflag, FLUSHO)) {
CLR(tp->t_lflag, FLUSHO);
CLR(tp->t_state, TS_TTSTOP);
ttstart(tp);
}
- splx(s);
+ crit_exit();
break;
case TIOCSTI: /* simulate terminal input */
if ((flag & FREAD) == 0 && suser(td))
return (EPERM);
if (!isctty(p, tp) && suser(td))
return (EACCES);
- s = spltty();
+ crit_enter();
(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
- splx(s);
+ crit_exit();
break;
case TIOCSTOP: /* stop output, like ^S */
- s = spltty();
+ crit_enter();
if (!ISSET(tp->t_state, TS_TTSTOP)) {
SET(tp->t_state, TS_TTSTOP);
(*tp->t_stop)(tp, 0);
}
- splx(s);
+ crit_exit();
break;
case TIOCSCTTY: /* become controlling tty */
/* Session ctty vnode pointer set in vnode layer. */
break;
}
case TIOCSTAT: /* simulate control-T */
- s = spltty();
+ crit_enter();
ttyinfo(tp);
- splx(s);
+ crit_exit();
break;
case TIOCSWINSZ: /* set window size */
if (bcmp((caddr_t)&tp->t_winsize, data,
int events;
struct thread *td;
{
- int s;
int revents = 0;
struct tty *tp;
return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM))
| POLLHUP);
- s = spltty();
+ crit_enter();
if (events & (POLLIN | POLLRDNORM)) {
if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(td, &tp->t_wsel);
}
- splx(s);
+ crit_exit();
return (revents);
}
{
struct tty *tp = dev->si_tty;
struct klist *klist;
- int s;
switch (kn->kn_filter) {
case EVFILT_READ:
kn->kn_hook = (caddr_t)dev;
- s = spltty();
+ crit_enter();
SLIST_INSERT_HEAD(klist, kn, kn_selnext);
- splx(s);
+ crit_exit();
return (0);
}
filt_ttyrdetach(struct knote *kn)
{
struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
- int s = spltty();
+ crit_enter();
SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext);
- splx(s);
+ crit_exit();
}
static int
filt_ttywdetach(struct knote *kn)
{
struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
- int s = spltty();
+ crit_enter();
SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext);
- splx(s);
+ crit_exit();
}
static int
}
/*
- * Must be called at spltty().
+ * Must be called while in a critical section.
*/
static int
ttnread(tp)
ttywait(tp)
struct tty *tp;
{
- int error, s;
+ int error;
error = 0;
- s = spltty();
+ crit_enter();
while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
(*tp->t_oproc)(tp);
}
if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
error = EIO;
- splx(s);
+ crit_exit();
return (error);
}
struct tty *tp;
int rw;
{
- int s;
-
- s = spltty();
+ crit_enter();
#if 0
again:
#endif
FLUSHQ(&tp->t_outq);
ttwwakeup(tp);
}
- splx(s);
+ crit_exit();
}
/*
void *tp_arg;
{
struct tty *tp;
- int s;
KASSERT(tp_arg != NULL, ("ttrstrt"));
tp = tp_arg;
- s = spltty();
-
+ crit_enter();
CLR(tp->t_state, TS_TIMEOUT);
ttstart(tp);
-
- splx(s);
+ crit_exit();
}
#endif
/*
* Reinput pending characters after state switch
- * call at spltty().
+ * call from a critical section.
*/
static void
ttypend(tp)
tcflag_t lflag;
cc_t *cc = tp->t_cc;
struct proc *pp;
- int s, first, error = 0;
+ int first, error = 0;
int has_stime = 0, last_cc = 0;
long slp = 0; /* XXX this should be renamed `timo'. */
struct timeval stime;
loop:
- s = spltty();
+ crit_enter();
lflag = tp->t_lflag;
/*
* take pending input first
*/
if (ISSET(lflag, PENDIN)) {
ttypend(tp);
- splx(s); /* reduce latency */
- s = spltty();
+ splz(); /* reduce latency */
lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
}
* Hang process if it's in the background.
*/
if ((pp = curproc) && isbackground(pp, tp)) {
- splx(s);
+ crit_exit();
if (SIGISMEMBER(pp->p_sigignore, SIGTTIN) ||
SIGISMEMBER(pp->p_sigmask, SIGTTIN) ||
(pp->p_flag & P_PPWAIT) || pp->p_pgrp->pg_jobc == 0)
}
if (ISSET(tp->t_state, TS_ZOMBIE)) {
- splx(s);
+ crit_exit();
return (0); /* EOF */
}
if (qp->c_cc > 0)
goto read;
if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
- splx(s);
+ crit_exit();
return (0);
}
- splx(s);
+ crit_exit();
return (EWOULDBLOCK);
}
if (!ISSET(lflag, ICANON)) {
goto read;
/* m, t and qp->c_cc are all 0. 0 is enough input. */
- splx(s);
+ crit_exit();
return (0);
}
t *= 100000; /* time in us */
slp = t - diff(timecopy, stime);
if (slp <= 0) {
/* Timed out, but 0 is enough input. */
- splx(s);
+ crit_exit();
return (0);
}
}
error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), PCATCH,
ISSET(tp->t_state, TS_CONNECTED) ?
"ttyin" : "ttyhup", (int)slp);
- splx(s);
+ crit_exit();
if (error == EWOULDBLOCK)
error = 0;
else if (error)
goto loop;
}
read:
- splx(s);
+ crit_exit();
/*
* Input present, check for input mapping and processing.
*/
* Look to unblock input now that (presumably)
* the input queue has gone down.
*/
- s = spltty();
+ crit_enter();
if (ISSET(tp->t_state, TS_TBLOCK) &&
tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
ttyunblock(tp);
- splx(s);
+ crit_exit();
return (error);
}
struct tty *tp;
int wait;
{
- int hiwat, s;
+ int hiwat;
sigset_t oldmask;
hiwat = tp->t_ohiwat;
SIGEMPTYSET(oldmask);
- s = spltty();
+ crit_enter();
if (wait)
oldmask = curproc->p_siglist;
- if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
+ if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) {
while (tp->t_outq.c_cc > hiwat) {
ttstart(tp);
if (tp->t_outq.c_cc <= hiwat)
break;
if (!(wait && SIGSETEQ(curproc->p_siglist, oldmask))) {
- splx(s);
+ crit_exit();
return (0);
}
SET(tp->t_state, TS_SO_OLOWAT);
tsleep(TSA_OLOWAT(tp), 0, "ttoutq", hz);
}
- splx(s);
+ }
+ crit_exit();
return (1);
}
char *cp = NULL;
int cc, ce;
struct proc *pp;
- int i, hiwat, cnt, error, s;
+ int i, hiwat, cnt, error;
char obuf[OBUFSIZ];
hiwat = tp->t_ohiwat;
error = 0;
cc = 0;
loop:
- s = spltty();
+ crit_enter();
if (ISSET(tp->t_state, TS_ZOMBIE)) {
- splx(s);
+ crit_exit();
if (uio->uio_resid == cnt)
error = EIO;
goto out;
}
if (!ISSET(tp->t_state, TS_CONNECTED)) {
if (flag & IO_NDELAY) {
- splx(s);
+ crit_exit();
error = EWOULDBLOCK;
goto out;
}
error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ttydcd", 0);
- splx(s);
+ crit_exit();
if (error)
goto out;
goto loop;
}
- splx(s);
+ crit_exit();
/*
* Hang the process if it's in the background.
ovhiwat:
ttstart(tp);
- s = spltty();
+ crit_enter();
/*
* This can only occur if FLUSHO is set in t_lflag,
* or if ttstart/oproc is synchronous (or very fast).
*/
if (tp->t_outq.c_cc <= hiwat) {
- splx(s);
+ crit_exit();
goto loop;
}
if (flag & IO_NDELAY) {
- splx(s);
+ crit_exit();
uio->uio_resid += cc;
return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
}
SET(tp->t_state, TS_SO_OLOWAT);
error = ttysleep(tp, TSA_OLOWAT(tp), PCATCH, "ttywri", tp->t_timeout);
- splx(s);
+ crit_exit();
if (error == EWOULDBLOCK)
error = EIO;
if (error)
{
char *cp;
int savecol;
- int tabc, s;
+ int tabc;
if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
return;
ttyretype(tp);
return;
}
- s = spltty();
+ crit_enter();
savecol = tp->t_column;
SET(tp->t_state, TS_CNTTB);
SET(tp->t_lflag, FLUSHO);
ttyecho(tabc, tp);
CLR(tp->t_lflag, FLUSHO);
CLR(tp->t_state, TS_CNTTB);
- splx(s);
+ crit_exit();
/* savecol will now be length of the tab. */
savecol -= tp->t_column;
struct tty *tp;
{
char *cp;
- int s, c;
+ int c;
/* Echo the reprint character. */
if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
* FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
* BIT OF FIRST CHAR.
*/
- s = spltty();
+ crit_enter();
for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
ttyecho(c, tp);
cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
ttyecho(c, tp);
CLR(tp->t_state, TS_ERASE);
- splx(s);
+ crit_exit();
tp->t_rocount = tp->t_rawq.c_cc;
tp->t_rocol = 0;
int c;
struct tty *tp;
{
- int s;
-
- s = spltty();
+ crit_enter();
if (!ISSET(tp->t_state, TS_CONNECTED)) {
- splx(s);
+ crit_exit();
return (-1);
}
if (c == '\n')
(void)ttyoutput('\r', tp);
(void)ttyoutput(c, tp);
ttstart(tp);
- splx(s);
+ crit_exit();
return (0);
}
*
* @(#)tty_pty.c 8.4 (Berkeley) 2/20/95
* $FreeBSD: src/sys/kern/tty_pty.c,v 1.74.2.4 2002/02/20 19:58:13 dillon Exp $
- * $DragonFly: src/sys/kern/tty_pty.c,v 1.12 2004/05/19 22:52:58 dillon Exp $
+ * $DragonFly: src/sys/kern/tty_pty.c,v 1.13 2005/06/06 15:02:28 dillon Exp $
*/
/*
#include <sys/signalvar.h>
#include <sys/malloc.h>
#include <sys/device.h>
+#include <sys/thread2.h>
MALLOC_DEFINE(M_PTY, "ptys", "pty data structures");
struct tty *tp = dev->si_tty;
struct pt_ioctl *pti = dev->si_drv1;
int revents = 0;
- int s;
if ((tp->t_state & TS_CONNECTED) == 0)
return (seltrue(dev, events, td) | POLLHUP);
/*
* Need to block timeouts (ttrstart).
*/
- s = spltty();
+ crit_enter();
if (events & (POLLIN | POLLRDNORM))
if ((tp->t_state & TS_ISOPEN) &&
if (events & (POLLOUT | POLLWRNORM))
selrecord(td, &pti->pt_selw);
}
- splx(s);
+ crit_exit();
return (revents);
}
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/uipc_accf.c,v 1.2.2.2 2000/09/20 21:19:21 ps Exp $
- * $DragonFly: src/sys/kern/uipc_accf.c,v 1.2 2003/06/17 04:28:41 dillon Exp $
+ * $DragonFly: src/sys/kern/uipc_accf.c,v 1.3 2005/06/06 15:02:28 dillon Exp $
*/
#define ACCEPT_FILTER_MOD
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/queue.h>
+#include <sys/thread2.h>
static SLIST_HEAD(, accept_filter) accept_filtlsthd =
SLIST_HEAD_INITIALIZER(&accept_filtlsthd);
{
struct accept_filter *p;
struct accept_filter *accfp = (struct accept_filter *) data;
- int s, error;
+ int error;
switch (event) {
case MOD_LOAD:
MALLOC(p, struct accept_filter *, sizeof(*p), M_ACCF, M_WAITOK);
bcopy(accfp, p, sizeof(*p));
- s = splnet();
+ crit_enter();
error = accept_filt_add(p);
- splx(s);
+ crit_exit();
break;
case MOD_UNLOAD:
* in the struct accept_filter.
*/
if (unloadable != 0) {
- s = splnet();
+ crit_enter();
error = accept_filt_del(accfp->accf_name);
- splx(s);
+ crit_exit();
} else
error = EOPNOTSUPP;
break;
*
* @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
* $FreeBSD: src/sys/kern/uipc_domain.c,v 1.22.2.1 2001/07/03 11:01:37 ume Exp $
- * $DragonFly: src/sys/kern/uipc_domain.c,v 1.8 2005/03/04 02:21:48 hsu Exp $
+ * $DragonFly: src/sys/kern/uipc_domain.c,v 1.9 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <vm/vm_zone.h>
+#include <sys/thread2.h>
+
/*
* System initialization
*
net_init_domain(struct domain *dp)
{
struct protosw *pr;
- int s;
- s = splnet();
+ crit_enter();
if (dp->dom_init)
(*dp->dom_init)();
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
*/
max_hdr = max_linkhdr + max_protohdr;
max_datalen = MHLEN - max_hdr;
- splx(s);
+ crit_exit();
}
/*
net_add_domain(void *data)
{
struct domain *dp = data;
- int s;
- s = splnet();
+ crit_enter();
SLIST_INSERT_HEAD(&domains, dp, dom_next);
- splx(s);
+ crit_exit();
net_init_domain(dp);
}
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
* $FreeBSD: src/sys/kern/uipc_socket.c,v 1.68.2.24 2003/11/11 17:18:18 silby Exp $
- * $DragonFly: src/sys/kern/uipc_socket.c,v 1.31 2005/05/29 16:32:20 hsu Exp $
+ * $DragonFly: src/sys/kern/uipc_socket.c,v 1.32 2005/06/06 15:02:28 dillon Exp $
*/
#include "opt_inet.h"
#include <sys/jail.h>
#include <vm/vm_zone.h>
+#include <sys/thread2.h>
+
#include <machine/limits.h>
#ifdef INET
int
sobind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
- int s = splnet();
int error;
+ crit_enter();
error = so_pru_bind(so, nam, td);
- splx(s);
+ crit_exit();
return (error);
}
int
solisten(struct socket *so, int backlog, struct thread *td)
{
- int s, error;
+ int error;
- s = splnet();
+ crit_enter();
if (so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING)) {
- splx(s);
+ crit_exit();
return (EINVAL);
}
error = so_pru_listen(so, td);
if (error) {
- splx(s);
+ crit_exit();
return (error);
}
if (TAILQ_EMPTY(&so->so_comp))
if (backlog < 0 || backlog > somaxconn)
backlog = somaxconn;
so->so_qlimit = backlog;
- splx(s);
+ crit_exit();
return (0);
}
int
soclose(struct socket *so)
{
- int s = splnet(); /* conservative */
int error = 0;
+ crit_enter();
funsetown(so->so_sigio);
if (so->so_pcb == NULL)
goto discard;
panic("soclose: NOFDREF");
so->so_state |= SS_NOFDREF;
sofree(so);
- splx(s);
+ crit_exit();
return (error);
}
/*
- * Must be called at splnet...
+ * Must be called from a critical section.
*/
int
soabort(so)
int
soaccept(struct socket *so, struct sockaddr **nam)
{
- int s = splnet();
int error;
+ crit_enter();
if ((so->so_state & SS_NOFDREF) == 0)
panic("soaccept: !NOFDREF");
so->so_state &= ~SS_NOFDREF;
error = so_pru_accept(so, nam);
- splx(s);
+ crit_exit();
return (error);
}
int
soconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
- int s;
int error;
if (so->so_options & SO_ACCEPTCONN)
return (EOPNOTSUPP);
- s = splnet();
+ crit_enter();
/*
* If protocol is connection-based, can only connect once.
* Otherwise, if connected, try to disconnect first.
so->so_error = 0;
error = so_pru_connect(so, nam, td);
}
- splx(s);
+ crit_exit();
return (error);
}
int
soconnect2(struct socket *so1, struct socket *so2)
{
- int s = splnet();
int error;
+ crit_enter();
error = so_pru_connect2(so1, so2);
- splx(s);
+ crit_exit();
return (error);
}
int
sodisconnect(struct socket *so)
{
- int s = splnet();
int error;
+ crit_enter();
if ((so->so_state & SS_ISCONNECTED) == 0) {
error = ENOTCONN;
goto bad;
}
error = so_pru_disconnect(so);
bad:
- splx(s);
+ crit_exit();
return (error);
}
struct mbuf **mp;
struct mbuf *m;
long space, len, resid;
- int clen = 0, error, s, dontroute, mlen;
+ int clen = 0, error, dontroute, mlen;
int atomic = sosendallatonce(so) || top;
int pru_flags;
td->td_proc->p_stats->p_ru.ru_msgsnd++;
if (control)
clen = control->m_len;
-#define gotoerr(errno) { error = errno; splx(s); goto release; }
+#define gotoerr(errno) { error = errno; crit_exit(); goto release; }
restart:
error = sblock(&so->so_snd, SBLOCKWAIT(flags));
if (error)
goto out;
do {
- s = splnet();
+ crit_enter();
if (so->so_state & SS_CANTSENDMORE)
gotoerr(EPIPE);
if (so->so_error) {
error = so->so_error;
so->so_error = 0;
- splx(s);
+ crit_exit();
goto release;
}
if ((so->so_state & SS_ISCONNECTED) == 0) {
gotoerr(EWOULDBLOCK);
sbunlock(&so->so_snd);
error = sbwait(&so->so_snd);
- splx(s);
+ crit_exit();
if (error)
goto out;
goto restart;
}
- splx(s);
+ crit_exit();
mp = ⊤
space -= clen;
do {
} else {
pru_flags = 0;
}
- s = splnet(); /* XXX */
+ crit_enter();
/*
* XXX all the SS_CANTSENDMORE checks previously
* done could be out of date. We could have recieved
* also happens. We must rethink this.
*/
error = so_pru_send(so, pru_flags, top, addr, control, td);
- splx(s);
+ crit_exit();
if (dontroute)
so->so_options &= ~SO_DONTROUTE;
clen = 0;
sosendudp(struct socket *so, struct sockaddr *addr, struct uio *uio,
struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
{
- int resid, error, s;
+ int resid, error;
boolean_t dontroute; /* temporary SO_DONTROUTE setting */
if (td->td_proc && td->td_proc->p_stats)
if (error)
goto out;
- s = splnet();
+ crit_enter();
if (so->so_state & SS_CANTSENDMORE)
gotoerr(EPIPE);
if (so->so_error) {
error = so->so_error;
so->so_error = 0;
- splx(s);
+ crit_exit();
goto release;
}
if (!(so->so_state & SS_ISCONNECTED) && addr == NULL)
gotoerr(EWOULDBLOCK);
sbunlock(&so->so_snd);
error = sbwait(&so->so_snd);
- splx(s);
+ crit_exit();
if (error)
goto out;
goto restart;
}
- splx(s);
+ crit_exit();
if (uio) {
top = m_uiomove(uio);
* followed by an optional mbuf or mbufs containing ancillary data,
* and then zero or more mbufs of data.
* In order to avoid blocking network interrupts for the entire time here,
- * we splx() while doing the actual copy to user space.
+ * we exit the critical section while doing the actual copy to user space.
* Although the sockbuf is locked, new data may still be appended,
* and thus we must maintain consistency of the sockbuf during that time.
*
int *flagsp;
{
struct mbuf *m, **mp;
- int flags, len, error, s, offset;
+ int flags, len, error, offset;
struct protosw *pr = so->so_proto;
struct mbuf *nextrecord;
int moff, type = 0;
error = sblock(&so->so_rcv, SBLOCKWAIT(flags));
if (error)
return (error);
- s = splnet();
+ crit_enter();
m = so->so_rcv.sb_mb;
/*
}
sbunlock(&so->so_rcv);
error = sbwait(&so->so_rcv);
- splx(s);
+ crit_exit();
if (error)
return (error);
goto restart;
* block interrupts again.
*/
if (mp == 0) {
- splx(s);
+ crit_exit();
error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);
- s = splnet();
+ crit_enter();
if (error)
goto release;
} else
error = sbwait(&so->so_rcv);
if (error) {
sbunlock(&so->so_rcv);
- splx(s);
+ crit_exit();
return (0);
}
m = so->so_rcv.sb_mb;
if (orig_resid == uio->uio_resid && orig_resid &&
(flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
sbunlock(&so->so_rcv);
- splx(s);
+ crit_exit();
goto restart;
}
*flagsp |= flags;
release:
sbunlock(&so->so_rcv);
- splx(s);
+ crit_exit();
return (error);
}
{
struct sockbuf *sb = &so->so_rcv;
struct protosw *pr = so->so_proto;
- int s;
struct sockbuf asb;
sb->sb_flags |= SB_NOINTR;
(void) sblock(sb, M_WAITOK);
- s = splimp();
+
+ crit_enter();
socantrcvmore(so);
sbunlock(sb);
asb = *sb;
sb->sb_sel.si_note = asb.sb_sel.si_note;
sb->sb_flags = SB_KNOTE;
}
- splx(s);
+ crit_exit();
+
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
(*pr->pr_domain->dom_dispose)(asb.sb_mb);
sbrelease(&asb, so);
sopoll(struct socket *so, int events, struct ucred *cred, struct thread *td)
{
int revents = 0;
- int s = splnet();
+
+ crit_enter();
if (events & (POLLIN | POLLRDNORM))
if (soreadable(so))
}
}
- splx(s);
+ crit_exit();
return (revents);
}
{
struct socket *so = (struct socket *)kn->kn_fp->f_data;
struct sockbuf *sb;
- int s;
switch (kn->kn_filter) {
case EVFILT_READ:
return (1);
}
- s = splnet();
+ crit_enter();
SLIST_INSERT_HEAD(&sb->sb_sel.si_note, kn, kn_selnext);
sb->sb_flags |= SB_KNOTE;
- splx(s);
+ crit_exit();
return (0);
}
filt_sordetach(struct knote *kn)
{
struct socket *so = (struct socket *)kn->kn_fp->f_data;
- int s = splnet();
+ crit_enter();
SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext);
if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note))
so->so_rcv.sb_flags &= ~SB_KNOTE;
- splx(s);
+ crit_exit();
}
/*ARGSUSED*/
filt_sowdetach(struct knote *kn)
{
struct socket *so = (struct socket *)kn->kn_fp->f_data;
- int s = splnet();
+ crit_enter();
SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext);
if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note))
so->so_snd.sb_flags &= ~SB_KNOTE;
- splx(s);
+ crit_exit();
}
/*ARGSUSED*/
* of the author. This software is distributed AS-IS.
*
* $FreeBSD: src/sys/kern/vfs_aio.c,v 1.70.2.28 2003/05/29 06:15:35 alc Exp $
- * $DragonFly: src/sys/kern/vfs_aio.c,v 1.14 2004/09/16 04:42:56 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_aio.c,v 1.15 2005/06/06 15:02:28 dillon Exp $
*/
/*
struct aio_liojob *lj;
struct proc *p;
int error;
- int s;
if (aiocbe->jobstate == JOBST_NULL)
panic("aio_free_entry: freeing already free job");
return error;
if (aiocbe->jobstate != JOBST_JOBBFINISHED)
panic("aio_free_entry: invalid physio finish-up state");
- s = splbio();
+ crit_enter();
TAILQ_REMOVE(&ki->kaio_bufdone, aiocbe, plist);
- splx(s);
+ crit_exit();
} else if (aiocbe->jobstate == JOBST_JOBQGLOBAL) {
- s = splnet();
+ crit_enter();
TAILQ_REMOVE(&aio_jobs, aiocbe, list);
TAILQ_REMOVE(&ki->kaio_jobqueue, aiocbe, plist);
- splx(s);
+ crit_exit();
} else if (aiocbe->jobstate == JOBST_JOBFINISHED)
TAILQ_REMOVE(&ki->kaio_jobdone, aiocbe, plist);
else if (aiocbe->jobstate == JOBST_JOBBFINISHED) {
- s = splbio();
+ crit_enter();
TAILQ_REMOVE(&ki->kaio_bufdone, aiocbe, plist);
- splx(s);
+ crit_exit();
if (aiocbe->bp) {
vunmapbuf(aiocbe->bp);
relpbuf(aiocbe->bp, NULL);
#ifndef VFS_AIO
return;
#else
- int s;
struct kaioinfo *ki;
struct aio_liojob *lj, *ljn;
struct aiocblist *aiocbe, *aiocbn;
* Move any aio ops that are waiting on socket I/O to the normal job
* queues so they are cleaned up with any others.
*/
- s = splnet();
+ crit_enter();
for (aiocbe = TAILQ_FIRST(&ki->kaio_sockqueue); aiocbe; aiocbe =
aiocbn) {
aiocbn = TAILQ_NEXT(aiocbe, plist);
TAILQ_INSERT_HEAD(&aio_jobs, aiocbe, list);
TAILQ_INSERT_HEAD(&ki->kaio_jobqueue, aiocbe, plist);
}
- splx(s);
+ crit_exit();
restart1:
for (aiocbe = TAILQ_FIRST(&ki->kaio_jobdone); aiocbe; aiocbe = aiocbn) {
goto restart2;
}
-/*
- * Note the use of lots of splbio here, trying to avoid splbio for long chains
- * of I/O. Probably unnecessary.
- */
restart3:
- s = splbio();
+ crit_enter();
while (TAILQ_FIRST(&ki->kaio_bufqueue)) {
ki->kaio_flags |= KAIO_WAKEUP;
tsleep(p, 0, "aioprn", 0);
- splx(s);
+ crit_exit();
goto restart3;
}
- splx(s);
+ crit_exit();
restart4:
- s = splbio();
+ crit_enter();
for (aiocbe = TAILQ_FIRST(&ki->kaio_bufdone); aiocbe; aiocbe = aiocbn) {
aiocbn = TAILQ_NEXT(aiocbe, plist);
if (aio_free_entry(aiocbe)) {
- splx(s);
+ crit_exit();
goto restart4;
}
}
- splx(s);
+ crit_exit();
/*
* If we've slept, jobs might have moved from one queue to another.
static struct aiocblist *
aio_selectjob(struct aioproclist *aiop)
{
- int s;
struct aiocblist *aiocbe;
struct kaioinfo *ki;
struct proc *userp;
- s = splnet();
+ crit_enter();
for (aiocbe = TAILQ_FIRST(&aio_jobs); aiocbe; aiocbe =
TAILQ_NEXT(aiocbe, list)) {
userp = aiocbe->userproc;
if (ki->kaio_active_count < ki->kaio_maxactive_count) {
TAILQ_REMOVE(&aio_jobs, aiocbe, list);
- splx(s);
+ crit_exit();
return aiocbe;
}
}
- splx(s);
+ crit_exit();
return NULL;
}
static void
aio_daemon(void *uproc)
{
- int s;
struct aio_liojob *lj;
struct aiocb *cb;
struct aiocblist *aiocbe;
aiop->aioproc = mycp;
aiop->aioprocflags |= AIOP_FREE;
- s = splnet();
+ crit_enter();
/*
* Place thread (lightweight process) onto the AIO free thread list.
wakeup(&aio_freeproc);
TAILQ_INSERT_HEAD(&aio_freeproc, aiop, list);
- splx(s);
+ crit_exit();
/* Make up a name for the daemon. */
strcpy(mycp->p_comm, "aiod");
* Take daemon off of free queue
*/
if (aiop->aioprocflags & AIOP_FREE) {
- s = splnet();
+ crit_enter();
TAILQ_REMOVE(&aio_freeproc, aiop, list);
TAILQ_INSERT_TAIL(&aio_activeproc, aiop, list);
aiop->aioprocflags &= ~AIOP_FREE;
- splx(s);
+ crit_exit();
}
aiop->aioprocflags &= ~AIOP_SCHED;
wakeup(userp);
}
- s = splbio();
+ crit_enter();
if (lj && (lj->lioj_flags &
(LIOJ_SIGNAL|LIOJ_SIGNAL_POSTED)) == LIOJ_SIGNAL) {
if ((lj->lioj_queue_finished_count ==
LIOJ_SIGNAL_POSTED;
}
}
- splx(s);
+ crit_exit();
aiocbe->jobstate = JOBST_JOBFINISHED;
- s = splnet();
+ crit_enter();
TAILQ_REMOVE(&ki->kaio_jobqueue, aiocbe, plist);
TAILQ_INSERT_TAIL(&ki->kaio_jobdone, aiocbe, plist);
- splx(s);
+ crit_exit();
KNOTE(&aiocbe->klist, 0);
if (aiocbe->jobflags & AIOCBLIST_RUNDOWN) {
* If we are the first to be put onto the free queue, wakeup
* anyone waiting for a daemon.
*/
- s = splnet();
+ crit_enter();
TAILQ_REMOVE(&aio_activeproc, aiop, list);
if (TAILQ_EMPTY(&aio_freeproc))
wakeup(&aio_freeproc);
TAILQ_INSERT_HEAD(&aio_freeproc, aiop, list);
aiop->aioprocflags |= AIOP_FREE;
- splx(s);
+ crit_exit();
/*
* If daemon is inactive for a long time, allow it to exit,
*/
if (((aiop->aioprocflags & AIOP_SCHED) == 0) && tsleep(mycp,
0, "aiordy", aiod_lifetime)) {
- s = splnet();
+ crit_enter();
if (TAILQ_EMPTY(&aio_jobs)) {
if ((aiop->aioprocflags & AIOP_FREE) &&
(num_aio_procs > target_aio_procs)) {
TAILQ_REMOVE(&aio_freeproc, aiop, list);
- splx(s);
+ crit_exit();
zfree(aiop_zone, aiop);
num_aio_procs--;
#ifdef DIAGNOSTIC
exit1(0);
}
}
- splx(s);
+ crit_exit();
}
}
}
struct vnode *vp;
struct kaioinfo *ki;
struct aio_liojob *lj;
- int s;
int notify;
cb = &aiocbe->uaiocb;
goto doerror;
}
- s = splbio();
+ crit_enter();
+
aiocbe->bp = bp;
bp->b_spc = (void *)aiocbe;
TAILQ_INSERT_TAIL(&aio_bufjobs, aiocbe, list);
num_buf_aio++;
bp->b_error = 0;
- splx(s);
+ crit_exit();
/* Perform transfer. */
BUF_STRATEGY(bp, 0);
notify = 0;
- s = splbio();
+ crit_enter();
/*
* If we had an error invoking the request, or an error in processing
notify = 1;
}
}
- splx(s);
+ crit_exit();
if (notify)
KNOTE(&aiocbe->klist, 0);
return 0;
static int
aio_fphysio(struct aiocblist *iocb)
{
- int s;
struct buf *bp;
int error;
bp = iocb->bp;
- s = splbio();
+ crit_enter();
while ((bp->b_flags & B_DONE) == 0) {
if (tsleep(bp, 0, "physstr", aiod_timeout)) {
if ((bp->b_flags & B_DONE) == 0) {
- splx(s);
+ crit_exit();
return EINPROGRESS;
} else
break;
}
}
- splx(s);
+ crit_exit();
/* Release mapping into kernel space. */
vunmapbuf(bp);
struct file *fp;
unsigned int fd;
struct socket *so;
- int s;
int error;
int opcode, user_opcode;
struct aiocblist *aiocbe;
* happens.
*/
so = (struct socket *)fp->f_data;
- s = splnet();
+ crit_enter();
if (((opcode == LIO_READ) && (!soreadable(so))) || ((opcode ==
LIO_WRITE) && (!sowriteable(so)))) {
TAILQ_INSERT_TAIL(&so->so_aiojobq, aiocbe, list);
aiocbe->jobstate = JOBST_JOBQGLOBAL; /* XXX */
ki->kaio_queue_count++;
num_queue_count++;
- splx(s);
+ crit_exit();
error = 0;
goto done;
}
- splx(s);
+ crit_exit();
}
if ((error = aio_qphysio(p, aiocbe)) == 0)
ki->kaio_queue_count++;
if (lj)
lj->lioj_queue_count++;
- s = splnet();
+ crit_enter();
TAILQ_INSERT_TAIL(&ki->kaio_jobqueue, aiocbe, plist);
TAILQ_INSERT_TAIL(&aio_jobs, aiocbe, list);
- splx(s);
+ crit_exit();
aiocbe->jobstate = JOBST_JOBQGLOBAL;
num_queue_count++;
* (thread) due to resource issues, we return an error for now (EAGAIN),
* which is likely not the correct thing to do.
*/
- s = splnet();
+ crit_enter();
retryproc:
if ((aiop = TAILQ_FIRST(&aio_freeproc)) != NULL) {
TAILQ_REMOVE(&aio_freeproc, aiop, list);
}
num_aio_resv_start--;
}
- splx(s);
+ crit_exit();
done:
return error;
}
return ENOSYS;
#else
struct proc *p = curproc;
- int s;
long jobref;
struct aiocblist *cb, *ncb;
struct aiocb *ujob;
return 0;
}
}
- s = splbio();
+ crit_enter();
for (cb = TAILQ_FIRST(&ki->kaio_bufdone); cb; cb = ncb) {
ncb = TAILQ_NEXT(cb, plist);
if (((intptr_t) cb->uaiocb._aiocb_private.kernelinfo)
== jobref) {
- splx(s);
+ crit_exit();
if (ujob == cb->uuaiocb) {
uap->sysmsg_result =
cb->uaiocb._aiocb_private.status;
return 0;
}
}
- splx(s);
+ crit_exit();
return (EINVAL);
#endif /* VFS_AIO */
}
}
- s = splbio();
+ crit_enter();
for (cb = TAILQ_FIRST(&ki->kaio_bufdone); cb; cb =
TAILQ_NEXT(cb, plist)) {
for (i = 0; i < njoblist; i++) {
if (((intptr_t)
cb->uaiocb._aiocb_private.kernelinfo) ==
ijoblist[i]) {
- splx(s);
+ crit_exit();
if (ujoblist[i] != cb->uuaiocb)
error = EINVAL;
zfree(aiol_zone, ijoblist);
ki->kaio_flags |= KAIO_WAKEUP;
error = tsleep(p, PCATCH, "aiospn", timo);
- splx(s);
+ crit_exit();
if (error == ERESTART || error == EINTR) {
zfree(aiol_zone, ijoblist);
struct filedesc *fdp;
struct socket *so;
struct proc *po;
- int s,error;
+ int error;
int cancelled=0;
int notcancelled=0;
struct vnode *vp;
} else if (fp->f_type == DTYPE_SOCKET) {
so = (struct socket *)fp->f_data;
- s = splnet();
+ crit_enter();
for (cbe = TAILQ_FIRST(&so->so_aiojobq); cbe; cbe = cbn) {
cbn = TAILQ_NEXT(cbe, list);
break;
}
}
- splx(s);
+ crit_exit();
if ((cancelled) && (uap->aiocbp)) {
uap->sysmsg_result = AIO_CANCELED;
ki=p->p_aioinfo;
if (ki == NULL)
goto done;
- s = splnet();
+ crit_enter();
for (cbe = TAILQ_FIRST(&ki->kaio_jobqueue); cbe; cbe = cbn) {
cbn = TAILQ_NEXT(cbe, plist);
}
}
}
- splx(s);
+ crit_exit();
done:
if (notcancelled) {
uap->sysmsg_result = AIO_NOTCANCELED;
return ENOSYS;
#else
struct proc *p = curproc;
- int s;
struct aiocblist *cb;
struct kaioinfo *ki;
long jobref;
}
}
- s = splnet();
+ crit_enter();
for (cb = TAILQ_FIRST(&ki->kaio_jobqueue); cb; cb = TAILQ_NEXT(cb,
plist)) {
if (((intptr_t)cb->uaiocb._aiocb_private.kernelinfo) ==
jobref) {
uap->sysmsg_result = EINPROGRESS;
- splx(s);
+ crit_exit();
return 0;
}
}
if (((intptr_t)cb->uaiocb._aiocb_private.kernelinfo) ==
jobref) {
uap->sysmsg_result = EINPROGRESS;
- splx(s);
+ crit_exit();
return 0;
}
}
- splx(s);
+ crit_exit();
- s = splbio();
+ crit_enter();
for (cb = TAILQ_FIRST(&ki->kaio_bufdone); cb; cb = TAILQ_NEXT(cb,
plist)) {
if (((intptr_t)cb->uaiocb._aiocb_private.kernelinfo) ==
jobref) {
uap->sysmsg_result = cb->uaiocb._aiocb_private.error;
- splx(s);
+ crit_exit();
return 0;
}
}
if (((intptr_t)cb->uaiocb._aiocb_private.kernelinfo) ==
jobref) {
uap->sysmsg_result = EINPROGRESS;
- splx(s);
+ crit_exit();
return 0;
}
}
- splx(s);
+ crit_exit();
#if (0)
/*
int error, runningcode;
int nerror;
int i;
- int s;
if ((uap->mode != LIO_NOWAIT) && (uap->mode != LIO_WAIT))
return EINVAL;
}
}
- s = splbio();
+ crit_enter();
TAILQ_FOREACH(cb, &ki->kaio_bufdone, plist) {
if (((intptr_t)cb->uaiocb._aiocb_private.kernelinfo)
== jobref) {
break;
}
}
- splx(s);
+ crit_exit();
}
/*
return cb->uaiocb._aiocb_private.error;
}
- s = splbio();
+ crit_enter();
if ((cb = TAILQ_FIRST(&ki->kaio_bufdone)) != 0 ) {
- splx(s);
+ crit_exit();
suword(uap->aiocbp, (uintptr_t)cb->uuaiocb);
uap->sysmsg_result = cb->uaiocb._aiocb_private.status;
aio_free_entry(cb);
ki->kaio_flags |= KAIO_WAKEUP;
error = tsleep(p, PCATCH, "aiowc", timo);
- splx(s);
+ crit_exit();
if (error == ERESTART)
return EINTR;
* John S. Dyson.
*
* $FreeBSD: src/sys/kern/vfs_bio.c,v 1.242.2.20 2003/05/28 18:38:10 alc Exp $
- * $DragonFly: src/sys/kern/vfs_bio.c,v 1.36 2005/05/08 00:12:22 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_bio.c,v 1.37 2005/06/06 15:02:28 dillon Exp $
*/
/*
* Disable background writes for now. There appear to be races in the
* flags tests and locking operations as well as races in the completion
* code modifying the original bp (origbp) without holding a lock, assuming
- * splbio protection when there might not be splbio protection.
+ * critical section protection when there might not be critical section
+ * protection.
*
* XXX disable also because the RB tree can't handle multiple blocks with
* the same lblkno.
static __inline void
waitrunningbufspace(void)
{
- while (runningbufspace > hirunningspace) {
- int s;
-
- s = splbio(); /* fix race against interrupt/biodone() */
- ++runningbufreq;
- tsleep(&runningbufreq, 0, "wdrain", 0);
- splx(s);
+ if (runningbufspace > hirunningspace) {
+ crit_enter();
+ while (runningbufspace > hirunningspace) {
+ ++runningbufreq;
+ tsleep(&runningbufreq, 0, "wdrain", 0);
+ }
+ crit_exit();
}
}
/*
* bfreekva() - free the kva allocation for a buffer.
*
- * Must be called at splbio() or higher as this is the only locking for
+ * Must be called from a critical section as this is the only locking for
* buffer_map.
*
* Since this call frees up buffer space, we call bufspacewakeup().
void
bremfree(struct buf * bp)
{
- int s = splbio();
- int old_qindex = bp->b_qindex;
+ int old_qindex;
+
+ crit_enter();
+ old_qindex = bp->b_qindex;
if (bp->b_qindex != QUEUE_NONE) {
KASSERT(BUF_REFCNTNB(bp) == 1,
break;
}
}
- splx(s);
+ crit_exit();
}
int
bwrite(struct buf * bp)
{
- int oldflags, s;
+ int oldflags;
#if 0
struct buf *newbp;
#endif
if (BUF_REFCNTNB(bp) == 0)
panic("bwrite: buffer is not busy???");
- s = splbio();
+ crit_enter();
/*
* If a background write is already in progress, delay
* writing this block if it is asynchronous. Otherwise
*/
if (bp->b_xflags & BX_BKGRDINPROG) {
if (bp->b_flags & B_ASYNC) {
- splx(s);
+ crit_exit();
bdwrite(bp);
return (0);
}
bp->b_runningbufspace = bp->b_bufsize;
runningbufspace += bp->b_runningbufspace;
- splx(s);
+ crit_exit();
if (oldflags & B_ASYNC)
BUF_KERNPROC(bp);
VOP_STRATEGY(bp->b_vp, bp);
* Since the buffer is not on a queue, we do not update the numfreebuffers
* count.
*
- * Must be called at splbio().
+ * Must be called from a critical section.
* The buffer must be on QUEUE_NONE.
*/
void
* Since the buffer is not on a queue, we do not update the numfreebuffers
* count.
*
- * Must be called at splbio().
+ * Must be called from a critical section.
*
* The buffer is typically on QUEUE_NONE but there is one case in
* brelse() that calls this function after placing the buffer on
bwillwrite(void)
{
if (numdirtybuffers >= hidirtybuffers) {
- int s;
-
- s = splbio();
+ crit_enter();
while (numdirtybuffers >= hidirtybuffers) {
bd_wakeup(1);
needsbuffer |= VFS_BIO_NEED_DIRTYFLUSH;
tsleep(&needsbuffer, 0, "flswai", 0);
}
- splx(s);
+ crit_exit();
}
}
void
brelse(struct buf * bp)
{
- int s;
-
KASSERT(!(bp->b_flags & (B_CLUSTER|B_PAGING)), ("brelse: inappropriate B_PAGING or B_CLUSTER bp %p", bp));
- s = splbio();
+ crit_enter();
if (bp->b_flags & B_LOCKED)
bp->b_flags &= ~B_ERROR;
* now. Note that we left these pages wired
* when we removed them so they had better exist,
* and they cannot be ripped out from under us so
- * no splvm() protection is necessary.
+ * no critical section protection is necessary.
*/
if (m == bogus_page) {
VOP_GETVOBJECT(vp, &obj);
panic("brelse: multiple refs");
/* do not release to free list */
BUF_UNLOCK(bp);
- splx(s);
+ crit_exit();
return;
}
BUF_UNLOCK(bp);
bp->b_flags &= ~(B_ORDERED | B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF |
B_DIRECT | B_NOWDRAIN);
- splx(s);
+ crit_exit();
}
/*
void
bqrelse(struct buf * bp)
{
- int s;
-
- s = splbio();
+ crit_enter();
KASSERT(!(bp->b_flags & (B_CLUSTER|B_PAGING)), ("bqrelse: inappropriate B_PAGING or B_CLUSTER bp %p", bp));
/* do not release to free list */
panic("bqrelse: multiple refs");
BUF_UNLOCK(bp);
- splx(s);
+ crit_exit();
return;
}
if (bp->b_flags & B_LOCKED) {
* buffer (most importantly: the wired pages making up its
* backing store) *now*.
*/
- splx(s);
+ crit_exit();
brelse(bp);
return;
} else {
/* unlock */
BUF_UNLOCK(bp);
bp->b_flags &= ~(B_ORDERED | B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF);
- splx(s);
+ crit_exit();
}
static void
vfs_vmio_release(struct buf *bp)
{
- int i, s;
+ int i;
vm_page_t m;
- s = splvm();
+ crit_enter();
for (i = 0; i < bp->b_xio.xio_npages; i++) {
m = bp->b_xio.xio_pages[i];
bp->b_xio.xio_pages[i] = NULL;
}
}
}
- splx(s);
+ crit_exit();
pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_xio.xio_npages);
if (bp->b_bufsize) {
bufspacewakeup();
int j;
daddr_t lblkno = bp->b_lblkno;
struct vnode *vp = bp->b_vp;
- int s;
int ncl;
struct buf *bpa;
int nwritten;
int size;
int maxcl;
- s = splbio();
+ crit_enter();
/*
* right now we support clustered writing only to regular files. If
* we find a clusterable block we could be in the middle of a cluster
*/
if (ncl != 1) {
nwritten = cluster_wbuild(vp, size, lblkno - j, ncl);
- splx(s);
+ crit_exit();
return nwritten;
}
}
bremfree(bp);
bp->b_flags |= B_ASYNC;
- splx(s);
+ crit_exit();
/*
* default (old) behavior, writing out only one block
*
LIST_INSERT_HEAD(&invalhash, bp, b_hash);
/*
- * spl protection not required when scrapping a buffer's
- * contents because it is already wired.
+ * critical section protection is not required when
+ * scrapping a buffer's contents because it is already
+ * wired.
*/
if (bp->b_bufsize)
allocbuf(bp, 0);
static void
buf_daemon()
{
- int s;
-
/*
* This process needs to be suspended prior to shutdown sync.
*/
/*
* This process is allowed to take the buffer cache to the limit
*/
- s = splbio();
+ crit_enter();
for (;;) {
kproc_suspend_loop();
*
* Note that we ignore vm_page_free() races from interrupts against our
* lookup, since if the caller is not protected our return value will not
- * be any more valid then otherwise once we splx().
+ * be any more valid then otherwise once we exit the critical section.
*/
int
inmem(struct vnode * vp, daddr_t blkno)
getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo)
{
struct buf *bp;
- int s;
struct bufhashhdr *bh;
if (size > MAXBSIZE)
panic("getblk: size(%d) > MAXBSIZE(%d)", size, MAXBSIZE);
- s = splbio();
+ crit_enter();
loop:
/*
* Block if we are low on buffers. Certain processes are allowed
if (BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL,
"getblk", slpflag, slptimeo) == ENOLCK)
goto loop;
- splx(s);
+ crit_exit();
return (struct buf *) NULL;
}
goto loop;
}
- splx(s);
+ crit_exit();
bp->b_flags &= ~B_DONE;
} else {
/*
if ((bp = getnewbuf(slpflag, slptimeo, size, maxsize)) == NULL) {
if (slpflag || slptimeo) {
- splx(s);
+ crit_exit();
return NULL;
}
goto loop;
* This can be a problem whether the vnode is locked or not.
* If the buffer is created out from under us, we have to
* throw away the one we just created. There is now window
- * race because we are safely running at splbio() from the
- * point of the duplicate buffer creation through to here,
- * and we've locked the buffer.
+ * race because we are safely running in a critical section
+ * from the point of the duplicate buffer creation through
+ * to here, and we've locked the buffer.
*/
if (gbincore(vp, blkno)) {
bp->b_flags |= B_INVAL;
allocbuf(bp, size);
- splx(s);
+ crit_exit();
bp->b_flags &= ~B_DONE;
}
return (bp);
* Get an empty, disassociated buffer of given size. The buffer is initially
* set to B_INVAL.
*
- * spl protection is not required for the allocbuf() call because races are
- * impossible here.
+ * critical section protection is not required for the allocbuf() call
+ * because races are impossible here.
*/
struct buf *
geteblk(int size)
{
struct buf *bp;
- int s;
int maxsize;
maxsize = (size + BKVAMASK) & ~BKVAMASK;
- s = splbio();
- while ((bp = getnewbuf(0, 0, size, maxsize)) == 0);
- splx(s);
+ crit_enter();
+ while ((bp = getnewbuf(0, 0, size, maxsize)) == 0)
+ ;
+ crit_exit();
allocbuf(bp, size);
bp->b_flags |= B_INVAL; /* b_dep cleared by getnewbuf() */
return (bp);
* allocbuf() only adjusts B_CACHE for VMIO buffers. getblk() deals with
* B_CACHE for the non-VMIO case.
*
- * This routine does not need to be called at splbio() but you must own the
- * buffer.
+ * This routine does not need to be called from a critical section but you
+ * must own the buffer.
*/
int
allocbuf(struct buf *bp, int size)
* B_CACHE if these pages are not valid for the
* range covered by the buffer.
*
- * spl protection is required to protect against
- * interrupts unbusying and freeing pages between
- * our vm_page_lookup() and our busycheck/wiring
- * call.
+ * critical section protection is required to protect
+ * against interrupts unbusying and freeing pages
+ * between our vm_page_lookup() and our
+ * busycheck/wiring call.
*/
vp = bp->b_vp;
VOP_GETVOBJECT(vp, &obj);
int
biowait(struct buf * bp)
{
- int s;
-
- s = splbio();
+ crit_enter();
while ((bp->b_flags & B_DONE) == 0) {
#if defined(NO_SCHEDULE_MODS)
tsleep(bp, 0, "biowait", 0);
tsleep(bp, 0, "biowr", 0);
#endif
}
- splx(s);
+ crit_exit();
if (bp->b_flags & B_EINTR) {
bp->b_flags &= ~B_EINTR;
return (EINTR);
void
biodone(struct buf *bp)
{
- int s, error;
+ int error;
- s = splbio();
+ crit_enter();
KASSERT(BUF_REFCNTNB(bp) > 0, ("biodone: bp %p not busy %d", bp, BUF_REFCNTNB(bp)));
KASSERT(!(bp->b_flags & B_DONE), ("biodone: bp %p already done", bp));
if (bp->b_flags & B_FREEBUF) {
brelse(bp);
- splx(s);
+ crit_exit();
return;
}
if (bp->b_flags & B_CALL) {
bp->b_flags &= ~B_CALL;
(*bp->b_iodone) (bp);
- splx(s);
+ crit_exit();
return;
}
if (LIST_FIRST(&bp->b_dep) != NULL && bioops.io_complete)
} else {
wakeup(bp);
}
- splx(s);
+ crit_exit();
}
/*
* When restoring bogus changes the original pages
* should still be wired, so we are in no danger of
* losing the object association and do not need
- * spl protection particularly.
+ * critical section protection particularly.
*/
if (m == bogus_page) {
m = vm_page_lookup(obj, OFF_TO_IDX(bp->b_offset) + i);
*
* @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94
* $FreeBSD: src/sys/kern/vfs_cluster.c,v 1.92.2.9 2001/11/18 07:10:59 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_cluster.c,v 1.12 2005/02/19 00:47:03 joerg Exp $
+ * $DragonFly: src/sys/kern/vfs_cluster.c,v 1.13 2005/06/06 15:02:28 dillon Exp $
*/
#include "opt_debug_cluster.h"
} else if ((bp->b_flags & B_RAM) == 0) {
return 0;
} else {
- int s;
struct buf *tbp;
bp->b_flags &= ~B_RAM;
/*
- * We do the spl here so that there is no window
+ * We do the crit here so that there is no window
* between the incore and the b_usecount increment
- * below. We opt to keep the spl out of the loop
+ * below. We opt to keep the crit out of the loop
* for efficiency.
*/
- s = splbio();
+ crit_enter();
for (i = 1; i < maxra; i++) {
if (!(tbp = incore(vp, lblkno+i))) {
(i == (maxra - 1)))
tbp->b_flags |= B_RAM;
}
- splx(s);
+ crit_exit();
if (i >= maxra) {
return 0;
}
cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len)
{
struct buf *bp, *tbp;
- int i, j, s;
+ int i, j;
int totalwritten = 0;
int dbsize = btodb(size);
while (len > 0) {
- s = splbio();
+ crit_enter();
/*
* If the buffer is not delayed-write (i.e. dirty), or it
* is delayed-write but either locked or inval, it cannot
BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) {
++start_lbn;
--len;
- splx(s);
+ crit_exit();
continue;
}
bremfree(tbp);
tbp->b_flags &= ~B_DONE;
- splx(s);
+ crit_exit();
/*
* Extra memory in the buffer, punt on this buffer.
*/
for (i = 0; i < len; ++i, ++start_lbn) {
if (i != 0) { /* If not the first buffer */
- s = splbio();
+ crit_enter();
/*
* If the adjacent data is not even in core it
* can't need to be written.
*/
if ((tbp = gbincore(vp, start_lbn)) == NULL) {
- splx(s);
+ crit_exit();
break;
}
(bp->b_flags & (B_VMIO | B_NEEDCOMMIT))) ||
(tbp->b_flags & B_LOCKED) ||
BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) {
- splx(s);
+ crit_exit();
break;
}
((tbp->b_xio.xio_npages + bp->b_xio.xio_npages) >
(vp->v_mount->mnt_iosize_max / PAGE_SIZE))) {
BUF_UNLOCK(tbp);
- splx(s);
+ crit_exit();
break;
}
/*
*/
bremfree(tbp);
tbp->b_flags &= ~B_DONE;
- splx(s);
+ crit_exit();
} /* end of code for non-first buffers only */
/* check for latent dependencies to be handled */
if ((LIST_FIRST(&tbp->b_dep)) != NULL &&
bp->b_bcount += size;
bp->b_bufsize += size;
- s = splbio();
+ crit_enter();
bundirty(tbp);
tbp->b_flags &= ~(B_READ | B_DONE | B_ERROR);
tbp->b_flags |= B_ASYNC;
reassignbuf(tbp, tbp->b_vp); /* put on clean list */
++tbp->b_vp->v_numoutput;
- splx(s);
+ crit_exit();
BUF_KERNPROC(tbp);
TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head,
tbp, b_cluster.cluster_entry);
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/kern/vfs_conf.c,v 1.49.2.5 2003/01/07 11:56:53 joerg Exp $
- * $DragonFly: src/sys/kern/vfs_conf.c,v 1.13 2005/04/19 17:54:42 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_conf.c,v 1.14 2005/06/06 15:02:28 dillon Exp $
*/
/*
#include <sys/device.h>
#include <sys/namecache.h>
#include <sys/paths.h>
+#include <sys/thread2.h>
#include "opt_ddb.h"
#ifdef DDB
char *vfsname, *devname;
int error;
char patt[32];
- int s;
vfsname = NULL;
devname = NULL;
if (mountfrom == NULL)
return(error); /* don't complain */
- s = splcam(); /* Overkill, but annoying without it */
+ crit_enter();
printf("Mounting root from %s\n", mountfrom);
- splx(s);
+ crit_exit();
/* parse vfs name and devname */
vfsname = malloc(MFSNAMELEN, M_MOUNT, M_WAITOK);
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $DragonFly: src/sys/kern/vfs_mount.c,v 1.10 2005/04/20 17:01:50 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_mount.c,v 1.11 2005/06/06 15:02:28 dillon Exp $
*/
/*
{
struct thread *td = curthread;
int done;
- int s;
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, td,
SHUTDOWN_PRI_FIRST);
- s = splbio();
+ crit_enter();
for (;;) {
kproc_suspend_loop();
if (numvnodes - freevnodes <= desiredvnodes * 9 / 10) {
vnlru_nowhere = 0;
}
}
- splx(s);
+ crit_exit();
}
/*
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
* $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_subr.c,v 1.56 2005/05/06 11:52:02 corecode Exp $
+ * $DragonFly: src/sys/kern/vfs_subr.c,v 1.57 2005/06/06 15:02:28 dillon Exp $
*/
/*
int slpflag, int slptimeo)
{
struct vinvalbuf_bp_info info;
- int s, error;
+ int error;
vm_object_t object;
/*
* is updated.
*/
if (flags & V_SAVE) {
- s = splbio();
+ crit_enter();
while (vp->v_numoutput) {
vp->v_flag |= VBWAIT;
error = tsleep((caddr_t)&vp->v_numoutput,
slpflag, "vinvlbuf", slptimeo);
if (error) {
- splx(s);
+ crit_exit();
return (error);
}
}
if (!RB_EMPTY(&vp->v_rbdirty_tree)) {
- splx(s);
+ crit_exit();
if ((error = VOP_FSYNC(vp, MNT_WAIT, td)) != 0)
return (error);
- s = splbio();
+ crit_enter();
if (vp->v_numoutput > 0 ||
!RB_EMPTY(&vp->v_rbdirty_tree))
panic("vinvalbuf: dirty bufs");
}
- splx(s);
+ crit_exit();
}
- s = splbio();
+ crit_enter();
info.slptimeo = slptimeo;
info.slpflag = slpflag;
info.flags = flags;
}
} while (vp->v_numoutput > 0);
- splx(s);
+ crit_exit();
/*
* Destroy the copy in the VM cache, too.
{
daddr_t trunclbn;
int count;
- int s;
/*
* Round up to the *next* lbn, then destroy the buffers in question.
*/
trunclbn = (length + blksize - 1) / blksize;
- s = splbio();
+ crit_enter();
do {
count = RB_SCAN(buf_rb_tree, &vp->v_rbclean_tree,
vtruncbuf_bp_trunc_cmp,
tsleep(&vp->v_numoutput, 0, "vbtrunc", 0);
}
- splx(s);
+ crit_exit();
vnode_pager_setsize(vp, length);
int lazycount;
int lazylimit;
daddr_t lbn;
- int s;
int (*checkdef)(struct buf *);
};
bzero(&info, sizeof(info));
info.vp = vp;
- info.s = splbio();
info.lbn = lbn;
if ((info.checkdef = checkdef) == NULL)
info.syncdeps = 1;
+ crit_enter();
+
switch(waitfor) {
case MNT_LAZY:
/*
}
break;
}
- splx(info.s);
+ crit_exit();
return(error);
}
bp->b_lblkno >= info->lbn) {
bremfree(bp);
bp->b_flags |= B_INVAL | B_NOCACHE;
- splx(info->s);
+ crit_exit();
brelse(bp);
- info->s = splbio();
+ crit_enter();
}
if (info->synchronous) {
* Synchronous flushing. An error may be returned.
*/
bremfree(bp);
- splx(info->s);
+ crit_exit();
error = bwrite(bp);
- info->s = splbio();
+ crit_enter();
} else {
/*
* Asynchronous flushing. A negative return value simply
} else {
info->lazycount += bp->b_bufsize;
bremfree(bp);
- splx(info->s);
+ crit_exit();
bawrite(bp);
- info->s = splbio();
+ crit_enter();
}
if (info->lazylimit && info->lazycount >= info->lazylimit)
error = 1;
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
* $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_sync.c,v 1.5 2005/04/19 17:54:42 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_sync.c,v 1.6 2005/06/06 15:02:28 dillon Exp $
*/
/*
struct synclist *slp;
struct vnode *vp;
long starttime;
- int s;
struct thread *td = curthread;
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, td,
* Push files whose dirty time has expired. Be careful
* of interrupt race on slp queue.
*/
- s = splbio();
+ crit_enter();
slp = &syncer_workitem_pending[syncer_delayno];
syncer_delayno += 1;
if (syncer_delayno == syncer_maxdelay)
syncer_delayno = 0;
- splx(s);
+ crit_exit();
while ((vp = LIST_FIRST(slp)) != NULL) {
if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT, td) == 0) {
VOP_FSYNC(vp, MNT_LAZY, td);
vput(vp);
}
- s = splbio();
+ crit_enter();
/*
* If the vnode is still at the head of the list
}
vn_syncer_add_to_worklist(vp, syncdelay);
}
- splx(s);
+ crit_exit();
}
/*
/*
* The syncer vnode is no longer needed and is being decommissioned.
*
- * Modifications to the worklist must be protected at splbio().
+ * Modifications to the worklist must be protected with a critical
+ * section.
*
* sync_reclaim { struct vnode *a_vp }
*/
sync_reclaim(struct vop_reclaim_args *ap)
{
struct vnode *vp = ap->a_vp;
- int s;
- s = splbio();
+ crit_enter();
vp->v_mount->mnt_syncer = NULL;
if (vp->v_flag & VONWORKLST) {
LIST_REMOVE(vp, v_synclist);
vp->v_flag &= ~VONWORKLST;
}
- splx(s);
+ crit_exit();
return (0);
}
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.61 2005/04/19 17:54:42 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.62 2005/06/06 15:02:28 dillon Exp $
*/
#include <sys/param.h>
void
vfs_bufstats(void)
{
- int s, i, j, count;
+ int i, j, count;
struct buf *bp;
struct bqueues *dp;
int counts[(MAXBSIZE / PAGE_SIZE) + 1];
count = 0;
for (j = 0; j <= MAXBSIZE/PAGE_SIZE; j++)
counts[j] = 0;
- s = splbio();
+ crit_enter();
TAILQ_FOREACH(bp, dp, b_freelist) {
counts[bp->b_bufsize/PAGE_SIZE]++;
count++;
}
- splx(s);
+ crit_exit();
printf("%s: total-%d", bname[i], count);
for (j = 0; j <= MAXBSIZE/PAGE_SIZE; j++)
if (counts[j] != 0)
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $FreeBSD: src/sys/i386/i386/autoconf.c,v 1.146.2.2 2001/06/07 06:05:58 dd Exp $
- * $DragonFly: src/sys/platform/pc32/i386/autoconf.c,v 1.15 2004/10/14 18:31:02 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/autoconf.c,v 1.16 2005/06/06 15:02:26 dillon Exp $
*/
/*
* completely safe (since a panic may occur in a critical region
* at splhigh()), but we want at least bio interrupts to work.
*/
- safepri = curthread->td_cpl;
+ safepri = TDPRI_KERN_USER;
}
static void
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
- * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.72 2005/03/17 08:22:38 swildner Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.73 2005/06/06 15:02:26 dillon Exp $
*/
#include "use_apm.h"
thread0.td_flags |= TDF_RUNNING;
thread0.td_proc = &proc0;
thread0.td_switch = cpu_heavy_switch; /* YYY eventually LWKT */
- safepri = thread0.td_cpl = SWI_MASK | HWI_MASK;
+ thread0.td_cpl = 0; /* crit section protects us */
+ safepri = TDPRI_MAX;
/* make ldt memory segments */
/*
* on a different cpu will not be immediately scheduled by a yield() on
* this cpu.
*
- * $DragonFly: src/sys/sys/thread2.h,v 1.18 2005/06/03 23:57:34 dillon Exp $
+ * $DragonFly: src/sys/sys/thread2.h,v 1.19 2005/06/06 15:02:24 dillon Exp $
*/
#ifndef _SYS_THREAD2_H_
}
static __inline int
-crit_panic_save(void)
-{
- thread_t td = curthread;
- int pri = td->td_pri;
- td->td_pri = td->td_pri & TDPRI_MASK;
- return(pri);
-}
-
-static __inline void
-crit_panic_restore(int cpri)
-{
- curthread->td_pri = cpri;
-}
-
-static __inline int
crit_test(thread_t td)
{
return(td->td_pri >= TDPRI_CRIT);