Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Mar 2002 16:11:31 -0800
From:      Alfred Perlstein <bright@mu.org>
To:        smp@freebsd.org
Cc:        davidc@freebsd.org, jhb@freebsd.org
Subject:   select fix and giant pushdown patch
Message-ID:  <20020311001131.GN26621@elvis.mu.org>

next in thread | raw e-mail | index | archive | help
Chad David and I have been working on fixing select(2) and poll(2)'s
locking.  I've been working on pushing pipe read/write ops down
out from under Giant.

The way it works is that there is a global select lock that is very
close to a leaf lock, under select/poll you'll see this order of
aquisition:

filedesc -> objlock -> sellock 

where objlock is aquired in the fo_poll routine, from interrupt
or writer POV you'll see:
objlock -> sellock.

Also, because pfind was broken by the proc locking such that it
requires an sx lock we've fixed select such that the selinfo structure
contains linkages back to the thread that is waiting on the resource,
when leaving select all linkages not removed via selwakeup are removed.

I've also been able to push down pipe reading/writing out from
under Giant, so far the performance numbers don't look much
better, hopefully they will improve as more code is pulled out
from under Giant.

It's starting to look like a lot of the system's requiring Giant
just for MALLOC/FREE which is really dissappointing considering
the work I put into fixing that months ago that was backed out.

This code relies slightly on psignal being MPSAFE, if it's not
a small amount of performance can be scrificed by grabbing Giant
before calling it.

Test, review please...

bye,
-Alfred

Index: dev/bktr/bktr_core.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/bktr/bktr_core.c,v
retrieving revision 1.117
diff -u -r1.117 bktr_core.c
--- dev/bktr/bktr_core.c	12 Sep 2001 08:37:02 -0000	1.117
+++ dev/bktr/bktr_core.c	10 Mar 2002 08:08:36 -0000
@@ -809,7 +809,7 @@
 		}
 
 		/* If someone has a select() on /dev/vbi, inform them */
-		if (bktr->vbi_select.si_pid) {
+		if (SEL_WAITING(&bktr->vbi_select)) {
 			selwakeup(&bktr->vbi_select);
 		}
 
Index: dev/kbd/kbd.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/kbd/kbd.c,v
retrieving revision 1.27
diff -u -r1.27 kbd.c
--- dev/kbd/kbd.c	12 Sep 2001 08:37:06 -0000	1.27
+++ dev/kbd/kbd.c	10 Mar 2002 08:08:36 -0000
@@ -524,7 +524,7 @@
 #endif
 	clist_alloc_cblocks(&sc->gkb_q, KB_QSIZE, KB_QSIZE/2); /* XXX */
 	sc->gkb_rsel.si_flags = 0;
-	sc->gkb_rsel.si_pid = 0;
+	SEL_INIT(&sc->gkb_rsel);
 	splx(s);
 
 	return 0;
Index: dev/snp/snp.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/snp/snp.c,v
retrieving revision 1.69
diff -u -r1.69 snp.c
--- dev/snp/snp.c	24 Nov 2001 15:59:46 -0000	1.69
+++ dev/snp/snp.c	10 Mar 2002 08:08:36 -0000
@@ -373,7 +373,6 @@
 		wakeup((caddr_t)snp);
 	}
 	selwakeup(&snp->snp_sel);
-	snp->snp_sel.si_pid = 0;
 
 	return (n);
 }
@@ -447,7 +446,6 @@
 
 detach_notty:
 	selwakeup(&snp->snp_sel);
-	snp->snp_sel.si_pid = 0;
 	if ((snp->snp_flags & SNOOP_OPEN) == 0) 
 		free(snp, M_SNP);
 
Index: dev/sound/pcm/channel.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pcm/channel.c,v
retrieving revision 1.81
diff -u -r1.81 channel.c
--- dev/sound/pcm/channel.c	24 Feb 2002 00:49:43 -0000	1.81
+++ dev/sound/pcm/channel.c	10 Mar 2002 08:08:36 -0000
@@ -116,7 +116,7 @@
     	struct snd_dbuf *bs = c->bufsoft;
 
 	CHN_LOCKASSERT(c);
