PERFORCE change 59784 for review

Robert Watson rwatson at FreeBSD.org
Sun Aug 15 21:48:53 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=59784

Change 59784 by rwatson at rwatson_tislabs on 2004/08/16 04:48:47

	Integrate netperf_socket:
	
	- Fixes to kqueue locking.
	- Loop back of UNP_LOCK() around "unp = sotounpcb(so)" in UNIX domain
	  sockets.

Affected files ...

.. //depot/projects/netperf_socket/sys/kern/kern_descrip.c#17 integrate
.. //depot/projects/netperf_socket/sys/kern/kern_event.c#11 integrate
.. //depot/projects/netperf_socket/sys/kern/uipc_usrreq.c#24 integrate
.. //depot/projects/netperf_socket/sys/vm/vm_map.c#21 integrate

Differences ...

==== //depot/projects/netperf_socket/sys/kern/kern_descrip.c#17 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_descrip.c,v 1.242 2004/08/15 06:24:40 jmg Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_descrip.c,v 1.243 2004/08/16 03:09:01 green Exp $");
 
 #include "opt_compat.h"
 
@@ -684,7 +684,6 @@
 	fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
 	if (new > fdp->fd_lastfile)
 		fdp->fd_lastfile = new;
-	FILEDESC_UNLOCK(fdp);
 	*retval = new;
 
 	/*
@@ -695,7 +694,8 @@
 	 * XXX this duplicates parts of close().
 	 */
 	if (delfp != NULL) {
-		/* XXX need to call knote_fdclose() */
+		knote_fdclose(td, new);
+		FILEDESC_UNLOCK(fdp);
 		mtx_lock(&Giant);
 		(void) closef(delfp, td);
 		mtx_unlock(&Giant);
@@ -709,6 +709,8 @@
 			}
 			FILEDESC_UNLOCK(fdp);
 		}
+	} else {
+		FILEDESC_UNLOCK(fdp);
 	}
 	return (0);
 }

==== //depot/projects/netperf_socket/sys/kern/kern_event.c#11 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_event.c,v 1.78 2004/08/15 06:27:49 jmg Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_event.c,v 1.79 2004/08/16 03:08:38 green Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1050,7 +1050,7 @@
 {
 	struct kevent *kevp;
 	struct timeval atv, rtv, ttv;
-	struct knote *kn, marker;
+	struct knote *kn, *marker;
 	int count, timeout, nkev, error;
 	int haskqglobal;
 
@@ -1058,7 +1058,6 @@
 	nkev = 0;
 	error = 0;
 	haskqglobal = 0;
-	marker.kn_status = KN_MARKER;
 
 	if (maxevents == 0)
 		goto done_nl;
@@ -1081,6 +1080,12 @@
 		atv.tv_usec = 0;
 		timeout = 0;
 	}
+	marker = knote_alloc(1);
+	if (marker == NULL) {
+		error = ENOMEM;
+		goto done_nl;
+	}
+	marker->kn_status = KN_MARKER;
 	KQ_LOCK(kq);
 	goto start;
 
@@ -1115,12 +1120,12 @@
 		goto done;
 	}
 
