Date: Mon, 16 Aug 2004 04:48:52 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 59784 for review Message-ID: <200408160448.i7G4mqXN048544@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=59784 Change 59784 by rwatson@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200408160448.i7G4mqXN048544>