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 Support destroy in shmif.
details: https://anonhg.NetBSD.org/src/rev/9f952f83e240
branches: trunk
changeset: 758837:9f952f83e240
user: pooka <pooka%NetBSD.org@localhost>
date: Wed Nov 17 17:51:22 2010 +0000
description:
Support destroy in shmif.
diffstat:
sys/rump/net/lib/libshmif/if_shmem.c | 154 ++++++++++++++++++++++++++--------
1 files changed, 118 insertions(+), 36 deletions(-)
diffs (truncated from 335 to 300 lines):
diff -r f5a7df461d77 -r 9f952f83e240 sys/rump/net/lib/libshmif/if_shmem.c
--- a/sys/rump/net/lib/libshmif/if_shmem.c Wed Nov 17 17:36:14 2010 +0000
+++ b/sys/rump/net/lib/libshmif/if_shmem.c Wed Nov 17 17:51:22 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_shmem.c,v 1.31 2010/11/16 20:08:24 pooka Exp $ */
+/* $NetBSD: if_shmem.c,v 1.32 2010/11/17 17:51:22 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.31 2010/11/16 20:08:24 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.32 2010/11/17 17:51:22 pooka Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -81,12 +81,19 @@
struct shmif_mem *sc_busmem;
int sc_memfd;
int sc_kq;
+ int sc_unit;
char *sc_backfile;
size_t sc_backfilelen;
uint64_t sc_devgen;
uint32_t sc_nextpacket;
+
+ kmutex_t sc_mtx;
+ kcondvar_t sc_cv;
+
+ struct lwp *sc_rcvl;
+ bool sc_dying;
};
static const uint32_t busversion = SHMIF_VERSION;
@@ -142,18 +149,19 @@
struct shmif_sc *sc;
struct ifnet *ifp;
uint32_t randnum;
- unsigned mynum = unit;
+ int error;
randnum = arc4random();
memcpy(&enaddr[2], &randnum, sizeof(randnum));
sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
sc->sc_memfd = -1;
+ sc->sc_unit = unit;
ifp = &sc->sc_ec.ec_if;
memcpy(sc->sc_myaddr, enaddr, sizeof(enaddr));
- sprintf(ifp->if_xname, "shmif%d", mynum);
+ sprintf(ifp->if_xname, "shmif%d", unit);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
ifp->if_init = shmif_init;
@@ -162,16 +170,32 @@
ifp->if_stop = shmif_stop;
ifp->if_mtu = ETHERMTU;
+ mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&sc->sc_cv, "shmifcv");
+
if_attach(ifp);
ether_ifattach(ifp, enaddr);
aprint_verbose("shmif%d: Ethernet address %s\n",
- mynum, ether_sprintf(enaddr));
+ unit, ether_sprintf(enaddr));
if (scp)
*scp = sc;
- return 0;
+ error = 0;
+ if (rump_threads) {
+ error = kthread_create(PRI_NONE,
+ KTHREAD_MPSAFE | KTHREAD_JOINABLE, NULL,
+ shmif_rcv, ifp, &sc->sc_rcvl, "shmif");
+ } else {
+ printf("WARNING: threads not enabled, shmif NOT working\n");
+ }
+
+ if (error) {
+ shmif_unclone(ifp);
+ }
+
+ return error;
}
static int
@@ -221,48 +245,56 @@
shmif_unlockbus(sc->sc_busmem);
sc->sc_kq = rumpuser_writewatchfile_setup(-1, memfd, 0, &error);
- if (sc->sc_kq == -1)
+ if (sc->sc_kq == -1) {
+ rumpuser_unmap(sc->sc_busmem, BUSMEM_SIZE);
return error;
+ }
sc->sc_memfd = memfd;
- return 0;
+
+ return error;
}
static void
finibackend(struct shmif_sc *sc)
{
- int dummy;
+
+ if (sc->sc_backfile == NULL)
+ return;
- kmem_free(sc->sc_backfile, sc->sc_backfilelen);
- sc->sc_backfile = NULL;
- sc->sc_backfilelen = 0;
+ if (sc->sc_backfile) {
+ 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);
+ rumpuser_close(sc->sc_memfd, NULL);
+ rumpuser_close(sc->sc_kq, NULL);
+
+ sc->sc_memfd = -1;
}
int
rump_shmif_create(const char *path, int *ifnum)
{
struct shmif_sc *sc;
- int mynum, error, memfd, dummy;
+ int unit, error, memfd;
memfd = rumpuser_open(path, O_RDWR | O_CREAT, &error);
if (memfd == -1)
return error;
- mynum = vmem_xalloc(shmif_units, 1, 0, 0, 0, 0, 0,
+ unit = vmem_xalloc(shmif_units, 1, 0, 0, 0, 0, 0,
VM_INSTANTFIT | VM_SLEEP) - 1;
- if ((error = allocif(mynum, &sc)) != 0) {
+ if ((error = allocif(unit, &sc)) != 0) {
rumpuser_close(memfd, NULL);
return error;
}
error = initbackend(sc, memfd);
if (error) {
- rumpuser_close(memfd, &dummy);
- /* XXX: free sc */
+ shmif_unclone(&sc->sc_ec.ec_if);
return error;
}
@@ -271,7 +303,7 @@
strcpy(sc->sc_backfile, path);
if (ifnum)
- *ifnum = mynum;
+ *ifnum = unit;
return 0;
}
@@ -300,8 +332,32 @@
static int
shmif_unclone(struct ifnet *ifp)
{
+ struct shmif_sc *sc = ifp->if_softc;
- return EOPNOTSUPP;
+ shmif_stop(ifp, 1);
+ if_down(ifp);
+ finibackend(sc);
+
+ mutex_enter(&sc->sc_mtx);
+ sc->sc_dying = true;
+ cv_broadcast(&sc->sc_cv);
+ mutex_exit(&sc->sc_mtx);
+
+ if (sc->sc_rcvl)
+ kthread_join(sc->sc_rcvl);
+ sc->sc_rcvl = NULL;
+
+ vmem_xfree(shmif_units, sc->sc_unit+1, 1);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ cv_destroy(&sc->sc_cv);
+ mutex_destroy(&sc->sc_mtx);
+
+ kmem_free(sc, sizeof(*sc));
+
+ return 0;
}
static int
@@ -312,15 +368,17 @@
if (sc->sc_memfd == -1)
return ENXIO;
-
- if (rump_threads) {
- error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
- shmif_rcv, ifp, NULL, "shmif");
- } else {
- printf("WARNING: threads not enabled, shmif NOT working\n");
- }
+ KASSERT(sc->sc_busmem);
ifp->if_flags |= IFF_RUNNING;
+
+ mutex_enter(&sc->sc_mtx);
+ sc->sc_nextpacket = sc->sc_busmem->shm_last;
+ sc->sc_devgen = sc->sc_busmem->shm_gen;
+
+ cv_broadcast(&sc->sc_cv);
+ mutex_exit(&sc->sc_mtx);
+
return error;
}
@@ -330,7 +388,7 @@
struct shmif_sc *sc = ifp->if_softc;
struct ifdrv *ifd;
char *path;
- int s, rv, memfd, dummy;
+ int s, rv, memfd;
s = splnet();
switch (cmd) {
@@ -397,7 +455,7 @@
rv = initbackend(sc, memfd);
if (rv) {
kmem_free(path, ifd->ifd_len);
- rumpuser_close(memfd, &dummy);
+ rumpuser_close(memfd, NULL);
break;
}
sc->sc_backfile = path;
@@ -415,7 +473,7 @@
return rv;
}
-/* send everything in-context */
+/* send everything in-context since it's just a matter of mem-to-mem copy */
static void
shmif_start(struct ifnet *ifp)
{
@@ -479,7 +537,7 @@
ifp->if_flags &= ~IFF_OACTIVE;
- /* wakeup */
+ /* wakeup? */
if (wrote)
rumpuser_pwrite(sc->sc_memfd,
&busversion, sizeof(busversion), IFMEM_WAKEUP, &error);
@@ -488,8 +546,18 @@
static void
shmif_stop(struct ifnet *ifp, int disable)
{
+ struct shmif_sc *sc = ifp->if_softc;
- panic("%s: unimpl", __func__);
+ ifp->if_flags &= ~IFF_RUNNING;
+ membar_producer();
+
+ /*
+ * wakeup thread. this will of course wake up all bus
+ * listeners, but that's life.
+ */
+ if (sc->sc_memfd != -1)
+ rumpuser_pwrite(sc->sc_memfd,
+ &busversion, sizeof(busversion), IFMEM_WAKEUP, NULL);
}
@@ -535,14 +603,22 @@
{
struct ifnet *ifp = arg;
struct shmif_sc *sc = ifp->if_softc;
- struct shmif_mem *busmem = sc->sc_busmem;
+ struct shmif_mem *busmem;
struct mbuf *m = NULL;
struct ether_header *eth;
uint32_t nextpkt;
bool wrap;
int error;
Home |
Main Index |
Thread Index |
Old Index