Make shmif memory access slightly more sane. Create a header which
is shared by the interface and the bus analyzer.
This commit is contained in:
parent
7049a3dc1c
commit
36e63e6874
@ -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 <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <pcap.h>
|
||||
@ -17,13 +18,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* 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;
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/param.h>
|
||||
#include <sys/atomic.h>
|
||||
@ -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)) {
|
||||
|
45
sys/rump/net/lib/libshmif/shmifvar.h
Normal file
45
sys/rump/net/lib/libshmif/shmifvar.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user