-	if (sndbuf_getsel(bs)->si_pid && chn_polltrigger(c))
+	if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
 		selwakeup(sndbuf_getsel(bs));
 	wakeup(bs);
 }
Index: dev/usb/ums.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ums.c,v
retrieving revision 1.48
diff -u -r1.48 ums.c
--- dev/usb/ums.c	15 Feb 2002 22:54:10 -0000	1.48
+++ dev/usb/ums.c	10 Mar 2002 08:08:36 -0000
@@ -345,7 +345,11 @@
 	sc->status.dx = sc->status.dy = sc->status.dz = 0;
 
 	sc->rsel.si_flags = 0;
+#ifdef __FreeBSD__
+	SEL_INIT(&sc->rsel);
+#else
 	sc->rsel.si_pid = 0;
+#endif
 
 	sc->dev = make_dev(&ums_cdevsw, device_get_unit(self),
 			UID_ROOT, GID_OPERATOR,
Index: isa/psm.c
===================================================================
RCS file: /home/ncvs/src/sys/isa/psm.c,v
retrieving revision 1.43
diff -u -r1.43 psm.c
--- isa/psm.c	19 Dec 2001 13:32:21 -0000	1.43
+++ isa/psm.c	10 Mar 2002 08:08:36 -0000
@@ -1314,8 +1314,7 @@
     device_busy(devclass_get_device(psm_devclass, unit));
 
     /* Initialize state */
-    sc->rsel.si_flags = 0;
-    sc->rsel.si_pid = 0;
+    SEL_INIT(&sc->rsel);
     sc->mode.level = sc->dflt_mode.level;
     sc->mode.protocol = sc->dflt_mode.protocol;
     sc->watchdog = FALSE;
Index: kern/kern_descrip.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.127
diff -u -r1.127 kern_descrip.c
--- kern/kern_descrip.c	27 Feb 2002 18:32:12 -0000	1.127
+++ kern/kern_descrip.c	10 Mar 2002 08:09:25 -0000
@@ -1716,6 +1716,7 @@
 		FILE_UNLOCK(fp);
 		return (0);
 	}
+	mtx_lock(&Giant);
 	if (fp->f_count < 0)
 		panic("fdrop: count < 0");
 	if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
@@ -1733,6 +1734,7 @@
 	else
 		error = 0;
 	ffree(fp);
+	mtx_unlock(&Giant);
 	return (error);
 }
 
Index: kern/kern_ktrace.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.60
diff -u -r1.60 kern_ktrace.c
--- kern/kern_ktrace.c	27 Feb 2002 19:10:50 -0000	1.60
+++ kern/kern_ktrace.c	10 Mar 2002 08:08:36 -0000
@@ -181,6 +181,8 @@
 
 	if (error)
 		return;
+
+	mtx_lock(&Giant);
 	/*
 	 * don't let p_tracep get ripped out from under us
 	 */
@@ -200,6 +202,7 @@
 		vrele(vp);
 	FREE(kth, M_KTRACE);
 	p->p_traceflag &= ~KTRFAC_ACTIVE;
+	mtx_unlock(&Giant);
 }
 
 void
Index: kern/sys_generic.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sys_generic.c,v
retrieving revision 1.92
diff -u -r1.92 sys_generic.c
--- kern/sys_generic.c	9 Mar 2002 22:44:37 -0000	1.92
+++ kern/sys_generic.c	10 Mar 2002 20:49:51 -0000
@@ -80,6 +80,7 @@
 		    size_t, off_t, int);
 static int	dofilewrite(struct thread *, struct file *, int,
 		    const void *, size_t, off_t, int);
