From 3ab69a246b2953d9e21457065faaacbd84b85dd1 Mon Sep 17 00:00:00 2001 From: luigi Date: Sat, 16 Aug 2014 15:00:01 +0000 Subject: Update to the current version of netmap. Mostly bugfixes or features developed in the past 6 months, so this is a 10.1 candidate. Basically no user API changes (some bugfixes in sys/net/netmap_user.h). In detail: 1. netmap support for virtio-net, including in netmap mode. Under bhyve and with a netmap backend [2] we reach over 1Mpps with standard APIs (e.g. libpcap), and 5-8 Mpps in netmap mode. 2. (kernel) add support for multiple memory allocators, so we can better partition physical and virtual interfaces giving access to separate users. The most visible effect is one additional argument to the various kernel functions to compute buffer addresses. All netmap-supported drivers are affected, but changes are mechanical and trivial 3. (kernel) simplify the prototype for *txsync() and *rxsync() driver methods. All netmap drivers affected, changes mostly mechanical. 4. add support for netmap-monitor ports. Think of it as a mirroring port on a physical switch: a netmap monitor port replicates traffic present on the main port. Restrictions apply. Drive carefully. 5. if_lem.c: support for various paravirtualization features, experimental and disabled by default. Most of these are described in our ANCS'13 paper [1]. Paravirtualized support in netmap mode is new, and beats the numbers in the paper by a large factor (under qemu-kvm, we measured gues-host throughput up to 10-12 Mpps). A lot of refactoring and additional documentation in the files in sys/dev/netmap, but apart from #2 and #3 above, almost nothing of this stuff is visible to other kernel parts. Example programs in tools/tools/netmap have been updated with bugfixes and to support more of the existing features. This is meant to go into 10.1 so we plan an MFC before the Aug.22 deadline. A lot of this code has been contributed by my colleagues at UNIPI, including Giuseppe Lettieri, Vincenzo Maffione, Stefano Garzarella. MFC after: 3 days. --- sys/dev/netmap/netmap_pipe.c | 53 +++++++++++++------------------------------- 1 file changed, 15 insertions(+), 38 deletions(-) (limited to 'sys/dev/netmap/netmap_pipe.c') diff --git a/sys/dev/netmap/netmap_pipe.c b/sys/dev/netmap/netmap_pipe.c index 9fcc4d2..bc998c0 100644 --- a/sys/dev/netmap/netmap_pipe.c +++ b/sys/dev/netmap/netmap_pipe.c @@ -126,7 +126,7 @@ void netmap_pipe_dealloc(struct netmap_adapter *na) { if (na->na_pipes) { - ND("freeing pipes for %s", NM_IFPNAME(na->ifp)); + ND("freeing pipes for %s", na->name); free(na->na_pipes, M_DEVBUF); na->na_pipes = NULL; na->na_max_pipes = 0; @@ -155,7 +155,7 @@ static int netmap_pipe_add(struct netmap_adapter *parent, struct netmap_pipe_adapter *na) { if (parent->na_next_pipe >= parent->na_max_pipes) { - D("%s: no space left for pipes", NM_IFPNAME(parent->ifp)); + D("%s: no space left for pipes", parent->name); return ENOMEM; } @@ -179,10 +179,9 @@ netmap_pipe_remove(struct netmap_adapter *parent, struct netmap_pipe_adapter *na } static int -netmap_pipe_txsync(struct netmap_adapter *na, u_int ring_nr, int flags) +netmap_pipe_txsync(struct netmap_kring *txkring, int flags) { - struct netmap_kring *txkring = na->tx_rings + ring_nr, - *rxkring = txkring->pipe; + struct netmap_kring *rxkring = txkring->pipe; u_int limit; /* slots to transfer */ u_int j, k, lim_tx = txkring->nkr_num_slots - 1, lim_rx = rxkring->nkr_num_slots - 1; @@ -245,10 +244,9 @@ netmap_pipe_txsync(struct netmap_adapter *na, u_int ring_nr, int flags) } static int -netmap_pipe_rxsync(struct netmap_adapter *na, u_int ring_nr, int flags) +netmap_pipe_rxsync(struct netmap_kring *rxkring, int flags) { - struct netmap_kring *rxkring = na->rx_rings + ring_nr, - *txkring = rxkring->pipe; + struct netmap_kring *txkring = rxkring->pipe; uint32_t oldhwcur = rxkring->nr_hwcur; ND("%s %x <- %s", rxkring->name, flags, txkring->name); @@ -425,12 +423,11 @@ netmap_pipe_reg(struct netmap_adapter *na, int onoff) { struct netmap_pipe_adapter *pna = (struct netmap_pipe_adapter *)na; - struct ifnet *ifp = na->ifp; ND("%p: onoff %d", na, onoff); if (onoff) { - ifp->if_capenable |= IFCAP_NETMAP; + na->na_flags |= NAF_NETMAP_ON; } else { - ifp->if_capenable &= ~IFCAP_NETMAP; + na->na_flags &= ~NAF_NETMAP_ON; } if (pna->peer_ref) { ND("%p: case 1.a or 2.a, nothing to do", na); @@ -522,8 +519,6 @@ netmap_pipe_dtor(struct netmap_adapter *na) if (pna->role == NR_REG_PIPE_MASTER) netmap_pipe_remove(pna->parent, pna); netmap_adapter_put(pna->parent); - free(na->ifp, M_DEVBUF); - na->ifp = NULL; pna->parent = NULL; } @@ -533,7 +528,6 @@ netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na, int create) struct nmreq pnmr; struct netmap_adapter *pna; /* parent adapter */ struct netmap_pipe_adapter *mna, *sna, *req; - struct ifnet *ifp, *ifp2; u_int pipe_id; int role = nmr->nr_flags & NR_REG_MASK; int error; @@ -556,7 +550,7 @@ netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na, int create) ND("parent lookup failed: %d", error); return error; } - ND("found parent: %s", NM_IFPNAME(pna->ifp)); + ND("found parent: %s", na->name); if (NETMAP_OWNED_BY_KERN(pna)) { ND("parent busy"); @@ -591,19 +585,12 @@ netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na, int create) * The endpoint we were asked for holds a reference to * the other one. */ - ifp = malloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT | M_ZERO); - if (!ifp) { - error = ENOMEM; - goto put_out; - } - strcpy(ifp->if_xname, NM_IFPNAME(pna->ifp)); - mna = malloc(sizeof(*mna), M_DEVBUF, M_NOWAIT | M_ZERO); if (mna == NULL) { error = ENOMEM; - goto free_ifp; + goto put_out; } - mna->up.ifp = ifp; + snprintf(mna->up.name, sizeof(mna->up.name), "%s{%d", pna->name, pipe_id); mna->id = pipe_id; mna->role = NR_REG_PIPE_MASTER; @@ -618,6 +605,7 @@ netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na, int create) mna->up.nm_mem = pna->nm_mem; mna->up.na_lut = pna->na_lut; mna->up.na_lut_objtotal = pna->na_lut_objtotal; + mna->up.na_lut_objsize = pna->na_lut_objsize; mna->up.num_tx_rings = 1; mna->up.num_rx_rings = 1; @@ -629,28 +617,21 @@ netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na, int create) 1, NM_PIPE_MAXSLOTS, NULL); error = netmap_attach_common(&mna->up); if (error) - goto free_ifp; + goto free_mna; /* register the master with the parent */ error = netmap_pipe_add(pna, mna); if (error) goto free_mna; /* create the slave */ - ifp2 = malloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT | M_ZERO); - if (!ifp) { - error = ENOMEM; - goto free_mna; - } - strcpy(ifp2->if_xname, NM_IFPNAME(pna->ifp)); - sna = malloc(sizeof(*mna), M_DEVBUF, M_NOWAIT | M_ZERO); if (sna == NULL) { error = ENOMEM; - goto free_ifp2; + goto free_mna; } /* most fields are the same, copy from master and then fix */ *sna = *mna; - sna->up.ifp = ifp2; + snprintf(sna->up.name, sizeof(sna->up.name), "%s}%d", pna->name, pipe_id); sna->role = NR_REG_PIPE_SLAVE; error = netmap_attach_common(&sna->up); if (error) @@ -696,12 +677,8 @@ found: free_sna: free(sna, M_DEVBUF); -free_ifp2: - free(ifp2, M_DEVBUF); free_mna: free(mna, M_DEVBUF); -free_ifp: - free(ifp, M_DEVBUF); put_out: netmap_adapter_put(pna); return error; -- cgit v1.1