socsvn commit: r306721 - soc2016/vincenzo/head/sys/dev/netmap

vincenzo at FreeBSD.org vincenzo at FreeBSD.org
Mon Jul 25 07:40:13 UTC 2016


Author: vincenzo
Date: Mon Jul 25 07:40:08 2016
New Revision: 306721
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=306721

Log:
  freebsd: ptnet: code cleanup and woraround removal
  
  Various changes:
      - add support for ptnetmap stats
      - share netmap adapter callbacks with the linux driver
        in order to reuse code
      - fix netmap drivers initialization long-standing workaround,
        introducing proper priorities
      - reorganize ptnetmap guest adapter to put more functionality
        in the common code (used by all the guest OS drivers)

Modified:
  soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c
  soc2016/vincenzo/head/sys/dev/netmap/netmap.c
  soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c
  soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h
  soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c
  soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c
  soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h
  soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c

Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c	Mon Jul 25 07:40:08 2016	(r306721)
@@ -42,6 +42,7 @@
 #include <sys/mutex.h>
 #include <sys/taskqueue.h>
 #include <sys/smp.h>
+#include <sys/time.h>
 #include <machine/smp.h>
 
 #include <vm/uma.h>
@@ -92,6 +93,7 @@
 #error "INET not defined, cannot support offloadings"
 #endif
 
+//#define PTNETMAP_STATS
 //#define DEBUG
 #ifdef DEBUG
 #define DBG(x) x
@@ -109,6 +111,10 @@
 	uint64_t	errors;	 /* if_[io]errors */
 	uint64_t	iqdrops; /* if_iqdrops */
 	uint64_t	mcasts;  /* if_[io]mcasts */
+#ifdef PTNETMAP_STATS
+	uint64_t	intrs;
+	uint64_t	kicks;
+#endif /* PTNETMAP_STATS */
 };
 
 struct ptnet_queue {
@@ -121,6 +127,9 @@
 	struct mtx			lock;
 	struct buf_ring			*bufring; /* for TX queues */
 	struct ptnet_queue_stats	stats;
+#ifdef PTNETMAP_STATS
+	struct ptnet_queue_stats	last_stats;
+#endif /* PTNETMAP_STATS */
 	struct taskqueue		*taskq;
 	struct task			task;
 	char				lock_name[16];
@@ -142,10 +151,6 @@
 	uint32_t		ptfeatures;
 	unsigned int		vnet_hdr_len;
 
-	/* Reference counter used to track the regif operations on the
-	 * passed-through netmap port. */
-	int backend_regifs;
-
 	/* PCI BARs support. */
 	struct resource		*iomem;
 	struct resource		*msix_mem;
@@ -158,12 +163,12 @@
 
 	unsigned int		min_tx_space;
 
-	struct netmap_pt_guest_adapter *ptna_nm;
-	struct netmap_pt_guest_adapter ptna_dr;
-	/* XXX we should move ptna_dr and backend_regifs inside struct
-	 * netmap_pt_guest_adapter and have just one instance of that. */
+	struct netmap_pt_guest_adapter *ptna;
 
 	struct callout		tick;
+#ifdef PTNETMAP_STATS
+	struct timeval		last_ts;
+#endif /* PTNETMAP_STATS */
 };
 
 #define PTNET_CORE_LOCK(_sc)	mtx_lock(&(_sc)->lock)
@@ -197,9 +202,6 @@
 static uint32_t ptnet_nm_ptctl(struct ifnet *ifp, uint32_t cmd);
 static int	ptnet_nm_config(struct netmap_adapter *na, unsigned *txr,
 				unsigned *txd, unsigned *rxr, unsigned *rxd);
-static int	ptnet_nm_krings_create(struct netmap_adapter *na);
-static void	ptnet_nm_krings_delete(struct netmap_adapter *na);
-static void	ptnet_nm_dtor(struct netmap_adapter *na);
 static void	ptnet_update_vnet_hdr(struct ptnet_softc *sc);
 static int	ptnet_nm_register(struct netmap_adapter *na, int onoff);
 static int	ptnet_nm_txsync(struct netmap_kring *kring, int flags);
