Module Name:    src
Committed By:   pooka
Date:           Mon Aug 16 17:33:52 UTC 2010

Modified Files:
        src/sys/rump/net/lib/libshmif: if_shmem.c shmif_busops.c

Log Message:
simplify, improve, etc.


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/rump/net/lib/libshmif/if_shmem.c
cvs rdiff -u -r1.4 -r1.5 src/sys/rump/net/lib/libshmif/shmif_busops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/net/lib/libshmif/if_shmem.c
diff -u src/sys/rump/net/lib/libshmif/if_shmem.c:1.25 src/sys/rump/net/lib/libshmif/if_shmem.c:1.26
--- src/sys/rump/net/lib/libshmif/if_shmem.c:1.25	Sun Aug 15 21:57:58 2010
+++ src/sys/rump/net/lib/libshmif/if_shmem.c	Mon Aug 16 17:33:52 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_shmem.c,v 1.25 2010/08/15 21:57:58 pooka Exp $	*/
+/*	$NetBSD: if_shmem.c,v 1.26 2010/08/16 17:33:52 pooka Exp $	*/
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.25 2010/08/15 21:57:58 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.26 2010/08/16 17:33:52 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -69,8 +69,8 @@
 	int sc_memfd;
 	int sc_kq;
 
+	uint64_t sc_devgen;
 	uint32_t sc_nextpacket;
-	uint32_t sc_prevgen;
 };
 
 static const uint32_t busversion = SHMIF_VERSION;
@@ -157,7 +157,7 @@
 	}
 
 	sc->sc_nextpacket = sc->sc_busmem->shm_last;
-	sc->sc_prevgen = sc->sc_busmem->shm_gen;
+	sc->sc_devgen = sc->sc_busmem->shm_gen;
 	shmif_unlockbus(sc->sc_busmem);
 
 	sc->sc_kq = rumpuser_writewatchfile_setup(-1, sc->sc_memfd, 0, &error);
@@ -171,7 +171,7 @@
 	ifp->if_ioctl = shmif_ioctl;
 	ifp->if_start = shmif_start;
 	ifp->if_stop = shmif_stop;
-	ifp->if_mtu = 1518;
+	ifp->if_mtu = ETHERMTU;
 
 	if_attach(ifp);
 	ether_ifattach(ifp, enaddr);
