Date: Wed, 4 Apr 2018 21:31:12 +0000 (UTC) From: Vincenzo Maffione <vmaffione@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332047 - in head/sys: dev/netmap net Message-ID: <201804042131.w34LVCKp060008@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: vmaffione Date: Wed Apr 4 21:31:12 2018 New Revision: 332047 URL: https://svnweb.freebsd.org/changeset/base/332047 Log: netmap: align if_ptnet guest driver to the upstream code (commit 0e15788) The change upgrades the driver to use the split Communication Status Block (CSB) format. In this way the variables written by the guest and read by the host are allocated in a different cacheline than the variables written by the host and read by the guest; this is needed to avoid cache thrashing. Approved by: hrs (mentor) Modified: head/sys/dev/netmap/if_ptnet.c head/sys/dev/netmap/netmap_kern.h head/sys/dev/netmap/netmap_pt.c head/sys/net/netmap_virt.h Modified: head/sys/dev/netmap/if_ptnet.c ============================================================================== --- head/sys/dev/netmap/if_ptnet.c Wed Apr 4 21:19:33 2018 (r332046) +++ head/sys/dev/netmap/if_ptnet.c Wed Apr 4 21:31:12 2018 (r332047) @@ -88,10 +88,6 @@ #include <dev/netmap/netmap_mem2.h> #include <dev/virtio/network/virtio_net.h> -#ifndef PTNET_CSB_ALLOC -#error "No support for on-device CSB" -#endif - #ifndef INET #error "INET not defined, cannot support offloadings" #endif @@ -132,7 +128,8 @@ struct ptnet_queue { struct resource *irq; void *cookie; int kring_id; - struct ptnet_ring *ptring; + struct ptnet_csb_gh *ptgh; + struct ptnet_csb_hg *pthg; unsigned int kick; struct mtx lock; struct buf_ring *bufring; /* for TX queues */ @@ -169,7 +166,8 @@ struct ptnet_softc { unsigned int num_tx_rings; struct ptnet_queue *queues; struct ptnet_queue *rxqueues; - struct ptnet_csb *csb; + struct ptnet_csb_gh *csb_gh; + struct ptnet_csb_hg *csb_hg; unsigned int min_tx_space; @@ -323,33 +321,48 @@ ptnet_attach(device_t dev) ptfeatures = bus_read_4(sc->iomem, PTNET_IO_PTFEAT); /* acked */ sc->ptfeatures = ptfeatures; - /* Allocate CSB and carry out CSB allocation protocol (CSBBAH first, - * then CSBBAL). */ - sc->csb = malloc(sizeof(struct ptnet_csb), M_DEVBUF, - M_NOWAIT | M_ZERO); - if (sc->csb == NULL) { + num_tx_rings = bus_read_4(sc->iomem, PTNET_IO_NUM_TX_RINGS); + num_rx_rings = bus_read_4(sc->iomem, PTNET_IO_NUM_RX_RINGS); + 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) { + device_printf(dev, "CSB cannot handle that many rings (%u)\n", + sc->num_rings); + err = ENOMEM; + goto err_path; + } + + /* Allocate CSB and carry out CSB allocation protocol. */ + sc->csb_gh = contigmalloc(2*PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO, + (size_t)0, -1UL, PAGE_SIZE, 0); + if (sc->csb_gh == NULL) { device_printf(dev, "Failed to allocate CSB\n"); err = ENOMEM; goto err_path; } + sc->csb_hg = (struct ptnet_csb_hg *)(((char *)sc->csb_gh) + PAGE_SIZE); { /* * We use uint64_t rather than vm_paddr_t since we * need 64 bit addresses even on 32 bit platforms. */ - uint64_t paddr = vtophys(sc->csb); + uint64_t paddr = vtophys(sc->csb_gh); - bus_write_4(sc->iomem, PTNET_IO_CSBBAH, - (paddr >> 32) & 0xffffffff); - bus_write_4(sc->iomem, PTNET_IO_CSBBAL, paddr & 0xffffffff); + /* CSB allocation protocol: write to BAH first, then + * to BAL (for both GH and HG sections). */ + bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAH, + (paddr >> 32) & 0xffffffff); + bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAL, + paddr & 0xffffffff); + paddr = vtophys(sc->csb_hg); + bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAH, + (paddr >> 32) & 0xffffffff); + bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAL, + paddr & 0xffffffff); } - num_tx_rings = bus_read_4(sc->iomem, PTNET_IO_NUM_TX_RINGS); - num_rx_rings = bus_read_4(sc->iomem, PTNET_IO_NUM_RX_RINGS); - sc->num_rings = num_tx_rings + num_rx_rings; - sc->num_tx_rings = num_tx_rings; - /* Allocate and initialize per-queue data structures. */ sc->queues = malloc(sizeof(struct ptnet_queue) * sc->num_rings, M_DEVBUF, M_NOWAIT | M_ZERO); @@ -365,7 +378,8 @@ ptnet_attach(device_t dev) pq->sc = sc; pq->kring_id = i; pq->kick = PTNET_IO_KICK_BASE + 4 * i; - pq->ptring = sc->csb->rings + i; + pq->ptgh = sc->csb_gh + i; + pq->pthg = 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); @@ -467,7 +481,7 @@ ptnet_attach(device_t dev) na_arg.nm_txsync = ptnet_nm_txsync; na_arg.nm_rxsync = ptnet_nm_rxsync; - netmap_pt_guest_attach(&na_arg, sc->csb, nifp_offset, + netmap_pt_guest_attach(&na_arg, nifp_offset, bus_read_4(sc->iomem, PTNET_IO_HOSTMEMID)); /* Now a netmap adapter for this ifp has been allocated, and it @@ -526,11 +540,14 @@ ptnet_detach(device_t dev) ptnet_irqs_fini(sc); - if (sc->csb) { - bus_write_4(sc->iomem, PTNET_IO_CSBBAH, 0); - bus_write_4(sc->iomem, PTNET_IO_CSBBAL, 0); - free(sc->csb, M_DEVBUF); - sc->csb = NULL; + 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; } if (sc->queues) { @@ -777,7 +794,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->ptring->guest_need_kick = 0; + pq->ptgh->guest_need_kick = 0; PTNET_Q_UNLOCK(pq); /* Wait for rescheduling to finish. */ if (pq->taskq) { @@ -791,7 +808,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->ptring->guest_need_kick = 1; + pq->ptgh->guest_need_kick = 1; PTNET_Q_UNLOCK(pq); } } @@ -1109,7 +1126,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_ring *ptring = sc->queues[i].ptring; + struct ptnet_csb_gh *ptgh = sc->queues[i].ptgh; + struct ptnet_csb_hg *pthg = sc->queues[i].pthg; struct netmap_kring *kring; if (i < na->num_tx_rings) { @@ -1117,15 +1135,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 = ptring->head; - kring->rcur = kring->ring->cur = ptring->cur; - kring->nr_hwcur = ptring->hwcur; + kring->rhead = kring->ring->head = ptgh->head; + kring->rcur = kring->ring->cur = ptgh->cur; + kring->nr_hwcur = pthg->hwcur; kring->nr_hwtail = kring->rtail = - kring->ring->tail = ptring->hwtail; + kring->ring->tail = pthg->hwtail; ND("%d,%d: csb {hc %u h %u c %u ht %u}", t, i, - ptring->hwcur, ptring->head, ptring->cur, - ptring->hwtail); + pthg->hwcur, ptgh->head, ptgh->cur, + pthg->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, @@ -1169,7 +1187,7 @@ 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->ptring->guest_need_kick = 1; + pq->ptgh->guest_need_kick = 1; } } @@ -1178,8 +1196,8 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff /* Initialize notification enable fields in the CSB. */ for (i = 0; i < sc->num_rings; i++) { pq = sc->queues + i; - pq->ptring->host_need_kick = 1; - pq->ptring->guest_need_kick = + pq->pthg->host_need_kick = 1; + pq->ptgh->guest_need_kick = (!(ifp->if_capenable & IFCAP_POLLING) && i >= sc->num_tx_rings); } @@ -1257,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->ptring, kring, flags); + notify = netmap_pt_guest_txsync(pq->ptgh, pq->pthg, kring, flags); if (notify) { ptnet_kick(pq); } @@ -1272,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->ptring, kring, flags); + notify = netmap_pt_guest_rxsync(pq->ptgh, pq->pthg, kring, flags); if (notify) { ptnet_kick(pq); } @@ -1643,12 +1661,12 @@ 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_ring *ptring, struct netmap_kring *kring) +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(ptring, kring); + ptnetmap_guest_read_kring_csb(pthg, kring); /* nm_sync_finalize */ ring->tail = kring->rtail = kring->nr_hwtail; @@ -1659,7 +1677,8 @@ ptnet_ring_update(struct ptnet_queue *pq, struct netma unsigned int head, unsigned int sync_flags) { struct netmap_ring *ring = kring->ring; - struct ptnet_ring *ptring = pq->ptring; + struct ptnet_csb_gh *ptgh = pq->ptgh; + struct ptnet_csb_hg *pthg = pq->pthg; /* Some packets have been pushed to the netmap ring. We have * to tell the host to process the new packets, updating cur @@ -1669,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(ptring, kring->rcur, kring->rhead); + ptnetmap_guest_write_kring_csb(ptgh, kring->rcur, kring->rhead); /* Kick the host if needed. */ - if (NM_ACCESS_ONCE(ptring->host_need_kick)) { - ptring->sync_flags = sync_flags; + if (NM_ACCESS_ONCE(pthg->host_need_kick)) { + ptgh->sync_flags = sync_flags; ptnet_kick(pq); } } @@ -1693,7 +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_ring *ptring; + struct ptnet_csb_gh *ptgh; + struct ptnet_csb_hg *pthg; struct netmap_kring *kring; struct netmap_ring *ring; struct netmap_slot *slot; @@ -1722,7 +1742,8 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, uns return ENETDOWN; } - ptring = pq->ptring; + ptgh = pq->ptgh; + pthg = pq->pthg; kring = na->tx_rings + pq->kring_id; ring = kring->ring; lim = kring->nkr_num_slots - 1; @@ -1734,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(ptring, kring); + ptnet_sync_tail(pthg, 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. */ - ptring->guest_need_kick = 1; + ptgh->guest_need_kick = 1; /* Double-check. */ - ptnet_sync_tail(ptring, kring); + ptnet_sync_tail(pthg, kring); if (likely(PTNET_TX_NOSPACE(head, kring, minspace))) { break; @@ -1753,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. */ - ptring->guest_need_kick = 0; + ptgh->guest_need_kick = 0; } } @@ -1983,15 +2004,16 @@ 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_ring *ptring = pq->ptring; + struct ptnet_csb_gh *ptgh = pq->ptgh; + struct ptnet_csb_hg *pthg = pq->pthg; struct netmap_adapter *na = &sc->ptna->dr.up; struct netmap_kring *kring = na->rx_rings + pq->kring_id; struct netmap_ring *ring = kring->ring; unsigned int const lim = kring->nkr_num_slots - 1; - unsigned int head = ring->head; unsigned int batch_count = 0; if_t ifp = sc->ifp; unsigned int count = 0; + uint32_t head; PTNET_Q_LOCK(pq); @@ -2001,33 +2023,35 @@ ptnet_rx_eof(struct ptnet_queue *pq, unsigned int budg kring->nr_kflags &= ~NKR_PENDINTR; + head = ring->head; while (count < budget) { - unsigned int prev_head = head; + uint32_t prev_head = head; struct mbuf *mhead, *mtail; struct virtio_net_hdr *vh; struct netmap_slot *slot; unsigned int nmbuf_len; uint8_t *nmbuf; + int deliver = 1; /* the mbuf to the network stack. */ host_sync: if (head == ring->tail) { /* 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(ptring, kring); + ptnet_sync_tail(pthg, 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. */ - ptring->guest_need_kick = 1; + ptgh->guest_need_kick = 1; /* Double-check. */ - ptnet_sync_tail(ptring, kring); + ptnet_sync_tail(pthg, kring); if (likely(head == ring->tail)) { break; } - ptring->guest_need_kick = 0; + ptgh->guest_need_kick = 0; } } @@ -2046,6 +2070,7 @@ host_sync: RD(1, "Fragmented vnet-hdr: dropping"); head = ptnet_rx_discard(kring, head); pq->stats.iqdrops ++; + deliver = 0; goto skip; } ND(1, "%s: vnet hdr: flags %x csum_start %u " @@ -2152,30 +2177,39 @@ host_sync: m_freem(mhead); RD(1, "Csum offload error: dropping"); pq->stats.iqdrops ++; - goto skip; + deliver = 0; } } - pq->stats.packets ++; - pq->stats.bytes += mhead->m_pkthdr.len; - - PTNET_Q_UNLOCK(pq); - (*ifp->if_input)(ifp, mhead); - PTNET_Q_LOCK(pq); - - if (unlikely(!(ifp->if_drv_flags & IFF_DRV_RUNNING))) { - /* The interface has gone down while we didn't - * have the lock. Stop any processing and exit. */ - goto unlock; - } skip: count ++; - if (++batch_count == PTNET_RX_BATCH) { - /* Some packets have been pushed to the network stack. - * We need to update the CSB to tell the host about the new - * ring->cur and ring->head (RX buffer refill). */ + if (++batch_count >= PTNET_RX_BATCH) { + /* Some packets have been (or will be) pushed to the network + * stack. We need to update the CSB to tell the host about + * the new ring->cur and ring->head (RX buffer refill). */ ptnet_ring_update(pq, kring, head, NAF_FORCE_READ); batch_count = 0; + } + + if (likely(deliver)) { + pq->stats.packets ++; + pq->stats.bytes += mhead->m_pkthdr.len; + + PTNET_Q_UNLOCK(pq); + (*ifp->if_input)(ifp, mhead); + PTNET_Q_LOCK(pq); + /* The ring->head index (and related indices) are + * updated under pq lock by ptnet_ring_update(). + * Since we dropped the lock to call if_input(), we + * must reload ring->head and restart processing the + * ring from there. */ + head = ring->head; + + if (unlikely(!(ifp->if_drv_flags & IFF_DRV_RUNNING))) { + /* The interface has gone down while we didn't + * have the lock. Stop any processing and exit. */ + goto unlock; + } } } escape: Modified: head/sys/dev/netmap/netmap_kern.h ============================================================================== --- head/sys/dev/netmap/netmap_kern.h Wed Apr 4 21:19:33 2018 (r332046) +++ head/sys/dev/netmap/netmap_kern.h Wed Apr 4 21:31:12 2018 (r332047) @@ -2126,8 +2126,6 @@ struct netmap_pt_guest_adapter { /* The netmap adapter to be used by the driver. */ struct netmap_hw_adapter dr; - void *csb; - /* Reference counter to track users of backend netmap port: the * network stack and netmap clients. * Used to decide when we need (de)allocate krings/rings and @@ -2136,13 +2134,18 @@ struct netmap_pt_guest_adapter { }; -int netmap_pt_guest_attach(struct netmap_adapter *na, void *csb, - unsigned int nifp_offset, unsigned int memid); -struct ptnet_ring; -bool netmap_pt_guest_txsync(struct ptnet_ring *ptring, struct netmap_kring *kring, - int flags); -bool netmap_pt_guest_rxsync(struct ptnet_ring *ptring, struct netmap_kring *kring, - int flags); +int netmap_pt_guest_attach(struct netmap_adapter *na, + unsigned int nifp_offset, + unsigned int memid); +struct ptnet_csb_gh; +struct ptnet_csb_hg; +bool netmap_pt_guest_txsync(struct ptnet_csb_gh *ptgh, + struct ptnet_csb_hg *pthg, + struct netmap_kring *kring, + int flags); +bool netmap_pt_guest_rxsync(struct ptnet_csb_gh *ptgh, + struct ptnet_csb_hg *pthg, + struct netmap_kring *kring, int flags); int ptnet_nm_krings_create(struct netmap_adapter *na); void ptnet_nm_krings_delete(struct netmap_adapter *na); void ptnet_nm_dtor(struct netmap_adapter *na); Modified: head/sys/dev/netmap/netmap_pt.c ============================================================================== --- head/sys/dev/netmap/netmap_pt.c Wed Apr 4 21:19:33 2018 (r332046) +++ head/sys/dev/netmap/netmap_pt.c Wed Apr 4 21:31:12 2018 (r332047) @@ -172,8 +172,9 @@ struct ptnetmap_state { /* Kthreads. */ struct nm_kctx **kctxs; - /* Shared memory with the guest (TX/RX) */ - struct ptnet_ring __user *ptrings; + /* Shared memory with the guest (TX/RX) */ + struct ptnet_csb_gh __user *csb_gh; + struct ptnet_csb_hg __user *csb_hg; bool stopped; @@ -200,29 +201,22 @@ ptnetmap_kring_dump(const char *title, const struct ne /* Enable or disable guest --> host kicks. */ static inline void -ptring_kick_enable(struct ptnet_ring __user *ptring, uint32_t val) +pthg_kick_enable(struct ptnet_csb_hg __user *pthg, uint32_t val) { - CSB_WRITE(ptring, host_need_kick, val); + CSB_WRITE(pthg, host_need_kick, val); } /* Are guest interrupt enabled or disabled? */ static inline uint32_t -ptring_intr_enabled(struct ptnet_ring __user *ptring) +ptgh_intr_enabled(struct ptnet_csb_gh __user *ptgh) { uint32_t v; - CSB_READ(ptring, guest_need_kick, v); + CSB_READ(ptgh, guest_need_kick, v); return v; } -/* Enable or disable guest interrupts. */ -static inline void -ptring_intr_enable(struct ptnet_ring __user *ptring, uint32_t val) -{ - CSB_WRITE(ptring, guest_need_kick, val); -} - /* Handle TX events: from the guest or from the backend */ static void ptnetmap_tx_handler(void *data, int is_kthread) @@ -231,7 +225,8 @@ ptnetmap_tx_handler(void *data, int is_kthread) struct netmap_pt_host_adapter *pth_na = (struct netmap_pt_host_adapter *)kring->na->na_private; struct ptnetmap_state *ptns = pth_na->ptns; - struct ptnet_ring __user *ptring; + struct ptnet_csb_gh __user *ptgh; + struct ptnet_csb_hg __user *pthg; struct netmap_ring shadow_ring; /* shadow copy of the netmap_ring */ bool more_txspace = false; struct nm_kctx *kth; @@ -257,18 +252,17 @@ ptnetmap_tx_handler(void *data, int is_kthread) /* This is a guess, to be fixed in the rate callback. */ IFRATE(ptns->rate_ctx.new.gtxk++); - /* Get TX ptring pointer from the CSB. */ - ptring = ptns->ptrings + kring->ring_id; + /* Get TX ptgh/pthg pointer from the CSB. */ + ptgh = ptns->csb_gh + kring->ring_id; + pthg = ptns->csb_hg + kring->ring_id; kth = ptns->kctxs[kring->ring_id]; num_slots = kring->nkr_num_slots; - shadow_ring.head = kring->rhead; - shadow_ring.cur = kring->rcur; /* Disable guest --> host notifications. */ - ptring_kick_enable(ptring, 0); + pthg_kick_enable(pthg, 0); /* Copy the guest kring pointers from the CSB */ - ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); + ptnetmap_host_read_kring_csb(ptgh, &shadow_ring, num_slots); for (;;) { /* If guest moves ahead too fast, let's cut the move so @@ -299,7 +293,7 @@ ptnetmap_tx_handler(void *data, int is_kthread) if (unlikely(nm_txsync_prologue(kring, &shadow_ring) >= num_slots)) { /* Reinit ring and enable notifications. */ netmap_ring_reinit(kring); - ptring_kick_enable(ptring, 1); + pthg_kick_enable(pthg, 1); break; } @@ -310,7 +304,7 @@ ptnetmap_tx_handler(void *data, int is_kthread) IFRATE(pre_tail = kring->rtail); if (unlikely(kring->nm_sync(kring, shadow_ring.flags))) { /* Reenable notifications. */ - ptring_kick_enable(ptring, 1); + pthg_kick_enable(pthg, 1); D("ERROR txsync()"); break; } @@ -320,7 +314,7 @@ ptnetmap_tx_handler(void *data, int is_kthread) * Copy host hwcur and hwtail into the CSB for the guest sync(), and * do the nm_sync_finalize. */ - ptnetmap_host_write_kring_csb(ptring, kring->nr_hwcur, + ptnetmap_host_write_kring_csb(pthg, kring->nr_hwcur, kring->nr_hwtail); if (kring->rtail != kring->nr_hwtail) { /* Some more room available in the parent adapter. */ @@ -337,16 +331,15 @@ ptnetmap_tx_handler(void *data, int is_kthread) #ifndef BUSY_WAIT /* Interrupt the guest if needed. */ - if (more_txspace && ptring_intr_enabled(ptring) && is_kthread) { + if (more_txspace && ptgh_intr_enabled(ptgh) && is_kthread) { /* Disable guest kick to avoid sending unnecessary kicks */ - ptring_intr_enable(ptring, 0); nm_os_kctx_send_irq(kth); IFRATE(ptns->rate_ctx.new.htxk++); more_txspace = false; } #endif /* Read CSB to see if there is more work to do. */ - ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); + ptnetmap_host_read_kring_csb(ptgh, &shadow_ring, num_slots); #ifndef BUSY_WAIT if (shadow_ring.head == kring->rhead) { /* @@ -358,13 +351,13 @@ ptnetmap_tx_handler(void *data, int is_kthread) usleep_range(1,1); } /* Reenable notifications. */ - ptring_kick_enable(ptring, 1); + pthg_kick_enable(pthg, 1); /* Doublecheck. */ - ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); + ptnetmap_host_read_kring_csb(ptgh, &shadow_ring, num_slots); if (shadow_ring.head != kring->rhead) { /* We won the race condition, there are more packets to * transmit. Disable notifications and do another cycle */ - ptring_kick_enable(ptring, 0); + pthg_kick_enable(pthg, 0); continue; } break; @@ -385,8 +378,7 @@ ptnetmap_tx_handler(void *data, int is_kthread) nm_kr_put(kring); - if (more_txspace && ptring_intr_enabled(ptring) && is_kthread) { - ptring_intr_enable(ptring, 0); + if (more_txspace && ptgh_intr_enabled(ptgh) && is_kthread) { nm_os_kctx_send_irq(kth); IFRATE(ptns->rate_ctx.new.htxk++); } @@ -411,12 +403,12 @@ ptnetmap_tx_nothread_notify(void *data) return; } - /* We cannot access the CSB here (to check ptring->guest_need_kick), + /* We cannot access the CSB here (to check ptgh->guest_need_kick), * unless we switch address space to the one of the guest. For now * we unconditionally inject an interrupt. */ - nm_os_kctx_send_irq(ptns->kctxs[kring->ring_id]); - IFRATE(ptns->rate_ctx.new.htxk++); - ND(1, "%s interrupt", kring->name); + nm_os_kctx_send_irq(ptns->kctxs[kring->ring_id]); + IFRATE(ptns->rate_ctx.new.htxk++); + ND(1, "%s interrupt", kring->name); } /* @@ -440,7 +432,8 @@ ptnetmap_rx_handler(void *data, int is_kthread) struct netmap_pt_host_adapter *pth_na = (struct netmap_pt_host_adapter *)kring->na->na_private; struct ptnetmap_state *ptns = pth_na->ptns; - struct ptnet_ring __user *ptring; + struct ptnet_csb_gh __user *ptgh; + struct ptnet_csb_hg __user *pthg; struct netmap_ring shadow_ring; /* shadow copy of the netmap_ring */ struct nm_kctx *kth; uint32_t num_slots; @@ -467,18 +460,17 @@ ptnetmap_rx_handler(void *data, int is_kthread) /* This is a guess, to be fixed in the rate callback. */ IFRATE(ptns->rate_ctx.new.grxk++); - /* Get RX ptring pointer from the CSB. */ - ptring = ptns->ptrings + (pth_na->up.num_tx_rings + kring->ring_id); + /* Get RX ptgh and pthg pointers from the CSB. */ + ptgh = ptns->csb_gh + (pth_na->up.num_tx_rings + kring->ring_id); + pthg = ptns->csb_hg + (pth_na->up.num_tx_rings + kring->ring_id); kth = ptns->kctxs[pth_na->up.num_tx_rings + kring->ring_id]; num_slots = kring->nkr_num_slots; - shadow_ring.head = kring->rhead; - shadow_ring.cur = kring->rcur; /* Disable notifications. */ - ptring_kick_enable(ptring, 0); + pthg_kick_enable(pthg, 0); /* Copy the guest kring pointers from the CSB */ - ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); + ptnetmap_host_read_kring_csb(ptgh, &shadow_ring, num_slots); for (;;) { uint32_t hwtail; @@ -488,7 +480,7 @@ ptnetmap_rx_handler(void *data, int is_kthread) if (unlikely(nm_rxsync_prologue(kring, &shadow_ring) >= num_slots)) { /* Reinit ring and enable notifications. */ netmap_ring_reinit(kring); - ptring_kick_enable(ptring, 1); + pthg_kick_enable(pthg, 1); break; } @@ -499,7 +491,7 @@ ptnetmap_rx_handler(void *data, int is_kthread) IFRATE(pre_tail = kring->rtail); if (unlikely(kring->nm_sync(kring, shadow_ring.flags))) { /* Reenable notifications. */ - ptring_kick_enable(ptring, 1); + pthg_kick_enable(pthg, 1); D("ERROR rxsync()"); break; } @@ -508,7 +500,7 @@ ptnetmap_rx_handler(void *data, int is_kthread) * Copy host hwcur and hwtail into the CSB for the guest sync() */ hwtail = NM_ACCESS_ONCE(kring->nr_hwtail); - ptnetmap_host_write_kring_csb(ptring, kring->nr_hwcur, hwtail); + ptnetmap_host_write_kring_csb(pthg, kring->nr_hwcur, hwtail); if (kring->rtail != hwtail) { kring->rtail = hwtail; some_recvd = true; @@ -526,16 +518,15 @@ ptnetmap_rx_handler(void *data, int is_kthread) #ifndef BUSY_WAIT /* Interrupt the guest if needed. */ - if (some_recvd && ptring_intr_enabled(ptring)) { + if (some_recvd && ptgh_intr_enabled(ptgh)) { /* Disable guest kick to avoid sending unnecessary kicks */ - ptring_intr_enable(ptring, 0); nm_os_kctx_send_irq(kth); IFRATE(ptns->rate_ctx.new.hrxk++); some_recvd = false; } #endif /* Read CSB to see if there is more work to do. */ - ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); + ptnetmap_host_read_kring_csb(ptgh, &shadow_ring, num_slots); #ifndef BUSY_WAIT if (ptnetmap_norxslots(kring, shadow_ring.head)) { /* @@ -545,13 +536,13 @@ ptnetmap_rx_handler(void *data, int is_kthread) */ usleep_range(1,1); /* Reenable notifications. */ - ptring_kick_enable(ptring, 1); + pthg_kick_enable(pthg, 1); /* Doublecheck. */ - ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); + ptnetmap_host_read_kring_csb(ptgh, &shadow_ring, num_slots); if (!ptnetmap_norxslots(kring, shadow_ring.head)) { /* We won the race condition, more slots are available. Disable * notifications and do another cycle. */ - ptring_kick_enable(ptring, 0); + pthg_kick_enable(pthg, 0); continue; } break; @@ -576,8 +567,7 @@ ptnetmap_rx_handler(void *data, int is_kthread) nm_kr_put(kring); /* Interrupt the guest if needed. */ - if (some_recvd && ptring_intr_enabled(ptring)) { - ptring_intr_enable(ptring, 0); + if (some_recvd && ptgh_intr_enabled(ptgh)) { nm_os_kctx_send_irq(kth); IFRATE(ptns->rate_ctx.new.hrxk++); } @@ -590,8 +580,8 @@ ptnetmap_print_configuration(struct ptnetmap_cfg *cfg) int k; D("ptnetmap configuration:"); - D(" CSB ptrings @%p, num_rings=%u, cfgtype %08x", cfg->ptrings, - cfg->num_rings, cfg->cfgtype); + D(" CSB @%p@:%p, num_rings=%u, cfgtype %08x", cfg->csb_gh, + cfg->csb_hg, cfg->num_rings, cfg->cfgtype); for (k = 0; k < cfg->num_rings; k++) { switch (cfg->cfgtype) { case PTNETMAP_CFGTYPE_QEMU: { @@ -624,16 +614,18 @@ ptnetmap_print_configuration(struct ptnetmap_cfg *cfg) /* Copy actual state of the host ring into the CSB for the guest init */ static int -ptnetmap_kring_snapshot(struct netmap_kring *kring, struct ptnet_ring __user *ptring) +ptnetmap_kring_snapshot(struct netmap_kring *kring, + struct ptnet_csb_gh __user *ptgh, + struct ptnet_csb_hg __user *pthg) { - if (CSB_WRITE(ptring, head, kring->rhead)) + if (CSB_WRITE(ptgh, head, kring->rhead)) goto err; - if (CSB_WRITE(ptring, cur, kring->rcur)) + if (CSB_WRITE(ptgh, cur, kring->rcur)) goto err; - if (CSB_WRITE(ptring, hwcur, kring->nr_hwcur)) + if (CSB_WRITE(pthg, hwcur, kring->nr_hwcur)) goto err; - if (CSB_WRITE(ptring, hwtail, NM_ACCESS_ONCE(kring->nr_hwtail))) + if (CSB_WRITE(pthg, hwtail, NM_ACCESS_ONCE(kring->nr_hwtail))) goto err; DBG(ptnetmap_kring_dump("ptnetmap_kring_snapshot", kring);) @@ -665,7 +657,8 @@ ptnetmap_krings_snapshot(struct netmap_pt_host_adapter for (k = 0; k < num_rings; k++) { kring = ptnetmap_kring(pth_na, k); - err |= ptnetmap_kring_snapshot(kring, ptns->ptrings + k); + err |= ptnetmap_kring_snapshot(kring, ptns->csb_gh + k, + ptns->csb_hg + k); } return err; @@ -842,7 +835,8 @@ ptnetmap_create(struct netmap_pt_host_adapter *pth_na, ptns->pth_na = pth_na; /* Store the CSB address provided by the hypervisor. */ - ptns->ptrings = cfg->ptrings; + ptns->csb_gh = cfg->csb_gh; + ptns->csb_hg = cfg->csb_hg; DBG(ptnetmap_print_configuration(cfg)); @@ -1321,26 +1315,26 @@ put_out_noputparent: * block (no space in the ring). */ bool -netmap_pt_guest_txsync(struct ptnet_ring *ptring, struct netmap_kring *kring, - int flags) +netmap_pt_guest_txsync(struct ptnet_csb_gh *ptgh, struct ptnet_csb_hg *pthg, + struct netmap_kring *kring, int flags) { bool notify = false; /* Disable notifications */ - ptring->guest_need_kick = 0; + ptgh->guest_need_kick = 0; /* * First part: tell the host (updating the CSB) to process the new * packets. */ - kring->nr_hwcur = ptring->hwcur; - ptnetmap_guest_write_kring_csb(ptring, kring->rcur, kring->rhead); + kring->nr_hwcur = pthg->hwcur; + ptnetmap_guest_write_kring_csb(ptgh, kring->rcur, kring->rhead); /* Ask for a kick from a guest to the host if needed. */ if (((kring->rhead != kring->nr_hwcur || nm_kr_txempty(kring)) - && NM_ACCESS_ONCE(ptring->host_need_kick)) || + && NM_ACCESS_ONCE(pthg->host_need_kick)) || (flags & NAF_FORCE_RECLAIM)) { - ptring->sync_flags = flags; + ptgh->sync_flags = flags; notify = true; } @@ -1348,7 +1342,7 @@ netmap_pt_guest_txsync(struct ptnet_ring *ptring, stru * Second part: reclaim buffers for completed transmissions. */ if (nm_kr_txempty(kring) || (flags & NAF_FORCE_RECLAIM)) { - ptnetmap_guest_read_kring_csb(ptring, kring); + ptnetmap_guest_read_kring_csb(pthg, kring); } /* @@ -1358,17 +1352,17 @@ netmap_pt_guest_txsync(struct ptnet_ring *ptring, stru */ if (nm_kr_txempty(kring)) { /* Reenable notifications. */ - ptring->guest_need_kick = 1; + ptgh->guest_need_kick = 1; /* Double check */ - ptnetmap_guest_read_kring_csb(ptring, kring); + ptnetmap_guest_read_kring_csb(pthg, kring); /* If there is new free space, disable notifications */ if (unlikely(!nm_kr_txempty(kring))) { - ptring->guest_need_kick = 0; + ptgh->guest_need_kick = 0; } } ND(1, "%s CSB(head:%u cur:%u hwtail:%u) KRING(head:%u cur:%u tail:%u)", - kring->name, ptring->head, ptring->cur, ptring->hwtail, + kring->name, ptgh->head, ptgh->cur, pthg->hwtail, kring->rhead, kring->rcur, kring->nr_hwtail); return notify; @@ -1386,20 +1380,20 @@ netmap_pt_guest_txsync(struct ptnet_ring *ptring, stru * block (no more completed slots in the ring). */ bool -netmap_pt_guest_rxsync(struct ptnet_ring *ptring, struct netmap_kring *kring, - int flags) +netmap_pt_guest_rxsync(struct ptnet_csb_gh *ptgh, struct ptnet_csb_hg *pthg, + struct netmap_kring *kring, int flags) { bool notify = false; /* Disable notifications */ - ptring->guest_need_kick = 0; + ptgh->guest_need_kick = 0; /* * First part: import newly received packets, by updating the kring * hwtail to the hwtail known from the host (read from the CSB). * This also updates the kring hwcur. */ - ptnetmap_guest_read_kring_csb(ptring, kring); + ptnetmap_guest_read_kring_csb(pthg, kring); kring->nr_kflags &= ~NKR_PENDINTR; /* @@ -1407,11 +1401,11 @@ netmap_pt_guest_rxsync(struct ptnet_ring *ptring, stru * released, by updating cur and head in the CSB. */ if (kring->rhead != kring->nr_hwcur) { - ptnetmap_guest_write_kring_csb(ptring, kring->rcur, + ptnetmap_guest_write_kring_csb(ptgh, kring->rcur, kring->rhead); /* Ask for a kick from the guest to the host if needed. */ - if (NM_ACCESS_ONCE(ptring->host_need_kick)) { - ptring->sync_flags = flags; + if (NM_ACCESS_ONCE(pthg->host_need_kick)) { + ptgh->sync_flags = flags; notify = true; } } @@ -1423,17 +1417,17 @@ netmap_pt_guest_rxsync(struct ptnet_ring *ptring, stru */ if (nm_kr_rxempty(kring)) { /* Reenable notifications. */ - ptring->guest_need_kick = 1; + ptgh->guest_need_kick = 1; /* Double check */ - ptnetmap_guest_read_kring_csb(ptring, kring); + ptnetmap_guest_read_kring_csb(pthg, kring); /* If there are new slots, disable notifications. */ if (!nm_kr_rxempty(kring)) { - ptring->guest_need_kick = 0; + ptgh->guest_need_kick = 0; } } ND(1, "%s CSB(head:%u cur:%u hwtail:%u) KRING(head:%u cur:%u tail:%u)", - kring->name, ptring->head, ptring->cur, ptring->hwtail, + kring->name, ptgh->head, ptgh->cur, pthg->hwtail, kring->rhead, kring->rcur, kring->nr_hwtail); return notify; @@ -1492,13 +1486,13 @@ ptnet_nm_dtor(struct netmap_adapter *na) struct netmap_pt_guest_adapter *ptna = (struct netmap_pt_guest_adapter *)na; - netmap_mem_put(ptna->dr.up.nm_mem); // XXX is this needed? + netmap_mem_put(ptna->dr.up.nm_mem); memset(&ptna->dr, 0, sizeof(ptna->dr)); netmap_mem_pt_guest_ifp_del(na->nm_mem, na->ifp); } int -netmap_pt_guest_attach(struct netmap_adapter *arg, void *csb, +netmap_pt_guest_attach(struct netmap_adapter *arg, unsigned int nifp_offset, unsigned int memid) { struct netmap_pt_guest_adapter *ptna; @@ -1516,7 +1510,6 @@ netmap_pt_guest_attach(struct netmap_adapter *arg, voi /* get the netmap_pt_guest_adapter */ ptna = (struct netmap_pt_guest_adapter *) NA(ifp); - ptna->csb = csb; /* Initialize a separate pass-through netmap adapter that is going to * be used by the ptnet driver only, and so never exposed to netmap Modified: head/sys/net/netmap_virt.h ============================================================================== --- head/sys/net/netmap_virt.h Wed Apr 4 21:19:33 2018 (r332046) +++ head/sys/net/netmap_virt.h Wed Apr 4 21:31:12 2018 (r332047) @@ -85,7 +85,8 @@ struct ptnetmap_cfg { uint16_t cfgtype; /* how to interpret the cfg entries */ uint16_t entry_size; /* size of a config entry */ uint32_t num_rings; /* number of config entries */ - void *ptrings; /* ptrings inside CSB */ + void *csb_gh; /* CSB for guest --> host communication */ + void *csb_hg; /* CSB for host --> guest communication */ /* Configuration entries are allocated right after the struct. */ }; @@ -146,8 +147,8 @@ nmreq_pointer_put(struct nmreq *nmr, void *userptr) #define PTNET_IO_PTCTL 4 #define PTNET_IO_MAC_LO 8 #define PTNET_IO_MAC_HI 12 -#define PTNET_IO_CSBBAH 16 -#define PTNET_IO_CSBBAL 20 +#define PTNET_IO_CSBBAH 16 /* deprecated */ +#define PTNET_IO_CSBBAL 20 /* deprecated */ #define PTNET_IO_NIFP_OFS 24 #define PTNET_IO_NUM_TX_RINGS 28 #define PTNET_IO_NUM_RX_RINGS 32 @@ -155,7 +156,11 @@ nmreq_pointer_put(struct nmreq *nmr, void *userptr) #define PTNET_IO_NUM_RX_SLOTS 40 #define PTNET_IO_VNET_HDR_LEN 44 #define PTNET_IO_HOSTMEMID 48 -#define PTNET_IO_END 52 +#define PTNET_IO_CSB_GH_BAH 52 +#define PTNET_IO_CSB_GH_BAL 56 +#define PTNET_IO_CSB_HG_BAH 60 +#define PTNET_IO_CSB_HG_BAL 64 +#define PTNET_IO_END 68 #define PTNET_IO_KICK_BASE 128 #define PTNET_IO_MASK 0xff @@ -163,28 +168,21 @@ nmreq_pointer_put(struct nmreq *nmr, void *userptr) #define PTNETMAP_PTCTL_CREATE 1 #define PTNETMAP_PTCTL_DELETE 2 *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804042131.w34LVCKp060008>