Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Apr 2006 22:02:14 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 94494 for review
Message-ID:  <200604022202.k32M2E0m003730@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=94494

Change 94494 by marcel@marcel_nfs on 2006/04/02 22:01:59

	IFC @94493

Affected files ...

.. //depot/projects/uart/amd64/amd64/pmap.c#28 integrate
.. //depot/projects/uart/dev/mpt/mpt.c#13 integrate
.. //depot/projects/uart/dev/uart/uart_bus.h#45 integrate
.. //depot/projects/uart/dev/uart/uart_bus_ebus.c#15 integrate
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#40 integrate
.. //depot/projects/uart/i386/i386/pmap.c#31 integrate
.. //depot/projects/uart/kern/kern_event.c#10 integrate
.. //depot/projects/uart/netinet/tcp_subr.c#16 integrate
.. //depot/projects/uart/netinet/tcp_usrreq.c#11 integrate
.. //depot/projects/uart/nfsserver/nfs_srvsubs.c#9 integrate

Differences ...

==== //depot/projects/uart/amd64/amd64/pmap.c#28 (text+ko) ====

@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.539 2006/03/21 18:07:41 alc Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.540 2006/04/02 05:45:05 alc Exp $");
 
 /*
  *	Manages physical address maps.
@@ -208,6 +208,8 @@
 static void pmap_remove_entry(struct pmap *pmap, vm_page_t m,
 		vm_offset_t va);
 static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m);
+static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
+    vm_page_t m);
 
 static vm_page_t pmap_allocpde(pmap_t pmap, vm_offset_t va, int flags);
 static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags);
@@ -1584,6 +1586,29 @@
 }
 
 /*
+ * Conditionally create a pv entry.
+ */
+static boolean_t
+pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
+{
+	pv_entry_t pv;
+
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	if (pv_entry_count < pv_entry_high_water && 
+	    (pv = uma_zalloc(pvzone, M_NOWAIT)) != NULL) {
+		pv_entry_count++;
+		pv->pv_va = va;
+		pv->pv_pmap = pmap;
+		TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
+		TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
+		m->md.pv_list_count++;
+		return (TRUE);
+	} else
+		return (FALSE);
+}
+
+/*
  * pmap_remove_pte: do the things to unmap a page in a process
  */
 static int
@@ -2370,7 +2395,6 @@
 	vm_offset_t addr;
 	vm_offset_t end_addr = src_addr + len;
 	vm_offset_t va_next;
-	vm_page_t m;
 
 	if (dst_addr != src_addr)
 		return;
@@ -2396,15 +2420,6 @@
 		if (addr >= UPT_MIN_ADDRESS)
 			panic("pmap_copy: invalid to pmap_copy page tables");
 
-		/*
-		 * Don't let optional prefaulting of pages make us go
-		 * way below the low water mark of free pages or way
-		 * above high water mark of used pv entries.
-		 */
-		if (cnt.v_free_count < cnt.v_free_reserved ||
-		    pv_entry_count > pv_entry_high_water)
-			break;
-		
 		pml4e = pmap_pml4e(src_pmap, addr);
 		if ((*pml4e & PG_V) == 0) {
 			va_next = (addr + NBPML4) & ~PML4MASK;
@@ -2467,16 +2482,16 @@
 				dst_pte = (pt_entry_t *)
 				    PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dstmpte));
 				dst_pte = &dst_pte[pmap_pte_index(addr)];
