Module Name:    src
Committed By:   pooka
Date:           Tue Aug 17 11:35:24 UTC 2010

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

Log Message:
* fix off-by-wrap case where current datagram aligns exactly with
  the end of the bus
* clarify the "can we still use the device's next pointer" calculation
  and move it to its own routine
* sprinkle dprintf


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/sys/rump/net/lib/libshmif/if_shmem.c
cvs rdiff -u -r1.5 -r1.6 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.26 src/sys/rump/net/lib/libshmif/if_shmem.c:1.27
--- src/sys/rump/net/lib/libshmif/if_shmem.c:1.26	Mon Aug 16 17:33:52 2010
+++ src/sys/rump/net/lib/libshmif/if_shmem.c	Tue Aug 17 11:35:23 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_shmem.c,v 1.26 2010/08/16 17:33:52 pooka Exp $	*/
+/*	$NetBSD: if_shmem.c,v 1.27 2010/08/17 11:35:23 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.26 2010/08/16 17:33:52 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.27 2010/08/17 11:35:23 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -267,16 +267,17 @@
 			    mtod(m, void *), m->m_len, &wrap);
 		}
 		KASSERT(pktwrote == pktsize);
-
-		if (wrap)
+		if (wrap) {
 			busmem->shm_gen++;
+			DPRINTF(("bus generation now %d\n", busmem->shm_gen));
+		}
 		shmif_unlockbus(busmem);
 
 		m_freem(m0);
 		wrote = true;
 
 		DPRINTF(("shmif_start: send %d bytes at off %d\n",
-		    pktsize, npktlenoff));
+		    pktsize, busmem->shm_last));
 	}
 
 	ifp->if_flags &= ~IFF_OACTIVE;
@@ -294,6 +295,44 @@
 	panic("%s: unimpl", __func__);
 }
 
+
+/*
+ * Check if we have been sleeping too long.  Basically,
+ * our in-sc nextpkt must by first <= nextpkt <= last"+1".
+ * We use the fact that first is guaranteed to never overlap
+ * with the last frame in the ring.
+ */
+static __inline bool
+stillvalid_p(struct shmif_sc *sc)
+{
+	struct shmif_mem *busmem = sc->sc_busmem;
+	unsigned gendiff = busmem->shm_gen - sc->sc_devgen;
+	uint32_t lastoff, devoff;
+
+	KASSERT(busmem->shm_first != busmem->shm_last);
+
+	/* normalize onto a 2x busmem chunk */
+	devoff = sc->sc_nextpacket;
+	lastoff = shmif_nextpktoff(busmem, busmem->shm_last);
+
+	/* trivial case */
+	if (gendiff > 1)
+		return false;
+	KASSERT(gendiff <= 1);
+
+	/* Normalize onto 2x busmem chunk */
+	if (busmem->shm_first >= lastoff) {
+		lastoff += BUSMEM_DATASIZE;
+		if (gendiff == 0)
+			devoff += BUSMEM_DATASIZE;
+	} else {
+		if (gendiff)
+			return false;
+	}
+
+	return devoff >= busmem->shm_first && devoff <= lastoff;
+}
+
 static void
 shmif_rcv(void *arg)
 {
@@ -302,7 +341,7 @@
 	struct shmif_mem *busmem = sc->sc_busmem;
 	struct mbuf *m = NULL;
 	struct ether_header *eth;
-	uint32_t nextpkt, busgen;
+	uint32_t nextpkt;
 	bool wrap;
 	int error;
 
@@ -318,12 +357,11 @@
 		KASSERT(m->m_flags & M_EXT);
 
 		shmif_lockbus(busmem);
-		busgen = busmem->shm_gen;
 		KASSERT(busmem->shm_magic == SHMIF_MAGIC);
-		KASSERT(busgen >= sc->sc_devgen);
+		KASSERT(busmem->shm_gen >= sc->sc_devgen);
 
 		/* need more data? */
-		if (sc->sc_devgen == busgen && 
+		if (sc->sc_devgen == busmem->shm_gen && 
 		    shmif_nextpktoff(busmem, busmem->shm_last)
 		     == sc->sc_nextpacket) {
 			shmif_unlockbus(busmem);
@@ -334,23 +372,17 @@
 			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);
+		if (stillvalid_p(sc)) {
+			nextpkt = sc->sc_nextpacket;
+		} else {
+			KASSERT(busmem->shm_gen > 0);
 			nextpkt = busmem->shm_first;
 			if (busmem->shm_first > busmem->shm_last)
-				sc->sc_devgen = busgen - 1;
+				sc->sc_devgen = busmem->shm_gen - 1;
 			else
-				sc->sc_devgen = busgen;
-		} else {
-			nextpkt = sc->sc_nextpacket;
+				sc->sc_devgen = busmem->shm_gen;
+			DPRINTF(("dev %p overrun, new data: %d/%d\n",
+			    sc, nextpkt, sc->sc_devgen));
 		}
 
 		/*
@@ -358,7 +390,7 @@
 		 * generation must be one behind.
 		 */
 		KASSERT(!(nextpkt > busmem->shm_last
-		    && sc->sc_devgen == busgen));
+		    && sc->sc_devgen == busmem->shm_gen));
 
 		wrap = false;
 		nextpkt = shmif_busread(busmem, &sp,
@@ -373,8 +405,11 @@
 		sc->sc_nextpacket = nextpkt;
 		shmif_unlockbus(sc->sc_busmem);
 
-		if (wrap)
+		if (wrap) {
 			sc->sc_devgen++;
+			DPRINTF(("dev %p generation now %d\n",
+			    sc, 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.5 src/sys/rump/net/lib/libshmif/shmif_busops.c:1.6
--- src/sys/rump/net/lib/libshmif/shmif_busops.c:1.5	Mon Aug 16 17:33:52 2010
+++ src/sys/rump/net/lib/libshmif/shmif_busops.c	Tue Aug 17 11:35:23 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: shmif_busops.c,v 1.5 2010/08/16 17:33:52 pooka Exp $	*/
+/*	$NetBSD: shmif_busops.c,v 1.6 2010/08/17 11:35:23 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.5 2010/08/16 17:33:52 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: shmif_busops.c,v 1.6 2010/08/17 11:35:23 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -64,11 +64,12 @@
 	memcpy(dest, busmem->shm_data + off, chunk);
 	len -= chunk;
 
-	if (len == 0)
-		return off + chunk;
+	if (off + chunk == BUSMEM_DATASIZE)
+		*wrap = true;
 
-	/* else, wraps around */
-	*wrap = true;
+	if (len == 0) {
+		return (off + chunk) % BUSMEM_DATASIZE;
+	}
 
 	/* finish reading */
 	memcpy((uint8_t *)dest + chunk, busmem->shm_data, len);
@@ -104,22 +105,21 @@
 
 	DPRINTF(("buswrite: wrote %d bytes to %d", chunk, off));
 
+	if (off + chunk == BUSMEM_DATASIZE)
+		*wrap = true;
+
 	if (len == 0) {
 		DPRINTF(("\n"));
-		return off + chunk;
+		return (off + chunk) % BUSMEM_DATASIZE;
 	}
 
 	DPRINTF((", wrapped bytes %d to 0\n", len));
 
-	/* else, wraps around */
-	off = 0;
-	*wrap = true;
-
-	shmif_advancefirst(busmem, off, len);
+	shmif_advancefirst(busmem, 0, len);
 
 	/* finish writing */
-	memcpy(busmem->shm_data + off, (uint8_t *)data + chunk, len);
-	return off + len;
+	memcpy(busmem->shm_data, (uint8_t *)data + chunk, len);
+	return len;
 }
 
 uint32_t

Reply via email to