+static void	clear_selinfo_list(struct thread *);
 
 /*
  * Read system call.
@@ -102,13 +103,11 @@
 	struct file *fp;
 	int error;
 
-	mtx_lock(&Giant);
 	if ((error = fget_read(td, uap->fd, &fp)) == 0) {
 		error = dofileread(td, fp, uap->fd, uap->buf,
 			    uap->nbyte, (off_t)-1, 0);
 		fdrop(fp, td);
 	}
-	mtx_unlock(&Giant);
 	return(error);
 }
 
@@ -137,7 +136,6 @@
 
 	if ((error = fget_read(td, uap->fd, &fp)) != 0)
 		return (error);
-	mtx_lock(&Giant);
 	if (fp->f_type != DTYPE_VNODE) {
 		error = ESPIPE;
 	} else {
@@ -145,7 +143,6 @@
 			    uap->offset, FOF_OFFSET);
 	}
 	fdrop(fp, td);
-	mtx_unlock(&Giant);
 	return(error);
 }
 
@@ -332,7 +329,6 @@
 	struct file *fp;
 	int error;
 
-	mtx_lock(&Giant);
 	if ((error = fget_write(td, uap->fd, &fp)) == 0) {
 		error = dofilewrite(td, fp, uap->fd, uap->buf, uap->nbyte,
 			    (off_t)-1, 0);
@@ -340,7 +336,6 @@
 	} else {
 		error = EBADF;	/* XXX this can't be right */
 	}
-	mtx_unlock(&Giant);
 	return(error);
 }
 
@@ -368,7 +363,6 @@
 	int error;
 
 	if ((error = fget_write(td, uap->fd, &fp)) == 0) {
-		mtx_lock(&Giant);
 		if (fp->f_type == DTYPE_VNODE) {
 			error = dofilewrite(td, fp, uap->fd, uap->buf,
 				    uap->nbyte, uap->offset, FOF_OFFSET);
@@ -376,7 +370,6 @@
 			error = ESPIPE;
 		}
 		fdrop(fp, td);
-		mtx_unlock(&Giant);
 	} else {
 		error = EBADF;	/* this can't be right */
 	}
@@ -423,8 +416,9 @@
 	}
 #endif
 	cnt = nbyte;
-	if (fp->f_type == DTYPE_VNODE)
+	if (fp->f_type == DTYPE_VNODE) {
 		bwillwrite();
+	}
 	if ((error = fo_write(fp, &auio, fp->f_cred, flags, td))) {
 		if (auio.uio_resid != cnt && (error == ERESTART ||
 		    error == EINTR || error == EWOULDBLOCK))
@@ -696,11 +690,40 @@
 	return (error);
 }
 
+/*
+ * These are initialized in selectinit() via SYSINIT
+ */
+static struct mtx sellock;
 static int	nselcoll;	/* Select collisions since boot */
 struct cv	selwait;
 SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, "");
 
 /*
+ * Remove the references to the thread from all of the objects
+ * we were polling.
+ *
+ * This code assumes that the underlying owner of the selinfo
+ * structure will hold sellock before it changes it, and that
+ * it will unlink itself from our list if it goes away.
+ */
+static void
+clear_selinfo_list(td)
+	struct thread *td;
+{
+	struct selinfo *si, *nsi;
+
+	mtx_assert(&sellock, MA_OWNED);
+
+	si = TAILQ_FIRST(&td->td_selinfo);
+	while (si != NULL) {
+		nsi = TAILQ_NEXT(si, si_thrlist);
+		si->si_thread = NULL;
+		si = nsi;
+	}
+	TAILQ_INIT(&td->td_selinfo);
+}
+
+/*
  * Select system call.
  */
 #ifndef _SYS_SYSPROTO_H_
@@ -801,34 +824,37 @@
 		atv.tv_usec = 0;
 	}
 	timo = 0;
-	PROC_LOCK(td->td_proc);
+	mtx_lock(&sellock);
 retry:
+
 	ncoll = nselcoll;
 	mtx_lock_spin(&sched_lock);
 	td->td_flags |= TDF_SELECT;
 	mtx_unlock_spin(&sched_lock);
-	PROC_UNLOCK(td->td_proc);
+	mtx_unlock(&sellock);
+
+	/* XXX Is there a better place for this? */
+	TAILQ_INIT(&td->td_selinfo);
 	error = selscan(td, ibits, obits, uap->nd);