-				if (*dst_pte == 0) {
+				if (*dst_pte == 0 &&
+				    pmap_try_insert_pv_entry(dst_pmap, addr,
+				    PHYS_TO_VM_PAGE(ptetemp & PG_FRAME))) {
 					/*
 					 * Clear the modified and
 					 * accessed (referenced) bits
 					 * during the copy.
 					 */
-					m = PHYS_TO_VM_PAGE(ptetemp & PG_FRAME);
 					*dst_pte = ptetemp & ~(PG_M | PG_A);
 					dst_pmap->pm_stats.resident_count++;
-					pmap_insert_entry(dst_pmap, addr, m);
 	 			} else
 					pmap_unwire_pte_hold(dst_pmap, addr, dstmpte);
 				if (dstmpte->wire_count >= srcmpte->wire_count)

==== //depot/projects/uart/dev/mpt/mpt.c#13 (text+ko) ====

@@ -92,7 +92,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt.c,v 1.24 2006/04/01 07:12:18 mjacob Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt.c,v 1.25 2006/04/01 19:49:55 mjacob Exp $");
 
 #include <dev/mpt/mpt.h>
 #include <dev/mpt/mpt_cam.h> /* XXX For static handler registration */
@@ -1398,11 +1398,11 @@
 	    (hdr->Function != MPI_FUNCTION_IOC_FACTS)){
 #if __FreeBSD_version >= 500000
 		mpt_prt(mpt, "reply length does not match message length: "
-			"got %x; expected %x for function %x\n",
+			"got %x; expected %zx for function %x\n",
 			hdr->MsgLength << 2, reply_len << 1, hdr->Function);
 #else
 		mpt_prt(mpt, "reply length does not match message length: "
-			"got %x; expected %zx for function %x\n",
+			"got %x; expected %x for function %x\n",
 			hdr->MsgLength << 2, reply_len << 1, hdr->Function);
 #endif
 	}

==== //depot/projects/uart/dev/uart/uart_bus.h#45 (text+ko) ====

@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/uart/uart_bus.h,v 1.12 2006/03/30 18:37:03 marcel Exp $
+ * $FreeBSD: src/sys/dev/uart/uart_bus.h,v 1.13 2006/04/02 21:45:54 marcel Exp $
  */
 
 #ifndef _DEV_UART_BUS_H_
@@ -93,7 +93,6 @@
 
 	int		sc_callout:1;	/* This UART is opened for callout. */
 	int		sc_fastintr:1;	/* This UART uses fast interrupts. */
-	int		sc_hasfifo:1;	/* This UART has FIFOs. */
 	int		sc_hwiflow:1;	/* This UART has HW input flow ctl. */
 	int		sc_hwoflow:1;	/* This UART has HW output flow ctl. */
 	int		sc_leaving:1;	/* This UART is going away. */

==== //depot/projects/uart/dev/uart/uart_bus_ebus.c#15 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_ebus.c,v 1.10 2006/02/24 05:36:44 marcel Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_ebus.c,v 1.12 2006/04/02 21:58:09 marcel Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -66,7 +66,6 @@
 	const char *nm, *cmpt;
 	struct uart_softc *sc;
 	struct uart_devinfo dummy;
-	int error;
 
 	sc = device_get_softc(dev);
 	sc->sc_class = NULL;

==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#40 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/uart/uart_dev_ns8250.c,v 1.18 2006/04/01 19:04:54 marcel Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/uart/uart_dev_ns8250.c,v 1.19 2006/04/02 21:45:54 marcel Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -443,7 +443,7 @@
 
 	bas = &sc->sc_bas;
 	uart_lock(sc->sc_hwmtx);