@@ -234,9 +236,10 @@
 	sizeof(struct ptnet_softc)
 };
 
+/* We use (SI_ORDER_MIDDLE+2) here, see DEV_MODULE_ORDERED() invocation. */
 static devclass_t ptnet_devclass;
 DRIVER_MODULE_ORDERED(ptnet, pci, ptnet_driver, ptnet_devclass,
-		      NULL, NULL, SI_ORDER_MIDDLE + 1);
+		      NULL, NULL, SI_ORDER_MIDDLE + 2);
 
 static int
 ptnet_probe(device_t dev)
@@ -251,7 +254,13 @@
 	return (BUS_PROBE_DEFAULT);
 }
 
-extern int netmap_initialized;
+static inline void ptnet_kick(struct ptnet_queue *pq)
+{
+#ifdef PTNETMAP_STATS
+	pq->stats.kicks ++;
+#endif /* PTNETMAP_STATS */
+	bus_write_4(pq->sc->iomem, pq->kick, 0);
+}
 
 #define PTNET_BUF_RING_SIZE	4096
 #define PTNET_RX_BUDGET		512
@@ -280,11 +289,6 @@
 	int err, rid;
 	int i;
 
-	if (!netmap_initialized) {
-		device_printf(dev, "Netmap still not initialized\n");
-		return (ENXIO);
-	}
-
 	sc = device_get_softc(dev);
 	sc->dev = dev;
 
@@ -435,8 +439,6 @@
 	mtx_init(&sc->lock, sc->lock_name, "ptnet core lock", MTX_DEF);
 	callout_init_mtx(&sc->tick, &sc->lock, 0);
 
-	sc->backend_regifs = 0;
-
 	/* Prepare a netmap_adapter struct instance to do netmap_attach(). */
 	nifp_offset = bus_read_4(sc->iomem, PTNET_IO_NIFP_OFS);
 	memset(&na_arg, 0, sizeof(na_arg));
@@ -458,24 +460,13 @@
 	/* Now a netmap adapter for this ifp has been allocated, and it
 	 * can be accessed through NA(ifp). We also have to initialize the CSB
 	 * pointer. */
-	sc->ptna_nm = (struct netmap_pt_guest_adapter *)NA(ifp);
-	sc->ptna_nm->csb = sc->csb;
+	sc->ptna = (struct netmap_pt_guest_adapter *)NA(ifp);
 
 	/* If virtio-net header was negotiated, set the virt_hdr_len field in
 	 * the netmap adapter, to inform users that this netmap adapter requires
 	 * the application to deal with the headers. */
 	ptnet_update_vnet_hdr(sc);
 
-	/* Initialize a separate pass-through netmap adapter that is going to
-	 * be used by this driver only, and so never exposed to netmap. We
-	 * only need a subset of the available fields. */
-	memset(&sc->ptna_dr, 0, sizeof(sc->ptna_dr));
-	sc->ptna_dr.hwup.up.ifp = ifp;
-	sc->ptna_dr.hwup.up.nm_mem = sc->ptna_nm->hwup.up.nm_mem;
-	netmap_mem_get(sc->ptna_dr.hwup.up.nm_mem);
-	sc->ptna_dr.hwup.up.nm_config = ptnet_nm_config;
-	sc->ptna_dr.csb = sc->csb;
-
 	device_printf(dev, "%s() completed\n", __func__);
 
 	return (0);
@@ -513,8 +504,6 @@
 		ether_ifdetach(sc->ifp);
 
 		/* Uninitialize netmap adapters for this device. */
-		netmap_mem_put(sc->ptna_dr.hwup.up.nm_mem);
-		memset(&sc->ptna_dr, 0, sizeof(sc->ptna_dr));
 		netmap_detach(sc->ifp);
 
 		ifmedia_removeall(&sc->media);
