From owner-svn-soc-all@freebsd.org Thu Aug 13 10:36:47 2015 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 361639B7B25 for ; Thu, 13 Aug 2015 10:36:47 +0000 (UTC) (envelope-from stefano@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2550A765 for ; Thu, 13 Aug 2015 10:36:47 +0000 (UTC) (envelope-from stefano@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id t7DAalxg052043 for ; Thu, 13 Aug 2015 10:36:47 GMT (envelope-from stefano@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id t7DAajKO051949 for svn-soc-all@FreeBSD.org; Thu, 13 Aug 2015 10:36:45 GMT (envelope-from stefano@FreeBSD.org) Date: Thu, 13 Aug 2015 10:36:45 GMT Message-Id: <201508131036.t7DAajKO051949@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to stefano@FreeBSD.org using -f From: stefano@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r289682 - in soc2015/stefano/ptnetmap/stable/10/sys: dev/netmap net MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Aug 2015 10:36:47 -0000 Author: stefano Date: Thu Aug 13 10:36:44 2015 New Revision: 289682 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289682 Log: [ptnetmap] sync netmap code with github version ptnetmap comments and cleanup Modified: soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_lem_netmap.h soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_vtnet_netmap.h soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_freebsd.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_generic.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_kern.h soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_mbq.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_mbq.h soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_mem2.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_mem2.h soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_monitor.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_offloadings.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_pipe.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_vale.c soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_virt.h soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/ptnetmap.c soc2015/stefano/ptnetmap/stable/10/sys/net/netmap.h soc2015/stefano/ptnetmap/stable/10/sys/net/netmap_user.h Modified: soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_lem_netmap.h ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_lem_netmap.h Thu Aug 13 09:47:12 2015 (r289681) +++ soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_lem_netmap.h Thu Aug 13 10:36:44 2015 (r289682) @@ -472,8 +472,14 @@ } #if defined (NIC_PTNETMAP) && defined (WITH_PTNETMAP_GUEST) +/* + * ptnetmap support for: lem (FreeBSD version) + * + * For details on ptnetmap support please see if_vtnet_netmap.h + */ static uint32_t lem_ptnetmap_ptctl(struct ifnet *, uint32_t); +/* Returns device configuration from the CSB */ static int lem_ptnetmap_config(struct netmap_adapter *na, u_int *txr, u_int *txd, u_int *rxr, u_int *rxd) @@ -501,6 +507,7 @@ return 0; } +/* Reconcile host and guest view of the transmit ring. */ static int lem_ptnetmap_txsync(struct netmap_kring *kring, int flags) { @@ -510,7 +517,7 @@ struct adapter *adapter = ifp->if_softc; int ret, notify = 0; - ret = ptnetmap_txsync(kring, flags, ¬ify); + ret = netmap_pt_guest_txsync(kring, flags, ¬ify); if (notify) E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0); @@ -518,6 +525,7 @@ return ret; } +/* Reconcile host and guest view of the receive ring. */ static int lem_ptnetmap_rxsync(struct netmap_kring *kring, int flags) { @@ -527,7 +535,7 @@ struct adapter *adapter = ifp->if_softc; int ret, notify = 0; - ret = ptnetmap_rxsync(kring, flags, ¬ify); + ret = netmap_pt_guest_rxsync(kring, flags, ¬ify); if (notify) E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), 0); @@ -535,6 +543,7 @@ return ret; } +/* Register/unregister. We are already under netmap lock. */ static int lem_ptnetmap_reg(struct netmap_adapter *na, int onoff) { @@ -555,8 +564,8 @@ * Init ring and kring pointers * After PARAVIRT_PTCTL_REGIF, the csb contains a snapshot of a * host kring pointers. - * XXX This initialization is required, because we don't close the - * host port on UNREGIF. + * XXX This initialization is required, because we don't close + * the host port on UNREGIF. */ // Init rx ring @@ -564,14 +573,16 @@ kring->rhead = kring->ring->head = csb->rx_ring.head; kring->rcur = kring->ring->cur = csb->rx_ring.cur; kring->nr_hwcur = csb->rx_ring.hwcur; - kring->nr_hwtail = kring->rtail = kring->ring->tail = csb->rx_ring.hwtail; + kring->nr_hwtail = kring->rtail = kring->ring->tail = + csb->rx_ring.hwtail; // Init tx ring kring = na->tx_rings; kring->rhead = kring->ring->head = csb->tx_ring.head; kring->rcur = kring->ring->cur = csb->tx_ring.cur; kring->nr_hwcur = csb->tx_ring.hwcur; - kring->nr_hwtail = kring->rtail = kring->ring->tail = csb->tx_ring.hwtail; + kring->nr_hwtail = kring->rtail = kring->ring->tail = + csb->tx_ring.hwtail; } else { na->na_flags &= ~NAF_NETMAP_ON; adapter->ptnetmap_enabled = 0; @@ -588,15 +599,21 @@ return EOPNOTSUPP; } +/* + * CSB (Communication Status Block) setup + * CSB is already allocated in if_lem (paravirt). + */ static void lem_ptnetmap_setup_csb(struct adapter *adapter) { struct ifnet *ifp = adapter->ifp; - struct netmap_pt_guest_adapter* ptna = (struct netmap_pt_guest_adapter *)NA(ifp); + struct netmap_pt_guest_adapter* ptna = + (struct netmap_pt_guest_adapter *)NA(ifp); ptna->csb = adapter->csb; } +/* Send command to the host through PTCTL register. */ static uint32_t lem_ptnetmap_ptctl(struct ifnet *ifp, uint32_t val) { @@ -610,8 +627,7 @@ return ret; } - - +/* Features negotiation with the host through PTFEAT */ static uint32_t lem_ptnetmap_features(struct adapter *adapter) { Modified: soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_vtnet_netmap.h ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_vtnet_netmap.h Thu Aug 13 09:47:12 2015 (r289681) +++ soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/if_vtnet_netmap.h Thu Aug 13 10:36:44 2015 (r289682) @@ -35,7 +35,8 @@ #ifdef WITH_PTNETMAP_GUEST #include static int vtnet_ptnetmap_txsync(struct netmap_kring *kring, int flags); -#define VTNET_PTNETMAP_ON(_na) ((nm_netmap_on(_na)) && ((_na)->nm_txsync == vtnet_ptnetmap_txsync)) +#define VTNET_PTNETMAP_ON(_na) \ + ((nm_netmap_on(_na)) && ((_na)->nm_txsync == vtnet_ptnetmap_txsync)) #else /* !WITH_PTNETMAP_GUEST */ #define VTNET_PTNETMAP_ON(_na) 0 #endif /* WITH_PTNETMAP_GUEST */ @@ -414,9 +415,20 @@ } #ifdef WITH_PTNETMAP_GUEST +/* + * ptnetmap support for: virtio-net (FreeBSD version) + * + * this part od this file is meant to be a reference on how to implement + * ptnetmap support for a network driver. + * this file contains code but only static or inline functions used + * by a single driver. + */ + +/* + * virtio-specific macro and fucntions + */ /* ptnetmap virtio register BASE */ #define PTNETMAP_VIRTIO_IO_BASE sizeof(struct virtio_net_config) - #ifndef VIRTIO_NET_F_PTNETMAP #define VIRTIO_NET_F_PTNETMAP 0x2000000 /* linux/qeum 25 */ #endif /* VIRTIO_NET_F_PTNETMAP */ @@ -425,9 +437,13 @@ vtnet_ptnetmap_iowrite4(device_t dev, uint32_t addr, uint32_t val) { int i; - /* virtio_pci config_set use multiple iowrite8, we need to split the call and reverse the order */ + /* + * virtio_pci config_set use multiple iowrite8, we need to split the + * call and reverse the order + */ for (i = 3; i >= 0; i--) { - virtio_write_dev_config_1(dev, PTNETMAP_VIRTIO_IO_BASE + addr + i, *(((uint8_t *)&val) + i)); + virtio_write_dev_config_1(dev, PTNETMAP_VIRTIO_IO_BASE + addr + i, + *(((uint8_t *)&val) + i)); } } @@ -438,25 +454,35 @@ int i; for (i = 0; i <= 3; i++) { - *(((uint8_t *)&val) + i) = virtio_read_dev_config_1(dev, PTNETMAP_VIRTIO_IO_BASE + addr + i); + *(((uint8_t *)&val) + i) = virtio_read_dev_config_1(dev, + PTNETMAP_VIRTIO_IO_BASE + addr + i); } return val; } +/* + * CSB (Communication Status Block) allocation. + * CSB is the shared memory used by the netmap instance running in the guest + * and the ptnetmap kthreads in the host. + * The CSBBAH/CSBBAL registers must be added to the virtio-net device. + * + * Only called after netmap_pt_guest_attach(). + */ static int vtnet_ptnetmap_alloc_csb(struct SOFTC_T *sc) { device_t dev = sc->vtnet_dev; struct ifnet *ifp = sc->vtnet_ifp; - struct netmap_pt_guest_adapter* ptna = (struct netmap_pt_guest_adapter *)NA(ifp); + struct netmap_pt_guest_adapter* ptna = + (struct netmap_pt_guest_adapter *)NA(ifp); vm_paddr_t csb_phyaddr; if (ptna->csb) return 0; - ptna->csb = contigmalloc(NET_PARAVIRT_CSB_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO, - (size_t)0, -1UL, PAGE_SIZE, 0); + ptna->csb = contigmalloc(NET_PARAVIRT_CSB_SIZE, M_DEVBUF, + M_NOWAIT | M_ZERO, (size_t)0, -1UL, PAGE_SIZE, 0); if (!ptna->csb) { D("Communication Status Block allocation failed!"); return ENOMEM; @@ -467,18 +493,24 @@ ptna->csb->guest_csb_on = 1; /* Tell the device the CSB physical address. */ - vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_CSBBAH, (uint32_t)(csb_phyaddr >> 32)); - vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_CSBBAL, (uint32_t)(csb_phyaddr)); + vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_CSBBAH, + (uint32_t)(csb_phyaddr >> 32)); + vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_CSBBAL, + (uint32_t)(csb_phyaddr)); return 0; } +/* + * CSB (Communication Status Block) deallocation. + */ static void vtnet_ptnetmap_free_csb(struct SOFTC_T *sc) { device_t dev = sc->vtnet_dev; struct ifnet *ifp = sc->vtnet_ifp; - struct netmap_pt_guest_adapter* ptna = (struct netmap_pt_guest_adapter *)NA(ifp); + struct netmap_pt_guest_adapter* ptna = + (struct netmap_pt_guest_adapter *)NA(ifp); if (ptna->csb) { /* CSB deallocation protocol. */ @@ -491,11 +523,19 @@ } static uint32_t vtnet_ptnetmap_ptctl(struct ifnet *, uint32_t); + +/* + * Returns device configuration from the CSB, after sending the PTCTL_CONFIG + * command to the host (hypervisor virtio fronted). + * The host reads the configuration from the netmap port (opened in the host) + * and it stores the values in the CSB. + */ static int vtnet_ptnetmap_config(struct netmap_adapter *na, u_int *txr, u_int *txd, u_int *rxr, u_int *rxd) { - struct netmap_pt_guest_adapter *ptna = (struct netmap_pt_guest_adapter *)na; + struct netmap_pt_guest_adapter *ptna = + (struct netmap_pt_guest_adapter *)na; struct paravirt_csb *csb = ptna->csb; int ret; @@ -511,11 +551,16 @@ *txd = csb->num_tx_slots; *rxd = csb->num_rx_slots; - D("txr %u rxr %u txd %u rxd %u", + ND("txr %u rxr %u txd %u rxd %u", *txr, *rxr, *txd, *rxd); return 0; } +/* + * Reconcile host and guest view of the transmit ring. + * Use generic netmap_pt_guest_txsync(). + * Only the notification to the host is device-specific. + */ static int vtnet_ptnetmap_txsync(struct netmap_kring *kring, int flags) { @@ -526,7 +571,7 @@ struct virtqueue *vq = sc->vtnet_txqs[ring_nr].vtntx_vq; int ret, notify = 0; - ret = ptnetmap_txsync(kring, flags, ¬ify); + ret = netmap_pt_guest_txsync(kring, flags, ¬ify); if (notify) virtqueue_notify(vq); @@ -536,6 +581,11 @@ return ret; } +/* + * Reconcile host and guest view of the receive ring. + * Use generic netmap_pt_guest_rxsync(). + * Only the notification to the host is device-specific. + */ static int vtnet_ptnetmap_rxsync(struct netmap_kring *kring, int flags) { @@ -546,7 +596,7 @@ struct virtqueue *vq = sc->vtnet_rxqs[ring_nr].vtnrx_vq; int ret, notify = 0; - ret = ptnetmap_rxsync(kring, flags, ¬ify); + ret = netmap_pt_guest_rxsync(kring, flags, ¬ify); if (notify) virtqueue_notify(vq); @@ -556,10 +606,15 @@ return ret; } +/* + * Register/unregister. We are already under netmap lock. + * Only called on the first register or the last unregister. + */ static int vtnet_ptnetmap_reg(struct netmap_adapter *na, int onoff) { - struct netmap_pt_guest_adapter *ptna = (struct netmap_pt_guest_adapter *)na; + struct netmap_pt_guest_adapter *ptna = + (struct netmap_pt_guest_adapter *)na; /* device-specific */ struct ifnet *ifp = na->ifp; @@ -597,22 +652,24 @@ * Init ring and kring pointers * After PARAVIRT_PTCTL_REGIF, the csb contains a snapshot of a * host kring pointers. - * XXX This initialization is required, because we don't close the - * host port on UNREGIF. + * XXX This initialization is required, because we don't close + * the host port on UNREGIF. */ // Init rx ring kring = na->rx_rings; kring->rhead = kring->ring->head = csb->rx_ring.head; kring->rcur = kring->ring->cur = csb->rx_ring.cur; kring->nr_hwcur = csb->rx_ring.hwcur; - kring->nr_hwtail = kring->rtail = kring->ring->tail = csb->rx_ring.hwtail; + kring->nr_hwtail = kring->rtail = kring->ring->tail = + csb->rx_ring.hwtail; // Init tx ring kring = na->tx_rings; kring->rhead = kring->ring->head = csb->tx_ring.head; kring->rcur = kring->ring->cur = csb->tx_ring.cur; kring->nr_hwcur = csb->tx_ring.hwcur; - kring->nr_hwtail = kring->rtail = kring->ring->tail = csb->tx_ring.hwtail; + kring->nr_hwtail = kring->rtail = kring->ring->tail = + csb->tx_ring.hwtail; } else { ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); //na->na_flags &= ~NAF_NETMAP_ON; @@ -631,6 +688,10 @@ return EOPNOTSUPP; } +/* + * Send command to the host (hypervisor virtio fronted) through PTCTL register. + * The PTCTL register must be added to the virtio-net device. + */ static uint32_t vtnet_ptnetmap_ptctl(struct ifnet *ifp, uint32_t val) { @@ -646,13 +707,19 @@ return ret; } +/* + * Features negotiation with the host (hypervisor virtio fronted) through PTFEAT + * register. + * The PTFEAT register must be added to the virtio-net device. + */ static uint32_t vtnet_ptnetmap_features(struct SOFTC_T *sc) { device_t dev = sc->vtnet_dev; uint32_t features; /* tell the device the features we support */ - vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_PTFEAT, NET_PTN_FEATURES_BASE); + vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_PTFEAT, + NET_PTN_FEATURES_BASE); /* get back the acknowledged features */ features = vtnet_ptnetmap_ioread4(dev, PTNETMAP_VIRTIO_IO_PTFEAT); D("ptnetmap support: %s\n", @@ -692,9 +759,9 @@ na.num_tx_rings = na.num_rx_rings = sc->vtnet_max_vq_pairs; D("max rings %d", sc->vtnet_max_vq_pairs); #ifdef WITH_PTNETMAP_GUEST - D("check ptnetmap support"); + /* check if virtio-net (guest and host) supports ptnetmap */ if (virtio_with_feature(sc->vtnet_dev, VIRTIO_NET_F_PTNETMAP) && - (vtnet_ptnetmap_features(sc) & NET_PTN_FEATURES_BASE)) { + (vtnet_ptnetmap_features(sc) & NET_PTN_FEATURES_BASE)) { D("ptnetmap supported"); na.nm_config = vtnet_ptnetmap_config; na.nm_register = vtnet_ptnetmap_reg; Modified: soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap.c ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap.c Thu Aug 13 09:47:12 2015 (r289681) +++ soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap.c Thu Aug 13 10:36:44 2015 (r289682) @@ -133,13 +133,12 @@ * > select()able file descriptor on which events are reported. * * Internally, we allocate a netmap_priv_d structure, that will be - * initialized on ioctl(NIOCREGIF). + * initialized on ioctl(NIOCREGIF). There is one netmap_priv_d + * structure for each open(). * * os-specific: - * FreeBSD: netmap_open (netmap_freebsd.c). The priv is - * per-thread. - * linux: linux_netmap_open (netmap_linux.c). The priv is - * per-open. + * FreeBSD: see netmap_open() (netmap_freebsd.c) + * linux: see linux_netmap_open() (netmap_linux.c) * * > 2. on each descriptor, the process issues an ioctl() to identify * > the interface that should report events to the file descriptor. @@ -306,7 +305,7 @@ * kring->nm_sync() == netmap_txsync_to_host_compat * netmap_txsync_to_host(na) * NM_SEND_UP() - * FreeBSD: na->if_input() == ?? XXX + * FreeBSD: na->if_input() == ether_input() * linux: netif_rx() with NM_MAGIC_PRIORITY_RX * * @@ -333,7 +332,7 @@ * generic_rx_handler() * mbq_safe_enqueue() * na->nm_notify() == netmap_notify() - * - rx from host stack: + * - rx from host stack (XXX why different from native?): * concurrently: * 1) host stack * linux: generic_ndo_start_xmit() @@ -344,13 +343,7 @@ * 2) ioctl(NIOCRXSYNC)/netmap_poll() in process context * kring->nm_sync() == netmap_rxsync_from_host_compat * netmap_rxsync_from_host(na, NULL, NULL) - * - tx to host stack: - * ioctl(NIOCTXSYNC)/netmap_poll() in process context - * kring->nm_sync() == netmap_txsync_to_host_compat - * netmap_txsync_to_host(na) - * NM_SEND_UP() - * FreeBSD: na->if_input() == ??? XXX - * linux: netif_rx() with NM_MAGIC_PRIORITY_RX + * - tx to host stack (same as native): * * * -= VALE =- @@ -464,20 +457,19 @@ knlist_init_mtx(&(x)->si.si_note, m); \ } while (0) -#define OS_selrecord(a, b) selrecord(a, &((b)->si)) -#define OS_selwakeup(a, b) freebsd_selwakeup(a, b) - #elif defined(linux) #include "bsd_glue.h" - - #elif defined(__APPLE__) #warning OSX support is only partial #include "osx_glue.h" +#elif defined (_WIN32) + +#include "win_glue.h" + #else #error Unsupported platform @@ -492,39 +484,22 @@ #include -MALLOC_DEFINE(M_NETMAP, "netmap", "Network memory map"); - /* user-controlled variables */ int netmap_verbose; static int netmap_no_timestamp; /* don't timestamp on rxsync */ - -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"); -SYSCTL_INT(_dev_netmap, OID_AUTO, no_timestamp, - CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp"); int netmap_mitigate = 1; -SYSCTL_INT(_dev_netmap, OID_AUTO, mitigate, CTLFLAG_RW, &netmap_mitigate, 0, ""); int netmap_no_pendintr = 1; -SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr, - CTLFLAG_RW, &netmap_no_pendintr, 0, "Always look for new received packets."); int netmap_txsync_retry = 2; -SYSCTL_INT(_dev_netmap, OID_AUTO, txsync_retry, CTLFLAG_RW, - &netmap_txsync_retry, 0 , "Number of txsync loops in bridge's flush."); - int netmap_adaptive_io = 0; -SYSCTL_INT(_dev_netmap, OID_AUTO, adaptive_io, CTLFLAG_RW, - &netmap_adaptive_io, 0 , "Adaptive I/O on paravirt"); - int netmap_flags = 0; /* debug flags */ -int netmap_fwd = 0; /* force transparent mode */ +static int netmap_fwd = 0; /* force transparent mode */ /* * netmap_admode selects the netmap mode to use. * Invalid values are reset to NETMAP_ADMODE_BEST */ -enum { NETMAP_ADMODE_BEST = 0, /* use native, fallback to generic */ +enum { NETMAP_ADMODE_BEST = 0, /* use native, fallback to generic */ NETMAP_ADMODE_NATIVE, /* either native or none */ NETMAP_ADMODE_GENERIC, /* force generic */ NETMAP_ADMODE_LAST }; @@ -534,6 +509,26 @@ int netmap_generic_ringsize = 1024; /* Generic ringsize. */ int netmap_generic_rings = 1; /* number of queues in generic. */ +/* + * SYSCTL calls are grouped between SYSBEGIN and SYSEND to be emulated + * in some other operating systems + */ +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"); +SYSCTL_INT(_dev_netmap, OID_AUTO, no_timestamp, + CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp"); +SYSCTL_INT(_dev_netmap, OID_AUTO, mitigate, CTLFLAG_RW, &netmap_mitigate, 0, ""); +SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr, + CTLFLAG_RW, &netmap_no_pendintr, 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."); +SYSCTL_INT(_dev_netmap, OID_AUTO, adaptive_io, CTLFLAG_RW, + &netmap_adaptive_io, 0 , "Adaptive I/O on paravirt"); + SYSCTL_INT(_dev_netmap, OID_AUTO, flags, CTLFLAG_RW, &netmap_flags, 0 , ""); SYSCTL_INT(_dev_netmap, OID_AUTO, fwd, CTLFLAG_RW, &netmap_fwd, 0 , ""); SYSCTL_INT(_dev_netmap, OID_AUTO, admode, CTLFLAG_RW, &netmap_admode, 0 , ""); @@ -541,6 +536,8 @@ SYSCTL_INT(_dev_netmap, OID_AUTO, generic_ringsize, CTLFLAG_RW, &netmap_generic_ringsize, 0 , ""); SYSCTL_INT(_dev_netmap, OID_AUTO, generic_rings, CTLFLAG_RW, &netmap_generic_rings, 0 , ""); +SYSEND; + NMG_LOCK_T netmap_global_lock; int netmap_use_count = 0; /* number of active netmap instances */ @@ -728,7 +725,7 @@ } static void netmap_txsync_to_host(struct netmap_adapter *na); -static int netmap_rxsync_from_host(struct netmap_adapter *na, struct thread *td, void *pwait); +static int netmap_rxsync_from_host(struct netmap_adapter *na, NM_SELRECORD_T *); /* kring->nm_sync callback for the host tx ring */ static int @@ -744,7 +741,7 @@ netmap_rxsync_from_host_compat(struct netmap_kring *kring, int flags) { (void)flags; /* unused */ - netmap_rxsync_from_host(kring->na, NULL, NULL); + netmap_rxsync_from_host(kring->na, NULL); return 0; } @@ -1036,13 +1033,18 @@ netmap_send_up(struct ifnet *dst, struct mbq *q) { struct mbuf *m; + struct mbuf *head = NULL, *prev = NULL; /* send packets up, outside the lock */ while ((m = mbq_dequeue(q)) != NULL) { if (netmap_verbose & NM_VERB_HOST) D("sending up pkt %p size %d", m, MBUF_LEN(m)); - NM_SEND_UP(dst, m); + prev = nm_os_send_up(dst, m, prev); + if (head == NULL) + head = prev; } + if (head) + nm_os_send_up(dst, NULL, head); mbq_destroy(q); } @@ -1179,7 +1181,7 @@ * transparent mode, or a negative value if error */ static int -netmap_rxsync_from_host(struct netmap_adapter *na, struct thread *td, void *pwait) +netmap_rxsync_from_host(struct netmap_adapter *na, NM_SELRECORD_T *sr) { struct netmap_kring *kring = &na->rx_rings[na->num_rx_rings]; struct netmap_ring *ring = kring->ring; @@ -1189,9 +1191,6 @@ int ret = 0; struct mbq *q = &kring->rx_queue, fq; - (void)pwait; /* disable unused warnings */ - (void)td; - mbq_init(&fq); /* fq holds packets to be freed */ mbq_lock(q); @@ -1232,8 +1231,8 @@ } /* access copies of cur,tail in the kring */ - if (kring->rcur == kring->rtail && td) /* no bufs available */ - OS_selrecord(td, &kring->si); + if (kring->rcur == kring->rtail && sr) /* no bufs available */ + nm_os_selrecord(sr, &kring->si); mbq_unlock(q); @@ -2078,21 +2077,16 @@ * Return 0 on success, errno otherwise. */ int -netmap_ioctl(struct cdev *dev, u_long cmd, caddr_t data, - int fflag, struct thread *td) +netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread *td) { - struct netmap_priv_d *priv = NULL; struct nmreq *nmr = (struct nmreq *) data; struct netmap_adapter *na = NULL; - int error; + int error = 0; u_int i, qfirst, qlast; struct netmap_if *nifp; struct netmap_kring *krings; enum txrx t; - (void)dev; /* UNUSED */ - (void)fflag; /* UNUSED */ - if (cmd == NIOCGINFO || cmd == NIOCREGIF) { /* truncate name */ nmr->nr_name[sizeof(nmr->nr_name) - 1] = '\0'; @@ -2107,15 +2101,6 @@ return EINVAL; } } - CURVNET_SET(TD_TO_VNET(td)); - - error = devfs_get_cdevpriv((void **)&priv); - if (error) { - CURVNET_RESTORE(); - /* XXX ENOENT should be impossible, since the priv - * is now created in the open */ - return (error == ENOENT ? ENXIO : error); - } switch (cmd) { case NIOCGINFO: /* return capabilities etc */ @@ -2335,7 +2320,6 @@ } out: - CURVNET_RESTORE(); return (error); } @@ -2355,9 +2339,8 @@ * hidden argument. */ int -netmap_poll(struct cdev *dev, int events, struct thread *td) +netmap_poll(struct netmap_priv_d *priv, int events, NM_SELRECORD_T *sr) { - struct netmap_priv_d *priv = NULL; struct netmap_adapter *na; struct netmap_kring *kring; struct netmap_ring *ring; @@ -2365,8 +2348,6 @@ #define want_tx want[NR_TX] #define want_rx want[NR_RX] struct mbq q; /* packets from hw queues to host stack */ - void *pwait = dev; /* linux compatibility */ - int is_kevent = 0; enum txrx t; /* @@ -2376,24 +2357,8 @@ */ int retry_tx = 1, retry_rx = 1; - (void)pwait; mbq_init(&q); - /* - * XXX kevent has curthread->tp_fop == NULL, - * so devfs_get_cdevpriv() fails. We circumvent this by passing - * priv as the first argument, which is also useful to avoid - * the selrecord() which are not necessary in that case. - */ - if (devfs_get_cdevpriv((void **)&priv) != 0) { - is_kevent = 1; - if (netmap_verbose) - D("called from kevent"); - priv = (struct netmap_priv_d *)dev; - } - if (priv == NULL) - return POLLERR; - if (priv->np_nifp == NULL) { D("No if registered"); return POLLERR; @@ -2501,8 +2466,8 @@ kring->nm_notify(kring, 0); } } - if (want_tx && retry_tx && !is_kevent) { - OS_selrecord(td, check_all_tx ? + if (want_tx && retry_tx && sr) { + nm_os_selrecord(sr, check_all_tx ? &na->si[NR_TX] : &na->tx_rings[priv->np_qfirst[NR_TX]].si); retry_tx = 0; goto flush_tx; @@ -2572,14 +2537,14 @@ && (netmap_fwd || ring->flags & NR_FORWARD)) { /* XXX fix to use kring fields */ if (nm_ring_empty(ring)) - send_down = netmap_rxsync_from_host(na, td, dev); + send_down = netmap_rxsync_from_host(na, sr); if (!nm_ring_empty(ring)) revents |= want_rx; } } - if (retry_rx && !is_kevent) - OS_selrecord(td, check_all_rx ? + if (retry_rx && sr) + nm_os_selrecord(sr, check_all_rx ? &na->si[NR_RX] : &na->rx_rings[priv->np_qfirst[NR_RX]].si); if (send_down > 0 || retry_rx) { retry_rx = 0; @@ -2622,13 +2587,13 @@ struct netmap_adapter *na = kring->na; enum txrx t = kring->tx; - OS_selwakeup(&kring->si, PI_NET); + nm_os_selwakeup(&kring->si); /* optimization: avoid a wake up on the global * queue if nobody has registered for more * than one ring */ if (na->si_users[t] > 0) - OS_selwakeup(&na->si[t], PI_NET); + nm_os_selwakeup(&na->si[t]); return 0; } @@ -3199,7 +3164,7 @@ goto fail; #ifdef __FreeBSD__ - nm_vi_init_index(); + nm_os_vi_init_index(); #endif printf("netmap: loaded module\n"); Modified: soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_freebsd.c ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_freebsd.c Thu Aug 13 09:47:12 2015 (r289681) +++ soc2015/stefano/ptnetmap/stable/10/sys/dev/netmap/netmap_freebsd.c Thu Aug 13 10:36:44 2015 (r289682) @@ -73,7 +73,7 @@ /* ======================== FREEBSD-SPECIFIC ROUTINES ================== */ rawsum_t -nm_csum_raw(uint8_t *data, size_t len, rawsum_t cur_sum) +nm_os_csum_raw(uint8_t *data, size_t len, rawsum_t cur_sum) { /* TODO XXX please use the FreeBSD implementation for this. */ uint16_t *words = (uint16_t *)data; @@ -93,7 +93,7 @@ * return value is in network byte order. */ uint16_t -nm_csum_fold(rawsum_t cur_sum) +nm_os_csum_fold(rawsum_t cur_sum) { /* TODO XXX please use the FreeBSD implementation for this. */ while (cur_sum >> 16) @@ -102,17 +102,17 @@ return htobe16((~cur_sum) & 0xFFFF); } -uint16_t nm_csum_ipv4(struct nm_iphdr *iph) +uint16_t nm_os_csum_ipv4(struct nm_iphdr *iph) { #if 0 return in_cksum_hdr((void *)iph); #else - return nm_csum_fold(nm_csum_raw((uint8_t*)iph, sizeof(struct nm_iphdr), 0)); + return nm_os_csum_fold(nm_os_csum_raw((uint8_t*)iph, sizeof(struct nm_iphdr), 0)); #endif } void -nm_csum_tcpudp_ipv4(struct nm_iphdr *iph, void *data, +nm_os_csum_tcpudp_ipv4(struct nm_iphdr *iph, void *data, size_t datalen, uint16_t *check) { #ifdef INET @@ -124,7 +124,7 @@ /* Compute the checksum on TCP/UDP header + payload * (includes the pseudo-header). */ - *check = nm_csum_fold(nm_csum_raw(data, datalen, 0)); + *check = nm_os_csum_fold(nm_csum_raw(data, datalen, 0)); #else static int notsupported = 0; if (!notsupported) { @@ -135,12 +135,12 @@ } void -nm_csum_tcpudp_ipv6(struct nm_ipv6hdr *ip6h, void *data, +nm_os_csum_tcpudp_ipv6(struct nm_ipv6hdr *ip6h, void *data, size_t datalen, uint16_t *check) { #ifdef INET6 *check = in6_cksum_pseudo((void*)ip6h, datalen, ip6h->nexthdr, 0); - *check = nm_csum_fold(nm_csum_raw(data, datalen, 0)); + *check = nm_os_csum_fold(nm_csum_raw(data, datalen, 0)); #else static int notsupported = 0; if (!notsupported) { @@ -150,13 +150,21 @@ #endif } +/* on FreeBSD we send up one packet at a time */ +void * +nm_os_send_up(struct ifnet *ifp, struct mbuf *m, struct mbuf *prev) +{ + + NA(ifp)->if_input(ifp, m); + return NULL; +} /* * Intercept the rx routine in the standard device driver. * Second argument is non-zero to intercept, 0 to restore */ int -netmap_catch_rx(struct netmap_generic_adapter *gna, int intercept) +nm_os_catch_rx(struct netmap_generic_adapter *gna, int intercept) { struct netmap_adapter *na = &gna->up.up; struct ifnet *ifp = na->ifp; @@ -188,7 +196,7 @@ * On freebsd we just intercept if_transmit. */ void -netmap_catch_tx(struct netmap_generic_adapter *gna, int enable) +nm_os_catch_tx(struct netmap_generic_adapter *gna, int enable) { struct netmap_adapter *na = &gna->up.up; struct ifnet *ifp = netmap_generic_getifp(gna); @@ -219,7 +227,7 @@ * */ int -generic_xmit_frame(struct ifnet *ifp, struct mbuf *m, +nm_os_generic_xmit_frame(struct ifnet *ifp, struct mbuf *m, void *addr, u_int len, u_int ring_nr) { int ret; @@ -269,7 +277,7 @@ * way to extract the info from the ifp */ int -generic_find_num_desc(struct ifnet *ifp, unsigned int *tx, unsigned int *rx) +nm_os_generic_find_num_desc(struct ifnet *ifp, unsigned int *tx, unsigned int *rx) { D("called, in tx %d rx %d", *tx, *rx); return 0; @@ -277,7 +285,7 @@ void -generic_find_num_queues(struct ifnet *ifp, u_int *txq, u_int *rxq) +nm_os_generic_find_num_queues(struct ifnet *ifp, u_int *txq, u_int *rxq) { D("called, in txq %d rxq %d", *txq, *rxq); *txq = netmap_generic_rings; @@ -286,7 +294,7 @@ void -netmap_mitigation_init(struct nm_generic_mit *mit, int idx, struct netmap_adapter *na) +nm_os_mitigation_init(struct nm_generic_mit *mit, int idx, struct netmap_adapter *na) { ND("called"); mit->mit_pending = 0; @@ -296,21 +304,21 @@ void -netmap_mitigation_start(struct nm_generic_mit *mit) +nm_os_mitigation_start(struct nm_generic_mit *mit) { ND("called"); } void -netmap_mitigation_restart(struct nm_generic_mit *mit) +nm_os_mitigation_restart(struct nm_generic_mit *mit) { ND("called"); } int -netmap_mitigation_active(struct nm_generic_mit *mit) +nm_os_mitigation_active(struct nm_generic_mit *mit) { ND("called"); return 0; @@ -318,7 +326,7 @@ void -netmap_mitigation_cleanup(struct nm_generic_mit *mit) +nm_os_mitigation_cleanup(struct nm_generic_mit *mit) { ND("called"); } @@ -348,7 +356,7 @@ } nm_vi_indices; void -nm_vi_init_index(void) +nm_os_vi_init_index(void) { int i; for (i = 0; i < NM_VI_MAX; i++) @@ -404,7 +412,7 @@ * increment this refcount on if_attach(). */ int -nm_vi_persist(const char *name, struct ifnet **ret) +nm_os_vi_persist(const char *name, struct ifnet **ret) { struct ifnet *ifp; u_short macaddr_hi; @@ -444,9 +452,10 @@ *ret = ifp; return 0; } + /* unregister from the system and drop the final refcount */ void -nm_vi_detach(struct ifnet *ifp) +nm_os_vi_detach(struct ifnet *ifp) { nm_vi_free_index(((char *)IF_LLADDR(ifp))[5]); ether_ifdetach(ifp); @@ -470,8 +479,7 @@ /* * ptnetmap memdev private data structure */ -struct ptnetmap_memdev -{ +struct ptnetmap_memdev { device_t dev; struct resource *pci_io; struct resource *pci_mem; @@ -496,20 +504,23 @@ PTN_MEMDEV_NAME, ptn_memdev_methods, sizeof(struct ptnetmap_memdev), }; -devclass_t ptnetmap_devclass; +static devclass_t ptnetmap_devclass; DRIVER_MODULE(netmap, pci, ptn_memdev_driver, ptnetmap_devclass, 0, 0); MODULE_DEPEND(netmap, pci, 1, 1, 1); /* * I/O port read/write wrappers. + * Some are not used, so we keep them commented out until needed */ -#define ptn_ioread8(ptn_dev, reg) bus_read_1((ptn_dev)->pci_io, (reg)) #define ptn_ioread16(ptn_dev, reg) bus_read_2((ptn_dev)->pci_io, (reg)) #define ptn_ioread32(ptn_dev, reg) bus_read_4((ptn_dev)->pci_io, (reg)) +#if 0 +#define ptn_ioread8(ptn_dev, reg) bus_read_1((ptn_dev)->pci_io, (reg)) #define ptn_iowrite8(ptn_dev, reg, val) bus_write_1((ptn_dev)->pci_io, (reg), (val)) #define ptn_iowrite16(ptn_dev, reg, val) bus_write_2((ptn_dev)->pci_io, (reg), (val)) #define ptn_iowrite32(ptn_dev, reg, val) bus_write_4((ptn_dev)->pci_io, (reg), (val)) +#endif /* unused */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***