-	if (sc->sc_hasfifo) {
+	if (sc->sc_rxfifosz > 1) {
 		ns8250_flush(bas, what);
 		uart_setreg(bas, REG_FCR, ns8250->fcr);
 		uart_barrier(bas);
@@ -635,14 +635,14 @@
 	 */
 	uart_setreg(bas, REG_FCR, FCR_ENABLE);
 	uart_barrier(bas);
-	sc->sc_hasfifo = (uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK) ? 1 : 0;
-	if (!sc->sc_hasfifo) {
+	if (!(uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK)) {
 		/*
 		 * NS16450 or INS8250. We don't bother to differentiate
 		 * between them. They're too old to be interesting.
 		 */
 		uart_setreg(bas, REG_MCR, mcr);
 		uart_barrier(bas);
+		sc->sc_rxfifosz = sc->sc_txfifosz = 1;
 		device_set_desc(sc->sc_dev, "8250 or 16450 or compatible");
 		return (0);
 	}

==== //depot/projects/uart/i386/i386/pmap.c#31 (text+ko) ====

@@ -75,7 +75,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/i386/i386/pmap.c,v 1.546 2006/03/21 18:07:42 alc Exp $");
+__FBSDID("$FreeBSD: src/sys/i386/i386/pmap.c,v 1.547 2006/04/02 05:45:05 alc Exp $");
 
 /*
  *	Manages physical address maps.
@@ -263,6 +263,8 @@
 static void pmap_remove_entry(struct pmap *pmap, vm_page_t m,
 					vm_offset_t va);
 static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m);
+static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
+    vm_page_t m);
 
 static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags);
 
@@ -1587,6 +1589,29 @@
 }
 
 /*
+ * Conditionally create a pv entry.
+ */
+static boolean_t
+pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
+{
+	pv_entry_t pv;
+
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	if (pv_entry_count < pv_entry_high_water && 
+	    (pv = uma_zalloc(pvzone, M_NOWAIT)) != NULL) {
+		pv_entry_count++;
+		pv->pv_va = va;
+		pv->pv_pmap = pmap;
+		TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
+		TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
+		m->md.pv_list_count++;
+		return (TRUE);
+	} else
+		return (FALSE);
+}
+
+/*
  * pmap_remove_pte: do the things to unmap a page in a process
  */
 static int
@@ -2341,7 +2366,6 @@
 	vm_offset_t addr;
 	vm_offset_t end_addr = src_addr + len;
 	vm_offset_t pdnxt;
-	vm_page_t m;
 
 	if (dst_addr != src_addr)
 		return;
@@ -2367,15 +2391,6 @@
 		if (addr >= UPT_MIN_ADDRESS)
 			panic("pmap_copy: invalid to pmap_copy page tables");
 
-		/*
-		 * Don't let optional prefaulting of pages make us go
-		 * way below the low water mark of free pages or way
-		 * above high water mark of used pv entries.
-		 */
-		if (cnt.v_free_count < cnt.v_free_reserved ||
-		    pv_entry_count > pv_entry_high_water)
-			break;
-		
 		pdnxt = (addr + NBPDR) & ~PDRMASK;
 		ptepindex = addr >> PDRSHIFT;
 
@@ -2417,16 +2432,16 @@
 				if (dstmpte == NULL)
 					break;
 				dst_pte = pmap_pte_quick(dst_pmap, addr);
-				if (*dst_pte == 0) {
+				if (*dst_pte == 0 &&
+				    pmap_try_insert_pv_entry(dst_pmap, addr,
+				    PHYS_TO_VM_PAGE(ptetemp & PG_FRAME))) {
 					/*
 					 * Clear the modified and
 					 * accessed (referenced) bits
 					 * during the copy.
 					 */
-					m = PHYS_TO_VM_PAGE(ptetemp);
 					*dst_pte = ptetemp & ~(PG_M | PG_A);
 					dst_pmap->pm_stats.resident_count++;
-					pmap_insert_entry(dst_pmap, addr, m);
 	 			} else
 					pmap_unwire_pte_hold(dst_pmap, dstmpte);
 				if (dstmpte->wire_count >= srcmpte->wire_count)

==== //depot/projects/uart/kern/kern_event.c#10 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_event.c,v 1.96 2006/03/29 18:15:30 jmg Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_event.c,v 1.97 2006/04/01 20:15:39 jmg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -887,6 +887,8 @@
 			kev->fflags = 0;
 			kev->data = 0;
 			kn->kn_kevent = *kev;
+			kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
+			    EV_ENABLE | EV_DISABLE);
 			kn->kn_status = KN_INFLUX|KN_DETACHED;
 
 			error = knote_attach(kn, kq);

==== //depot/projects/uart/netinet/tcp_subr.c#16 (text+ko) ====

@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)tcp_subr.c	8.2 (Berkeley) 5/24/95
- * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.238 2006/04/01 16:36:36 rwatson Exp $
+ * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.239 2006/04/01 23:53:25 rwatson Exp $
  */
 
 #include "opt_compat.h"
@@ -1823,10 +1823,14 @@
 	struct inpcb *inp;
 
 	/*
-	 * At this point, we should have an inpcb<->twtcp pair, with no
-	 * associated socket.  Validate that this is the case.
+	 * At this point, we are in one of two situations:
+	 *
+	 * (1) We have no socket, just an inpcb<->twtcp pair.  Release it all
+	 * after validating.
 	 *
-	 * XXXRW: This comment stale -- could still have socket ...?
+	 * (2) We have a socket, which we may or may now own the reference
+	 * for.  If we own the reference, release all the state after
+	 * validating.  If not, leave it for the socket close to clean up.
 	 */
 	inp = tw->tw_inpcb;
 	KASSERT((inp->inp_vflag & INP_TIMEWAIT), ("tcp_twclose: !timewait"));
@@ -1840,32 +1844,45 @@
 	inp->inp_vflag |= INP_DROPPED;
 
 	so = inp->inp_socket;
-	if (so != NULL && inp->inp_vflag & INP_SOCKREF) {
-		KASSERT(so->so_state & SS_PROTOREF,
-		    ("tcp_twclose: !SS_PROTOREF"));
-		inp->inp_vflag &= ~INP_SOCKREF;
+	if (so != NULL) {
+		if (inp->inp_vflag & INP_SOCKREF) {
+			/*
+			 * If a socket is present, and we own the only
+			 * reference, we need to tear down the socket and the
+			 * inpcb.
+			 */
+			inp->inp_vflag &= ~INP_SOCKREF;
 #ifdef INET6
-		if (inp->inp_vflag & INP_IPV6PROTO) {
-			in6_pcbdetach(inp);
-			in6_pcbfree(inp);
+			if (inp->inp_vflag & INP_IPV6PROTO) {
+				in6_pcbdetach(inp);
+				in6_pcbfree(inp);
+			} else {
+				in_pcbdetach(inp);
+				in_pcbfree(inp);
+			}
+#endif
+			ACCEPT_LOCK();
+			SOCK_LOCK(so);
+			KASSERT(so->so_state & SS_PROTOREF,
+			    ("tcp_twclose: INP_SOCKREF && !SS_PROTOREF"));
+			so->so_state &= ~SS_PROTOREF;
+			sofree(so);
 		} else {
-			in_pcbdetach(inp);
-			in_pcbfree(inp);
+			/*
+			 * If we don't own the only reference, the socket and
+			 * inpcb need to be left around to be handled by
+			 * tcp_usr_detach() later.
+			 */
+			INP_UNLOCK(inp);
 		}
-#endif
-		ACCEPT_LOCK();
-		SOCK_LOCK(so);
-		so->so_state &= ~SS_PROTOREF;
-		sofree(so);
-	} else if (so == NULL) {
+	} else {
 #ifdef INET6
 		if (inp->inp_vflag & INP_IPV6PROTO)
 			in6_pcbfree(inp);
 		else
 #endif
 			in_pcbfree(inp);
-	} else
-		printf("tcp_twclose: so != NULL but !INP_SOCKREF");
+	}
 	tcpstat.tcps_closed++;
 	crfree(tw->tw_cred);
 	tw->tw_cred = NULL;

==== //depot/projects/uart/netinet/tcp_usrreq.c#11 (text+ko) ====

@@ -29,7 +29,7 @@
  * SUCH DAMAGE.
  *
  *	From: @(#)tcp_usrreq.c	8.2 (Berkeley) 1/3/94
- * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.131 2006/04/01 16:36:36 rwatson Exp $
+ * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.133 2006/04/02 16:42:51 rwatson Exp $
  */
 
 #include "opt_inet.h"
@@ -161,16 +161,33 @@
 	INP_LOCK(inp);
 	KASSERT(inp->inp_socket != NULL,
 	    ("tcp_usr_detach: inp_socket == NULL"));
+	TCPDEBUG1();
 
-	TCPDEBUG1();
-	tp = intotcpcb(inp);
+	/*
+	 * First, if we still have full TCP state, and we're not dropped,
+	 * initiate a disconnect.
+	 */
+	if (!(inp->inp_vflag & INP_TIMEWAIT) &&
+	    !(inp->inp_vflag & INP_DROPPED)) {
+		tp = intotcpcb(inp);
+		tcp_disconnect(tp);
+	}
 
+	/*
+	 * Second, release any protocol state that we can reasonably release.
+	 * Note that the call to tcp_disconnect() may actually have changed
+	 * the TCP state, so we have to re-evaluate INP_TIMEWAIT and
+	 * INP_DROPPED.
+	 */
 	if (inp->inp_vflag & INP_TIMEWAIT) {
 		if (inp->inp_vflag & INP_DROPPED) {
 			/*
 			 * Connection was in time wait and has been dropped;
-			 * the calling path is via tcp_twclose(), which will
-			 * free the tcptw, so we can discard the remainder.
+			 * the calling path is either via tcp_twclose(), or
+			 * as a result of an eventual soclose() after
+			 * tcp_twclose() has been called.  In either case,
+			 * tcp_twclose() has detached the tcptw from the
+			 * inpcb, so we just detach and free the inpcb.
 			 *
 			 * XXXRW: Would it be cleaner to free the tcptw
 			 * here?
@@ -222,10 +239,6 @@
 			}
 #endif
 		} else {
-			/*
-			 * Connection state still required, as is socket, so
-			 * mark socket for TCP to free later.
-			 */
 			SOCK_LOCK(so);
 			so->so_state |= SS_PROTOREF;
 			SOCK_UNLOCK(so);
@@ -1447,7 +1460,8 @@
 		soisdisconnecting(so);
 		sbflush(&so->so_rcv);
 		tcp_usrclosed(tp);
-		tcp_output(tp);
+		if (!(inp->inp_vflag & INP_DROPPED))
+			tcp_output(tp);
 	}
 }
 

==== //depot/projects/uart/nfsserver/nfs_srvsubs.c#9 (text+ko) ====

@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsubs.c,v 1.139 2006/03/31 03:54:19 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsubs.c,v 1.140 2006/04/02 04:24:57 cel Exp $");
 
 /*
  * These functions support the macros and help fiddle mbuf chains for
@@ -1399,6 +1399,7 @@
 nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos)
 {
 	u_int32_t *tl;
+	int toclient = 0;
 
 	NFSD_LOCK_DONTCARE();
 
@@ -1447,9 +1448,11 @@
 		if (tl == NULL)
 			return EBADRPC;
 		fxdr_nfsv3time(tl, &(a)->va_atime);
+		toclient = 1;
 		break;
 	case NFSV3SATTRTIME_TOSERVER:
 		getnanotime(&(a)->va_atime);
+		a->va_vaflags |= VA_UTIMES_NULL;
 		break;
 	}
 	tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
@@ -1461,9 +1464,12 @@
 		if (tl == NULL)
 			return EBADRPC;
 		fxdr_nfsv3time(tl, &(a)->va_mtime);
+		a->va_vaflags &= ~VA_UTIMES_NULL;
 		break;
 	case NFSV3SATTRTIME_TOSERVER:
 		getnanotime(&(a)->va_mtime);
+		if (toclient == 0)
+			a->va_vaflags |= VA_UTIMES_NULL;
 		break;
 	}
 	return 0;



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