-	PROC_LOCK(td->td_proc);
+	mtx_lock(&sellock);
 	if (error || td->td_retval[0])
 		goto done;
 	if (atv.tv_sec || atv.tv_usec) {
 		getmicrouptime(&rtv);
 		if (timevalcmp(&rtv, &atv, >=)) {
 			/*
-			 * An event of our interest may occur during locking a process.
-			 * In order to avoid missing the event that occured during locking
-			 * the process, test TDF_SELECT and rescan file descriptors if
-			 * necessary.
+			 * An event of interest may occur while we do not hold
+			 * sellock, so check TDF_SELECT and the number of collisions
+			 * and rescan the file descriptors if necessary.
 			 */
 			mtx_lock_spin(&sched_lock);
 			if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
 				ncoll = nselcoll;
 				td->td_flags |= TDF_SELECT;
 				mtx_unlock_spin(&sched_lock);
-				PROC_UNLOCK(td->td_proc);
+				mtx_unlock(&sellock);
 				error = selscan(td, ibits, obits, uap->nd);
-				PROC_LOCK(td->td_proc);
+				mtx_lock(&sellock);
 			} else
 				mtx_unlock_spin(&sched_lock);
 			goto done;
@@ -838,23 +864,28 @@
 		timo = ttv.tv_sec > 24 * 60 * 60 ?
 		    24 * 60 * 60 * hz : tvtohz(&ttv);
 	}
+
+	/* XXX What is the point of this? */
 	mtx_lock_spin(&sched_lock);
 	td->td_flags &= ~TDF_SELECT;
 	mtx_unlock_spin(&sched_lock);
 
 	if (timo > 0)
-		error = cv_timedwait_sig(&selwait, &td->td_proc->p_mtx, timo);
+		error = cv_timedwait_sig(&selwait, &sellock, timo);
 	else
-		error = cv_wait_sig(&selwait, &td->td_proc->p_mtx);
+		error = cv_wait_sig(&selwait, &sellock);
 	
 	if (error == 0)
 		goto retry;
 
 done:
+	clear_selinfo_list(td);
+
 	mtx_lock_spin(&sched_lock);
 	td->td_flags &= ~TDF_SELECT;
 	mtx_unlock_spin(&sched_lock);
-	PROC_UNLOCK(td->td_proc);
+	mtx_unlock(&sellock);
+
 done_noproclock:
 	/* select is not restarted after signals... */
 	if (error == ERESTART)
@@ -982,36 +1013,39 @@
 		atv.tv_usec = 0;
 	}
 	timo = 0;
-	PROC_LOCK(td->td_proc);
+	mtx_lock(&sellock);
 retry:
 	ncoll = nselcoll;
 	mtx_lock_spin(&sched_lock);
 	td->td_flags |= TDF_SELECT;
 	mtx_unlock_spin(&sched_lock);
-	PROC_UNLOCK(td->td_proc);
+	mtx_unlock(&sellock);
+
+	/* XXX Is there a better place for this? */
+	TAILQ_INIT(&td->td_selinfo);
 	error = pollscan(td, (struct pollfd *)bits, nfds);
-	PROC_LOCK(td->td_proc);
+	mtx_lock(&sellock);
 	if (error || td->td_retval[0])
 		goto done;
 	if (atv.tv_sec || atv.tv_usec) {
 		getmicrouptime(&rtv);
 		if (timevalcmp(&rtv, &atv, >=)) {
 			/*
-			 * An event of our interest may occur during locking a process.
-			 * In order to avoid missing the event that occured during locking
-			 * the process, test TDF_SELECT and rescan file descriptors if
-			 * necessary.
+			 * An event of interest may occur while we do not hold
+			 * sellock, so check TDF_SELECT and the number of collisions
+			 * and rescan the file descriptors if necessary.
 			 */
 			mtx_lock_spin(&sched_lock);
 			if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
 				ncoll = nselcoll;
 				td->td_flags |= TDF_SELECT;
 				mtx_unlock_spin(&sched_lock);
-				PROC_UNLOCK(td->td_proc);
+				mtx_unlock(&sellock);
 				error = pollscan(td, (struct pollfd *)bits, nfds);
-				PROC_LOCK(td->td_proc);
+				mtx_lock(&sellock);
 			} else
 				mtx_unlock_spin(&sched_lock);
+
 			goto done;
 		}
 		ttv = atv;
@@ -1019,21 +1053,28 @@
 		timo = ttv.tv_sec > 24 * 60 * 60 ?
 		    24 * 60 * 60 * hz : tvtohz(&ttv);
 	}
