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 * make interface a cloner
details: https://anonhg.NetBSD.org/src/rev/f462198b048b
branches: trunk
changeset: 758802:f462198b048b
user: pooka <pooka%NetBSD.org@localhost>
date: Mon Nov 15 22:48:06 2010 +0000
description:
* make interface a cloner
* use SIOCSLINKSTR for supplying bus filename in case of cloned if
TODO: downing interface, unclone, and some tweaks for robustness
diffstat:
sys/rump/net/lib/libshmif/Makefile | 3 +-
sys/rump/net/lib/libshmif/if_shmem.c | 254 ++++++++++++++++++++++++++++------
2 files changed, 208 insertions(+), 49 deletions(-)
diffs (truncated from 351 to 300 lines):
diff -r d9654d424df6 -r f462198b048b sys/rump/net/lib/libshmif/Makefile
--- a/sys/rump/net/lib/libshmif/Makefile Mon Nov 15 22:45:23 2010 +0000
+++ b/sys/rump/net/lib/libshmif/Makefile Mon Nov 15 22:48:06 2010 +0000
@@ -1,9 +1,10 @@
-# $NetBSD: Makefile,v 1.2 2010/08/12 21:41:47 pooka Exp $
+# $NetBSD: Makefile,v 1.3 2010/11/15 22:48:06 pooka Exp $
#
LIB= rumpnet_shmif
SRCS= if_shmem.c shmif_busops.c
+SRCS+= component.c
CPPFLAGS+= -I${.CURDIR}/../../../librump/rumpkern
diff -r d9654d424df6 -r f462198b048b sys/rump/net/lib/libshmif/if_shmem.c
--- a/sys/rump/net/lib/libshmif/if_shmem.c Mon Nov 15 22:45:23 2010 +0000
+++ b/sys/rump/net/lib/libshmif/if_shmem.c Mon Nov 15 22:48:06 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_shmem.c,v 1.28 2010/08/17 20:42:47 pooka Exp $ */
+/* $NetBSD: if_shmem.c,v 1.29 2010/11/15 22:48:06 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.28 2010/08/17 20:42:47 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.29 2010/11/15 22:48:06 pooka Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -50,14 +50,17 @@
#include "rump_private.h"
#include "rump_net_private.h"
+static int shmif_clone(struct if_clone *, int);
+static int shmif_unclone(struct ifnet *);
+
+struct if_clone shmif_cloner =
+ IF_CLONE_INITIALIZER("shmif", shmif_clone, shmif_unclone);
+
/*
* Do r/w prefault for backend pages when attaching the interface.
- * This works aroud the most likely kernel/ffs/x86pmap bug described
- * in http://mail-index.netbsd.org/tech-kern/2010/08/17/msg008749.html
- *
- * NOTE: read prefaulting is not enough (that's done always)!
+ * At least logically thinking improves performance (although no
+ * mlocking is done, so they might go away).
*/
-
#define PREFAULT_RW
/*
@@ -79,6 +82,9 @@
int sc_memfd;
int sc_kq;
+ char *sc_backfile;
+ size_t sc_backfilelen;
+
uint64_t sc_devgen;
uint32_t sc_nextpacket;
};
@@ -129,38 +135,64 @@
KASSERT(old == LOCK_LOCKED);
}
-int
-rump_shmif_create(const char *path, int *ifnum)
+static int
+allocif(int unit, struct shmif_sc **scp)
{
+ uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0xa0, 0x00, 0x00, 0x00, 0x00 };
struct shmif_sc *sc;
struct ifnet *ifp;
- uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0xa0, 0x00, 0x00, 0x00, 0x00 };
uint32_t randnum;
- unsigned mynum;
+ unsigned mynum = unit;
+
+ randnum = arc4random();
+ memcpy(&enaddr[2], &randnum, sizeof(randnum));
+
+ sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
+ sc->sc_memfd = -1;
+
+ ifp = &sc->sc_ec.ec_if;
+ memcpy(sc->sc_myaddr, enaddr, sizeof(enaddr));
+
+ sprintf(ifp->if_xname, "shmif%d", mynum);
+ ifp->if_softc = sc;
+ ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
+ ifp->if_init = shmif_init;
+ ifp->if_ioctl = shmif_ioctl;
+ ifp->if_start = shmif_start;
+ ifp->if_stop = shmif_stop;
+ ifp->if_mtu = ETHERMTU;
+
+ if_attach(ifp);
+ ether_ifattach(ifp, enaddr);
+
+ aprint_verbose("shmif%d: Ethernet address %s\n",
+ mynum, ether_sprintf(enaddr));
+
+ if (scp)
+ *scp = sc;
+
+ return 0;
+}
+
+static int
+initbackend(struct shmif_sc *sc, int memfd)
+{
volatile uint8_t v;
volatile uint8_t *p;
int error;
- randnum = arc4random();
- memcpy(&enaddr[2], &randnum, sizeof(randnum));
- mynum = atomic_inc_uint_nv(&numif)-1;
-
- sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
- ifp = &sc->sc_ec.ec_if;
- memcpy(sc->sc_myaddr, enaddr, sizeof(enaddr));
-
- sc->sc_memfd = rumpuser_open(path, O_RDWR | O_CREAT, &error);
- if (sc->sc_memfd == -1)
- goto fail;
- sc->sc_busmem = rumpuser_filemmap(sc->sc_memfd, 0, BUSMEM_SIZE,
+ sc->sc_busmem = rumpuser_filemmap(memfd, 0, BUSMEM_SIZE,
RUMPUSER_FILEMMAP_TRUNCATE | RUMPUSER_FILEMMAP_SHARED
| RUMPUSER_FILEMMAP_READ | RUMPUSER_FILEMMAP_WRITE, &error);
if (error)
- goto fail;
+ return error;
- if (sc->sc_busmem->shm_magic && sc->sc_busmem->shm_magic != SHMIF_MAGIC)
- panic("bus is not magical");
-
+ if (sc->sc_busmem->shm_magic
+ && sc->sc_busmem->shm_magic != SHMIF_MAGIC) {
+ printf("bus is not magical");
+ rumpuser_unmap(sc->sc_busmem, BUSMEM_SIZE);
+ return ENOEXEC;
+ }
/* Prefault in pages to minimize runtime penalty with buslock */
for (p = (uint8_t *)sc->sc_busmem;
@@ -188,39 +220,88 @@
#endif
shmif_unlockbus(sc->sc_busmem);
- sc->sc_kq = rumpuser_writewatchfile_setup(-1, sc->sc_memfd, 0, &error);
+ sc->sc_kq = rumpuser_writewatchfile_setup(-1, memfd, 0, &error);
if (sc->sc_kq == -1)
- goto fail;
+ return error;
+
+ sc->sc_memfd = memfd;
+ return 0;
+}
+
+static void
+finibackend(struct shmif_sc *sc)
+{
+ int dummy;
+
+ kmem_free(sc->sc_backfile, sc->sc_backfilelen);
+ sc->sc_backfile = NULL;
+ sc->sc_backfilelen = 0;
+
+ rumpuser_unmap(sc->sc_busmem, BUSMEM_SIZE);
+ rumpuser_close(sc->sc_memfd, &dummy);
+ rumpuser_close(sc->sc_kq, &dummy);
+}
- sprintf(ifp->if_xname, "shmif%d", mynum);
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
- ifp->if_init = shmif_init;
- ifp->if_ioctl = shmif_ioctl;
- ifp->if_start = shmif_start;
- ifp->if_stop = shmif_stop;
- ifp->if_mtu = ETHERMTU;
+int
+rump_shmif_create(const char *path, int *ifnum)
+{
+ struct shmif_sc *sc;
+ int mynum, error, memfd, dummy;
+
+ memfd = rumpuser_open(path, O_RDWR | O_CREAT, &error);
+ if (memfd == -1)
+ return error;
- if_attach(ifp);
- ether_ifattach(ifp, enaddr);
+ mynum = atomic_inc_uint_nv(&numif)-1;
+ if ((error = allocif(mynum, &sc)) != 0) {
+ rumpuser_close(memfd, &dummy);
+ return error;
+ }
+ error = initbackend(sc, memfd);
+ if (error) {
+ rumpuser_close(memfd, &dummy);
+ /* XXX: free sc */
+ return error;
+ }
- aprint_verbose("shmif%d: bus %s\n", mynum, path);
- aprint_verbose("shmif%d: Ethernet address %s\n",
- mynum, ether_sprintf(enaddr));
+ sc->sc_backfilelen = strlen(path)+1;
+ sc->sc_backfile = kmem_alloc(sc->sc_backfilelen, KM_SLEEP);
+ strcpy(sc->sc_backfile, path);
if (ifnum)
*ifnum = mynum;
+
return 0;
+}
+
+static int
+shmif_clone(struct if_clone *ifc, int unit)
+{
+ int mynum;
- fail:
- panic("rump_shmemif_create: fixme");
+ /* not atomic against rump_shmif_create(). so "don't do it". */
+ if (unit >= mynum)
+ mynum = unit+1;
+
+ return allocif(unit, NULL);
+}
+
+static int
+shmif_unclone(struct ifnet *ifp)
+{
+
+ return EOPNOTSUPP;
}
static int
shmif_init(struct ifnet *ifp)
{
+ struct shmif_sc *sc = ifp->if_softc;
int error = 0;
+ if (sc->sc_memfd == -1)
+ return ENXIO;
+
if (rump_threads) {
error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
shmif_rcv, ifp, NULL, "shmif");
@@ -235,12 +316,89 @@
static int
shmif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
- int s, rv;
+ struct shmif_sc *sc = ifp->if_softc;
+ struct ifdrv *ifd;
+ char *path;
+ int s, rv, memfd, dummy;
s = splnet();
- rv = ether_ioctl(ifp, cmd, data);
- if (rv == ENETRESET)
- rv = 0;
+ switch (cmd) {
+ case SIOCGLINKSTR:
+ ifd = data;
+
+ if (sc->sc_backfilelen == 0) {
+ rv = ENOENT;
+ break;
+ }
+
+ ifd->ifd_len = sc->sc_backfilelen;
+ if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) {
+ rv = 0;
+ break;
+ }
+
+ if (ifd->ifd_cmd != 0) {
+ rv = EINVAL;
+ break;
+ }
+
+ rv = copyoutstr(sc->sc_backfile, ifd->ifd_data,
+ MIN(sc->sc_backfilelen, ifd->ifd_len), NULL);
+ break;
+ case SIOCSLINKSTR:
+ if (ifp->if_flags & IFF_UP) {
+ rv = EBUSY;
+ break;
+ }
+
Home |
Main Index |
Thread Index |
Old Index