From 36e63e68745f9dd828ed4c8bc3900d1fc3513f56 Mon Sep 17 00:00:00 2001 From: pooka Date: Thu, 12 Aug 2010 17:33:55 +0000 Subject: [PATCH] Make shmif memory access slightly more sane. Create a header which is shared by the interface and the bus analyzer. --- sys/rump/net/lib/libshmif/dumpbus.c | 33 ++++++++---------- sys/rump/net/lib/libshmif/if_shmem.c | 51 ++++++++++++---------------- sys/rump/net/lib/libshmif/shmifvar.h | 45 ++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 48 deletions(-) create mode 100644 sys/rump/net/lib/libshmif/shmifvar.h diff --git a/sys/rump/net/lib/libshmif/dumpbus.c b/sys/rump/net/lib/libshmif/dumpbus.c index d13f406d0359..8eb32be1a295 100644 --- a/sys/rump/net/lib/libshmif/dumpbus.c +++ b/sys/rump/net/lib/libshmif/dumpbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: dumpbus.c,v 1.2 2010/08/12 17:00:41 pooka Exp $ */ +/* $NetBSD: dumpbus.c,v 1.3 2010/08/12 17:33:55 pooka Exp $ */ /* * Little utility to convert shmif bus traffic to a pcap file @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -17,13 +18,7 @@ #include #include -/* XXX: sync with driver */ -struct bushdr { - uint32_t lock; - uint32_t gen; - uint32_t last; - uint32_t version; -}; +#include "shmifvar.h" static void usage(void) @@ -40,8 +35,9 @@ main(int argc, char *argv[]) void *busmem; const char *pcapfile = NULL; uint8_t *curbus, *buslast; - struct bushdr *bhdr; + struct shmif_mem *bmem; int fd, pfd, i, ch; + uint32_t pktlen; while ((ch = getopt(argc, argv, "p:")) != -1) { switch (ch) { @@ -70,13 +66,13 @@ main(int argc, char *argv[]) if (busmem == MAP_FAILED) err(1, "mmap"); - bhdr = busmem; - if (bhdr->version != 1) - errx(1, "cannot handle bus version %d", bhdr->version); + bmem = busmem; + if (bmem->shm_version != 1) + errx(1, "cannot handle bus version %d", bmem->shm_version); printf("bus version %d, lock: %d, generation: %d, lastoff: 0x%x\n", - bhdr->version, bhdr->lock, bhdr->gen, bhdr->last); + bmem->shm_version, bmem->shm_lock, bmem->shm_gen, bmem->shm_last); - if (bhdr->gen != 0) { + if (bmem->shm_gen != 0) { printf("this dumper can manage only generation 0, sorry\n"); exit(0); } @@ -99,13 +95,12 @@ main(int argc, char *argv[]) err(1, "phdr write"); } - curbus = busmem; - buslast = curbus + bhdr->last; - curbus += sizeof(*bhdr); + curbus = bmem->shm_data; + buslast = bmem->shm_data + bmem->shm_last; + assert(sizeof(pktlen) == PKTLEN_SIZE); i = 0; while (curbus <= buslast) { - uint32_t pktlen; struct pcap_pkthdr packhdr; pktlen = *(uint32_t *)curbus; @@ -116,7 +111,7 @@ main(int argc, char *argv[]) continue; printf("packet %d, offset 0x%x, length 0x%x\n", - i++, curbus - (uint8_t *)(bhdr + 1), pktlen); + i++, curbus - (uint8_t *)(bmem + 1), pktlen); if (!pcapfile || pktlen == 0) { curbus += pktlen; diff --git a/sys/rump/net/lib/libshmif/if_shmem.c b/sys/rump/net/lib/libshmif/if_shmem.c index d47ff6c347e6..f9d676030f8c 100644 --- a/sys/rump/net/lib/libshmif/if_shmem.c +++ b/sys/rump/net/lib/libshmif/if_shmem.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_shmem.c,v 1.15 2010/08/11 12:10:39 pooka Exp $ */ +/* $NetBSD: if_shmem.c,v 1.16 2010/08/12 17:33:55 pooka Exp $ */ /* * Copyright (c) 2009 Antti Kantee. All Rights Reserved. @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.15 2010/08/11 12:10:39 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.16 2010/08/12 17:33:55 pooka Exp $"); #include #include @@ -66,27 +66,20 @@ static int shmif_ioctl(struct ifnet *, u_long, void *); static void shmif_start(struct ifnet *); static void shmif_stop(struct ifnet *, int); +#include "shmifvar.h" + struct shmif_sc { struct ethercom sc_ec; uint8_t sc_myaddr[6]; - uint8_t *sc_busmem; + struct shmif_mem *sc_busmem; int sc_memfd; int sc_kq; uint32_t sc_nextpacket; uint32_t sc_prevgen; }; -#define IFMEM_LOCK (0x00) -#define IFMEM_GENERATION (0x04) -#define IFMEM_LASTPACKET (0x08) -#define IFMEM_WAKEUP (0x0c) -#define IFMEM_BUSVERSION IFMEM_WAKEUP -#define IFMEM_DATA (0x10) - -#define BUSCTRL_ATOFF(sc, off) ((uint32_t *)(sc->sc_busmem+(off))) #define BUSMEM_SIZE (1024*1024) /* need write throttling? */ -#define PKTLEN_SIZE 4 /* just in case ... */ static const uint32_t busversion = 1; @@ -107,7 +100,7 @@ static void lockbus(struct shmif_sc *sc) { - while (atomic_cas_32((uint32_t *)sc->sc_busmem, + while (atomic_cas_32(&sc->sc_busmem->shm_lock, LOCK_UNLOCKED, LOCK_LOCKED) == LOCK_LOCKED) continue; membar_enter(); @@ -119,7 +112,7 @@ unlockbus(struct shmif_sc *sc) unsigned int old; membar_exit(); - old = atomic_swap_32((uint32_t *)sc->sc_busmem, LOCK_UNLOCKED); + old = atomic_swap_32(&sc->sc_busmem->shm_lock, LOCK_UNLOCKED); KASSERT(old == LOCK_LOCKED); } @@ -130,7 +123,7 @@ busread(struct shmif_sc *sc, void *dest, uint32_t off, size_t len) KASSERT(len < (BUSMEM_SIZE - IFMEM_DATA) && off <= BUSMEM_SIZE); chunk = MIN(len, BUSMEM_SIZE - off); - memcpy(dest, sc->sc_busmem + off, chunk); + memcpy(dest, (uint8_t *)sc->sc_busmem + off, chunk); len -= chunk; if (len == 0) @@ -138,10 +131,10 @@ busread(struct shmif_sc *sc, void *dest, uint32_t off, size_t len) /* else, wraps around */ off = IFMEM_DATA; - sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); + sc->sc_prevgen = sc->sc_busmem->shm_gen; /* finish reading */ - memcpy((uint8_t *)dest + chunk, sc->sc_busmem + off, len); + memcpy((uint8_t *)dest + chunk, (uint8_t *)sc->sc_busmem + off, len); return off + len; } @@ -154,7 +147,7 @@ buswrite(struct shmif_sc *sc, uint32_t off, void *data, size_t len) && off >= IFMEM_DATA); chunk = MIN(len, BUSMEM_SIZE - off); - memcpy(sc->sc_busmem + off, data, chunk); + memcpy((uint8_t *)sc->sc_busmem + off, data, chunk); len -= chunk; if (len == 0) @@ -165,11 +158,11 @@ buswrite(struct shmif_sc *sc, uint32_t off, void *data, size_t len) /* else, wraps around */ off = IFMEM_DATA; - (*BUSCTRL_ATOFF(sc, IFMEM_GENERATION))++; - sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); + sc->sc_prevgen = sc->sc_busmem->shm_gen; + sc->sc_busmem->shm_gen++; /* finish writing */ - memcpy(sc->sc_busmem + off, (uint8_t *)data + chunk, len); + memcpy((uint8_t *)sc->sc_busmem + off, (uint8_t *)data + chunk, len); return off + len; } @@ -224,10 +217,10 @@ rump_shmif_create(const char *path, int *ifnum) goto fail; lockbus(sc); - if (*BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) == 0) - *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) = IFMEM_DATA; - sc->sc_nextpacket = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET); - sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); + if (sc->sc_busmem->shm_last == 0) + sc->sc_busmem->shm_last = IFMEM_DATA; + sc->sc_nextpacket = sc->sc_busmem->shm_last; + sc->sc_prevgen = sc->sc_busmem->shm_gen; unlockbus(sc); sc->sc_kq = rumpuser_writewatchfile_setup(-1, sc->sc_memfd, 0, &error); @@ -306,7 +299,7 @@ shmif_start(struct ifnet *ifp) } lockbus(sc); - lastoff = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET); + lastoff = sc->sc_busmem->shm_last; npktlenoff = nextpktoff(sc, lastoff); dataoff = advance(npktlenoff, PKTLEN_SIZE); @@ -317,7 +310,7 @@ shmif_start(struct ifnet *ifp) m->m_len); } buswrite(sc, npktlenoff, &pktsize, PKTLEN_SIZE); - *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) = npktlenoff; + sc->sc_busmem->shm_last = npktlenoff; unlockbus(sc); m_freem(m0); @@ -359,8 +352,8 @@ shmif_rcv(void *arg) KASSERT(m->m_flags & M_EXT); lockbus(sc); - lastpkt = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET); - busgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); + lastpkt = sc->sc_busmem->shm_last; + busgen = sc->sc_busmem->shm_gen; lastnext = nextpktoff(sc, lastpkt); if ((lastnext > sc->sc_nextpacket && busgen > sc->sc_prevgen) || (busgen > sc->sc_prevgen+1)) { diff --git a/sys/rump/net/lib/libshmif/shmifvar.h b/sys/rump/net/lib/libshmif/shmifvar.h new file mode 100644 index 000000000000..02b0b1ee2e04 --- /dev/null +++ b/sys/rump/net/lib/libshmif/shmifvar.h @@ -0,0 +1,45 @@ +/* $NetBSD: shmifvar.h,v 1.1 2010/08/12 17:33:55 pooka Exp $ */ + +/*- + * Copyright (c) 2009 Antti Kantee. All Rights Reserved. + * + * Development of this software was supported by The Nokia Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _RUMP_NET_SHMIFVAR_H_ +#define _RUMP_NET_SHMIFVAR_H_ + +struct shmif_mem { + uint32_t shm_lock; + uint32_t shm_gen; + uint32_t shm_last; + uint32_t shm_version; + uint8_t shm_data[0]; +}; + +#define IFMEM_DATA (offsetof(struct shmif_mem, shm_data)) +#define IFMEM_WAKEUP (offsetof(struct shmif_mem, shm_version)) +#define PKTLEN_SIZE (sizeof(uint32_t)) + +#endif