+
+	/* XXX What is the point of this? */
 	mtx_lock_spin(&sched_lock);
 	td->td_flags &= ~TDF_SELECT;
 	mtx_unlock_spin(&sched_lock);
+
 	if (timo > 0)
-		error = cv_timedwait_sig(&selwait, &td->td_proc->p_mtx, timo);
+		error = cv_timedwait_sig(&selwait, &sellock, timo);
 	else
-		error = cv_wait_sig(&selwait, &td->td_proc->p_mtx);
+		error = cv_wait_sig(&selwait, &sellock);
+
 	if (error == 0)
 		goto retry;
 
 done:
+	clear_selinfo_list(td);
+
 	mtx_lock_spin(&sched_lock);
 	td->td_flags &= ~TDF_SELECT;
 	mtx_unlock_spin(&sched_lock);
-	PROC_UNLOCK(td->td_proc);
+	mtx_unlock(&sellock);
+
 done_noproclock:
 	/* poll is not restarted after signals... */
 	if (error == ERESTART)
@@ -1126,18 +1167,6 @@
 	return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
 }
 
-static int
-find_thread_in_proc(struct proc *p, struct thread *td)
-{
-	struct thread *td2;
-	FOREACH_THREAD_IN_PROC(p, td2) {
-		if (td2 == td) {
-			return (1);
-		}
-	}
-	return (0);
-}
-
 /*
  * Record a select request.
  */