-	TAILQ_INSERT_TAIL(&kq->kq_head, &marker, kn_tqe);
+	TAILQ_INSERT_TAIL(&kq->kq_head, marker, kn_tqe);
 	while (count) {
 		KQ_OWNED(kq);
 		kn = TAILQ_FIRST(&kq->kq_head);
 
-		if ((kn->kn_status == KN_MARKER && kn != &marker) ||
+		if ((kn->kn_status == KN_MARKER && kn != marker) ||
 		    (kn->kn_status & KN_INFLUX) == KN_INFLUX) {
 			kq->kq_state |= KQ_FLUXWAIT;
 			error = msleep(kq, &kq->kq_lock, PSOCK,
@@ -1134,7 +1139,7 @@
 			kq->kq_count--;
 			continue;
 		}
-		if (kn == &marker) {
+		if (kn == marker) {
 			KQ_FLUX_WAKEUP(kq);
 			if (count == maxevents)
 				goto retry;
@@ -1200,11 +1205,12 @@
 				break;
 		}
 	}
-	TAILQ_REMOVE(&kq->kq_head, &marker, kn_tqe);
+	TAILQ_REMOVE(&kq->kq_head, marker, kn_tqe);
 done:
 	KQ_OWNED(kq);
 	KQ_UNLOCK_FLUX(kq);
 	KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal);
+	knote_free(marker);
 done_nl:
 	KQ_NOTOWNED(kq);
 	if (nkev != 0)

==== //depot/projects/netperf_socket/sys/kern/uipc_usrreq.c#24 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.137 2004/08/16 01:52:04 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.138 2004/08/16 04:41:03 rwatson Exp $");
 
 #include "opt_mac.h"
 
@@ -128,11 +128,14 @@
 static int
 uipc_abort(struct socket *so)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 
-	if (unp == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-	UNP_LOCK();
+	}
 	unp_drop(unp, ECONNABORTED);
 	unp_detach(unp);	/* NB: unlocks */
 	SOCK_LOCK(so);
@@ -143,12 +146,9 @@
 static int
 uipc_accept(struct socket *so, struct sockaddr **nam)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	const struct sockaddr *sa;
 
-	if (unp == NULL)
-		return (EINVAL);
-
 	/*
 	 * Pass back name of connected socket,
 	 * if it was bound and we are still connected
@@ -156,6 +156,13 @@
 	 */
 	*nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
 	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
+		free(*nam, M_SONAME);
+		*nam = NULL;
+		return (EINVAL);
+	}
 	if (unp->unp_conn != NULL && unp->unp_conn->unp_addr != NULL)
 		sa = (struct sockaddr *) unp->unp_conn->unp_addr;
 	else
@@ -178,12 +185,18 @@
 static int
 uipc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
+	int error;
 
-	if (unp == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-
-	return (unp_bind(unp, nam, td));
+	}
+	error = unp_bind(unp, nam, td);
+	UNP_UNLOCK();
+	return (error);
 }
 
 static int
@@ -197,11 +210,10 @@
 	UNP_LOCK();
 	unp = sotounpcb(so);
 	if (unp == NULL) {
-		error = EINVAL;
-		goto out;
+		UNP_UNLOCK();
+		return (EINVAL);
 	}
 	error = unp_connect(so, nam, td);
-out:
 	UNP_UNLOCK();
 	return (error);
 }
@@ -209,13 +221,15 @@
 int
 uipc_connect2(struct socket *so1, struct socket *so2)
 {
-	struct unpcb *unp = sotounpcb(so1);
+	struct unpcb *unp;
 	int error;
 
-	if (unp == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so1);
+	if (unp == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-
-	UNP_LOCK();
+	}
 	error = unp_connect2(so1, so2);
 	UNP_UNLOCK();
 	return (error);
@@ -226,12 +240,14 @@
 static int
 uipc_detach(struct socket *so)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 
-	if (unp == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-
-	UNP_LOCK();
+	}
 	unp_detach(unp);	/* NB: unlocks unp */
 	return (0);
 }
@@ -239,11 +255,14 @@
 static int
 uipc_disconnect(struct socket *so)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 
-	if (unp == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-	UNP_LOCK();
+	}
 	unp_disconnect(unp);
 	UNP_UNLOCK();
 	return (0);
@@ -252,12 +271,15 @@
 static int
 uipc_listen(struct socket *so, struct thread *td)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	int error;
 
-	if (unp == NULL || unp->unp_vnode == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL || unp->unp_vnode == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-	UNP_LOCK();
+	}
 	error = unp_listen(unp, td);
 	UNP_UNLOCK();
 	return (error);
@@ -266,13 +288,18 @@
 static int
 uipc_peeraddr(struct socket *so, struct sockaddr **nam)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	const struct sockaddr *sa;
 
-	if (unp == NULL)
-		return (EINVAL);
 	*nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
 	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
