svn commit: r341516 - in head/sys: conf dev/netmap modules/netmap net
Vincenzo Maffione
vmaffione at FreeBSD.org
Wed Dec 5 11:57:18 UTC 2018
Author: vmaffione
Date: Wed Dec 5 11:57:16 2018
New Revision: 341516
URL: https://svnweb.freebsd.org/changeset/base/341516
Log:
netmap: align codebase to the current upstream (760279cfb2730a585)
Changelist:
- Replace netmap passthrough host support with a more general
mechanism to call TXSYNC/RXSYNC from an in-kernel event-loop.
No kernel threads are used to use this feature: the application
is required to spawn a thread (or a process) and issue a
SYNC_KLOOP_START (NIOCCTRL) command in the thread body. The
kernel loop is executed by the ioctl implementation, which returns
to userspace only when a different thread calls SYNC_KLOOP_STOP
or the netmap file descriptor is closed.
- Update the if_ptnet driver to cope with the new data structures,
and prune all the obsolete ptnetmap code.
- Add support for "null" netmap ports, useful to allocate netmap_if,
netmap_ring and netmap buffers to be used by specialized applications
(e.g. hypervisors). TXSYNC/RXSYNC on these ports have no effect.
- Various fixes and code refactoring.
Sponsored by: Sunny Valley Networks
Differential Revision: https://reviews.freebsd.org/D18015
Added:
head/sys/dev/netmap/netmap_kloop.c (contents, props changed)
head/sys/dev/netmap/netmap_null.c (contents, props changed)
Modified:
head/sys/conf/files
head/sys/dev/netmap/if_ixl_netmap.h
head/sys/dev/netmap/if_ptnet.c
head/sys/dev/netmap/if_vtnet_netmap.h
head/sys/dev/netmap/netmap.c
head/sys/dev/netmap/netmap_bdg.c
head/sys/dev/netmap/netmap_bdg.h
head/sys/dev/netmap/netmap_freebsd.c
head/sys/dev/netmap/netmap_generic.c
head/sys/dev/netmap/netmap_kern.h
head/sys/dev/netmap/netmap_legacy.c
head/sys/dev/netmap/netmap_mem2.c
head/sys/dev/netmap/netmap_mem2.h
head/sys/dev/netmap/netmap_pipe.c
head/sys/dev/netmap/netmap_vale.c
head/sys/modules/netmap/Makefile
head/sys/net/netmap.h
head/sys/net/netmap_user.h
head/sys/net/netmap_virt.h
Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files Wed Dec 5 10:58:02 2018 (r341515)
+++ head/sys/conf/files Wed Dec 5 11:57:16 2018 (r341516)
@@ -2517,17 +2517,19 @@ dev/nand/nandsim_swap.c optional nandsim nand
dev/nand/nfc_if.m optional nand
dev/netmap/if_ptnet.c optional netmap inet
dev/netmap/netmap.c optional netmap
+dev/netmap/netmap_bdg.c optional netmap
dev/netmap/netmap_freebsd.c optional netmap
dev/netmap/netmap_generic.c optional netmap
+dev/netmap/netmap_kloop.c optional netmap
+dev/netmap/netmap_legacy.c optional netmap
dev/netmap/netmap_mbq.c optional netmap
dev/netmap/netmap_mem2.c optional netmap
dev/netmap/netmap_monitor.c optional netmap
+dev/netmap/netmap_null.c optional netmap
dev/netmap/netmap_offloadings.c optional netmap
dev/netmap/netmap_pipe.c optional netmap
dev/netmap/netmap_pt.c optional netmap
dev/netmap/netmap_vale.c optional netmap
-dev/netmap/netmap_legacy.c optional netmap
-dev/netmap/netmap_bdg.c optional netmap
# compile-with "${NORMAL_C} -Wconversion -Wextra"
dev/nfsmb/nfsmb.c optional nfsmb pci
dev/nge/if_nge.c optional nge
Modified: head/sys/dev/netmap/if_ixl_netmap.h
==============================================================================
--- head/sys/dev/netmap/if_ixl_netmap.h Wed Dec 5 10:58:02 2018 (r341515)
+++ head/sys/dev/netmap/if_ixl_netmap.h Wed Dec 5 11:57:16 2018 (r341516)
@@ -129,7 +129,7 @@ ixl_netmap_attach(struct ixl_vsi *vsi)
na.ifp = vsi->ifp;
na.na_flags = NAF_BDG_MAYSLEEP;
// XXX check that queues is set.
- nm_prinf("queues is %p\n", vsi->queues);
+ nm_prinf("queues is %p", vsi->queues);
if (vsi->queues) {
na.num_tx_desc = vsi->queues[0].num_desc;
na.num_rx_desc = vsi->queues[0].num_desc;
Modified: head/sys/dev/netmap/if_ptnet.c
==============================================================================
--- head/sys/dev/netmap/if_ptnet.c Wed Dec 5 10:58:02 2018 (r341515)
+++ head/sys/dev/netmap/if_ptnet.c Wed Dec 5 11:57:16 2018 (r341516)
@@ -128,8 +128,8 @@ struct ptnet_queue {
struct resource *irq;
void *cookie;
int kring_id;
- struct ptnet_csb_gh *ptgh;
- struct ptnet_csb_hg *pthg;
+ struct nm_csb_atok *atok;
+ struct nm_csb_ktoa *ktoa;
unsigned int kick;
struct mtx lock;
struct buf_ring *bufring; /* for TX queues */
@@ -166,8 +166,8 @@ struct ptnet_softc {
unsigned int num_tx_rings;
struct ptnet_queue *queues;
struct ptnet_queue *rxqueues;
- struct ptnet_csb_gh *csb_gh;
- struct ptnet_csb_hg *csb_hg;
+ struct nm_csb_atok *csb_gh;
+ struct nm_csb_ktoa *csb_hg;
unsigned int min_tx_space;
@@ -209,7 +209,7 @@ static void ptnet_tick(void *opaque);
static int ptnet_irqs_init(struct ptnet_softc *sc);
static void ptnet_irqs_fini(struct ptnet_softc *sc);
-static uint32_t ptnet_nm_ptctl(if_t ifp, uint32_t cmd);
+static uint32_t ptnet_nm_ptctl(struct ptnet_softc *sc, uint32_t cmd);
static int ptnet_nm_config(struct netmap_adapter *na,
struct nm_config_info *info);
static void ptnet_update_vnet_hdr(struct ptnet_softc *sc);
@@ -327,7 +327,7 @@ ptnet_attach(device_t dev)
sc->num_rings = num_tx_rings + num_rx_rings;
sc->num_tx_rings = num_tx_rings;
- if (sc->num_rings * sizeof(struct ptnet_csb_gh) > PAGE_SIZE) {
+ if (sc->num_rings * sizeof(struct nm_csb_atok) > PAGE_SIZE) {
device_printf(dev, "CSB cannot handle that many rings (%u)\n",
sc->num_rings);
err = ENOMEM;
@@ -342,7 +342,7 @@ ptnet_attach(device_t dev)
err = ENOMEM;
goto err_path;
}
- sc->csb_hg = (struct ptnet_csb_hg *)(((char *)sc->csb_gh) + PAGE_SIZE);
+ sc->csb_hg = (struct nm_csb_ktoa *)(((char *)sc->csb_gh) + PAGE_SIZE);
{
/*
@@ -379,8 +379,8 @@ ptnet_attach(device_t dev)
pq->sc = sc;
pq->kring_id = i;
pq->kick = PTNET_IO_KICK_BASE + 4 * i;
- pq->ptgh = sc->csb_gh + i;
- pq->pthg = sc->csb_hg + i;
+ pq->atok = sc->csb_gh + i;
+ pq->ktoa = sc->csb_hg + i;
snprintf(pq->lock_name, sizeof(pq->lock_name), "%s-%d",
device_get_nameunit(dev), i);
mtx_init(&pq->lock, pq->lock_name, NULL, MTX_DEF);
@@ -505,12 +505,25 @@ err_path:
return err;
}
+/* Stop host sync-kloop if it was running. */
+static void
+ptnet_device_shutdown(struct ptnet_softc *sc)
+{
+ ptnet_nm_ptctl(sc, PTNETMAP_PTCTL_DELETE);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAH, 0);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAL, 0);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAH, 0);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAL, 0);
+}
+
static int
ptnet_detach(device_t dev)
{
struct ptnet_softc *sc = device_get_softc(dev);
int i;
+ ptnet_device_shutdown(sc);
+
#ifdef DEVICE_POLLING
if (sc->ifp->if_capenable & IFCAP_POLLING) {
ether_poll_deregister(sc->ifp);
@@ -543,10 +556,6 @@ ptnet_detach(device_t dev)
ptnet_irqs_fini(sc);
if (sc->csb_gh) {
- bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAH, 0);
- bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAL, 0);
- bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAH, 0);
- bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAL, 0);
contigfree(sc->csb_gh, 2*PAGE_SIZE, M_DEVBUF);
sc->csb_gh = NULL;
sc->csb_hg = NULL;
@@ -583,9 +592,8 @@ ptnet_detach(device_t dev)
static int
ptnet_suspend(device_t dev)
{
- struct ptnet_softc *sc;
+ struct ptnet_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
(void)sc;
return (0);
@@ -594,9 +602,8 @@ ptnet_suspend(device_t dev)
static int
ptnet_resume(device_t dev)
{
- struct ptnet_softc *sc;
+ struct ptnet_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
(void)sc;
return (0);
@@ -605,11 +612,11 @@ ptnet_resume(device_t dev)
static int
ptnet_shutdown(device_t dev)
{
- /*
- * Suspend already does all of what we need to
- * do here; we just never expect to be resumed.
- */
- return (ptnet_suspend(dev));
+ struct ptnet_softc *sc = device_get_softc(dev);
+
+ ptnet_device_shutdown(sc);
+
+ return (0);
}
static int
@@ -796,7 +803,7 @@ ptnet_ioctl(if_t ifp, u_long cmd, caddr_t data)
/* Make sure the worker sees the
* IFF_DRV_RUNNING down. */
PTNET_Q_LOCK(pq);
- pq->ptgh->guest_need_kick = 0;
+ pq->atok->appl_need_kick = 0;
PTNET_Q_UNLOCK(pq);
/* Wait for rescheduling to finish. */
if (pq->taskq) {
@@ -810,7 +817,7 @@ ptnet_ioctl(if_t ifp, u_long cmd, caddr_t data)
for (i = 0; i < sc->num_rings; i++) {
pq = sc-> queues + i;
PTNET_Q_LOCK(pq);
- pq->ptgh->guest_need_kick = 1;
+ pq->atok->appl_need_kick = 1;
PTNET_Q_UNLOCK(pq);
}
}
@@ -881,7 +888,7 @@ ptnet_init_locked(struct ptnet_softc *sc)
return ret;
}
- if (sc->ptna->backend_regifs == 0) {
+ if (sc->ptna->backend_users == 0) {
ret = ptnet_nm_krings_create(na_nm);
if (ret) {
device_printf(sc->dev, "ptnet_nm_krings_create() "
@@ -962,7 +969,7 @@ ptnet_stop(struct ptnet_softc *sc)
ptnet_nm_register(na_dr, 0 /* off */);
- if (sc->ptna->backend_regifs == 0) {
+ if (sc->ptna->backend_users == 0) {
netmap_mem_rings_delete(na_dr);
ptnet_nm_krings_delete(na_nm);
}
@@ -1092,9 +1099,8 @@ ptnet_media_status(if_t ifp, struct ifmediareq *ifmr)
}
static uint32_t
-ptnet_nm_ptctl(if_t ifp, uint32_t cmd)
+ptnet_nm_ptctl(struct ptnet_softc *sc, uint32_t cmd)
{
- struct ptnet_softc *sc = if_getsoftc(ifp);
/*
* Write a command and read back error status,
* with zero meaning success.
@@ -1130,8 +1136,8 @@ ptnet_sync_from_csb(struct ptnet_softc *sc, struct net
/* Sync krings from the host, reading from
* CSB. */
for (i = 0; i < sc->num_rings; i++) {
- struct ptnet_csb_gh *ptgh = sc->queues[i].ptgh;
- struct ptnet_csb_hg *pthg = sc->queues[i].pthg;
+ struct nm_csb_atok *atok = sc->queues[i].atok;
+ struct nm_csb_ktoa *ktoa = sc->queues[i].ktoa;
struct netmap_kring *kring;
if (i < na->num_tx_rings) {
@@ -1139,15 +1145,15 @@ ptnet_sync_from_csb(struct ptnet_softc *sc, struct net
} else {
kring = na->rx_rings[i - na->num_tx_rings];
}
- kring->rhead = kring->ring->head = ptgh->head;
- kring->rcur = kring->ring->cur = ptgh->cur;
- kring->nr_hwcur = pthg->hwcur;
+ kring->rhead = kring->ring->head = atok->head;
+ kring->rcur = kring->ring->cur = atok->cur;
+ kring->nr_hwcur = ktoa->hwcur;
kring->nr_hwtail = kring->rtail =
- kring->ring->tail = pthg->hwtail;
+ kring->ring->tail = ktoa->hwtail;
ND("%d,%d: csb {hc %u h %u c %u ht %u}", t, i,
- pthg->hwcur, ptgh->head, ptgh->cur,
- pthg->hwtail);
+ ktoa->hwcur, atok->head, atok->cur,
+ ktoa->hwtail);
ND("%d,%d: kring {hc %u rh %u rc %u h %u c %u ht %u rt %u t %u}",
t, i, kring->nr_hwcur, kring->rhead, kring->rcur,
kring->ring->head, kring->ring->cur, kring->nr_hwtail,
@@ -1178,7 +1184,7 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff
int i;
if (!onoff) {
- sc->ptna->backend_regifs--;
+ sc->ptna->backend_users--;
}
/* If this is the last netmap client, guest interrupt enable flags may
@@ -1191,17 +1197,17 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff
D("Exit netmap mode, re-enable interrupts");
for (i = 0; i < sc->num_rings; i++) {
pq = sc->queues + i;
- pq->ptgh->guest_need_kick = 1;
+ pq->atok->appl_need_kick = 1;
}
}
if (onoff) {
- if (sc->ptna->backend_regifs == 0) {
+ if (sc->ptna->backend_users == 0) {
/* Initialize notification enable fields in the CSB. */
for (i = 0; i < sc->num_rings; i++) {
pq = sc->queues + i;
- pq->pthg->host_need_kick = 1;
- pq->ptgh->guest_need_kick =
+ pq->ktoa->kern_need_kick = 1;
+ pq->atok->appl_need_kick =
(!(ifp->if_capenable & IFCAP_POLLING)
&& i >= sc->num_tx_rings);
}
@@ -1211,17 +1217,13 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff
/* Make sure the host adapter passed through is ready
* for txsync/rxsync. */
- ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_CREATE);
+ ret = ptnet_nm_ptctl(sc, PTNETMAP_PTCTL_CREATE);
if (ret) {
return ret;
}
- }
- /* 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->ptna->backend_regifs == 0) ||
- (native && na->active_fds == 0)) {
+ /* Align the guest krings and rings to the state stored
+ * in the CSB. */
ptnet_sync_from_csb(sc, na);
}
@@ -1254,19 +1256,13 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff
}
}
- /* Sync from CSB must be done before UNREGIF PTCTL, on the last
- * netmap client. */
- if (native && na->active_fds == 0) {
- ptnet_sync_from_csb(sc, na);
+ if (sc->ptna->backend_users == 0) {
+ ret = ptnet_nm_ptctl(sc, PTNETMAP_PTCTL_DELETE);
}
-
- if (sc->ptna->backend_regifs == 0) {
- ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_DELETE);
- }
}
if (onoff) {
- sc->ptna->backend_regifs++;
+ sc->ptna->backend_users++;
}
return ret;
@@ -1279,7 +1275,7 @@ ptnet_nm_txsync(struct netmap_kring *kring, int flags)
struct ptnet_queue *pq = sc->queues + kring->ring_id;
bool notify;
- notify = netmap_pt_guest_txsync(pq->ptgh, pq->pthg, kring, flags);
+ notify = netmap_pt_guest_txsync(pq->atok, pq->ktoa, kring, flags);
if (notify) {
ptnet_kick(pq);
}
@@ -1294,7 +1290,7 @@ ptnet_nm_rxsync(struct netmap_kring *kring, int flags)
struct ptnet_queue *pq = sc->rxqueues + kring->ring_id;
bool notify;
- notify = netmap_pt_guest_rxsync(pq->ptgh, pq->pthg, kring, flags);
+ notify = netmap_pt_guest_rxsync(pq->atok, pq->ktoa, kring, flags);
if (notify) {
ptnet_kick(pq);
}
@@ -1310,7 +1306,7 @@ ptnet_nm_intr(struct netmap_adapter *na, int onoff)
for (i = 0; i < sc->num_rings; i++) {
struct ptnet_queue *pq = sc->queues + i;
- pq->ptgh->guest_need_kick = onoff;
+ pq->atok->appl_need_kick = onoff;
}
}
@@ -1676,25 +1672,13 @@ ptnet_rx_csum(struct mbuf *m, struct virtio_net_hdr *h
}
/* End of offloading-related functions to be shared with vtnet. */
-static inline void
-ptnet_sync_tail(struct ptnet_csb_hg *pthg, struct netmap_kring *kring)
-{
- struct netmap_ring *ring = kring->ring;
-
- /* Update hwcur and hwtail as known by the host. */
- ptnetmap_guest_read_kring_csb(pthg, kring);
-
- /* nm_sync_finalize */
- ring->tail = kring->rtail = kring->nr_hwtail;
-}
-
static void
ptnet_ring_update(struct ptnet_queue *pq, struct netmap_kring *kring,
unsigned int head, unsigned int sync_flags)
{
struct netmap_ring *ring = kring->ring;
- struct ptnet_csb_gh *ptgh = pq->ptgh;
- struct ptnet_csb_hg *pthg = pq->pthg;
+ struct nm_csb_atok *atok = pq->atok;
+ struct nm_csb_ktoa *ktoa = pq->ktoa;
/* Some packets have been pushed to the netmap ring. We have
* to tell the host to process the new packets, updating cur
@@ -1704,11 +1688,11 @@ ptnet_ring_update(struct ptnet_queue *pq, struct netma
/* Mimic nm_txsync_prologue/nm_rxsync_prologue. */
kring->rcur = kring->rhead = head;
- ptnetmap_guest_write_kring_csb(ptgh, kring->rcur, kring->rhead);
+ ptnetmap_guest_write_kring_csb(atok, kring->rcur, kring->rhead);
/* Kick the host if needed. */
- if (NM_ACCESS_ONCE(pthg->host_need_kick)) {
- ptgh->sync_flags = sync_flags;
+ if (NM_ACCESS_ONCE(ktoa->kern_need_kick)) {
+ atok->sync_flags = sync_flags;
ptnet_kick(pq);
}
}
@@ -1728,8 +1712,8 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, uns
struct netmap_adapter *na = &sc->ptna->dr.up;
if_t ifp = sc->ifp;
unsigned int batch_count = 0;
- struct ptnet_csb_gh *ptgh;
- struct ptnet_csb_hg *pthg;
+ struct nm_csb_atok *atok;
+ struct nm_csb_ktoa *ktoa;
struct netmap_kring *kring;
struct netmap_ring *ring;
struct netmap_slot *slot;
@@ -1758,8 +1742,8 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, uns
return ENETDOWN;
}
- ptgh = pq->ptgh;
- pthg = pq->pthg;
+ atok = pq->atok;
+ ktoa = pq->ktoa;
kring = na->tx_rings[pq->kring_id];
ring = kring->ring;
lim = kring->nkr_num_slots - 1;
@@ -1771,17 +1755,17 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, uns
/* We ran out of slot, let's see if the host has
* freed up some, by reading hwcur and hwtail from
* the CSB. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (PTNET_TX_NOSPACE(head, kring, minspace)) {
/* Still no slots available. Reactivate the
* interrupts so that we can be notified
* when some free slots are made available by
* the host. */
- ptgh->guest_need_kick = 1;
+ atok->appl_need_kick = 1;
/* Double-check. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (likely(PTNET_TX_NOSPACE(head, kring,
minspace))) {
break;
@@ -1790,7 +1774,7 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, uns
RD(1, "Found more slots by doublecheck");
/* More slots were freed before reactivating
* the interrupts. */
- ptgh->guest_need_kick = 0;
+ atok->appl_need_kick = 0;
}
}
@@ -2020,8 +2004,8 @@ ptnet_rx_eof(struct ptnet_queue *pq, unsigned int budg
{
struct ptnet_softc *sc = pq->sc;
bool have_vnet_hdr = sc->vnet_hdr_len;
- struct ptnet_csb_gh *ptgh = pq->ptgh;
- struct ptnet_csb_hg *pthg = pq->pthg;
+ struct nm_csb_atok *atok = pq->atok;
+ struct nm_csb_ktoa *ktoa = pq->ktoa;
struct netmap_adapter *na = &sc->ptna->dr.up;
struct netmap_kring *kring = na->rx_rings[pq->kring_id];
struct netmap_ring *ring = kring->ring;
@@ -2053,21 +2037,21 @@ host_sync:
/* We ran out of slot, let's see if the host has
* added some, by reading hwcur and hwtail from
* the CSB. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (head == ring->tail) {
/* Still no slots available. Reactivate
* interrupts as they were disabled by the
* host thread right before issuing the
* last interrupt. */
- ptgh->guest_need_kick = 1;
+ atok->appl_need_kick = 1;
/* Double-check. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (likely(head == ring->tail)) {
break;
}
- ptgh->guest_need_kick = 0;
+ atok->appl_need_kick = 0;
}
}
Modified: head/sys/dev/netmap/if_vtnet_netmap.h
==============================================================================
--- head/sys/dev/netmap/if_vtnet_netmap.h Wed Dec 5 10:58:02 2018 (r341515)
+++ head/sys/dev/netmap/if_vtnet_netmap.h Wed Dec 5 11:57:16 2018 (r341516)
@@ -79,7 +79,7 @@ vtnet_free_used(struct virtqueue *vq, int netmap_bufs,
}
if (deq)
- nm_prinf("%d sgs dequeued from %s-%d (netmap=%d)\n",
+ nm_prinf("%d sgs dequeued from %s-%d (netmap=%d)",
deq, nm_txrx2str(t), idx, netmap_bufs);
}
@@ -230,7 +230,7 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl
/*writeable=*/0);
if (unlikely(err)) {
if (err != ENOSPC)
- nm_prerr("virtqueue_enqueue(%s) failed: %d\n",
+ nm_prerr("virtqueue_enqueue(%s) failed: %d",
kring->name, err);
break;
}
@@ -251,7 +251,7 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl
if (token == NULL)
break;
if (unlikely(token != (void *)txq))
- nm_prerr("BUG: TX token mismatch\n");
+ nm_prerr("BUG: TX token mismatch");
else
n++;
}
@@ -307,7 +307,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring,
/*readable=*/0, /*writeable=*/sg.sg_nseg);
if (unlikely(err)) {
if (err != ENOSPC)
- nm_prerr("virtqueue_enqueue(%s) failed: %d\n",
+ nm_prerr("virtqueue_enqueue(%s) failed: %d",
kring->name, err);
break;
}
@@ -391,7 +391,7 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl
break;
}
if (unlikely(token != (void *)rxq)) {
- nm_prerr("BUG: RX token mismatch\n");
+ nm_prerr("BUG: RX token mismatch");
} else {
/* Skip the virtio-net header. */
len -= sc->vtnet_hdr_size;
@@ -533,7 +533,7 @@ vtnet_netmap_attach(struct vtnet_softc *sc)
netmap_attach(&na);
- nm_prinf("vtnet attached txq=%d, txd=%d rxq=%d, rxd=%d\n",
+ nm_prinf("vtnet attached txq=%d, txd=%d rxq=%d, rxd=%d",
na.num_tx_rings, na.num_tx_desc,
na.num_tx_rings, na.num_rx_desc);
}
Modified: head/sys/dev/netmap/netmap.c
==============================================================================
--- head/sys/dev/netmap/netmap.c Wed Dec 5 10:58:02 2018 (r341515)
+++ head/sys/dev/netmap/netmap.c Wed Dec 5 11:57:16 2018 (r341516)
@@ -480,6 +480,9 @@ ports attached to the switch)
/* user-controlled variables */
int netmap_verbose;
+#ifdef CONFIG_NETMAP_DEBUG
+int netmap_debug;
+#endif /* CONFIG_NETMAP_DEBUG */
static int netmap_no_timestamp; /* don't timestamp on rxsync */
int netmap_no_pendintr = 1;
@@ -527,9 +530,6 @@ int netmap_generic_hwcsum = 0;
/* Non-zero if ptnet devices are allowed to use virtio-net headers. */
int ptnet_vnet_hdr = 1;
-/* 0 if ptnetmap should not use worker threads for TX processing */
-int ptnetmap_tx_workers = 1;
-
/*
* SYSCTL calls are grouped between SYSBEGIN and SYSEND to be emulated
* in some other operating systems
@@ -540,6 +540,10 @@ SYSCTL_DECL(_dev_netmap);
SYSCTL_NODE(_dev, OID_AUTO, netmap, CTLFLAG_RW, 0, "Netmap args");
SYSCTL_INT(_dev_netmap, OID_AUTO, verbose,
CTLFLAG_RW, &netmap_verbose, 0, "Verbose mode");
+#ifdef CONFIG_NETMAP_DEBUG
+SYSCTL_INT(_dev_netmap, OID_AUTO, debug,
+ CTLFLAG_RW, &netmap_debug, 0, "Debug messages");
+#endif /* CONFIG_NETMAP_DEBUG */
SYSCTL_INT(_dev_netmap, OID_AUTO, no_timestamp,
CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp");
SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr, CTLFLAG_RW, &netmap_no_pendintr,
@@ -569,8 +573,6 @@ SYSCTL_INT(_dev_netmap, OID_AUTO, generic_txqdisc, CTL
#endif
SYSCTL_INT(_dev_netmap, OID_AUTO, ptnet_vnet_hdr, CTLFLAG_RW, &ptnet_vnet_hdr,
0, "Allow ptnet devices to use virtio-net headers");
-SYSCTL_INT(_dev_netmap, OID_AUTO, ptnetmap_tx_workers, CTLFLAG_RW,
- &ptnetmap_tx_workers, 0, "Use worker threads for pnetmap TX processing");
SYSEND;
@@ -692,7 +694,7 @@ nm_bound_var(u_int *v, u_int dflt, u_int lo, u_int hi,
op = "Clamp";
}
if (op && msg)
- nm_prinf("%s %s to %d (was %d)\n", op, msg, *v, oldv);
+ nm_prinf("%s %s to %d (was %d)", op, msg, *v, oldv);
return *v;
}
@@ -776,13 +778,14 @@ netmap_update_config(struct netmap_adapter *na)
na->num_rx_rings = info.num_rx_rings;
na->num_rx_desc = info.num_rx_descs;
na->rx_buf_maxsize = info.rx_buf_maxsize;
- D("configuration changed for %s: txring %d x %d, "
- "rxring %d x %d, rxbufsz %d",
- na->name, na->num_tx_rings, na->num_tx_desc,
- na->num_rx_rings, na->num_rx_desc, na->rx_buf_maxsize);
+ if (netmap_verbose)
+ nm_prinf("configuration changed for %s: txring %d x %d, "
+ "rxring %d x %d, rxbufsz %d",
+ na->name, na->num_tx_rings, na->num_tx_desc,
+ na->num_rx_rings, na->num_rx_desc, na->rx_buf_maxsize);
return 0;
}
- D("WARNING: configuration changed for %s while active: "
+ nm_prerr("WARNING: configuration changed for %s while active: "
"txring %d x %d, rxring %d x %d, rxbufsz %d",
na->name, info.num_tx_rings, info.num_tx_descs,
info.num_rx_rings, info.num_rx_descs,
@@ -828,7 +831,8 @@ netmap_krings_create(struct netmap_adapter *na, u_int
enum txrx t;
if (na->tx_rings != NULL) {
- D("warning: krings were already created");
+ if (netmap_debug & NM_DEBUG_ON)
+ nm_prerr("warning: krings were already created");
return 0;
}
@@ -842,7 +846,7 @@ netmap_krings_create(struct netmap_adapter *na, u_int
na->tx_rings = nm_os_malloc((size_t)len);
if (na->tx_rings == NULL) {
- D("Cannot allocate krings");
+ nm_prerr("Cannot allocate krings");
return ENOMEM;
}
na->rx_rings = na->tx_rings + n[NR_TX];
@@ -910,7 +914,8 @@ netmap_krings_delete(struct netmap_adapter *na)
enum txrx t;
if (na->tx_rings == NULL) {
- D("warning: krings were already deleted");
+ if (netmap_debug & NM_DEBUG_ON)
+ nm_prerr("warning: krings were already deleted");
return;
}
@@ -1012,11 +1017,11 @@ netmap_do_unregif(struct netmap_priv_d *priv)
* happens if the close() occurs while a concurrent
* syscall is running.
*/
- if (netmap_verbose)
- D("deleting last instance for %s", na->name);
+ if (netmap_debug & NM_DEBUG_ON)
+ nm_prinf("deleting last instance for %s", na->name);
if (nm_netmap_on(na)) {
- D("BUG: netmap on while going to delete the krings");
+ nm_prerr("BUG: netmap on while going to delete the krings");
}
na->nm_krings_delete(na);
@@ -1033,14 +1038,6 @@ netmap_do_unregif(struct netmap_priv_d *priv)
priv->np_nifp = NULL;
}
-/* call with NMG_LOCK held */
-static __inline int
-nm_si_user(struct netmap_priv_d *priv, enum txrx t)
-{
- return (priv->np_na != NULL &&
- (priv->np_qlast[t] - priv->np_qfirst[t] > 1));
-}
-
struct netmap_priv_d*
netmap_priv_new(void)
{
@@ -1136,8 +1133,8 @@ netmap_send_up(struct ifnet *dst, struct mbq *q)
/* Send packets up, outside the lock; head/prev machinery
* is only useful for Windows. */
while ((m = mbq_dequeue(q)) != NULL) {
- if (netmap_verbose & NM_VERB_HOST)
- D("sending up pkt %p size %d", m, MBUF_LEN(m));
+ if (netmap_debug & NM_DEBUG_HOST)
+ nm_prinf("sending up pkt %p size %d", m, MBUF_LEN(m));
prev = nm_os_send_up(dst, m, prev);
if (head == NULL)
head = prev;
@@ -1332,8 +1329,8 @@ netmap_rxsync_from_host(struct netmap_kring *kring, in
m_copydata(m, 0, len, NMB(na, slot));
ND("nm %d len %d", nm_i, len);
- if (netmap_verbose)
- D("%s", nm_dump_buf(NMB(na, slot),len, 128, NULL));
+ if (netmap_debug & NM_DEBUG_HOST)
+ nm_prinf("%s", nm_dump_buf(NMB(na, slot),len, 128, NULL));
slot->len = len;
slot->flags = 0;
@@ -1500,7 +1497,7 @@ netmap_get_na(struct nmreq_header *hdr,
if (req->nr_mode == NR_REG_PIPE_MASTER ||
req->nr_mode == NR_REG_PIPE_SLAVE) {
/* Do not accept deprecated pipe modes. */
- D("Deprecated pipe nr_mode, use xx{yy or xx}yy syntax");
+ nm_prerr("Deprecated pipe nr_mode, use xx{yy or xx}yy syntax");
return EINVAL;
}
@@ -1527,9 +1524,7 @@ netmap_get_na(struct nmreq_header *hdr,
* 0 !NULL type matches and na created/found
* !0 !NULL impossible
*/
-
- /* try to see if this is a ptnetmap port */
- error = netmap_get_pt_host_na(hdr, na, nmd, create);
+ error = netmap_get_null_na(hdr, na, nmd, create);
if (error || *na != NULL)
goto out;
@@ -1739,7 +1734,7 @@ nm_rxsync_prologue(struct netmap_kring *kring, struct
/*
* Error routine called when txsync/rxsync detects an error.
- * Can't do much more than resetting head =cur = hwcur, tail = hwtail
+ * Can't do much more than resetting head = cur = hwcur, tail = hwtail
* Return 1 on reinit.
*
* This routine is only called by the upper half of the kernel.
@@ -1810,12 +1805,6 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint3
enum txrx t;
u_int j;
- if ((nr_flags & NR_PTNETMAP_HOST) && ((nr_mode != NR_REG_ALL_NIC) ||
- nr_flags & (NR_RX_RINGS_ONLY|NR_TX_RINGS_ONLY))) {
- D("Error: only NR_REG_ALL_NIC supported with netmap passthrough");
- return EINVAL;
- }
-
for_rx_tx(t) {
if (nr_flags & excluded_direction[t]) {
priv->np_qfirst[t] = priv->np_qlast[t] = 0;
@@ -1823,6 +1812,7 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint3
}
switch (nr_mode) {
case NR_REG_ALL_NIC:
+ case NR_REG_NULL:
priv->np_qfirst[t] = 0;
priv->np_qlast[t] = nma_get_nrings(na, t);
ND("ALL/PIPE: %s %d %d", nm_txrx2str(t),
@@ -1831,7 +1821,7 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint3
case NR_REG_SW:
case NR_REG_NIC_SW:
if (!(na->na_flags & NAF_HOST_RINGS)) {
- D("host rings not supported");
+ nm_prerr("host rings not supported");
return EINVAL;
}
priv->np_qfirst[t] = (nr_mode == NR_REG_SW ?
@@ -1844,7 +1834,7 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint3
case NR_REG_ONE_NIC:
if (nr_ringid >= na->num_tx_rings &&
nr_ringid >= na->num_rx_rings) {
- D("invalid ring id %d", nr_ringid);
+ nm_prerr("invalid ring id %d", nr_ringid);
return EINVAL;
}
/* if not enough rings, use the first one */
@@ -1857,11 +1847,11 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint3
priv->np_qfirst[t], priv->np_qlast[t]);
break;
default:
- D("invalid regif type %d", nr_mode);
+ nm_prerr("invalid regif type %d", nr_mode);
return EINVAL;
}
}
- priv->np_flags = nr_flags | nr_mode; // TODO
+ priv->np_flags = nr_flags;
/* Allow transparent forwarding mode in the host --> nic
* direction only if all the TX hw rings have been opened. */
@@ -1871,7 +1861,7 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint3
}
if (netmap_verbose) {
- D("%s: tx [%d,%d) rx [%d,%d) id %d",
+ nm_prinf("%s: tx [%d,%d) rx [%d,%d) id %d",
na->name,
priv->np_qfirst[NR_TX],
priv->np_qlast[NR_TX],
@@ -1927,6 +1917,7 @@ netmap_unset_ringid(struct netmap_priv_d *priv)
}
priv->np_flags = 0;
priv->np_txpoll = 0;
+ priv->np_kloop_state = 0;
}
@@ -1943,8 +1934,8 @@ netmap_krings_get(struct netmap_priv_d *priv)
int excl = (priv->np_flags & NR_EXCLUSIVE);
enum txrx t;
- if (netmap_verbose)
- D("%s: grabbing tx [%d, %d) rx [%d, %d)",
+ if (netmap_debug & NM_DEBUG_ON)
+ nm_prinf("%s: grabbing tx [%d, %d) rx [%d, %d)",
na->name,
priv->np_qfirst[NR_TX],
priv->np_qlast[NR_TX],
@@ -2021,6 +2012,110 @@ nm_priv_rx_enabled(struct netmap_priv_d *priv)
return (priv->np_qfirst[NR_RX] != priv->np_qlast[NR_RX]);
}
+/* Validate the CSB entries for both directions (atok and ktoa).
+ * To be called under NMG_LOCK(). */
+static int
+netmap_csb_validate(struct netmap_priv_d *priv, struct nmreq_opt_csb *csbo)
+{
+ struct nm_csb_atok *csb_atok_base =
+ (struct nm_csb_atok *)(uintptr_t)csbo->csb_atok;
+ struct nm_csb_ktoa *csb_ktoa_base =
+ (struct nm_csb_ktoa *)(uintptr_t)csbo->csb_ktoa;
+ enum txrx t;
+ int num_rings[NR_TXRX], tot_rings;
+ size_t entry_size[2];
+ void *csb_start[2];
+ int i;
+
+ if (priv->np_kloop_state & NM_SYNC_KLOOP_RUNNING) {
+ nm_prerr("Cannot update CSB while kloop is running");
+ return EBUSY;
+ }
+
+ tot_rings = 0;
+ for_rx_tx(t) {
+ num_rings[t] = priv->np_qlast[t] - priv->np_qfirst[t];
+ tot_rings += num_rings[t];
+ }
+ if (tot_rings <= 0)
+ return 0;
+
+ if (!(priv->np_flags & NR_EXCLUSIVE)) {
+ nm_prerr("CSB mode requires NR_EXCLUSIVE");
+ return EINVAL;
+ }
+
+ entry_size[0] = sizeof(*csb_atok_base);
+ entry_size[1] = sizeof(*csb_ktoa_base);
+ csb_start[0] = (void *)csb_atok_base;
+ csb_start[1] = (void *)csb_ktoa_base;
+
+ for (i = 0; i < 2; i++) {
+ /* On Linux we could use access_ok() to simplify
+ * the validation. However, the advantage of
+ * this approach is that it works also on
+ * FreeBSD. */
+ size_t csb_size = tot_rings * entry_size[i];
+ void *tmp;
+ int err;
+
+ if ((uintptr_t)csb_start[i] & (entry_size[i]-1)) {
+ nm_prerr("Unaligned CSB address");
+ return EINVAL;
+ }
+
+ tmp = nm_os_malloc(csb_size);
+ if (!tmp)
+ return ENOMEM;
+ if (i == 0) {
+ /* Application --> kernel direction. */
+ err = copyin(csb_start[i], tmp, csb_size);
+ } else {
+ /* Kernel --> application direction. */
+ memset(tmp, 0, csb_size);
+ err = copyout(tmp, csb_start[i], csb_size);
+ }
+ nm_os_free(tmp);
+ if (err) {
+ nm_prerr("Invalid CSB address");
+ return err;
+ }
+ }
+
+ priv->np_csb_atok_base = csb_atok_base;
+ priv->np_csb_ktoa_base = csb_ktoa_base;
+
+ /* Initialize the CSB. */
+ for_rx_tx(t) {
+ for (i = 0; i < num_rings[t]; i++) {
+ struct netmap_kring *kring =
+ NMR(priv->np_na, t)[i + priv->np_qfirst[t]];
+ struct nm_csb_atok *csb_atok = csb_atok_base + i;
+ struct nm_csb_ktoa *csb_ktoa = csb_ktoa_base + i;
+
+ if (t == NR_RX) {
+ csb_atok += num_rings[NR_TX];
+ csb_ktoa += num_rings[NR_TX];
+ }
+
+ CSB_WRITE(csb_atok, head, kring->rhead);
+ CSB_WRITE(csb_atok, cur, kring->rcur);
+ CSB_WRITE(csb_atok, appl_need_kick, 1);
+ CSB_WRITE(csb_atok, sync_flags, 1);
+ CSB_WRITE(csb_ktoa, hwcur, kring->nr_hwcur);
+ CSB_WRITE(csb_ktoa, hwtail, kring->nr_hwtail);
+ CSB_WRITE(csb_ktoa, kern_need_kick, 1);
+
+ nm_prinf("csb_init for kring %s: head %u, cur %u, "
+ "hwcur %u, hwtail %u", kring->name,
+ kring->rhead, kring->rcur, kring->nr_hwcur,
+ kring->nr_hwtail);
+ }
+ }
+
+ return 0;
+}
+
/*
* possibly move the interface to netmap-mode.
* If success it returns a pointer to netmap_if, otherwise NULL.
@@ -2137,7 +2232,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct net
na->name, mtu, na->rx_buf_maxsize, nbs);
if (na->rx_buf_maxsize == 0) {
- D("%s: error: rx_buf_maxsize == 0", na->name);
+ nm_prerr("%s: error: rx_buf_maxsize == 0", na->name);
error = EIO;
goto err_drop_mem;
}
@@ -2149,7 +2244,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct net
* cannot be used in this case. */
if (nbs < mtu) {
nm_prerr("error: netmap buf size (%u) "
- "< device MTU (%u)\n", nbs, mtu);
+ "< device MTU (%u)", nbs, mtu);
error = EINVAL;
goto err_drop_mem;
}
@@ -2162,14 +2257,14 @@ netmap_do_regif(struct netmap_priv_d *priv, struct net
if (!(na->na_flags & NAF_MOREFRAG)) {
nm_prerr("error: large MTU (%d) needed "
"but %s does not support "
- "NS_MOREFRAG\n", mtu,
+ "NS_MOREFRAG", mtu,
na->ifp->if_xname);
error = EINVAL;
goto err_drop_mem;
} else if (nbs < na->rx_buf_maxsize) {
nm_prerr("error: using NS_MOREFRAG on "
"%s requires netmap buf size "
- ">= %u\n", na->ifp->if_xname,
+ ">= %u", na->ifp->if_xname,
na->rx_buf_maxsize);
error = EINVAL;
goto err_drop_mem;
@@ -2177,7 +2272,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct net
nm_prinf("info: netmap application on "
"%s needs to support "
"NS_MOREFRAG "
- "(MTU=%u,netmap_buf_size=%u)\n",
+ "(MTU=%u,netmap_buf_size=%u)",
na->ifp->if_xname, mtu, nbs);
}
}
@@ -2307,7 +2402,6 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, c
struct ifnet *ifp = NULL;
int error = 0;
u_int i, qfirst, qlast;
- struct netmap_if *nifp;
struct netmap_kring **krings;
int sync_flags;
enum txrx t;
@@ -2316,14 +2410,10 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, c
case NIOCCTRL: {
struct nmreq_header *hdr = (struct nmreq_header *)data;
- if (hdr->nr_version != NETMAP_API) {
- D("API mismatch for reqtype %d: got %d need %d",
- hdr->nr_version,
- hdr->nr_version, NETMAP_API);
- hdr->nr_version = NETMAP_API;
- }
if (hdr->nr_version < NETMAP_MIN_API ||
hdr->nr_version > NETMAP_MAX_API) {
+ nm_prerr("API mismatch: got %d need %d",
+ hdr->nr_version, NETMAP_API);
return EINVAL;
}
@@ -2345,13 +2435,13 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, c
case NETMAP_REQ_REGISTER: {
struct nmreq_register *req =
(struct nmreq_register *)(uintptr_t)hdr->nr_body;
+ struct netmap_if *nifp;
+
/* Protect access to priv from concurrent requests. */
NMG_LOCK();
do {
- u_int memflags;
-#ifdef WITH_EXTMEM
struct nmreq_option *opt;
-#endif /* WITH_EXTMEM */
+ u_int memflags;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list