@@ -1146,29 +1175,21 @@
 	struct thread *selector;
 	struct selinfo *sip;
 {
-	struct proc *p;
-	pid_t mypid;
 
-	mypid = selector->td_proc->p_pid;
-	if ((sip->si_pid == mypid) &&
-	    (sip->si_thread == selector)) { /* XXXKSE should be an ID? */
-		return;
-	}
-	if (sip->si_pid &&
-	    (p = pfind(sip->si_pid)) &&
-	    (find_thread_in_proc(p, sip->si_thread))) {
-		mtx_lock_spin(&sched_lock);
-	    	if (sip->si_thread->td_wchan == (caddr_t)&selwait) {
-			mtx_unlock_spin(&sched_lock);
-			PROC_UNLOCK(p);
-			sip->si_flags |= SI_COLL;
-			return;
-		}
-		mtx_unlock_spin(&sched_lock);
-		PROC_UNLOCK(p);
+	mtx_lock(&sellock);
+	/*
+	 * If the thread is not NULL there is another thread
+	 * interested in this object, and we need to flag the
+	 * collision so selwakeup() can broadcast.
+	 */
+	if (sip->si_thread != NULL) {
+		sip->si_flags |= SI_COLL;
+	} else {
+		sip->si_thread = selector;
+		TAILQ_INSERT_TAIL(&selector->td_selinfo, sip, si_thrlist);
 	}
-	sip->si_pid = mypid;
-	sip->si_thread = selector;
+
+	mtx_unlock(&sellock);
 }
 
 /*
@@ -1176,37 +1197,37 @@
  */
 void
 selwakeup(sip)
-	register struct selinfo *sip;
+	struct selinfo *sip;
 {
 	struct thread *td;
-	register struct proc *p;
 
-	if (sip->si_pid == 0)
-		return;
-	if (sip->si_flags & SI_COLL) {
+	mtx_lock(&sellock);
+	td = sip->si_thread;
+
+	if ((sip->si_flags & SI_COLL) != 0) {
 		nselcoll++;
 		sip->si_flags &= ~SI_COLL;
 		cv_broadcast(&selwait);
 	}
-	p = pfind(sip->si_pid);
-	sip->si_pid = 0;
-	td = sip->si_thread;
-	if (p != NULL) {
-		if (!find_thread_in_proc(p, td)) {
-			PROC_UNLOCK(p); /* lock is in pfind() */;
-			return;
-		}
-		mtx_lock_spin(&sched_lock);
-		if (td->td_wchan == (caddr_t)&selwait) {
-			if (td->td_proc->p_stat == SSLEEP)
-				setrunnable(td);
-			else
-				cv_waitq_remove(td);
-		} else
-			td->td_flags &= ~TDF_SELECT;
-		mtx_unlock_spin(&sched_lock);
-		PROC_UNLOCK(p); /* Lock is in pfind() */
+	
+	if (td == NULL) {
+		mtx_unlock(&sellock);
+		return;
 	}
+
+	TAILQ_REMOVE(&td->td_selinfo, sip, si_thrlist);
+	mtx_lock_spin(&sched_lock);
+	if (td->td_wchan == (caddr_t)&selwait) {
+		if (td->td_proc->p_stat == SSLEEP)
+			setrunnable(td);
+		else
+			cv_waitq_remove(td);
+	} else
+		td->td_flags &= ~TDF_SELECT;
+	mtx_unlock_spin(&sched_lock);
+
+	sip->si_thread = NULL;
+	mtx_unlock(&sellock);
 }
 
 static void selectinit __P((void *));
@@ -1218,4 +1239,5 @@
 	void *dummy;
 {
 	cv_init(&selwait, "select");
+	mtx_init(&sellock, "sellck", MTX_DEF);
 }
Index: kern/sys_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sys_socket.c,v
retrieving revision 1.37
diff -u -r1.37 sys_socket.c
--- kern/sys_socket.c	13 Jan 2002 11:57:59 -0000	1.37
+++ kern/sys_socket.c	10 Mar 2002 08:08:37 -0000
@@ -65,7 +65,12 @@
 	int flags;
 {
 	struct socket *so = (struct socket *)fp->f_data;
-	return so->so_proto->pr_usrreqs->pru_soreceive(so, 0, uio, 0, 0, 0);
+	int error;
+
+	mtx_lock(&Giant);
+	error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, uio, 0, 0, 0);
+	mtx_unlock(&Giant);
+	return (error);
 }
 
 /* ARGSUSED */
@@ -78,8 +83,13 @@
 	int flags;
 {
 	struct socket *so = (struct socket *)fp->f_data;
-	return so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0,
+	int error;
+
+	mtx_lock(&Giant);
+	error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0,
 						    uio->uio_td);
+	mtx_unlock(&Giant);
+	return (error);
 }
 
 int
Index: kern/tty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty.c,v
retrieving revision 1.165
diff -u -r1.165 tty.c
--- kern/tty.c	2 Mar 2002 12:42:23 -0000	1.165
+++ kern/tty.c	10 Mar 2002 08:08:37 -0000
@@ -2273,7 +2273,7 @@
 	register struct tty *tp;
 {
 
-	if (tp->t_rsel.si_pid != 0)
+	if (SEL_WAITING(&tp->t_rsel))
 		selwakeup(&tp->t_rsel);
 	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
 		pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
@@ -2289,7 +2289,7 @@
 	register struct tty *tp;
 {
 
-	if (tp->t_wsel.si_pid != 0 && tp->t_outq.c_cc <= tp->t_olowat)
+	if (SEL_WAITING(&tp->t_wsel) && tp->t_outq.c_cc <= tp->t_olowat)
 		selwakeup(&tp->t_wsel);
 	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
 		pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
Index: kern/vfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.302
diff -u -r1.302 vfs_bio.c
--- kern/vfs_bio.c	5 Mar 2002 18:20:58 -0000	1.302
+++ kern/vfs_bio.c	10 Mar 2002 20:44:01 -0000
@@ -1079,6 +1079,7 @@
 	if (numdirtybuffers >= hidirtybuffers) {
 		int s;
 
+		mtx_lock(&Giant);
 		s = splbio();
 		while (numdirtybuffers >= hidirtybuffers) {
 			bd_wakeup(1);
@@ -1086,6 +1087,7 @@
 			tsleep(&needsbuffer, (PRIBIO + 4), "flswai", 0);
 		}
 		splx(s);
+		mtx_unlock(&Giant);
 	}
 }
 
Index: kern/vfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.136
diff -u -r1.136 vfs_vnops.c
--- kern/vfs_vnops.c	5 Mar 2002 15:38:49 -0000	1.136
+++ kern/vfs_vnops.c	10 Mar 2002 08:08:37 -0000
@@ -409,6 +409,7 @@
 	struct vnode *vp;
 	int error, ioflag;
 
+	mtx_lock(&Giant);
 	KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
 	    uio->uio_td, td));
 	vp = (struct vnode *)fp->f_data;