@@ -223,13 +223,16 @@
 shmif_start(struct ifnet *ifp)
 {
 	struct shmif_sc *sc = ifp->if_softc;
+	struct shmif_mem *busmem = sc->sc_busmem;
 	struct mbuf *m, *m0;
-	uint32_t lastoff, dataoff, npktlenoff;
-	uint32_t pktsize;
+	uint32_t dataoff;
+	uint32_t pktsize, pktwrote;
 	bool wrote = false;
 	bool wrap;
 	int error;
 
+	ifp->if_flags |= IFF_OACTIVE;
+
 	for (;;) {
 		struct shmif_pkthdr sp;
 		struct timeval tv;
@@ -243,29 +246,31 @@
 		for (m = m0; m != NULL; m = m->m_next) {
 			pktsize += m->m_len;
 		}
+		KASSERT(pktsize <= ETHERMTU + ETHER_HDR_LEN);
 
 		getmicrouptime(&tv);
-
 		sp.sp_len = pktsize;
 		sp.sp_sec = tv.tv_sec;
 		sp.sp_usec = tv.tv_usec;
 
-		shmif_lockbus(sc->sc_busmem);
-		lastoff = sc->sc_busmem->shm_last;
-		npktlenoff = shmif_nextpktoff(sc->sc_busmem, lastoff);
+		shmif_lockbus(busmem);
+		KASSERT(busmem->shm_magic == SHMIF_MAGIC);
+		busmem->shm_last = shmif_nextpktoff(busmem, busmem->shm_last);
 
 		wrap = false;
-		dataoff = shmif_buswrite(sc->sc_busmem,
-		    npktlenoff, &sp, sizeof(sp), &wrap);
+		dataoff = shmif_buswrite(busmem,
+		    busmem->shm_last, &sp, sizeof(sp), &wrap);
+		pktwrote = 0;
 		for (m = m0; m != NULL; m = m->m_next) {
-			dataoff = shmif_buswrite(sc->sc_busmem, dataoff,
+			pktwrote += m->m_len;
+			dataoff = shmif_buswrite(busmem, dataoff,
 			    mtod(m, void *), m->m_len, &wrap);
 		}
+		KASSERT(pktwrote == pktsize);
 
 		if (wrap)
-			sc->sc_busmem->shm_gen++;
-		sc->sc_busmem->shm_last = npktlenoff;
-		shmif_unlockbus(sc->sc_busmem);
+			busmem->shm_gen++;
+		shmif_unlockbus(busmem);
 
 		m_freem(m0);
 		wrote = true;
@@ -273,6 +278,9 @@
 		DPRINTF(("shmif_start: send %d bytes at off %d\n",
 		    pktsize, npktlenoff));
 	}
+
+	ifp->if_flags &= ~IFF_OACTIVE;
+
 	/* wakeup */
 	if (wrote)
 		rumpuser_pwrite(sc->sc_memfd,
@@ -291,9 +299,10 @@
 {
 	struct ifnet *ifp = arg;
 	struct shmif_sc *sc = ifp->if_softc;
+	struct shmif_mem *busmem = sc->sc_busmem;
 	struct mbuf *m = NULL;
 	struct ether_header *eth;
-	uint32_t nextpkt, lastpkt, busgen, lastnext;
+	uint32_t nextpkt, busgen;
 	bool wrap;
 	int error;
 
@@ -305,26 +314,19 @@
 			MCLGET(m, M_WAIT);
 		}
 
-		DPRINTF(("waiting %d/%d\n", sc->sc_nextpacket, sc->sc_prevgen));
-
+		DPRINTF(("waiting %d/%d\n", sc->sc_nextpacket, sc->sc_devgen));
 		KASSERT(m->m_flags & M_EXT);
-		shmif_lockbus(sc->sc_busmem);
-		lastpkt = sc->sc_busmem->shm_last;
-		busgen = sc->sc_busmem->shm_gen;
-		lastnext = shmif_nextpktoff(sc->sc_busmem, lastpkt);
-		if ((lastnext > sc->sc_nextpacket && busgen > sc->sc_prevgen)
-		    || (busgen > sc->sc_prevgen+1)) {
-			nextpkt = lastpkt;
-			sc->sc_prevgen = busgen;
-			rumpuser_dprintf("shmif_rcv: generation overrun, "
-			    "skipping invalid packets\n");
-		} else {
-			nextpkt = sc->sc_nextpacket;
-		}
+
+		shmif_lockbus(busmem);
+		busgen = busmem->shm_gen;
+		KASSERT(busmem->shm_magic == SHMIF_MAGIC);
+		KASSERT(busgen >= sc->sc_devgen);
 
 		/* need more data? */
-		if (lastnext == nextpkt && sc->sc_prevgen == busgen){
-			shmif_unlockbus(sc->sc_busmem);
+		if (sc->sc_devgen == busgen && 
+		    shmif_nextpktoff(busmem, busmem->shm_last)
+		     == sc->sc_nextpacket) {
+			shmif_unlockbus(busmem);
 			error = 0;
 			rumpuser_writewatchfile_wait(sc->sc_kq, NULL, &error);
 			if (__predict_false(error))
@@ -332,22 +334,48 @@
 			continue;
 		}
 
+		/*
+		 * Check if we have been sleeping too long.  There are
+		 * basically two scenarios:
+		 *  1) our next packet is behind the first packet and
+		 *     we are a generation behind
+		 *  2) we are over two generations behind
+		 */
+		if ((sc->sc_nextpacket < busmem->shm_first
+		  && sc->sc_devgen < busgen) || (sc->sc_devgen+1 < busgen)) {
+			KASSERT(busgen > 0);
+			nextpkt = busmem->shm_first;
+			if (busmem->shm_first > busmem->shm_last)
+				sc->sc_devgen = busgen - 1;
+			else
+				sc->sc_devgen = busgen;
+		} else {
+			nextpkt = sc->sc_nextpacket;
+		}
+
+		/*
+		 * If our read pointer is ahead the bus last write, our
+		 * generation must be one behind.
+		 */
+		KASSERT(!(nextpkt > busmem->shm_last
+		    && sc->sc_devgen == busgen));
+
 		wrap = false;
-		shmif_busread(sc->sc_busmem,
-		    &sp, nextpkt, sizeof(sp), &wrap);
-		KASSERT(sp.sp_len <= MCLBYTES);
-		shmif_busread(sc->sc_busmem, mtod(m, void *),
-		    shmif_advance(nextpkt, sizeof(sp)), sp.sp_len, &wrap);
-		if (wrap)
-			sc->sc_prevgen = sc->sc_busmem->shm_gen;
+		nextpkt = shmif_busread(busmem, &sp,
+		    nextpkt, sizeof(sp), &wrap);
+		KASSERT(sp.sp_len <= ETHERMTU + ETHER_HDR_LEN);
+		nextpkt = shmif_busread(busmem, mtod(m, void *),
+		    nextpkt, sp.sp_len, &wrap);
 
 		DPRINTF(("shmif_rcv: read packet of length %d at %d\n",
 		    sp.sp_len, nextpkt));
 
-		sc->sc_nextpacket = shmif_nextpktoff(sc->sc_busmem, nextpkt);
-		sc->sc_prevgen = busgen;
+		sc->sc_nextpacket = nextpkt;
 		shmif_unlockbus(sc->sc_busmem);
 
+		if (wrap)
+			sc->sc_devgen++;
+
 		m->m_len = m->m_pkthdr.len = sp.sp_len;
 		m->m_pkthdr.rcvif = ifp;
 

Index: src/sys/rump/net/lib/libshmif/shmif_busops.c
diff -u src/sys/rump/net/lib/libshmif/shmif_busops.c:1.4 src/sys/rump/net/lib/libshmif/shmif_busops.c:1.5
--- src/sys/rump/net/lib/libshmif/shmif_busops.c:1.4	Sun Aug 15 18:55:03 2010
+++ src/sys/rump/net/lib/libshmif/shmif_busops.c	Mon Aug 16 17:33:52 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: shmif_busops.c,v 1.4 2010/08/15 18:55:03 pooka Exp $	*/
+/*	$NetBSD: shmif_busops.c,v 1.5 2010/08/16 17:33:52 pooka Exp $	*/
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: shmif_busops.c,v 1.4 2010/08/15 18:55:03 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: shmif_busops.c,v 1.5 2010/08/16 17:33:52 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -49,9 +49,8 @@
 
 	newoff = oldoff + delta;
 	if (newoff >= BUSMEM_DATASIZE)
-		newoff -= (BUSMEM_DATASIZE);
+		newoff -= BUSMEM_DATASIZE;
 	return newoff;
-
 }
 
 uint32_t
@@ -60,7 +59,7 @@
 {
 	size_t chunk;
 
-	KASSERT(len < (BUSMEM_DATASIZE) && off <= BUSMEM_DATASIZE);
+	KASSERT(len < (BUSMEM_DATASIZE/2) && off <= BUSMEM_DATASIZE);
 	chunk = MIN(len, BUSMEM_DATASIZE - off);
 	memcpy(dest, busmem->shm_data + off, chunk);
 	len -= chunk;
@@ -69,12 +68,11 @@
 		return off + chunk;
 
 	/* else, wraps around */
-	off = 0;
 	*wrap = true;
 
 	/* finish reading */
-	memcpy((uint8_t *)dest + chunk, busmem->shm_data + off, len);
-	return off + len;
+	memcpy((uint8_t *)dest + chunk, busmem->shm_data, len);
+	return len;
 }
 
 void
@@ -95,7 +93,7 @@
 {
 	size_t chunk;
 
-	KASSERT(len < (BUSMEM_DATASIZE) && off <= BUSMEM_DATASIZE);
+	KASSERT(len < (BUSMEM_DATASIZE/2) && off <= BUSMEM_DATASIZE);
 
 	chunk = MIN(len, BUSMEM_DATASIZE - off);
 	len -= chunk;

Reply via email to