Date: Tue, 18 Oct 2016 16:18:25 +0000 (UTC) From: Luigi Rizzo <luigi@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r307574 - in head/sys: dev/netmap net Message-ID: <201610181618.u9IGIPbG064539@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: luigi Date: Tue Oct 18 16:18:25 2016 New Revision: 307574 URL: https://svnweb.freebsd.org/changeset/base/307574 Log: remove stale and unused code from various files fix build on 32 bit platforms simplify logic in netmap_virt.h The commands (in net/netmap.h) to configure communication with the hypervisor may be revised soon. At the moment they are unused so this will not be a change of API. Modified: head/sys/dev/netmap/if_lem_netmap.h head/sys/dev/netmap/if_ptnet.c head/sys/dev/netmap/netmap.c head/sys/dev/netmap/netmap_freebsd.c head/sys/dev/netmap/netmap_generic.c head/sys/dev/netmap/netmap_kern.h head/sys/dev/netmap/netmap_pt.c head/sys/net/netmap.h head/sys/net/netmap_virt.h Modified: head/sys/dev/netmap/if_lem_netmap.h ============================================================================== --- head/sys/dev/netmap/if_lem_netmap.h Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/dev/netmap/if_lem_netmap.h Tue Oct 18 16:18:25 2016 (r307574) @@ -35,12 +35,8 @@ #include <net/netmap.h> #include <sys/selinfo.h> -#include <vm/vm.h> -#include <vm/pmap.h> /* vtophys ? */ #include <dev/netmap/netmap_kern.h> -extern int netmap_adaptive_io; - /* * Register/unregister. We are already under netmap lock. */ Modified: head/sys/dev/netmap/if_ptnet.c ============================================================================== --- head/sys/dev/netmap/if_ptnet.c Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/dev/netmap/if_ptnet.c Tue Oct 18 16:18:25 2016 (r307574) @@ -341,7 +341,11 @@ ptnet_attach(device_t dev) } { - vm_paddr_t paddr = vtophys(sc->csb); + /* + * 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); bus_write_4(sc->iomem, PTNET_IO_CSBBAH, (paddr >> 32) & 0xffffffff); @@ -1139,9 +1143,11 @@ ptnet_sync_from_csb(struct ptnet_softc * static void ptnet_update_vnet_hdr(struct ptnet_softc *sc) { - sc->vnet_hdr_len = ptnet_vnet_hdr ? PTNET_HDR_SIZE : 0; + unsigned int wanted_hdr_len = ptnet_vnet_hdr ? PTNET_HDR_SIZE : 0; + + bus_write_4(sc->iomem, PTNET_IO_VNET_HDR_LEN, wanted_hdr_len); + sc->vnet_hdr_len = bus_read_4(sc->iomem, PTNET_IO_VNET_HDR_LEN); sc->ptna->hwup.up.virt_hdr_len = sc->vnet_hdr_len; - bus_write_4(sc->iomem, PTNET_IO_VNET_HDR_LEN, sc->vnet_hdr_len); } static int Modified: head/sys/dev/netmap/netmap.c ============================================================================== --- head/sys/dev/netmap/netmap.c Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/dev/netmap/netmap.c Tue Oct 18 16:18:25 2016 (r307574) @@ -483,7 +483,6 @@ static int netmap_no_timestamp; /* don't int netmap_mitigate = 1; int netmap_no_pendintr = 1; int netmap_txsync_retry = 2; -int netmap_adaptive_io = 0; int netmap_flags = 0; /* debug flags */ static int netmap_fwd = 0; /* force transparent mode */ @@ -540,8 +539,6 @@ SYSCTL_INT(_dev_netmap, OID_AUTO, no_pen 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 , ""); @@ -1559,7 +1556,7 @@ nm_txsync_prologue(struct netmap_kring * } } if (ring->tail != kring->rtail) { - RD(5, "tail overwritten was %d need %d", + RD(5, "%s tail overwritten was %d need %d", kring->name, ring->tail, kring->rtail); ring->tail = kring->rtail; } Modified: head/sys/dev/netmap/netmap_freebsd.c ============================================================================== --- head/sys/dev/netmap/netmap_freebsd.c Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/dev/netmap/netmap_freebsd.c Tue Oct 18 16:18:25 2016 (r307574) @@ -353,7 +353,7 @@ nm_os_generic_xmit_frame(struct nm_os_ge bcopy(a->addr, m->m_data, len); #else /* __FreeBSD_version >= 1100000 */ /* New FreeBSD versions. Link the external storage to - * the netmap buffer, so that no copy is necessary. */ + * the netmap buffer, so that no copy is necessary. */ m->m_ext.ext_buf = m->m_data = a->addr; m->m_ext.ext_size = len; #endif /* __FreeBSD_version >= 1100000 */ @@ -644,7 +644,8 @@ DRIVER_MODULE_ORDERED(ptn_memdev, pci, p * of the netmap memory mapped in the guest. */ int -nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr, void **nm_addr) +nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr, + void **nm_addr) { uint32_t mem_size; int rid; @@ -668,8 +669,8 @@ nm_os_pt_memdev_iomap(struct ptnetmap_me D("=== BAR %d start %lx len %lx mem_size %x ===", PTNETMAP_MEM_PCI_BAR, - *nm_paddr, - rman_get_size(ptn_dev->pci_mem), + (unsigned long)(*nm_paddr), + (unsigned long)rman_get_size(ptn_dev->pci_mem), mem_size); return (0); } Modified: head/sys/dev/netmap/netmap_generic.c ============================================================================== --- head/sys/dev/netmap/netmap_generic.c Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/dev/netmap/netmap_generic.c Tue Oct 18 16:18:25 2016 (r307574) @@ -95,7 +95,7 @@ __FBSDID("$FreeBSD$"); /* * For older versions of FreeBSD: - * + * * We allocate EXT_PACKET mbuf+clusters, but need to set M_NOFREE * so that the destructor, if invoked, will not free the packet. * In principle we should set the destructor only on demand, @@ -628,8 +628,6 @@ generic_mbuf_destructor(struct mbuf *m) #endif } -extern int netmap_adaptive_io; - /* Record completed transmissions and update hwtail. * * The oldest tx buffer not yet completed is at nr_hwtail + 1, @@ -690,23 +688,6 @@ generic_netmap_tx_clean(struct netmap_kr n++; nm_i = nm_next(nm_i, lim); -#if 0 /* rate adaptation */ - if (netmap_adaptive_io > 1) { - if (n >= netmap_adaptive_io) - break; - } else if (netmap_adaptive_io) { - /* if hwcur - nm_i < lim/8 do an early break - * so we prevent the sender from stalling. See CVT. - */ - if (hwcur >= nm_i) { - if (hwcur - nm_i < lim/2) - break; - } else { - if (hwcur + lim + 1 - nm_i < lim/2) - break; - } - } -#endif } kring->nr_hwtail = nm_prev(nm_i, lim); ND("tx completed [%d] -> hwtail %d", n, kring->nr_hwtail); Modified: head/sys/dev/netmap/netmap_kern.h ============================================================================== --- head/sys/dev/netmap/netmap_kern.h Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/dev/netmap/netmap_kern.h Tue Oct 18 16:18:25 2016 (r307574) @@ -1512,9 +1512,9 @@ int netmap_adapter_put(struct netmap_ada */ #define NETMAP_BUF_BASE(_na) ((_na)->na_lut.lut[0].vaddr) #define NETMAP_BUF_SIZE(_na) ((_na)->na_lut.objsize) -extern int netmap_mitigate; // XXX not really used extern int netmap_no_pendintr; -extern int netmap_verbose; // XXX debugging +extern int netmap_mitigate; +extern int netmap_verbose; /* for debugging */ enum { /* verbose flags */ NM_VERB_ON = 1, /* generic verbose */ NM_VERB_HOST = 0x2, /* verbose host stack */ @@ -1527,7 +1527,6 @@ enum { }; extern int netmap_txsync_retry; -extern int netmap_adaptive_io; extern int netmap_flags; extern int netmap_generic_mit; extern int netmap_generic_ringsize; Modified: head/sys/dev/netmap/netmap_pt.c ============================================================================== --- head/sys/dev/netmap/netmap_pt.c Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/dev/netmap/netmap_pt.c Tue Oct 18 16:18:25 2016 (r307574) @@ -64,13 +64,10 @@ * results in random drops in the VALE txsync. */ //#define PTN_TX_BATCH_LIM(_n) ((_n >> 1)) -/* XXX: avoid nm_*sync_prologue(). XXX-vin: this should go away, - * we should never trust the guest. */ -#define PTN_AVOID_NM_PROLOGUE //#define BUSY_WAIT -#define DEBUG /* Enables communication debugging. */ -#ifdef DEBUG +#define NETMAP_PT_DEBUG /* Enables communication debugging. */ +#ifdef NETMAP_PT_DEBUG #define DBG(x) x #else #define DBG(x) @@ -196,22 +193,6 @@ ptnetmap_kring_dump(const char *title, c kring->ring->head, kring->ring->cur, kring->ring->tail); } -#if 0 -static inline void -ptnetmap_ring_reinit(struct netmap_kring *kring, uint32_t g_head, uint32_t g_cur) -{ - struct netmap_ring *ring = kring->ring; - - //XXX: trust guest? - ring->head = g_head; - ring->cur = g_cur; - ring->tail = NM_ACCESS_ONCE(kring->nr_hwtail); - - netmap_ring_reinit(kring); - ptnetmap_kring_dump("kring reinit", kring); -} -#endif - /* * TX functions to set/get and to handle host/guest kick. */ @@ -251,7 +232,7 @@ ptnetmap_tx_handler(void *data) (struct netmap_pt_host_adapter *)kring->na->na_private; struct ptnetmap_state *ptns = pth_na->ptns; struct ptnet_ring __user *ptring; - struct netmap_ring g_ring; /* guest ring pointer, copied from CSB */ + struct netmap_ring shadow_ring; /* shadow copy of the netmap_ring */ bool more_txspace = false; struct nm_kthread *kth; uint32_t num_slots; @@ -281,18 +262,18 @@ ptnetmap_tx_handler(void *data) kth = ptns->kthreads[kring->ring_id]; num_slots = kring->nkr_num_slots; - g_ring.head = kring->rhead; - g_ring.cur = kring->rcur; + shadow_ring.head = kring->rhead; + shadow_ring.cur = kring->rcur; /* Disable guest --> host notifications. */ ptring_kick_enable(ptring, 0); /* Copy the guest kring pointers from the CSB */ - ptnetmap_host_read_kring_csb(ptring, &g_ring, num_slots); + ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); for (;;) { /* If guest moves ahead too fast, let's cut the move so * that we don't exceed our batch limit. */ - batch = g_ring.head - kring->nr_hwcur; + batch = shadow_ring.head - kring->nr_hwcur; if (batch < 0) batch += num_slots; @@ -302,37 +283,35 @@ ptnetmap_tx_handler(void *data) if (head_lim >= num_slots) head_lim -= num_slots; - ND(1, "batch: %d head: %d head_lim: %d", batch, g_ring.head, + ND(1, "batch: %d head: %d head_lim: %d", batch, shadow_ring.head, head_lim); - g_ring.head = head_lim; + shadow_ring.head = head_lim; batch = PTN_TX_BATCH_LIM(num_slots); } #endif /* PTN_TX_BATCH_LIM */ if (nm_kr_txspace(kring) <= (num_slots >> 1)) { - g_ring.flags |= NAF_FORCE_RECLAIM; + shadow_ring.flags |= NAF_FORCE_RECLAIM; } -#ifndef PTN_AVOID_NM_PROLOGUE + /* Netmap prologue */ - if (unlikely(nm_txsync_prologue(kring, &g_ring) >= num_slots)) { - ptnetmap_ring_reinit(kring, g_ring.head, g_ring.cur); - /* Reenable notifications. */ + shadow_ring.tail = kring->rtail; + if (unlikely(nm_txsync_prologue(kring, &shadow_ring) >= num_slots)) { + /* Reinit ring and enable notifications. */ + netmap_ring_reinit(kring); ptring_kick_enable(ptring, 1); break; } -#else /* PTN_AVOID_NM_PROLOGUE */ - kring->rhead = g_ring.head; - kring->rcur = g_ring.cur; -#endif /* !PTN_AVOID_NM_PROLOGUE */ + if (unlikely(netmap_verbose & NM_VERB_TXSYNC)) { ptnetmap_kring_dump("pre txsync", kring); } IFRATE(pre_tail = kring->rtail); - if (unlikely(kring->nm_sync(kring, g_ring.flags))) { + if (unlikely(kring->nm_sync(kring, shadow_ring.flags))) { /* Reenable notifications. */ ptring_kick_enable(ptring, 1); - D("ERROR txsync"); + D("ERROR txsync()"); break; } @@ -350,7 +329,7 @@ ptnetmap_tx_handler(void *data) } IFRATE(rate_batch_stats_update(&ptns->rate_ctx.new.txbs, pre_tail, - kring->rtail, num_slots)); + kring->rtail, num_slots)); if (unlikely(netmap_verbose & NM_VERB_TXSYNC)) { ptnetmap_kring_dump("post txsync", kring); @@ -367,9 +346,9 @@ ptnetmap_tx_handler(void *data) } #endif /* Read CSB to see if there is more work to do. */ - ptnetmap_host_read_kring_csb(ptring, &g_ring, num_slots); + ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); #ifndef BUSY_WAIT - if (g_ring.head == kring->rhead) { + if (shadow_ring.head == kring->rhead) { /* * No more packets to transmit. We enable notifications and * go to sleep, waiting for a kick from the guest when new @@ -379,8 +358,8 @@ ptnetmap_tx_handler(void *data) /* Reenable notifications. */ ptring_kick_enable(ptring, 1); /* Doublecheck. */ - ptnetmap_host_read_kring_csb(ptring, &g_ring, num_slots); - if (g_ring.head != kring->rhead) { + ptnetmap_host_read_kring_csb(ptring, &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); @@ -433,7 +412,7 @@ ptnetmap_rx_handler(void *data) (struct netmap_pt_host_adapter *)kring->na->na_private; struct ptnetmap_state *ptns = pth_na->ptns; struct ptnet_ring __user *ptring; - struct netmap_ring g_ring; /* guest ring pointer, copied from CSB */ + struct netmap_ring shadow_ring; /* shadow copy of the netmap_ring */ struct nm_kthread *kth; uint32_t num_slots; int dry_cycles = 0; @@ -464,36 +443,32 @@ ptnetmap_rx_handler(void *data) kth = ptns->kthreads[pth_na->up.num_tx_rings + kring->ring_id]; num_slots = kring->nkr_num_slots; - g_ring.head = kring->rhead; - g_ring.cur = kring->rcur; + shadow_ring.head = kring->rhead; + shadow_ring.cur = kring->rcur; /* Disable notifications. */ ptring_kick_enable(ptring, 0); /* Copy the guest kring pointers from the CSB */ - ptnetmap_host_read_kring_csb(ptring, &g_ring, num_slots); + ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); for (;;) { uint32_t hwtail; -#ifndef PTN_AVOID_NM_PROLOGUE /* Netmap prologue */ - if (unlikely(nm_rxsync_prologue(kring, &g_ring) >= num_slots)) { - ptnetmap_ring_reinit(kring, g_ring.head, g_ring.cur); - /* Reenable notifications. */ + shadow_ring.tail = kring->rtail; + if (unlikely(nm_rxsync_prologue(kring, &shadow_ring) >= num_slots)) { + /* Reinit ring and enable notifications. */ + netmap_ring_reinit(kring); ptring_kick_enable(ptring, 1); break; } -#else /* PTN_AVOID_NM_PROLOGUE */ - kring->rhead = g_ring.head; - kring->rcur = g_ring.cur; -#endif /* !PTN_AVOID_NM_PROLOGUE */ - if (unlikely(netmap_verbose & NM_VERB_RXSYNC)) + if (unlikely(netmap_verbose & NM_VERB_RXSYNC)) { ptnetmap_kring_dump("pre rxsync", kring); + } IFRATE(pre_tail = kring->rtail); - - if (unlikely(kring->nm_sync(kring, g_ring.flags))) { + if (unlikely(kring->nm_sync(kring, shadow_ring.flags))) { /* Reenable notifications. */ ptring_kick_enable(ptring, 1); D("ERROR rxsync()"); @@ -516,8 +491,9 @@ ptnetmap_rx_handler(void *data) IFRATE(rate_batch_stats_update(&ptns->rate_ctx.new.rxbs, pre_tail, kring->rtail, num_slots)); - if (unlikely(netmap_verbose & NM_VERB_RXSYNC)) + if (unlikely(netmap_verbose & NM_VERB_RXSYNC)) { ptnetmap_kring_dump("post rxsync", kring); + } #ifndef BUSY_WAIT /* Interrupt the guest if needed. */ @@ -530,9 +506,9 @@ ptnetmap_rx_handler(void *data) } #endif /* Read CSB to see if there is more work to do. */ - ptnetmap_host_read_kring_csb(ptring, &g_ring, num_slots); + ptnetmap_host_read_kring_csb(ptring, &shadow_ring, num_slots); #ifndef BUSY_WAIT - if (ptnetmap_norxslots(kring, g_ring.head)) { + if (ptnetmap_norxslots(kring, shadow_ring.head)) { /* * No more slots available for reception. We enable notification and * go to sleep, waiting for a kick from the guest when new receive @@ -542,8 +518,8 @@ ptnetmap_rx_handler(void *data) /* Reenable notifications. */ ptring_kick_enable(ptring, 1); /* Doublecheck. */ - ptnetmap_host_read_kring_csb(ptring, &g_ring, num_slots); - if (!ptnetmap_norxslots(kring, g_ring.head)) { + ptnetmap_host_read_kring_csb(ptring, &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); @@ -578,7 +554,7 @@ ptnetmap_rx_handler(void *data) } } -#ifdef DEBUG +#ifdef NETMAP_PT_DEBUG static void ptnetmap_print_configuration(struct ptnetmap_cfg *cfg) { @@ -594,7 +570,7 @@ ptnetmap_print_configuration(struct ptne } } -#endif +#endif /* NETMAP_PT_DEBUG */ /* Copy actual state of the host ring into the CSB for the guest init */ static int Modified: head/sys/net/netmap.h ============================================================================== --- head/sys/net/netmap.h Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/net/netmap.h Tue Oct 18 16:18:25 2016 (r307574) @@ -655,8 +655,8 @@ struct ptn_vmm_ioctl_msix { /* IOCTL parameters */ struct nm_kth_ioctl { - u_long com; - /* TODO: use union */ + uint64_t com; + /* We use union to support more ioctl commands. */ union { struct ptn_vmm_ioctl_msix msix; } data; @@ -667,5 +667,6 @@ struct ptnet_ring_cfg { uint64_t ioeventfd; /* eventfd in linux, tsleep() parameter in FreeBSD */ uint64_t irqfd; /* eventfd in linux, ioctl fd in FreeBSD */ struct nm_kth_ioctl ioctl; /* ioctl parameter to send irq (only used in bhyve/FreeBSD) */ + uint64_t reserved[4]; /* reserved to support of more hypervisors */ }; #endif /* _NET_NETMAP_H_ */ Modified: head/sys/net/netmap_virt.h ============================================================================== --- head/sys/net/netmap_virt.h Tue Oct 18 15:50:20 2016 (r307573) +++ head/sys/net/netmap_virt.h Tue Oct 18 16:18:25 2016 (r307574) @@ -58,13 +58,11 @@ /* Registers for the ptnetmap memdev */ /* 32 bit r/o */ -#define PTNETMAP_IO_PCI_FEATURES 0 /* XXX should be removed */ -/* 32 bit r/o */ -#define PTNETMAP_IO_PCI_MEMSIZE 4 /* size of the netmap memory shared +#define PTNETMAP_IO_PCI_MEMSIZE 0 /* size of the netmap memory shared * between guest and host */ /* 16 bit r/o */ -#define PTNETMAP_IO_PCI_HOSTID 8 /* memory allocator ID in netmap host */ -#define PTNETMAP_IO_SIZE 10 +#define PTNETMAP_IO_PCI_HOSTID 4 /* memory allocator ID in netmap host */ +#define PTNETMAP_IO_SIZE 6 /* * ptnetmap configuration @@ -115,18 +113,17 @@ ptnetmap_write_cfg(struct nmreq *nmr, st #define PTNET_IO_PTFEAT 0 #define PTNET_IO_PTCTL 4 #define PTNET_IO_PTSTS 8 -/* hole */ -#define PTNET_IO_MAC_LO 16 -#define PTNET_IO_MAC_HI 20 -#define PTNET_IO_CSBBAH 24 -#define PTNET_IO_CSBBAL 28 -#define PTNET_IO_NIFP_OFS 32 -#define PTNET_IO_NUM_TX_RINGS 36 -#define PTNET_IO_NUM_RX_RINGS 40 -#define PTNET_IO_NUM_TX_SLOTS 44 -#define PTNET_IO_NUM_RX_SLOTS 48 -#define PTNET_IO_VNET_HDR_LEN 52 -#define PTNET_IO_END 56 +#define PTNET_IO_MAC_LO 12 +#define PTNET_IO_MAC_HI 16 +#define PTNET_IO_CSBBAH 20 +#define PTNET_IO_CSBBAL 24 +#define PTNET_IO_NIFP_OFS 28 +#define PTNET_IO_NUM_TX_RINGS 32 +#define PTNET_IO_NUM_RX_RINGS 36 +#define PTNET_IO_NUM_TX_SLOTS 40 +#define PTNET_IO_NUM_RX_SLOTS 44 +#define PTNET_IO_VNET_HDR_LEN 48 +#define PTNET_IO_END 52 #define PTNET_IO_KICK_BASE 128 #define PTNET_IO_MASK 0xff @@ -139,11 +136,11 @@ struct ptnet_ring { uint32_t head; /* GW+ HR+ the head of the guest netmap_ring */ uint32_t cur; /* GW+ HR+ the cur of the guest netmap_ring */ uint32_t guest_need_kick; /* GW+ HR+ host-->guest notification enable */ - char pad[4]; + uint32_t sync_flags; /* GW+ HR+ the flags of the guest [tx|rx]sync() */ uint32_t hwcur; /* GR+ HW+ the hwcur of the host netmap_kring */ uint32_t hwtail; /* GR+ HW+ the hwtail of the host netmap_kring */ uint32_t host_need_kick; /* GR+ HW+ guest-->host notification enable */ - uint32_t sync_flags; /* GW+ HR+ the flags of the guest [tx|rx]sync() */ + char pad[4]; }; /* CSB for the ptnet device. */ @@ -165,161 +162,119 @@ ptn_sub(uint32_t l_elem, uint32_t r_elem } #endif /* WITH_PTNETMAP_HOST || WITH_PTNETMAP_GUEST */ -#ifdef WITH_PTNETMAP_HOST -/* - * ptnetmap kernel thread routines - * */ - -/* Functions to read and write CSB fields in the host */ -#if defined (linux) -#define CSB_READ(csb, field, r) (get_user(r, &csb->field)) -#define CSB_WRITE(csb, field, v) (put_user(v, &csb->field)) -#else /* ! linux */ -#define CSB_READ(csb, field, r) (r = fuword32(&csb->field)) -#define CSB_WRITE(csb, field, v) (suword32(&csb->field, v)) -#endif /* ! linux */ +#ifdef WITH_PTNETMAP_GUEST -/* - * HOST read/write kring pointers from/in CSB - */ +/* ptnetmap_memdev routines used to talk with ptnetmap_memdev device driver */ +struct ptnetmap_memdev; +int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **); +void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *); -/* Host: Read kring pointers (head, cur, sync_flags) from CSB */ +/* Guest driver: Write kring pointers (cur, head) to the CSB. + * This routine is coupled with ptnetmap_host_read_kring_csb(). */ static inline void -ptnetmap_host_read_kring_csb(struct ptnet_ring __user *ptr, - struct netmap_ring *g_ring, - uint32_t num_slots) +ptnetmap_guest_write_kring_csb(struct ptnet_ring *ptr, uint32_t cur, + uint32_t head) { - uint32_t old_head = g_ring->head, old_cur = g_ring->cur; - uint32_t d, inc_h, inc_c; - - //mb(); /* Force memory complete before read CSB */ - /* - * We must first read head and then cur with a barrier in the - * middle, because cur can exceed head, but not vice versa. - * The guest must first write cur and then head with a barrier. - * - * head <= cur - * - * guest host - * - * STORE(cur) LOAD(head) - * mb() ----------- mb() - * STORE(head) LOAD(cur) - * - * This approach ensures that every head that we read is - * associated with the correct cur. In this way head can not exceed cur. + * We need to write cur and head to the CSB but we cannot do it atomically. + * There is no way we can prevent the host from reading the updated value + * of one of the two and the old value of the other. However, if we make + * sure that the host never reads a value of head more recent than the + * value of cur we are safe. We can allow the host to read a value of cur + * more recent than the value of head, since in the netmap ring cur can be + * ahead of head and cur cannot wrap around head because it must be behind + * tail. Inverting the order of writes below could instead result into the + * host to think head went ahead of cur, which would cause the sync + * prologue to fail. + * + * The following memory barrier scheme is used to make this happen: + * + * Guest Host + * + * STORE(cur) LOAD(head) + * mb() <-----------> mb() + * STORE(head) LOAD(cur) */ - CSB_READ(ptr, head, g_ring->head); + ptr->cur = cur; mb(); - CSB_READ(ptr, cur, g_ring->cur); - CSB_READ(ptr, sync_flags, g_ring->flags); - - /* - * Even with the previous barrier, it is still possible that we read an - * updated cur and an old head. - * To detect this situation, we can check if the new cur overtakes - * the (apparently) new head. - */ - d = ptn_sub(old_cur, old_head, num_slots); /* previous distance */ - inc_c = ptn_sub(g_ring->cur, old_cur, num_slots); /* increase of cur */ - inc_h = ptn_sub(g_ring->head, old_head, num_slots); /* increase of head */ - - if (unlikely(inc_c > num_slots - d + inc_h)) { /* cur overtakes head */ - ND(1,"ERROR cur overtakes head - old_cur: %u cur: %u old_head: %u head: %u", - old_cur, g_ring->cur, old_head, g_ring->head); - g_ring->cur = nm_prev(g_ring->head, num_slots - 1); - //*g_cur = *g_head; - } + ptr->head = head; } -/* Host: Write kring pointers (hwcur, hwtail) into the CSB */ +/* Guest driver: Read kring pointers (hwcur, hwtail) from the CSB. + * This routine is coupled with ptnetmap_host_write_kring_csb(). */ static inline void -ptnetmap_host_write_kring_csb(struct ptnet_ring __user *ptr, uint32_t hwcur, - uint32_t hwtail) +ptnetmap_guest_read_kring_csb(struct ptnet_ring *ptr, struct netmap_kring *kring) { - /* We must write hwtail before hwcur (see below). */ - CSB_WRITE(ptr, hwtail, hwtail); + /* + * We place a memory barrier to make sure that the update of hwtail never + * overtakes the update of hwcur. + * (see explanation in ptnetmap_host_write_kring_csb). + */ + kring->nr_hwtail = ptr->hwtail; mb(); - CSB_WRITE(ptr, hwcur, hwcur); - - //mb(); /* Force memory complete before send notification */ + kring->nr_hwcur = ptr->hwcur; } -#endif /* WITH_PTNETMAP_HOST */ +#endif /* WITH_PTNETMAP_GUEST */ -#ifdef WITH_PTNETMAP_GUEST +#ifdef WITH_PTNETMAP_HOST /* - * GUEST read/write kring pointers from/in CSB. - * To use into device driver. - */ + * ptnetmap kernel thread routines + * */ + +/* Functions to read and write CSB fields in the host */ +#if defined (linux) +#define CSB_READ(csb, field, r) (get_user(r, &csb->field)) +#define CSB_WRITE(csb, field, v) (put_user(v, &csb->field)) +#else /* ! linux */ +#define CSB_READ(csb, field, r) (r = fuword32(&csb->field)) +#define CSB_WRITE(csb, field, v) (suword32(&csb->field, v)) +#endif /* ! linux */ -/* Guest: Write kring pointers (cur, head) into the CSB */ +/* Host netmap: Write kring pointers (hwcur, hwtail) to the CSB. + * This routine is coupled with ptnetmap_guest_read_kring_csb(). */ static inline void -ptnetmap_guest_write_kring_csb(struct ptnet_ring *ptr, uint32_t cur, - uint32_t head) +ptnetmap_host_write_kring_csb(struct ptnet_ring __user *ptr, uint32_t hwcur, + uint32_t hwtail) { - /* We must write cur before head for sync reason (see above) */ - ptr->cur = cur; + /* + * The same scheme used in ptnetmap_guest_write_kring_csb() applies here. + * We allow the guest to read a value of hwcur more recent than the value + * of hwtail, since this would anyway result in a consistent view of the + * ring state (and hwcur can never wraparound hwtail, since hwcur must be + * behind head). + * + * The following memory barrier scheme is used to make this happen: + * + * Guest Host + * + * STORE(hwcur) LOAD(hwtail) + * mb() <-------------> mb() + * STORE(hwtail) LOAD(hwcur) + */ + CSB_WRITE(ptr, hwcur, hwcur); mb(); - ptr->head = head; - - //mb(); /* Force memory complete before send notification */ + CSB_WRITE(ptr, hwtail, hwtail); } -/* Guest: Read kring pointers (hwcur, hwtail) from CSB */ +/* Host netmap: Read kring pointers (head, cur, sync_flags) from the CSB. + * This routine is coupled with ptnetmap_guest_write_kring_csb(). */ static inline void -ptnetmap_guest_read_kring_csb(struct ptnet_ring *ptr, struct netmap_kring *kring) +ptnetmap_host_read_kring_csb(struct ptnet_ring __user *ptr, + struct netmap_ring *shadow_ring, + uint32_t num_slots) { - uint32_t old_hwcur = kring->nr_hwcur, old_hwtail = kring->nr_hwtail; - uint32_t num_slots = kring->nkr_num_slots; - uint32_t d, inc_hc, inc_ht; - - //mb(); /* Force memory complete before read CSB */ - /* - * We must first read hwcur and then hwtail with a barrier in the - * middle, because hwtail can exceed hwcur, but not vice versa. - * The host must first write hwtail and then hwcur with a barrier. - * - * hwcur <= hwtail - * - * host guest - * - * STORE(hwtail) LOAD(hwcur) - * mb() --------- mb() - * STORE(hwcur) LOAD(hwtail) - * - * This approach ensures that every hwcur that the guest reads is - * associated with the correct hwtail. In this way hwcur can not exceed - * hwtail. + * We place a memory barrier to make sure that the update of head never + * overtakes the update of cur. + * (see explanation in ptnetmap_guest_write_kring_csb). */ - kring->nr_hwcur = ptr->hwcur; + CSB_READ(ptr, head, shadow_ring->head); mb(); - kring->nr_hwtail = ptr->hwtail; - - /* - * Even with the previous barrier, it is still possible that we read an - * updated hwtail and an old hwcur. - * To detect this situation, we can check if the new hwtail overtakes - * the (apparently) new hwcur. - */ - d = ptn_sub(old_hwtail, old_hwcur, num_slots); /* previous distance */ - inc_ht = ptn_sub(kring->nr_hwtail, old_hwtail, num_slots); /* increase of hwtail */ - inc_hc = ptn_sub(kring->nr_hwcur, old_hwcur, num_slots); /* increase of hwcur */ - - if (unlikely(inc_ht > num_slots - d + inc_hc)) { - ND(1, "ERROR hwtail overtakes hwcur - old_hwtail: %u hwtail: %u old_hwcur: %u hwcur: %u", - old_hwtail, kring->nr_hwtail, old_hwcur, kring->nr_hwcur); - kring->nr_hwtail = nm_prev(kring->nr_hwcur, num_slots - 1); - //kring->nr_hwtail = kring->nr_hwcur; - } + CSB_READ(ptr, cur, shadow_ring->cur); + CSB_READ(ptr, sync_flags, shadow_ring->flags); } -/* ptnetmap_memdev routines used to talk with ptnetmap_memdev device driver */ -struct ptnetmap_memdev; -int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **); -void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *); -#endif /* WITH_PTNETMAP_GUEST */ +#endif /* WITH_PTNETMAP_HOST */ #endif /* NETMAP_VIRT_H */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610181618.u9IGIPbG064539>