+		free(*nam, M_SONAME);
+		*nam = NULL;
+		return (EINVAL);
+	}
 	if (unp->unp_conn != NULL && unp->unp_conn->unp_addr!= NULL)
 		sa = (struct sockaddr *) unp->unp_conn->unp_addr;
 	else {
@@ -291,12 +318,10 @@
 static int
 uipc_rcvd(struct socket *so, int flags)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	struct socket *so2;
 	u_long newhiwat;
 
-	if (unp == NULL)
-		return (EINVAL);
 	/*
 	 * Reorder locks to avoid LORs.  Note that we
 	 * delay re-locking so_rcv to below so it can
@@ -304,6 +329,12 @@
 	 */
 	SOCKBUF_UNLOCK(&so>so_rcv);
 	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
+		return (EINVAL);
+	}
+	UNP_LOCK();
 	switch (so->so_type) {
 	case SOCK_DGRAM:
 		panic("uipc_rcvd DGRAM?");
@@ -346,10 +377,11 @@
 	  struct mbuf *control, struct thread *td)
 {
 	int error = 0;
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	struct socket *so2;
 	u_long newhiwat;
 
+	unp = sotounpcb(so);
 	if (unp == NULL) {
 		error = EINVAL;
 		goto release;
@@ -367,6 +399,12 @@
 	 */
 	SOCKBUF_UNLOCK(&so->so_snd);
 	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
+		error = EINVAL;
+		goto dispose_release;
+	}
 	SOCKBUF_LOCK(&so->so_snd);
 
 	switch (so->so_type) {
@@ -474,6 +512,7 @@
 	}
 	UNP_UNLOCK();
 
+dispose_release:
 	if (control != NULL && error != 0)
 		unp_dispose(control);
 
@@ -488,12 +527,15 @@
 static int
 uipc_sense(struct socket *so, struct stat *sb)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	struct socket *so2;
 
-	if (unp == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-	UNP_LOCK();
+	}
 	sb->st_blksize = so->so_snd.sb_hiwat;
 	if (so->so_type == SOCK_STREAM && unp->unp_conn != NULL) {
 		so2 = unp->unp_conn->unp_socket;
@@ -510,11 +552,14 @@
 static int
 uipc_shutdown(struct socket *so)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 
-	if (unp == NULL)
+	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
 		return (EINVAL);
-	UNP_LOCK();
+	}
 	/* XXX socket lock? */
 	socantsendmore(so);
 	unp_shutdown(unp);
@@ -525,13 +570,18 @@
 static int
 uipc_sockaddr(struct socket *so, struct sockaddr **nam)
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	const struct sockaddr *sa;
 
-	if (unp == NULL)
-		return (EINVAL);
 	*nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
 	UNP_LOCK();
+	unp = sotounpcb(so);
+	if (unp == NULL) {
+		UNP_UNLOCK();
+		free(*nam, M_SONAME);
+		*nam = NULL;
+		return (EINVAL);
+	}
 	if (unp->unp_addr != NULL)
 		sa = (struct sockaddr *) unp->unp_addr;
 	else
@@ -554,7 +604,7 @@
 	struct socket *so;
 	struct sockopt *sopt;
 {
-	struct unpcb *unp = sotounpcb(so);
+	struct unpcb *unp;
 	struct xucred xu;
 	int error;
 
@@ -564,6 +614,12 @@
 		case LOCAL_PEERCRED:
 			error = 0;
 			UNP_LOCK();
+			unp = sotounpcb(so);
+			if (unp == NULL) {
+				UNP_UNLOCK();
+				error = EINVAL;
+				break;
+			}
 			if (unp->unp_flags & UNP_HAVEPC)
 				xu = unp->unp_peercred;
 			else {
@@ -656,9 +712,9 @@
 	unp_count++;
 	LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead
 			 : &unp_shead, unp, unp_link);
+	so->so_pcb = unp;
 	UNP_UNLOCK();
 
-	so->so_pcb = unp;
 	return (0);
 }
 
@@ -725,6 +781,8 @@
 	struct nameidata nd;
 	char *buf;
 
+	UNP_LOCK_ASSERT();
+
 	/*
 	 * XXXRW: This test-and-set of unp_vnode is non-atomic; the
 	 * unlocked read here is fine, but the value of unp_vnode needs
@@ -738,6 +796,8 @@
 	if (namelen <= 0)
 		return (EINVAL);
 
+	UNP_UNLOCK();
+
 	buf = malloc(namelen + 1, M_TEMP, M_WAITOK);
 	strlcpy(buf, soun->sun_path, namelen + 1);
 
@@ -795,6 +855,7 @@
 done:
 	mtx_unlock(&Giant);
 	free(buf, M_TEMP);
+	UNP_LOCK();
 	return (error);
 }
 

==== //depot/projects/netperf_socket/sys/vm/vm_map.c#21 (text+ko) ====

@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/vm/vm_map.c,v 1.358 2004/08/14 18:57:41 alc Exp $");
+__FBSDID("$FreeBSD: src/sys/vm/vm_map.c,v 1.359 2004/08/16 03:11:09 green Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -2236,8 +2236,12 @@
 
 		/*
 		 * Wait for wiring or unwiring of an entry to complete.
+		 * Also wait for any system wirings to disappear on
+		 * user maps.
 		 */
-		if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0) {
+		if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0 ||
+		    (vm_map_pmap(map) != kernel_pmap &&
+		    vm_map_entry_system_wired_count(entry) != 0)) {
 			unsigned int last_timestamp;
 			vm_offset_t saved_start;
 			vm_map_entry_t tmp_entry;


More information about the p4-projects mailing list