@@ -429,6 +430,7 @@
 		fp->f_offset = uio->uio_offset;
 	fp->f_nextoff = uio->uio_offset;
 	VOP_UNLOCK(vp, 0, td);
+	mtx_unlock(&Giant);
 	return (error);
 }
 
@@ -447,6 +449,7 @@
 	struct mount *mp;
 	int error, ioflag;
 
+	mtx_lock(&Giant);
 	KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
 	    uio->uio_td, td));
 	vp = (struct vnode *)fp->f_data;
@@ -464,8 +467,10 @@
 		ioflag |= IO_SYNC;
 	mp = NULL;
 	if (vp->v_type != VCHR &&
-	    (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
+	    (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
+		mtx_unlock(&Giant);
 		return (error);
+	}
 	VOP_LEASE(vp, td, cred, LEASE_WRITE);
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
 	if ((flags & FOF_OFFSET) == 0)
@@ -477,6 +482,7 @@
 	fp->f_nextoff = uio->uio_offset;
 	VOP_UNLOCK(vp, 0, td);
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);
 	return (error);
 }
 
Index: net/bpf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/bpf.c,v
retrieving revision 1.86
diff -u -r1.86 bpf.c
--- net/bpf.c	14 Dec 2001 22:17:54 -0000	1.86
+++ net/bpf.c	10 Mar 2002 08:08:37 -0000
@@ -514,8 +514,6 @@
 		pgsigio(d->bd_sigio, d->bd_sig, 0);
 
 	selwakeup(&d->bd_sel);
-	/* XXX */
-	d->bd_sel.si_pid = 0;
 }
 
 static void
Index: sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.206
diff -u -r1.206 proc.h
--- sys/proc.h	23 Feb 2002 11:12:57 -0000	1.206
+++ sys/proc.h	10 Mar 2002 08:08:37 -0000
@@ -147,6 +147,7 @@
  *      m - Giant
  *      n - not locked, lazy
  *      o - locked by pgrpsess_lock sx
+ *      p - select lock (sellock)
  *
  * If the locking key specifies two identifiers (for example, p_pptr) then
  * either lock is sufficient for read access, but both locks must be held
@@ -259,6 +260,8 @@
 	TAILQ_ENTRY(thread) td_slpq; 	/* (j) Sleep queue. XXXKSE */ 
 	TAILQ_ENTRY(thread) td_blkq; 	/* (j) Mutex queue. XXXKSE */ 
 	TAILQ_ENTRY(thread) td_runq; 	/* (j) Run queue(s). XXXKSE */ 
+
+	TAILQ_HEAD(, selinfo) td_selinfo;	/* (p) List of selinfos */
 
 #define	td_startzero td_flags
 	int		td_flags;	/* (j) TDF_* flags. */
Index: sys/selinfo.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/selinfo.h,v
retrieving revision 1.12
diff -u -r1.12 selinfo.h
--- sys/selinfo.h	27 Sep 2001 20:33:15 -0000	1.12
+++ sys/selinfo.h	10 Mar 2002 08:08:37 -0000
@@ -45,12 +45,21 @@
  * notified when I/O becomes possible.
  */
 struct selinfo {
-	pid_t	si_pid;		/* process to be notified */
+	TAILQ_ENTRY(selinfo)	si_thrlist;	/* list hung off of thread */
 	struct	thread *si_thread;	/* thread in that process XXXKSE */
 	struct	klist si_note;	/* kernel note list */
 	short	si_flags;	/* see below */
 };
 #define	SI_COLL	0x0001		/* collision occurred */
+
+#define SEL_WAITING(si)	\
+	((si)->si_thread != NULL || ((si)->si_flags & SI_COLL) != 0)
+
+#define SEL_INIT(si) \
+	do {								\
+		(si)->si_thread = NULL;					\
+		(si)->si_flags = 0;					\
+	} while (0)
 
 #ifdef _KERNEL
 struct thread;


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-smp" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020311001131.GN26621>