Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/rump/net/lib/libshmif * fix off-by-wrap case where curre...
details: https://anonhg.NetBSD.org/src/rev/cb0233c5893a
branches: trunk
changeset: 757168:cb0233c5893a
user: pooka <pooka%NetBSD.org@localhost>
date: Tue Aug 17 11:35:23 2010 +0000
description:
* 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
diffstat:
sys/rump/net/lib/libshmif/if_shmem.c | 85 ++++++++++++++++++++++---------
sys/rump/net/lib/libshmif/shmif_busops.c | 28 +++++-----
2 files changed, 74 insertions(+), 39 deletions(-)
diffs (227 lines):
diff -r 1786eea9d820 -r cb0233c5893a sys/rump/net/lib/libshmif/if_shmem.c
--- a/sys/rump/net/lib/libshmif/if_shmem.c Tue Aug 17 10:57:30 2010 +0000
+++ b/sys/rump/net/lib/libshmif/if_shmem.c Tue Aug 17 11:35:23 2010 +0000
@@ -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;
diff -r 1786eea9d820 -r cb0233c5893a sys/rump/net/lib/libshmif/shmif_busops.c
--- a/sys/rump/net/lib/libshmif/shmif_busops.c Tue Aug 17 10:57:30 2010 +0000
+++ b/sys/rump/net/lib/libshmif/shmif_busops.c Tue Aug 17 11:35:23 2010 +0000
@@ -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
Home |
Main Index |
Thread Index |
Old Index