From owner-svn-src-stable@FreeBSD.ORG Wed Nov 6 22:36:39 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 363006B8; Wed, 6 Nov 2013 22:36:39 +0000 (UTC) (envelope-from luigi@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 20B4A2488; Wed, 6 Nov 2013 22:36:39 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rA6MadbV075446; Wed, 6 Nov 2013 22:36:39 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rA6Maax1075431; Wed, 6 Nov 2013 22:36:36 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201311062236.rA6Maax1075431@svn.freebsd.org> From: Luigi Rizzo Date: Wed, 6 Nov 2013 22:36:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r257768 - in stable/9: sys/conf sys/dev/e1000 sys/dev/ixgbe sys/dev/netmap sys/dev/re sys/net tools/tools/netmap X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Nov 2013 22:36:39 -0000 Author: luigi Date: Wed Nov 6 22:36:36 2013 New Revision: 257768 URL: http://svnweb.freebsd.org/changeset/base/257768 Log: Merge from head: sync the netmap code with the one in HEAD Added: stable/9/sys/dev/netmap/netmap_mem2.h (contents, props changed) stable/9/tools/tools/netmap/vale-ctl.c (contents, props changed) Modified: stable/9/sys/conf/files stable/9/sys/dev/e1000/if_em.c stable/9/sys/dev/e1000/if_igb.c stable/9/sys/dev/e1000/if_lem.c stable/9/sys/dev/ixgbe/ixgbe.c stable/9/sys/dev/netmap/if_em_netmap.h stable/9/sys/dev/netmap/if_igb_netmap.h stable/9/sys/dev/netmap/if_lem_netmap.h stable/9/sys/dev/netmap/if_re_netmap.h stable/9/sys/dev/netmap/ixgbe_netmap.h stable/9/sys/dev/netmap/netmap.c stable/9/sys/dev/netmap/netmap_kern.h stable/9/sys/dev/netmap/netmap_mem2.c stable/9/sys/dev/re/if_re.c stable/9/sys/net/netmap.h stable/9/sys/net/netmap_user.h stable/9/tools/tools/netmap/Makefile stable/9/tools/tools/netmap/bridge.c stable/9/tools/tools/netmap/nm_util.c stable/9/tools/tools/netmap/pcap.c stable/9/tools/tools/netmap/pkt-gen.c Modified: stable/9/sys/conf/files ============================================================================== --- stable/9/sys/conf/files Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/conf/files Wed Nov 6 22:36:36 2013 (r257768) @@ -1601,6 +1601,7 @@ dev/my/if_my.c optional my dev/ncv/ncr53c500.c optional ncv dev/ncv/ncr53c500_pccard.c optional ncv pccard dev/netmap/netmap.c optional netmap +dev/netmap/netmap_mem2.c optional netmap dev/nge/if_nge.c optional nge dev/nxge/if_nxge.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" Modified: stable/9/sys/dev/e1000/if_em.c ============================================================================== --- stable/9/sys/dev/e1000/if_em.c Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/e1000/if_em.c Wed Nov 6 22:36:36 2013 (r257768) @@ -3835,8 +3835,7 @@ em_txeof(struct tx_ring *txr) EM_TX_LOCK_ASSERT(txr); #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, txr->me | - (NETMAP_LOCKED_ENTER | NETMAP_LOCKED_EXIT))) + if (netmap_tx_irq(ifp, txr->me)) return; #endif /* DEV_NETMAP */ @@ -4432,8 +4431,10 @@ em_rxeof(struct rx_ring *rxr, int count, EM_RX_LOCK(rxr); #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed)) + if (netmap_rx_irq(ifp, rxr->me, &processed)) { + EM_RX_UNLOCK(rxr); return (FALSE); + } #endif /* DEV_NETMAP */ for (i = rxr->next_to_check, processed = 0; count != 0;) { Modified: stable/9/sys/dev/e1000/if_igb.c ============================================================================== --- stable/9/sys/dev/e1000/if_igb.c Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/e1000/if_igb.c Wed Nov 6 22:36:36 2013 (r257768) @@ -3910,8 +3910,7 @@ igb_txeof(struct tx_ring *txr) IGB_TX_LOCK_ASSERT(txr); #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, txr->me | - (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT))) + if (netmap_tx_irq(ifp, txr->me )) return (FALSE); #endif /* DEV_NETMAP */ if (txr->tx_avail == adapter->num_tx_desc) { @@ -4766,8 +4765,10 @@ igb_rxeof(struct igb_queue *que, int cou BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed)) + if (netmap_rx_irq(ifp, rxr->me, &processed)) { + IGB_RX_UNLOCK(rxr); return (FALSE); + } #endif /* DEV_NETMAP */ /* Main clean loop */ Modified: stable/9/sys/dev/e1000/if_lem.c ============================================================================== --- stable/9/sys/dev/e1000/if_lem.c Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/e1000/if_lem.c Wed Nov 6 22:36:36 2013 (r257768) @@ -2985,7 +2985,7 @@ lem_txeof(struct adapter *adapter) EM_TX_LOCK_ASSERT(adapter); #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT))) + if (netmap_tx_irq(ifp, 0)) return; #endif /* DEV_NETMAP */ if (adapter->num_tx_desc_avail == adapter->num_tx_desc) @@ -3454,8 +3454,10 @@ lem_rxeof(struct adapter *adapter, int c BUS_DMASYNC_POSTREAD); #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, 0 | NETMAP_LOCKED_ENTER, &rx_sent)) + if (netmap_rx_irq(ifp, 0, &rx_sent)) { + EM_RX_UNLOCK(adapter); return (FALSE); + } #endif /* DEV_NETMAP */ if (!((current_desc->status) & E1000_RXD_STAT_DD)) { Modified: stable/9/sys/dev/ixgbe/ixgbe.c ============================================================================== --- stable/9/sys/dev/ixgbe/ixgbe.c Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/ixgbe/ixgbe.c Wed Nov 6 22:36:36 2013 (r257768) @@ -3620,16 +3620,11 @@ ixgbe_txeof(struct tx_ring *txr) * means the user thread should not be woken up); * - the driver ignores tx interrupts unless netmap_mitigate=0 * or the slot has the DD bit set. - * - * When the driver has separate locks, we need to - * release and re-acquire txlock to avoid deadlocks. - * XXX see if we can find a better way. */ if (!netmap_mitigate || (kring->nr_kflags < kring->nkr_num_slots && txd[kring->nr_kflags].wb.status & IXGBE_TXD_STAT_DD)) { - netmap_tx_irq(ifp, txr->me | - (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)); + netmap_tx_irq(ifp, txr->me); } return; } @@ -4421,8 +4416,10 @@ ixgbe_rxeof(struct ix_queue *que) #ifdef DEV_NETMAP /* Same as the txeof routine: wakeup clients on intr. */ - if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed)) + if (netmap_rx_irq(ifp, rxr->me, &processed)) { + IXGBE_RX_UNLOCK(rxr); return (FALSE); + } #endif /* DEV_NETMAP */ for (i = rxr->next_to_check; count != 0;) { Modified: stable/9/sys/dev/netmap/if_em_netmap.h ============================================================================== --- stable/9/sys/dev/netmap/if_em_netmap.h Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/netmap/if_em_netmap.h Wed Nov 6 22:36:36 2013 (r257768) @@ -43,35 +43,6 @@ static void em_netmap_block_tasks(struct static void em_netmap_unblock_tasks(struct adapter *); -static void -em_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid) -{ - struct adapter *adapter = ifp->if_softc; - - ASSERT(queueid < adapter->num_queues); - switch (what) { - case NETMAP_CORE_LOCK: - EM_CORE_LOCK(adapter); - break; - case NETMAP_CORE_UNLOCK: - EM_CORE_UNLOCK(adapter); - break; - case NETMAP_TX_LOCK: - EM_TX_LOCK(&adapter->tx_rings[queueid]); - break; - case NETMAP_TX_UNLOCK: - EM_TX_UNLOCK(&adapter->tx_rings[queueid]); - break; - case NETMAP_RX_LOCK: - EM_RX_LOCK(&adapter->rx_rings[queueid]); - break; - case NETMAP_RX_UNLOCK: - EM_RX_UNLOCK(&adapter->rx_rings[queueid]); - break; - } -} - - // XXX do we need to block/unblock the tasks ? static void em_netmap_block_tasks(struct adapter *adapter) @@ -137,7 +108,7 @@ em_netmap_reg(struct ifnet *ifp, int ono ifp->if_capenable |= IFCAP_NETMAP; na->if_transmit = ifp->if_transmit; - ifp->if_transmit = netmap_start; + ifp->if_transmit = netmap_transmit; em_init_locked(adapter); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) == 0) { @@ -160,7 +131,7 @@ fail: * Reconcile kernel and user view of the transmit ring. */ static int -em_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +em_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct tx_ring *txr = &adapter->tx_rings[ring_nr]; @@ -176,8 +147,6 @@ em_netmap_txsync(struct ifnet *ifp, u_in if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - EM_TX_LOCK(txr); bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_POSTREAD); @@ -202,8 +171,6 @@ em_netmap_txsync(struct ifnet *ifp, u_in u_int len = slot->len; if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) { - if (do_lock) - EM_TX_UNLOCK(txr); return netmap_ring_reinit(kring); } @@ -252,8 +219,6 @@ em_netmap_txsync(struct ifnet *ifp, u_in /* update avail to what the kernel knows */ ring->avail = kring->nr_hwavail; - if (do_lock) - EM_TX_UNLOCK(txr); return 0; } @@ -262,7 +227,7 @@ em_netmap_txsync(struct ifnet *ifp, u_in * Reconcile kernel and user view of the receive ring. */ static int -em_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +em_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct rx_ring *rxr = &adapter->rx_rings[ring_nr]; @@ -270,16 +235,13 @@ em_netmap_rxsync(struct ifnet *ifp, u_in struct netmap_kring *kring = &na->rx_rings[ring_nr]; struct netmap_ring *ring = kring->ring; u_int j, l, n, lim = kring->nkr_num_slots - 1; - int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR; + int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; u_int k = ring->cur, resvd = ring->reserved; k = ring->cur; if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - EM_RX_LOCK(rxr); - /* XXX check sync modes */ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); @@ -334,8 +296,6 @@ em_netmap_rxsync(struct ifnet *ifp, u_in void *addr = PNMB(slot, &paddr); if (addr == netmap_buffer_base) { /* bad buf */ - if (do_lock) - EM_RX_UNLOCK(rxr); return netmap_ring_reinit(kring); } @@ -364,8 +324,6 @@ em_netmap_rxsync(struct ifnet *ifp, u_in } /* tell userspace that there are new packets */ ring->avail = kring->nr_hwavail - resvd; - if (do_lock) - EM_RX_UNLOCK(rxr); return 0; } @@ -378,12 +336,11 @@ em_netmap_attach(struct adapter *adapter bzero(&na, sizeof(na)); na.ifp = adapter->ifp; - na.separate_locks = 1; + na.na_flags = NAF_BDG_MAYSLEEP; na.num_tx_desc = adapter->num_tx_desc; na.num_rx_desc = adapter->num_rx_desc; na.nm_txsync = em_netmap_txsync; na.nm_rxsync = em_netmap_rxsync; - na.nm_lock = em_netmap_lock_wrapper; na.nm_register = em_netmap_reg; netmap_attach(&na, adapter->num_queues); } Modified: stable/9/sys/dev/netmap/if_igb_netmap.h ============================================================================== --- stable/9/sys/dev/netmap/if_igb_netmap.h Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/netmap/if_igb_netmap.h Wed Nov 6 22:36:36 2013 (r257768) @@ -39,38 +39,6 @@ /* - * wrapper to export locks to the generic code - */ -static void -igb_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid) -{ - struct adapter *adapter = ifp->if_softc; - - ASSERT(queueid < adapter->num_queues); - switch (what) { - case NETMAP_CORE_LOCK: - IGB_CORE_LOCK(adapter); - break; - case NETMAP_CORE_UNLOCK: - IGB_CORE_UNLOCK(adapter); - break; - case NETMAP_TX_LOCK: - IGB_TX_LOCK(&adapter->tx_rings[queueid]); - break; - case NETMAP_TX_UNLOCK: - IGB_TX_UNLOCK(&adapter->tx_rings[queueid]); - break; - case NETMAP_RX_LOCK: - IGB_RX_LOCK(&adapter->rx_rings[queueid]); - break; - case NETMAP_RX_UNLOCK: - IGB_RX_UNLOCK(&adapter->rx_rings[queueid]); - break; - } -} - - -/* * register-unregister routine */ static int @@ -92,7 +60,7 @@ igb_netmap_reg(struct ifnet *ifp, int on ifp->if_capenable |= IFCAP_NETMAP; na->if_transmit = ifp->if_transmit; - ifp->if_transmit = netmap_start; + ifp->if_transmit = netmap_transmit; igb_init_locked(adapter); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) == 0) { @@ -114,7 +82,7 @@ fail: * Reconcile kernel and user view of the transmit ring. */ static int -igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct tx_ring *txr = &adapter->tx_rings[ring_nr]; @@ -130,8 +98,6 @@ igb_netmap_txsync(struct ifnet *ifp, u_i if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - IGB_TX_LOCK(txr); bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_POSTREAD); @@ -153,7 +119,14 @@ igb_netmap_txsync(struct ifnet *ifp, u_i /* curr is the current slot in the nic ring */ union e1000_adv_tx_desc *curr = (union e1000_adv_tx_desc *)&txr->tx_base[l]; - struct igb_tx_buffer *txbuf = &txr->tx_buffers[l]; +#ifndef IGB_MEDIA_RESET +/* at the same time as IGB_MEDIA_RESET was defined, the + * tx buffer descriptor was renamed, so use this to revert + * back to the old name. + */ +#define igb_tx_buf igb_tx_buffer +#endif + struct igb_tx_buf *txbuf = &txr->tx_buffers[l]; int flags = ((slot->flags & NS_REPORT) || j == 0 || j == report_frequency) ? E1000_ADVTXD_DCMD_RS : 0; @@ -162,8 +135,6 @@ igb_netmap_txsync(struct ifnet *ifp, u_i u_int len = slot->len; if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) { - if (do_lock) - IGB_TX_UNLOCK(txr); return netmap_ring_reinit(kring); } @@ -223,8 +194,6 @@ igb_netmap_txsync(struct ifnet *ifp, u_i /* update avail to what the kernel knows */ ring->avail = kring->nr_hwavail; - if (do_lock) - IGB_TX_UNLOCK(txr); return 0; } @@ -233,7 +202,7 @@ igb_netmap_txsync(struct ifnet *ifp, u_i * Reconcile kernel and user view of the receive ring. */ static int -igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct rx_ring *rxr = &adapter->rx_rings[ring_nr]; @@ -241,16 +210,13 @@ igb_netmap_rxsync(struct ifnet *ifp, u_i struct netmap_kring *kring = &na->rx_rings[ring_nr]; struct netmap_ring *ring = kring->ring; u_int j, l, n, lim = kring->nkr_num_slots - 1; - int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR; + int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; u_int k = ring->cur, resvd = ring->reserved; k = ring->cur; if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - IGB_RX_LOCK(rxr); - /* XXX check sync modes */ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); @@ -303,8 +269,6 @@ igb_netmap_rxsync(struct ifnet *ifp, u_i void *addr = PNMB(slot, &paddr); if (addr == netmap_buffer_base) { /* bad buf */ - if (do_lock) - IGB_RX_UNLOCK(rxr); return netmap_ring_reinit(kring); } @@ -332,8 +296,6 @@ igb_netmap_rxsync(struct ifnet *ifp, u_i } /* tell userspace that there are new packets */ ring->avail = kring->nr_hwavail - resvd; - if (do_lock) - IGB_RX_UNLOCK(rxr); return 0; } @@ -346,12 +308,11 @@ igb_netmap_attach(struct adapter *adapte bzero(&na, sizeof(na)); na.ifp = adapter->ifp; - na.separate_locks = 1; + na.na_flags = NAF_BDG_MAYSLEEP; na.num_tx_desc = adapter->num_tx_desc; na.num_rx_desc = adapter->num_rx_desc; na.nm_txsync = igb_netmap_txsync; na.nm_rxsync = igb_netmap_rxsync; - na.nm_lock = igb_netmap_lock_wrapper; na.nm_register = igb_netmap_reg; netmap_attach(&na, adapter->num_queues); } Modified: stable/9/sys/dev/netmap/if_lem_netmap.h ============================================================================== --- stable/9/sys/dev/netmap/if_lem_netmap.h Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/netmap/if_lem_netmap.h Wed Nov 6 22:36:36 2013 (r257768) @@ -39,35 +39,6 @@ #include -static void -lem_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int ringid) -{ - struct adapter *adapter = ifp->if_softc; - - /* only one ring here so ignore the ringid */ - switch (what) { - case NETMAP_CORE_LOCK: - EM_CORE_LOCK(adapter); - break; - case NETMAP_CORE_UNLOCK: - EM_CORE_UNLOCK(adapter); - break; - case NETMAP_TX_LOCK: - EM_TX_LOCK(adapter); - break; - case NETMAP_TX_UNLOCK: - EM_TX_UNLOCK(adapter); - break; - case NETMAP_RX_LOCK: - EM_RX_LOCK(adapter); - break; - case NETMAP_RX_UNLOCK: - EM_RX_UNLOCK(adapter); - break; - } -} - - /* * Register/unregister */ @@ -81,6 +52,8 @@ lem_netmap_reg(struct ifnet *ifp, int on if (na == NULL) return EINVAL; + EM_CORE_LOCK(adapter); + lem_disable_intr(adapter); /* Tell the stack that the interface is no longer active */ @@ -95,7 +68,7 @@ lem_netmap_reg(struct ifnet *ifp, int on ifp->if_capenable |= IFCAP_NETMAP; na->if_transmit = ifp->if_transmit; - ifp->if_transmit = netmap_start; + ifp->if_transmit = netmap_transmit; lem_init_locked(adapter); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) == 0) { @@ -114,6 +87,8 @@ fail: taskqueue_unblock(adapter->tq); // XXX do we need this ? #endif /* !EM_LEGCY_IRQ */ + EM_CORE_UNLOCK(adapter); + return (error); } @@ -122,7 +97,7 @@ fail: * Reconcile kernel and user view of the transmit ring. */ static int -lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct netmap_adapter *na = NA(ifp); @@ -133,13 +108,16 @@ lem_netmap_txsync(struct ifnet *ifp, u_i /* generate an interrupt approximately every half ring */ int report_frequency = kring->nkr_num_slots >> 1; + ND("%s: hwofs %d, hwcur %d hwavail %d lease %d cur %d avail %d", + ifp->if_xname, + kring->nkr_hwofs, kring->nr_hwcur, kring->nr_hwavail, + kring->nkr_hwlease, + ring->cur, ring->avail); /* take a copy of ring->cur now, and never read it again */ k = ring->cur; if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - EM_TX_LOCK(adapter); bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, BUS_DMASYNC_POSTREAD); /* @@ -147,6 +125,8 @@ lem_netmap_txsync(struct ifnet *ifp, u_i * netmap ring, l is the corresponding index in the NIC ring. */ j = kring->nr_hwcur; + if (netmap_verbose > 255) + RD(5, "device %s send %d->%d", ifp->if_xname, j, k); if (j != k) { /* we have new packets to send */ l = netmap_idx_k2n(kring, j); for (n = 0; j != k; n++) { @@ -163,13 +143,12 @@ lem_netmap_txsync(struct ifnet *ifp, u_i u_int len = slot->len; if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) { - if (do_lock) - EM_TX_UNLOCK(adapter); return netmap_ring_reinit(kring); } + ND("slot %d NIC %d %s", j, l, nm_dump_buf(addr, len, 128, NULL)); slot->flags &= ~NS_REPORT; - if (slot->flags & NS_BUF_CHANGED) { + if (1 || slot->flags & NS_BUF_CHANGED) { /* buffer has changed, reload map */ netmap_reload_map(adapter->txtag, txbuf->map, addr); curr->buffer_addr = htole64(paddr); @@ -180,11 +159,13 @@ lem_netmap_txsync(struct ifnet *ifp, u_i htole32( adapter->txd_cmd | len | (E1000_TXD_CMD_EOP | flags) ); + ND("len %d kring %d nic %d", len, j, l); bus_dmamap_sync(adapter->txtag, txbuf->map, BUS_DMASYNC_PREWRITE); j = (j == lim) ? 0 : j + 1; l = (l == lim) ? 0 : l + 1; } + ND("sent %d packets from %d, TDT now %d", n, kring->nr_hwcur, l); kring->nr_hwcur = k; /* the saved ring->cur */ kring->nr_hwavail -= n; @@ -199,6 +180,7 @@ lem_netmap_txsync(struct ifnet *ifp, u_i /* record completed transmissions using TDH */ l = E1000_READ_REG(&adapter->hw, E1000_TDH(0)); + ND("tdh is now %d", l); if (l >= kring->nkr_num_slots) { /* XXX can it happen ? */ D("bad TDH %d", l); l -= kring->nkr_num_slots; @@ -208,6 +190,9 @@ lem_netmap_txsync(struct ifnet *ifp, u_i /* some tx completed, increment hwavail. */ if (delta < 0) delta += kring->nkr_num_slots; + if (netmap_verbose > 255) + RD(5, "%s tx recover %d bufs", + ifp->if_xname, delta); adapter->next_tx_to_clean = l; kring->nr_hwavail += delta; } @@ -215,8 +200,6 @@ lem_netmap_txsync(struct ifnet *ifp, u_i /* update avail to what the kernel knows */ ring->avail = kring->nr_hwavail; - if (do_lock) - EM_TX_UNLOCK(adapter); return 0; } @@ -225,21 +208,19 @@ lem_netmap_txsync(struct ifnet *ifp, u_i * Reconcile kernel and user view of the receive ring. */ static int -lem_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +lem_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct netmap_adapter *na = NA(ifp); struct netmap_kring *kring = &na->rx_rings[ring_nr]; struct netmap_ring *ring = kring->ring; int j, l, n, lim = kring->nkr_num_slots - 1; - int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR; + int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; u_int k = ring->cur, resvd = ring->reserved; if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - EM_RX_LOCK(adapter); /* XXX check sync modes */ bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, @@ -251,6 +232,10 @@ lem_netmap_rxsync(struct ifnet *ifp, u_i */ l = adapter->next_rx_desc_to_check; j = netmap_idx_n2k(kring, l); + ND("%s: next NIC %d kring %d (ofs %d), hwcur %d hwavail %d cur %d avail %d", + ifp->if_xname, + l, j, kring->nkr_hwofs, kring->nr_hwcur, kring->nr_hwavail, + ring->cur, ring->avail); if (netmap_no_pendintr || force_update) { uint16_t slot_flags = kring->nkr_slot_flags; @@ -266,6 +251,8 @@ lem_netmap_rxsync(struct ifnet *ifp, u_i D("bogus pkt size at %d", j); len = 0; } + ND("\n%s", nm_dump_buf(NMB(&ring->slot[j]), + len, 128, NULL)); ring->slot[j].len = len; ring->slot[j].flags = slot_flags; bus_dmamap_sync(adapter->rxtag, @@ -300,8 +287,6 @@ lem_netmap_rxsync(struct ifnet *ifp, u_i void *addr = PNMB(slot, &paddr); if (addr == netmap_buffer_base) { /* bad buf */ - if (do_lock) - EM_RX_UNLOCK(adapter); return netmap_ring_reinit(kring); } @@ -332,8 +317,6 @@ lem_netmap_rxsync(struct ifnet *ifp, u_i } /* tell userspace that there are new packets */ ring->avail = kring->nr_hwavail - resvd; - if (do_lock) - EM_RX_UNLOCK(adapter); return 0; } @@ -346,12 +329,11 @@ lem_netmap_attach(struct adapter *adapte bzero(&na, sizeof(na)); na.ifp = adapter->ifp; - na.separate_locks = 1; + na.na_flags = NAF_BDG_MAYSLEEP; na.num_tx_desc = adapter->num_tx_desc; na.num_rx_desc = adapter->num_rx_desc; na.nm_txsync = lem_netmap_txsync; na.nm_rxsync = lem_netmap_rxsync; - na.nm_lock = lem_netmap_lock_wrapper; na.nm_register = lem_netmap_reg; netmap_attach(&na, 1); } Modified: stable/9/sys/dev/netmap/if_re_netmap.h ============================================================================== --- stable/9/sys/dev/netmap/if_re_netmap.h Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/netmap/if_re_netmap.h Wed Nov 6 22:36:36 2013 (r257768) @@ -39,33 +39,6 @@ /* - * wrapper to export locks to the generic code - * We should not use the tx/rx locks - */ -static void -re_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid) -{ - struct rl_softc *adapter = ifp->if_softc; - - switch (what) { - case NETMAP_CORE_LOCK: - RL_LOCK(adapter); - break; - case NETMAP_CORE_UNLOCK: - RL_UNLOCK(adapter); - break; - - case NETMAP_TX_LOCK: - case NETMAP_RX_LOCK: - case NETMAP_TX_UNLOCK: - case NETMAP_RX_UNLOCK: - D("invalid lock call %d, no tx/rx locks here", what); - break; - } -} - - -/* * support for netmap register/unregisted. We are already under core lock. * only called on the first register or the last unregister. */ @@ -88,7 +61,7 @@ re_netmap_reg(struct ifnet *ifp, int ono /* save if_transmit to restore it later */ na->if_transmit = ifp->if_transmit; - ifp->if_transmit = netmap_start; + ifp->if_transmit = netmap_transmit; re_init_locked(adapter); @@ -111,7 +84,7 @@ fail: * Reconcile kernel and user view of the transmit ring. */ static int -re_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +re_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct rl_softc *sc = ifp->if_softc; struct rl_txdesc *txd = sc->rl_ldata.rl_tx_desc; @@ -124,9 +97,6 @@ re_netmap_txsync(struct ifnet *ifp, u_in if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - RL_LOCK(sc); - /* Sync the TX descriptor list */ bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag, sc->rl_ldata.rl_tx_list_map, @@ -164,8 +134,6 @@ re_netmap_txsync(struct ifnet *ifp, u_in int len = slot->len; if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) { - if (do_lock) - RL_UNLOCK(sc); // XXX what about prodidx ? return netmap_ring_reinit(kring); } @@ -200,8 +168,6 @@ re_netmap_txsync(struct ifnet *ifp, u_in /* start ? */ CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START); } - if (do_lock) - RL_UNLOCK(sc); return 0; } @@ -210,7 +176,7 @@ re_netmap_txsync(struct ifnet *ifp, u_in * Reconcile kernel and user view of the receive ring. */ static int -re_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +re_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct rl_softc *sc = ifp->if_softc; struct rl_rxdesc *rxd = sc->rl_ldata.rl_rx_desc; @@ -218,15 +184,13 @@ re_netmap_rxsync(struct ifnet *ifp, u_in struct netmap_kring *kring = &na->rx_rings[ring_nr]; struct netmap_ring *ring = kring->ring; int j, l, n, lim = kring->nkr_num_slots - 1; - int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR; + int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; u_int k = ring->cur, resvd = ring->reserved; k = ring->cur; if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - RL_LOCK(sc); /* XXX check sync modes */ bus_dmamap_sync(sc->rl_ldata.rl_rx_list_tag, sc->rl_ldata.rl_rx_list_map, @@ -291,8 +255,6 @@ re_netmap_rxsync(struct ifnet *ifp, u_in void *addr = PNMB(slot, &paddr); if (addr == netmap_buffer_base) { /* bad buf */ - if (do_lock) - RL_UNLOCK(sc); return netmap_ring_reinit(kring); } @@ -323,8 +285,6 @@ re_netmap_rxsync(struct ifnet *ifp, u_in } /* tell userspace that there are new packets */ ring->avail = kring->nr_hwavail - resvd; - if (do_lock) - RL_UNLOCK(sc); return 0; } @@ -411,12 +371,11 @@ re_netmap_attach(struct rl_softc *sc) bzero(&na, sizeof(na)); na.ifp = sc->rl_ifp; - na.separate_locks = 0; + na.na_flags = NAF_BDG_MAYSLEEP; na.num_tx_desc = sc->rl_ldata.rl_tx_desc_cnt; na.num_rx_desc = sc->rl_ldata.rl_rx_desc_cnt; na.nm_txsync = re_netmap_txsync; na.nm_rxsync = re_netmap_rxsync; - na.nm_lock = re_netmap_lock_wrapper; na.nm_register = re_netmap_reg; netmap_attach(&na, 1); } Modified: stable/9/sys/dev/netmap/ixgbe_netmap.h ============================================================================== --- stable/9/sys/dev/netmap/ixgbe_netmap.h Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/netmap/ixgbe_netmap.h Wed Nov 6 22:36:36 2013 (r257768) @@ -72,37 +72,6 @@ SYSCTL_INT(_dev_netmap, OID_AUTO, ix_rx_ SYSCTL_INT(_dev_netmap, OID_AUTO, ix_rx_miss_bufs, CTLFLAG_RW, &ix_rx_miss_bufs, 0, "potentially missed rx intr bufs"); -/* - * wrapper to export locks to the generic netmap code. - */ -static void -ixgbe_netmap_lock_wrapper(struct ifnet *_a, int what, u_int queueid) -{ - struct adapter *adapter = _a->if_softc; - - ASSERT(queueid < adapter->num_queues); - switch (what) { - case NETMAP_CORE_LOCK: - IXGBE_CORE_LOCK(adapter); - break; - case NETMAP_CORE_UNLOCK: - IXGBE_CORE_UNLOCK(adapter); - break; - case NETMAP_TX_LOCK: - IXGBE_TX_LOCK(&adapter->tx_rings[queueid]); - break; - case NETMAP_TX_UNLOCK: - IXGBE_TX_UNLOCK(&adapter->tx_rings[queueid]); - break; - case NETMAP_RX_LOCK: - IXGBE_RX_LOCK(&adapter->rx_rings[queueid]); - break; - case NETMAP_RX_UNLOCK: - IXGBE_RX_UNLOCK(&adapter->rx_rings[queueid]); - break; - } -} - static void set_crcstrip(struct ixgbe_hw *hw, int onoff) @@ -155,6 +124,7 @@ ixgbe_netmap_reg(struct ifnet *ifp, int if (na == NULL) return EINVAL; /* no netmap support here */ + IXGBE_CORE_LOCK(adapter); ixgbe_disable_intr(adapter); /* Tell the stack that the interface is no longer active */ @@ -166,7 +136,7 @@ ixgbe_netmap_reg(struct ifnet *ifp, int /* save if_transmit and replace with our routine */ na->if_transmit = ifp->if_transmit; - ifp->if_transmit = netmap_start; + ifp->if_transmit = netmap_transmit; /* * reinitialize the adapter, now with netmap flag set, @@ -186,6 +156,7 @@ fail: ixgbe_init_locked(adapter); /* also enables intr */ } set_crcstrip(&adapter->hw, onoff); + IXGBE_CORE_UNLOCK(adapter); return (error); } @@ -213,12 +184,11 @@ fail: * * ring->avail is never used, only checked for bogus values. * - * do_lock is set iff the function is called from the ioctl handler. - * In this case, grab a lock around the body, and also reclaim transmitted + * I flags & FORCE_RECLAIM, reclaim transmitted * buffers irrespective of interrupt mitigation. */ static int -ixgbe_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +ixgbe_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct tx_ring *txr = &adapter->tx_rings[ring_nr]; @@ -237,8 +207,6 @@ ixgbe_netmap_txsync(struct ifnet *ifp, u if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - IXGBE_TX_LOCK(txr); bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_POSTREAD); @@ -303,8 +271,6 @@ ixgbe_netmap_txsync(struct ifnet *ifp, u */ if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) { ring_reset: - if (do_lock) - IXGBE_TX_UNLOCK(txr); return netmap_ring_reinit(kring); } @@ -347,7 +313,7 @@ ring_reset: * In all cases kring->nr_kflags indicates which slot will be * checked upon a tx interrupt (nkr_num_slots means none). */ - if (do_lock) { + if (flags & NAF_FORCE_RECLAIM) { j = 1; /* forced reclaim, ignore interrupts */ kring->nr_kflags = kring->nkr_num_slots; } else if (kring->nr_hwavail > 0) { @@ -422,8 +388,6 @@ ring_reset: /* update avail to what the kernel knows */ ring->avail = kring->nr_hwavail; - if (do_lock) - IXGBE_TX_UNLOCK(txr); return 0; } @@ -442,10 +406,11 @@ ring_reset: * from nr_hwavail, make the descriptors available for the next reads, * and set kring->nr_hwcur = ring->cur and ring->avail = kring->nr_hwavail. * - * do_lock has a special meaning: please refer to txsync. + * If (flags & NAF_FORCE_READ) also check for incoming packets irrespective + * of whether or not we received an interrupt. */ static int -ixgbe_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock) +ixgbe_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int flags) { struct adapter *adapter = ifp->if_softc; struct rx_ring *rxr = &adapter->rx_rings[ring_nr]; @@ -453,14 +418,12 @@ ixgbe_netmap_rxsync(struct ifnet *ifp, u struct netmap_kring *kring = &na->rx_rings[ring_nr]; struct netmap_ring *ring = kring->ring; u_int j, l, n, lim = kring->nkr_num_slots - 1; - int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR; + int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; u_int k = ring->cur, resvd = ring->reserved; if (k > lim) return netmap_ring_reinit(kring); - if (do_lock) - IXGBE_RX_LOCK(rxr); /* XXX check sync modes */ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); @@ -571,13 +534,9 @@ ixgbe_netmap_rxsync(struct ifnet *ifp, u /* tell userspace that there are new packets */ ring->avail = kring->nr_hwavail - resvd; - if (do_lock) - IXGBE_RX_UNLOCK(rxr); return 0; ring_reset: - if (do_lock) - IXGBE_RX_UNLOCK(rxr); return netmap_ring_reinit(kring); } @@ -597,12 +556,11 @@ ixgbe_netmap_attach(struct adapter *adap bzero(&na, sizeof(na)); na.ifp = adapter->ifp; - na.separate_locks = 1; /* this card has separate rx/tx locks */ + na.na_flags = NAF_BDG_MAYSLEEP; na.num_tx_desc = adapter->num_tx_desc; na.num_rx_desc = adapter->num_rx_desc; na.nm_txsync = ixgbe_netmap_txsync; na.nm_rxsync = ixgbe_netmap_rxsync; - na.nm_lock = ixgbe_netmap_lock_wrapper; na.nm_register = ixgbe_netmap_reg; netmap_attach(&na, adapter->num_queues); } Modified: stable/9/sys/dev/netmap/netmap.c ============================================================================== --- stable/9/sys/dev/netmap/netmap.c Wed Nov 6 22:35:52 2013 (r257767) +++ stable/9/sys/dev/netmap/netmap.c Wed Nov 6 22:36:36 2013 (r257768) @@ -23,7 +23,6 @@ * SUCH DAMAGE. */ -#define NM_BRIDGE /* * This module supports memory mapped access to network devices, @@ -52,18 +51,84 @@ * packets on the output interface. * 6. select() or poll() can be used to wait for events on individual * transmit or receive queues (or all queues for a given interface). - */ + * -#ifdef linux -#include "bsd_glue.h" -static netdev_tx_t linux_netmap_start(struct sk_buff *skb, struct net_device *dev); -#endif /* linux */ + SYNCHRONIZATION (USER) -#ifdef __APPLE__ -#include "osx_glue.h" -#endif /* __APPLE__ */ +The netmap rings and data structures may be shared among multiple +user threads or even independent processes. +Any synchronization among those threads/processes is delegated +to the threads themselves. Only one thread at a time can be in +a system call on the same netmap ring. The OS does not enforce +this and only guarantees against system crashes in case of +invalid usage. + + LOCKING (INTERNAL) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***