@@ -827,7 +816,8 @@
 ptnet_init_locked(struct ptnet_softc *sc)
 {
 	struct ifnet *ifp = sc->ifp;
-	struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up;
+	struct netmap_adapter *na_dr = &sc->ptna->dr.up;
+	struct netmap_adapter *na_nm = &sc->ptna->hwup.up;
 	unsigned int nm_buf_size;
 	int ret;
 
@@ -859,8 +849,8 @@
 		return ret;
 	}
 
-	if (sc->backend_regifs == 0) {
-		ret = ptnet_nm_krings_create(na_dr);
+	if (sc->ptna->backend_regifs == 0) {
+		ret = ptnet_nm_krings_create(na_nm);
 		if (ret) {
 			device_printf(sc->dev, "ptnet_nm_krings_create() "
 					       "failed\n");
@@ -905,7 +895,7 @@
 err_get_lut:
 	netmap_mem_rings_delete(na_dr);
 err_rings_create:
-	ptnet_nm_krings_delete(na_dr);
+	ptnet_nm_krings_delete(na_nm);
 err_mem_finalize:
 	netmap_mem_deref(na_dr->nm_mem, na_dr);
 
@@ -917,7 +907,8 @@
 ptnet_stop(struct ptnet_softc *sc)
 {
 	struct ifnet *ifp = sc->ifp;
-	struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up;
+	struct netmap_adapter *na_dr = &sc->ptna->dr.up;
+	struct netmap_adapter *na_nm = &sc->ptna->hwup.up;
 	int i;
 
 	device_printf(sc->dev, "%s\n", __func__);
@@ -938,9 +929,9 @@
 
 	ptnet_nm_register(na_dr, 0 /* off */);
 
-	if (sc->backend_regifs == 0) {
+	if (sc->ptna->backend_regifs == 0) {
 		netmap_mem_rings_delete(na_dr);
-		ptnet_nm_krings_delete(na_dr);
+		ptnet_nm_krings_delete(na_nm);
 	}
 	netmap_mem_deref(na_dr->nm_mem, na_dr);
 
@@ -1016,6 +1007,31 @@
 	ifp->if_ierrors		= stats[1].errors;
 	ifp->if_iqdrops		= stats[1].iqdrops;
 
+#ifdef PTNETMAP_STATS
+	for (i = 0; i < sc->num_rings; i++) {
+		struct ptnet_queue *pq = sc->queues + i;
+		struct ptnet_queue_stats cur = pq->stats;
+		struct timeval now;
+		unsigned int delta;
+
+		microtime(&now);
+		delta = now.tv_usec - sc->last_ts.tv_usec +
+			(now.tv_sec - sc->last_ts.tv_sec) * 1000000;
+		delta /= 1000; /* in milliseconds */
+
+		if (delta == 0)
+			continue;
+
+		device_printf(sc->dev, "#%d[%u ms]:pkts %lu, kicks %lu, "
+			      "intr %lu\n", i, delta,
+			      (cur.packets - pq->last_stats.packets),
+			      (cur.kicks - pq->last_stats.kicks),
+			      (cur.intrs - pq->last_stats.intrs));
+		pq->last_stats = cur;
+	}
+	microtime(&sc->last_ts);
+#endif /* PTNETMAP_STATS */
+
 	callout_schedule(&sc->tick, hz);
 }
 
@@ -1058,58 +1074,6 @@
 	return 0;
 }
 
-/* XXX krings create/delete and register functions should be shared
- *     with the Linux driver. */
-static int
-ptnet_nm_krings_create(struct netmap_adapter *na)
-{
-	/* Here (na == &sc->ptna_nm->hwup.up || na == &sc->ptna_dr.hwup.up). */
-	struct ptnet_softc *sc = na->ifp->if_softc;
-	struct netmap_adapter *na_nm = &sc->ptna_nm->hwup.up;
-	struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up;
-	int ret;
-
-	if (sc->backend_regifs) {
-		return 0;
-	}
-
-	/* Create krings on the public netmap adapter. */
-	ret = netmap_hw_krings_create(na_nm);
-	if (ret) {
-		return ret;
-	}
-
-	/* Copy krings into the netmap adapter private to the driver. */
-	na_dr->tx_rings = na_nm->tx_rings;
-	na_dr->rx_rings = na_nm->rx_rings;
-
-	return 0;
-}
-
-static void
-ptnet_nm_krings_delete(struct netmap_adapter *na)
-{
-	/* Here (na == &sc->ptna_nm->hwup.up || na == &sc->ptna_dr.hwup.up). */
-	struct ptnet_softc *sc = na->ifp->if_softc;
-	struct netmap_adapter *na_nm = &sc->ptna_nm->hwup.up;
-	struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up;
-
-	if (sc->backend_regifs) {
-		return;
-	}
-
-	na_dr->tx_rings = NULL;
-	na_dr->rx_rings = NULL;
-
-	netmap_hw_krings_delete(na_nm);
-}
-
-static void
-ptnet_nm_dtor(struct netmap_adapter *na)
-{
-	netmap_mem_pt_guest_ifp_del(na->nm_mem, na->ifp);
-}
-
 static void
 ptnet_sync_from_csb(struct ptnet_softc *sc, struct netmap_adapter *na)
 {
@@ -1146,7 +1110,7 @@
 ptnet_update_vnet_hdr(struct ptnet_softc *sc)
 {
 	sc->vnet_hdr_len = ptnet_vnet_hdr ? PTNET_HDR_SIZE : 0;
-	sc->ptna_nm->hwup.up.virt_hdr_len = sc->vnet_hdr_len;
+	sc->ptna->hwup.up.virt_hdr_len = sc->vnet_hdr_len;
 	bus_write_4(sc->iomem, PTNET_IO_VNET_HDR_LEN, sc->vnet_hdr_len);
 }
 
@@ -1156,14 +1120,14 @@
 	/* device-specific */
 	struct ifnet *ifp = na->ifp;
 	struct ptnet_softc *sc = ifp->if_softc;
-	int native = (na == &sc->ptna_nm->hwup.up);
+	int native = (na == &sc->ptna->hwup.up);
 	struct ptnet_queue *pq;
 	enum txrx t;
 	int ret = 0;
 	int i;
 
 	if (!onoff) {
-		sc->backend_regifs--;
+		sc->ptna->backend_regifs--;
 	}
 
 	/* If this is the last netmap client, guest interrupt enable flags may
@@ -1181,7 +1145,7 @@
 	}
 
 	if (onoff) {
-		if (sc->backend_regifs == 0) {
+		if (sc->ptna->backend_regifs == 0) {
 			/* Initialize notification enable fields in the CSB. */
 			for (i = 0; i < sc->num_rings; i++) {
 				pq = sc->queues + i;
@@ -1205,7 +1169,7 @@
 		/* Sync from CSB must be done after REGIF PTCTL. Skip this
 		 * step only if this is a netmap client and it is not the
 		 * first one. */
-		if ((!native && sc->backend_regifs == 0) ||
+		if ((!native && sc->ptna->backend_regifs == 0) ||
 				(native && na->active_fds == 0)) {
 			ptnet_sync_from_csb(sc, na);
 		}
@@ -1214,7 +1178,7 @@
 		 * to replace if_transmit method, nor set NAF_NETMAP_ON */
 		if (native) {
 			for_rx_tx(t) {
-				for (i=0; i<nma_get_nrings(na, t); i++) {
+				for (i = 0; i <= nma_get_nrings(na, t); i++) {
 					struct netmap_kring *kring = &NMR(na, t)[i];
 
 					if (nm_kring_pending_on(kring)) {
@@ -1229,7 +1193,7 @@
 		if (native) {
 			nm_clear_native_flags(na);
 			for_rx_tx(t) {
-				for (i=0; i<nma_get_nrings(na, t); i++) {
+				for (i = 0; i <= nma_get_nrings(na, t); i++) {
 					struct netmap_kring *kring = &NMR(na, t)[i];
 
 					if (nm_kring_pending_off(kring)) {
@@ -1245,13 +1209,13 @@
 			ptnet_sync_from_csb(sc, na);
 		}
 
-		if (sc->backend_regifs == 0) {
+		if (sc->ptna->backend_regifs == 0) {
 			ret = ptnet_nm_ptctl(ifp, NET_PARAVIRT_PTCTL_UNREGIF);
 		}
 	}
 
 	if (onoff) {
-		sc->backend_regifs++;
+		sc->ptna->backend_regifs++;
 	}
 
 	return ret;
@@ -1266,7 +1230,7 @@
 
 	notify = netmap_pt_guest_txsync(pq->ptring, kring, flags);
 	if (notify) {
-		bus_write_4(sc->iomem, pq->kick, 0);
+		ptnet_kick(pq);
 	}
 
 	return 0;
@@ -1281,7 +1245,7 @@
 
 	notify = netmap_pt_guest_rxsync(pq->ptring, kring, flags);
 	if (notify) {
-		bus_write_4(sc->iomem, pq->kick, 0);
+		ptnet_kick(pq);
 	}
 
 	return 0;
@@ -1294,6 +1258,9 @@
 	struct ptnet_softc *sc = pq->sc;
 
 	DBG(device_printf(sc->dev, "Tx interrupt #%d\n", pq->kring_id));
+#ifdef PTNETMAP_STATS
+	pq->stats.intrs ++;
+#endif /* PTNETMAP_STATS */
 
 	if (netmap_tx_irq(sc->ifp, pq->kring_id) != NM_IRQ_PASS) {
 		return;
@@ -1314,6 +1281,9 @@
 	unsigned int unused;
 
 	DBG(device_printf(sc->dev, "Rx interrupt #%d\n", pq->kring_id));
+#ifdef PTNETMAP_STATS
+	pq->stats.intrs ++;
+#endif /* PTNETMAP_STATS */
 
 	if (netmap_rx_irq(sc->ifp, pq->kring_id, &unused) != NM_IRQ_PASS) {
 		return;
@@ -1675,7 +1645,7 @@
 	/* Kick the host if needed. */
 	if (NM_ACCESS_ONCE(ptring->host_need_kick)) {
 		ptring->sync_flags = sync_flags;
-		bus_write_4(pq->sc->iomem, pq->kick, 0);
+		ptnet_kick(pq);
 	}
 }
 
@@ -1691,7 +1661,7 @@
 {
 	struct ptnet_softc *sc = pq->sc;
 	bool have_vnet_hdr = sc->vnet_hdr_len;
-	struct netmap_adapter *na = &sc->ptna_dr.hwup.up;
+	struct netmap_adapter *na = &sc->ptna->dr.up;
 	struct ifnet *ifp = sc->ifp;
 	unsigned int batch_count = 0;
 	struct ptnet_ring *ptring;
@@ -1985,7 +1955,7 @@
 	struct ptnet_softc *sc = pq->sc;
 	bool have_vnet_hdr = sc->vnet_hdr_len;
 	struct ptnet_ring *ptring = pq->ptring;
-	struct netmap_adapter *na = &sc->ptna_dr.hwup.up;
+	struct netmap_adapter *na = &sc->ptna->dr.up;
 	struct netmap_kring *kring = na->rx_rings + pq->kring_id;
 	struct netmap_ring *ring = kring->ring;
 	unsigned int const lim = kring->nkr_num_slots - 1;

Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/netmap.c	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/netmap.c	Mon Jul 25 07:40:08 2016	(r306721)
@@ -2865,6 +2865,17 @@
 	ptna = (struct netmap_pt_guest_adapter *) NA(ifp);
 	ptna->csb = csb;
 
+	/* Initialize a separate pass-through netmap adapter that is going to
+	 * be used by the ptnet driver only, and so never exposed to netmap
+         * applications. We only need a subset of the available fields. */
+	memset(&ptna->dr, 0, sizeof(ptna->dr));
+	ptna->dr.up.ifp = ifp;
+	ptna->dr.up.nm_mem = ptna->hwup.up.nm_mem;
+	netmap_mem_get(ptna->dr.up.nm_mem);
+        ptna->dr.up.nm_config = ptna->hwup.up.nm_config;
+
+	ptna->backend_regifs = 0;
+
 	return 0;
 }
 #endif /* WITH_PTNETMAP_GUEST */

Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c	Mon Jul 25 07:40:08 2016	(r306721)
@@ -33,7 +33,7 @@
 #include <sys/param.h>  /* defines used in kernel.h */
 #include <sys/poll.h>  /* POLLIN, POLLOUT */
 #include <sys/kernel.h> /* types used in module initialization */
-#include <sys/conf.h>	/* DEV_MODULE */
+#include <sys/conf.h>	/* DEV_MODULE_ORDERED */
 #include <sys/endian.h>
 #include <sys/syscallsubr.h> /* kern_ioctl() */
 
@@ -595,9 +595,11 @@
 	sizeof(struct ptnetmap_memdev),
 };
 
+/* We use (SI_ORDER_MIDDLE+1) here, see DEV_MODULE_ORDERED() invocation
+ * below. */
 static devclass_t ptnetmap_devclass;
 DRIVER_MODULE_ORDERED(ptn_memdev, pci, ptn_memdev_driver, ptnetmap_devclass,
-		      NULL, NULL, SI_ORDER_MIDDLE);
+		      NULL, NULL, SI_ORDER_MIDDLE + 1);
 
 /*
  * I/O port read/write wrappers.
@@ -680,8 +682,6 @@
 	return (BUS_PROBE_DEFAULT);
 }
 
-int netmap_initialized = 0; /* XXX temporary hack */
-
 /* Device initialization routine. */
 static int
 ptn_memdev_attach(device_t dev)
@@ -692,11 +692,6 @@
 
 	D("ptn_memdev_driver attach");
 
-	if (!netmap_initialized) {
-		device_printf(dev, "Netmap still not initialized\n");
-		return (ENXIO);
-	}
-
 	ptn_dev = device_get_softc(dev);
 	ptn_dev->dev = dev;
 
@@ -759,11 +754,6 @@
 	return bus_generic_shutdown(dev);
 }
 
-int
-nm_os_pt_memdev_init(void) { return 0; }
-
-void
-nm_os_pt_memdev_uninit(void) { }
 #endif /* WITH_PTNETMAP_GUEST */
 
 /*
@@ -1047,11 +1037,11 @@
 	struct nm_kthread_ctx *ctx = &nmk->worker_ctx;
 	uint64_t old_scheduled = nmk->scheduled;
 
-	thread_lock(curthread);
 	if (nmk->affinity >= 0) {
+		thread_lock(curthread);
 		sched_bind(curthread, nmk->affinity);
+		thread_unlock(curthread);
 	}
-	thread_unlock(curthread);
 
 	while (nmk->run) {
 		/*
@@ -1071,7 +1061,7 @@
 		 * mechanism and we continually execute worker_fn()
 		 */
 		if (!ctx->ioevent_file) {
-			ctx->worker_fn(ctx->worker_private); /* worker_body */
+			ctx->worker_fn(ctx->worker_private); /* worker body */
 		} else {
 			/* checks if there is a pending notification */
 			mtx_lock(&nmk->worker_lock);
@@ -1079,13 +1069,13 @@
 				old_scheduled = nmk->scheduled;
 				mtx_unlock(&nmk->worker_lock);
 
-				ctx->worker_fn(ctx->worker_private); /* worker_body */
+				ctx->worker_fn(ctx->worker_private); /* worker body */
 
 				continue;
 			} else if (nmk->run) {
-				/* wait on event with timetout 1 second */
-				msleep_spin_sbt(ctx->ioevent_file, &nmk->worker_lock,
-						"nmk_event", SBT_1S, SBT_1S, C_ABSOLUTE);
+				/* wait on event with one second timeout */
+				msleep_spin(ctx->ioevent_file, &nmk->worker_lock,
+					    "nmk_ev", hz);
 				nmk->scheduled++;
 			}
 			mtx_unlock(&nmk->worker_lock);
@@ -1436,8 +1426,6 @@
 	switch (event) {
 	case MOD_LOAD:
 		error = netmap_init();
-		if (!error)
-			netmap_initialized = 1;
 		break;
 
 	case MOD_UNLOAD:
@@ -1451,7 +1439,6 @@
 			error = EBUSY;
 			break;
 		}
-		netmap_initialized = 0;
 		netmap_fini();
 		break;
 
@@ -1463,8 +1450,18 @@
 	return (error);
 }
 
-
-DEV_MODULE(netmap, netmap_loader, NULL);
+/*
+ * The netmap module contains three drivers: (i) the netmap character device
+ * driver; (ii) the ptnetmap memdev PCI device driver, (iii) the ptnet PCI
+ * device driver. The attach() routines of both (ii) and (iii) need the
+ * lock of the global allocator, and such lock is initialized in netmap_init(),
+ * which is part of (i).
+ * Therefore, we make sure that (i) is loaded before (ii) and (iii), using
+ * the 'order' parameter of driver declaration macros. For (i), we specify
+ * SI_ORDER_MIDDLE, while higher orders are used with the DRIVER_MODULE_ORDERED
+ * macros for (ii) and (iii).
+ */
+DEV_MODULE_ORDERED(netmap, netmap_loader, NULL, SI_ORDER_MIDDLE);
 MODULE_DEPEND(netmap, pci, 1, 1, 1);
 MODULE_VERSION(netmap, 1);
 /* reduce conditional code */

Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h	Mon Jul 25 07:40:08 2016	(r306721)
@@ -2049,8 +2049,21 @@
  * netmap adapter for guest ptnetmap ports
  */
 struct netmap_pt_guest_adapter {
+        /* The netmap adapter to be used by netmap applications.
+	 * This field must be the first, to allow upcast. */
 	struct netmap_hw_adapter hwup;
+
+        /* The netmap adapter to be used by the driver. */
+        struct netmap_hw_adapter dr;
+
 	void *csb;
+
+	/* Reference counter to track users of backend netmap port: the
+	 * network stack and netmap clients.
+	 * Used to decide when we need (de)allocate krings/rings and
+	 * start (stop) ptnetmap kthreads. */
+	int backend_regifs;
+
 };
 
 int netmap_pt_guest_attach(struct netmap_adapter *, void *,
@@ -2060,6 +2073,9 @@
 			    int flags);
 bool netmap_pt_guest_rxsync(struct ptnet_ring *ptring, struct netmap_kring *kring,
 			    int flags);
+int ptnet_nm_krings_create(struct netmap_adapter *na);
+void ptnet_nm_krings_delete(struct netmap_adapter *na);
+void ptnet_nm_dtor(struct netmap_adapter *na);
 #endif /* WITH_PTNETMAP_GUEST */
 
 #endif /* _NET_NETMAP_KERN_H_ */

Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c	Mon Jul 25 07:40:08 2016	(r306721)
@@ -562,19 +562,9 @@
 	return ret;
 }
 
-#if defined(__FreeBSD__)
-extern int netmap_initialized;
-#endif
-
 static void
 nm_mem_release_id(struct netmap_mem_d *nmd)
 {
-#if defined(__FreeBSD__)
-	if (!netmap_initialized) {
-		D("skip, nm_mem could be gone");
-		return;
-	}
-#endif
 	NMA_LOCK(&nm_mem);
 
 	nmd->prev->next = nmd->next;

Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c	Mon Jul 25 07:40:08 2016	(r306721)
@@ -1514,6 +1514,7 @@
 	uint32_t sh, dh;
 	u_int dst, mysrc = na->bdg_port;
 	uint64_t smac, dmac;
+	uint8_t indbuf[12];
 
 	/* safety check, unfortunately we have many cases */
 	if (buf_len >= 14 + na->up.virt_hdr_len) {
@@ -1529,6 +1530,14 @@
 		RD(5, "invalid buf format, length %d", buf_len);
 		return NM_BDG_NOPORT;
 	}
+
+	if (ft->ft_flags & NS_INDIRECT) {
+		if (copyin(buf, indbuf, sizeof(indbuf))) {
+			return NM_BDG_NOPORT;
+		}
+		buf = indbuf;
+	}
+
 	dmac = le64toh(*(uint64_t *)(buf)) & 0xffffffffffff;
 	smac = le64toh(*(uint64_t *)(buf + 4));
 	smac >>= 16;

Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h	Mon Jul 25 07:40:08 2016	(r306721)
@@ -475,8 +475,6 @@
 
 /* ptnetmap_memdev routines used to talk with ptnetmap_memdev device driver */
 struct ptnetmap_memdev;
-int nm_os_pt_memdev_init(void);
-void nm_os_pt_memdev_uninit(void);
 int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **);
 void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *);
 #endif /* WITH_PTNETMAP_GUEST */

Modified: soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c	Mon Jul 25 05:33:19 2016	(r306720)
+++ soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c	Mon Jul 25 07:40:08 2016	(r306721)
@@ -1130,6 +1130,11 @@
 
     DBG(D("%s", pth_na->up.name));
 
+    /* The equivalent of NETMAP_PT_HOST_DELETE if the hypervisor
+     * didn't do it. */
+    ptnetmap_stop_kthreads(pth_na);
+    ptnetmap_delete(pth_na);
+
     parent->na_flags &= ~NAF_BUSY;
 
     netmap_adapter_put(pth_na->parent);
@@ -1382,4 +1387,63 @@
 
 	return notify;
 }
+
+/*
+ * Callbacks for ptnet drivers: nm_krings_create, nm_krings_delete, nm_dtor.
+ */
+int
+ptnet_nm_krings_create(struct netmap_adapter *na)
+{
+	struct netmap_pt_guest_adapter *ptna =
+			(struct netmap_pt_guest_adapter *)na; /* Upcast. */
+	struct netmap_adapter *na_nm = &ptna->hwup.up;
+	struct netmap_adapter *na_dr = &ptna->dr.up;
+	int ret;
+
+	if (ptna->backend_regifs) {
+		return 0;
+	}
+
+	/* Create krings on the public netmap adapter. */
+	ret = netmap_hw_krings_create(na_nm);
+	if (ret) {
+		return ret;
+	}
+
+	/* Copy krings into the netmap adapter private to the driver. */
+	na_dr->tx_rings = na_nm->tx_rings;
+	na_dr->rx_rings = na_nm->rx_rings;
+
+	return 0;
+}
+
+void
+ptnet_nm_krings_delete(struct netmap_adapter *na)
+{
+	struct netmap_pt_guest_adapter *ptna =
+			(struct netmap_pt_guest_adapter *)na; /* Upcast. */
+	struct netmap_adapter *na_nm = &ptna->hwup.up;
+	struct netmap_adapter *na_dr = &ptna->dr.up;
+
+	if (ptna->backend_regifs) {
+		return;
+	}
+
+	na_dr->tx_rings = NULL;
+	na_dr->rx_rings = NULL;
+
+	netmap_hw_krings_delete(na_nm);
+}
+
+void
+ptnet_nm_dtor(struct netmap_adapter *na)
+{
+	struct netmap_pt_guest_adapter *ptna =
+			(struct netmap_pt_guest_adapter *)na;
+
+	netmap_mem_put(ptna->dr.up.nm_mem);
+	memset(&ptna->dr, 0, sizeof(ptna->dr));
+	netmap_mem_pt_guest_ifp_del(na->nm_mem, na->ifp);
+}
+
 #endif /* WITH_PTNETMAP_GUEST */


More information about the svn-soc-all mailing list