diff options
Diffstat (limited to 'sys/dev/netmap/netmap.c')
| -rw-r--r-- | sys/dev/netmap/netmap.c | 147 |
1 files changed, 78 insertions, 69 deletions
diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c index d6230dfb8ebe..fef919f4ed57 100644 --- a/sys/dev/netmap/netmap.c +++ b/sys/dev/netmap/netmap.c @@ -536,35 +536,35 @@ SYSBEGIN(main_init); 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"); + CTLFLAG_RW, &netmap_verbose, 0, "Verbose mode"); SYSCTL_INT(_dev_netmap, OID_AUTO, no_timestamp, - CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp"); + CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp"); SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr, CTLFLAG_RW, &netmap_no_pendintr, - 0, "Always look for new received packets."); + 0, "Always look for new received packets."); SYSCTL_INT(_dev_netmap, OID_AUTO, txsync_retry, CTLFLAG_RW, - &netmap_txsync_retry, 0, "Number of txsync loops in bridge's flush."); + &netmap_txsync_retry, 0, "Number of txsync loops in bridge's flush."); SYSCTL_INT(_dev_netmap, OID_AUTO, fwd, CTLFLAG_RW, &netmap_fwd, 0, - "Force NR_FORWARD mode"); + "Force NR_FORWARD mode"); SYSCTL_INT(_dev_netmap, OID_AUTO, admode, CTLFLAG_RW, &netmap_admode, 0, - "Adapter mode. 0 selects the best option available," - "1 forces native adapter, 2 forces emulated adapter"); + "Adapter mode. 0 selects the best option available," + "1 forces native adapter, 2 forces emulated adapter"); SYSCTL_INT(_dev_netmap, OID_AUTO, generic_mit, CTLFLAG_RW, &netmap_generic_mit, - 0, "RX notification interval in nanoseconds"); + 0, "RX notification interval in nanoseconds"); SYSCTL_INT(_dev_netmap, OID_AUTO, generic_ringsize, CTLFLAG_RW, - &netmap_generic_ringsize, 0, - "Number of per-ring slots for emulated netmap mode"); + &netmap_generic_ringsize, 0, + "Number of per-ring slots for emulated netmap mode"); SYSCTL_INT(_dev_netmap, OID_AUTO, generic_rings, CTLFLAG_RW, - &netmap_generic_rings, 0, - "Number of TX/RX queues for emulated netmap adapters"); + &netmap_generic_rings, 0, + "Number of TX/RX queues for emulated netmap adapters"); #ifdef linux SYSCTL_INT(_dev_netmap, OID_AUTO, generic_txqdisc, CTLFLAG_RW, - &netmap_generic_txqdisc, 0, "Use qdisc for generic adapters"); + &netmap_generic_txqdisc, 0, "Use qdisc for generic adapters"); #endif SYSCTL_INT(_dev_netmap, OID_AUTO, ptnet_vnet_hdr, CTLFLAG_RW, &ptnet_vnet_hdr, - 0, "Allow ptnet devices to use virtio-net headers"); + 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"); + &ptnetmap_tx_workers, 0, "Use worker threads for pnetmap TX processing"); SYSEND; @@ -765,15 +765,15 @@ netmap_update_config(struct netmap_adapter *na) na->rx_buf_maxsize == info.rx_buf_maxsize) return 0; /* nothing changed */ if (na->active_fds == 0) { - 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); na->num_tx_rings = info.num_tx_rings; na->num_tx_desc = info.num_tx_descs; 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); return 0; } D("WARNING: configuration changed for %s while active: " @@ -830,7 +830,7 @@ netmap_krings_create(struct netmap_adapter *na, u_int tailroom) n[NR_TX] = na->num_tx_rings + 1; n[NR_RX] = na->num_rx_rings + 1; - len = (n[NR_TX] + n[NR_RX]) * + len = (n[NR_TX] + n[NR_RX]) * (sizeof(struct netmap_kring) + sizeof(struct netmap_kring *)) + tailroom; @@ -841,7 +841,7 @@ netmap_krings_create(struct netmap_adapter *na, u_int tailroom) } na->rx_rings = na->tx_rings + n[NR_TX]; na->tailroom = na->rx_rings + n[NR_RX]; - + /* link the krings in the krings array */ kring = (struct netmap_kring *)((char *)na->tailroom + tailroom); for (i = 0; i < n[NR_TX] + n[NR_RX]; i++) { @@ -1006,9 +1006,9 @@ netmap_do_unregif(struct netmap_priv_d *priv) if (netmap_verbose) D("deleting last instance for %s", na->name); - if (nm_netmap_on(na)) { - D("BUG: netmap on while going to delete the krings"); - } + if (nm_netmap_on(na)) { + D("BUG: netmap on while going to delete the krings"); + } na->nm_krings_delete(na); } @@ -1324,7 +1324,7 @@ netmap_rxsync_from_host(struct netmap_kring *kring, int flags) 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)); + D("%s", nm_dump_buf(NMB(na, slot),len, 128, NULL)); slot->len = len; slot->flags = 0; @@ -1476,7 +1476,7 @@ netmap_get_na(struct nmreq_header *hdr, struct netmap_adapter **na, struct ifnet **ifp, struct netmap_mem_d *nmd, int create) { - struct nmreq_register *req = (struct nmreq_register *)hdr->nr_body; + struct nmreq_register *req = (struct nmreq_register *)(uintptr_t)hdr->nr_body; int error = 0; struct netmap_adapter *ret = NULL; int nmd_ref = 0; @@ -2091,9 +2091,6 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na, NMG_LOCK_ASSERT(); priv->np_na = na; /* store the reference */ - error = netmap_set_ringid(priv, nr_mode, nr_ringid, nr_flags); - if (error) - goto err; error = netmap_mem_finalize(na->nm_mem, na); if (error) goto err; @@ -2109,7 +2106,14 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na, /* ring configuration may have changed, fetch from the card */ netmap_update_config(na); + } + + /* compute the range of tx and rx rings to monitor */ + error = netmap_set_ringid(priv, nr_mode, nr_ringid, nr_flags); + if (error) + goto err_put_lut; + if (na->active_fds == 0) { /* * If this is the first registration of the adapter, * perform sanity checks and create the in-kernel view @@ -2117,11 +2121,17 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na, */ if (na->ifp && nm_priv_rx_enabled(priv)) { /* This netmap adapter is attached to an ifnet. */ - unsigned nbs = netmap_mem_bufsize(na->nm_mem); + unsigned nbs = NETMAP_BUF_SIZE(na); unsigned mtu = nm_os_ifnet_mtu(na->ifp); - ND("mtu %d rx_buf_maxsize %d netmap_buf_size %d", - mtu, na->rx_buf_maxsize, nbs); + ND("%s: mtu %d rx_buf_maxsize %d netmap_buf_size %d", + na->name, mtu, na->rx_buf_maxsize, nbs); + + if (na->rx_buf_maxsize == 0) { + D("%s: error: rx_buf_maxsize == 0", na->name); + error = EIO; + goto err_drop_mem; + } if (mtu <= na->rx_buf_maxsize) { /* The MTU fits a single NIC slot. We only @@ -2191,7 +2201,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na, nifp = netmap_mem_if_new(na, priv); if (nifp == NULL) { error = ENOMEM; - goto err_del_rings; + goto err_rel_excl; } if (nm_kring_pending(priv)) { @@ -2217,10 +2227,9 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na, err_del_if: netmap_mem_if_delete(na, nifp); -err_del_rings: - netmap_mem_rings_delete(na); err_rel_excl: netmap_krings_put(priv); + netmap_mem_rings_delete(na); err_del_krings: if (na->active_fds == 0) na->nm_krings_delete(na); @@ -2313,8 +2322,8 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, * For convenince, the nr_body pointer and the pointers * in the options list will be replaced with their * kernel-space counterparts. The original pointers are - * saved internally and later restored by nmreq_copyout - */ + * saved internally and later restored by nmreq_copyout + */ error = nmreq_copyin(hdr, nr_body_is_user); if (error) { return error; @@ -2326,7 +2335,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, switch (hdr->nr_reqtype) { case NETMAP_REQ_REGISTER: { struct nmreq_register *req = - (struct nmreq_register *)hdr->nr_body; + (struct nmreq_register *)(uintptr_t)hdr->nr_body; /* Protect access to priv from concurrent requests. */ NMG_LOCK(); do { @@ -2341,7 +2350,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, } #ifdef WITH_EXTMEM - opt = nmreq_findoption((struct nmreq_option *)hdr->nr_options, + opt = nmreq_findoption((struct nmreq_option *)(uintptr_t)hdr->nr_options, NETMAP_REQ_OPT_EXTMEM); if (opt != NULL) { struct nmreq_opt_extmem *e = @@ -2444,7 +2453,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, case NETMAP_REQ_PORT_INFO_GET: { struct nmreq_port_info_get *req = - (struct nmreq_port_info_get *)hdr->nr_body; + (struct nmreq_port_info_get *)(uintptr_t)hdr->nr_body; NMG_LOCK(); do { @@ -2463,10 +2472,10 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, /* get a refcount */ hdr->nr_reqtype = NETMAP_REQ_REGISTER; - hdr->nr_body = (uint64_t)®req; + hdr->nr_body = (uintptr_t)®req; error = netmap_get_na(hdr, &na, &ifp, NULL, 1 /* create */); hdr->nr_reqtype = NETMAP_REQ_PORT_INFO_GET; /* reset type */ - hdr->nr_body = (uint64_t)req; /* reset nr_body */ + hdr->nr_body = (uintptr_t)req; /* reset nr_body */ if (error) { na = NULL; ifp = NULL; @@ -2517,7 +2526,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, case NETMAP_REQ_PORT_HDR_SET: { struct nmreq_port_hdr *req = - (struct nmreq_port_hdr *)hdr->nr_body; + (struct nmreq_port_hdr *)(uintptr_t)hdr->nr_body; /* Build a nmreq_register out of the nmreq_port_hdr, * so that we can call netmap_get_bdg_na(). */ struct nmreq_register regreq; @@ -2533,10 +2542,10 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, } NMG_LOCK(); hdr->nr_reqtype = NETMAP_REQ_REGISTER; - hdr->nr_body = (uint64_t)®req; + hdr->nr_body = (uintptr_t)®req; error = netmap_get_bdg_na(hdr, &na, NULL, 0); hdr->nr_reqtype = NETMAP_REQ_PORT_HDR_SET; - hdr->nr_body = (uint64_t)req; + hdr->nr_body = (uintptr_t)req; if (na && !error) { struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter *)na; @@ -2556,7 +2565,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, case NETMAP_REQ_PORT_HDR_GET: { /* Get vnet-header length for this netmap port */ struct nmreq_port_hdr *req = - (struct nmreq_port_hdr *)hdr->nr_body; + (struct nmreq_port_hdr *)(uintptr_t)hdr->nr_body; /* Build a nmreq_register out of the nmreq_port_hdr, * so that we can call netmap_get_bdg_na(). */ struct nmreq_register regreq; @@ -2565,10 +2574,10 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, bzero(®req, sizeof(regreq)); NMG_LOCK(); hdr->nr_reqtype = NETMAP_REQ_REGISTER; - hdr->nr_body = (uint64_t)®req; + hdr->nr_body = (uintptr_t)®req; error = netmap_get_na(hdr, &na, &ifp, NULL, 0); hdr->nr_reqtype = NETMAP_REQ_PORT_HDR_GET; - hdr->nr_body = (uint64_t)req; + hdr->nr_body = (uintptr_t)req; if (na && !error) { req->nr_hdr_len = na->virt_hdr_len; } @@ -2595,7 +2604,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, #endif /* WITH_VALE */ case NETMAP_REQ_POOLS_INFO_GET: { struct nmreq_pools_info *req = - (struct nmreq_pools_info *)hdr->nr_body; + (struct nmreq_pools_info *)(uintptr_t)hdr->nr_body; /* Get information from the memory allocator. This * netmap device must already be bound to a port. * Note that hdr->nr_name is ignored. */ @@ -2774,8 +2783,8 @@ nmreq_copyin(struct nmreq_header *hdr, int nr_body_is_user) error = EMSGSIZE; goto out_err; } - if ((rqsz && hdr->nr_body == (uint64_t)NULL) || - (!rqsz && hdr->nr_body != (uint64_t)NULL)) { + if ((rqsz && hdr->nr_body == (uintptr_t)NULL) || + (!rqsz && hdr->nr_body != (uintptr_t)NULL)) { /* Request body expected, but not found; or * request body found but unexpected. */ error = EINVAL; @@ -2784,8 +2793,8 @@ nmreq_copyin(struct nmreq_header *hdr, int nr_body_is_user) bufsz = 2 * sizeof(void *) + rqsz; optsz = 0; - for (src = (struct nmreq_option *)hdr->nr_options; src; - src = (struct nmreq_option *)buf.nro_next) + for (src = (struct nmreq_option *)(uintptr_t)hdr->nr_options; src; + src = (struct nmreq_option *)(uintptr_t)buf.nro_next) { error = copyin(src, &buf, sizeof(*src)); if (error) @@ -2813,11 +2822,11 @@ nmreq_copyin(struct nmreq_header *hdr, int nr_body_is_user) p = (char *)ptrs; /* copy the body */ - error = copyin((void *)hdr->nr_body, p, rqsz); + error = copyin((void *)(uintptr_t)hdr->nr_body, p, rqsz); if (error) goto out_restore; /* overwrite the user pointer with the in-kernel one */ - hdr->nr_body = (uint64_t)p; + hdr->nr_body = (uintptr_t)p; p += rqsz; /* copy the options */ @@ -2874,7 +2883,7 @@ static int nmreq_copyout(struct nmreq_header *hdr, int rerror) { struct nmreq_option *src, *dst; - void *ker = (void *)hdr->nr_body, *bufstart; + void *ker = (void *)(uintptr_t)hdr->nr_body, *bufstart; uint64_t *ptrs; size_t bodysz; int error; @@ -2886,13 +2895,13 @@ nmreq_copyout(struct nmreq_header *hdr, int rerror) ptrs = (uint64_t *)ker - 2; bufstart = ptrs; hdr->nr_body = *ptrs++; - src = (struct nmreq_option *)hdr->nr_options; + src = (struct nmreq_option *)(uintptr_t)hdr->nr_options; hdr->nr_options = *ptrs; if (!rerror) { /* copy the body */ bodysz = nmreq_size_by_type(hdr->nr_reqtype); - error = copyout(ker, (void *)hdr->nr_body, bodysz); + error = copyout(ker, (void *)(uintptr_t)hdr->nr_body, bodysz); if (error) { rerror = error; goto out; @@ -2900,7 +2909,7 @@ nmreq_copyout(struct nmreq_header *hdr, int rerror) } /* copy the options */ - dst = (struct nmreq_option *)hdr->nr_options; + dst = (struct nmreq_option *)(uintptr_t)hdr->nr_options; while (src) { size_t optsz; uint64_t next; @@ -2916,7 +2925,7 @@ nmreq_copyout(struct nmreq_header *hdr, int rerror) rerror = error; goto out; } - + /* copy the option body only if there was no error */ if (!rerror && !src->nro_status) { optsz = nmreq_opt_size_by_type(src->nro_reqtype); @@ -2928,8 +2937,8 @@ nmreq_copyout(struct nmreq_header *hdr, int rerror) } } } - src = (struct nmreq_option *)next; - dst = (struct nmreq_option *)*ptrs; + src = (struct nmreq_option *)(uintptr_t)next; + dst = (struct nmreq_option *)(uintptr_t)*ptrs; } @@ -2942,7 +2951,7 @@ out: struct nmreq_option * nmreq_findoption(struct nmreq_option *opt, uint16_t reqtype) { - for ( ; opt; opt = (struct nmreq_option *)opt->nro_next) + for ( ; opt; opt = (struct nmreq_option *)(uintptr_t)opt->nro_next) if (opt->nro_reqtype == reqtype) return opt; return NULL; @@ -2953,7 +2962,7 @@ nmreq_checkduplicate(struct nmreq_option *opt) { uint16_t type = opt->nro_reqtype; int dup = 0; - while ((opt = nmreq_findoption((struct nmreq_option *)opt->nro_next, + while ((opt = nmreq_findoption((struct nmreq_option *)(uintptr_t)opt->nro_next, type))) { dup++; opt->nro_status = EINVAL; @@ -2969,8 +2978,8 @@ nmreq_checkoptions(struct nmreq_header *hdr) * marked as not supported */ - for (opt = (struct nmreq_option *)hdr->nr_options; opt; - opt = (struct nmreq_option *)opt->nro_next) + for (opt = (struct nmreq_option *)(uintptr_t)hdr->nr_options; opt; + opt = (struct nmreq_option *)(uintptr_t)opt->nro_next) if (opt->nro_status == EOPNOTSUPP) return EOPNOTSUPP; @@ -3643,9 +3652,9 @@ netmap_transmit(struct ifnet *ifp, struct mbuf *m) */ mbq_lock(q); - busy = kring->nr_hwtail - kring->nr_hwcur; - if (busy < 0) - busy += kring->nkr_num_slots; + busy = kring->nr_hwtail - kring->nr_hwcur; + if (busy < 0) + busy += kring->nkr_num_slots; if (busy + mbq_len(q) >= kring->nkr_num_slots - 1) { RD(2, "%s full hwcur %d hwtail %d qlen %d", na->name, kring->nr_hwcur, kring->nr_hwtail, mbq_len(q)); |
