Module Name:    src
Committed By:   martin
Date:           Tue Feb 23 18:50:21 UTC 2021

Modified Files:
        src/sys/arch/xen/xen [netbsd-9]: xennetback_xenbus.c

Log Message:
Pull up following revision(s) (requested by jdolecek in ticket #1211):

        sys/arch/xen/xen/xennetback_xenbus.c: revision 1.92 (via patch)

remove support for legacy rx-flip mode for xennet(4)/xvif(4), making
rx-copy (first shipped in NetBSD 6.0 in 2012) the only supported
mode

this is mostly to simplify maintenance and future development
rx-flip is not supported by Linux Dom0/DomU, and NetBSD Dom0/DomU
defaults to rx-copy for over 8 years now too, so there is little
need to keep the support for compatibility

besides compatibility there is no other reason to keep rx-flip -
page transfer is generally slower than copy due to necessary MMU/TLB
manipulation, especially on MP systems


To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.75.4.1 src/sys/arch/xen/xen/xennetback_xenbus.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/xen/xen/xennetback_xenbus.c
diff -u src/sys/arch/xen/xen/xennetback_xenbus.c:1.75 src/sys/arch/xen/xen/xennetback_xenbus.c:1.75.4.1
--- src/sys/arch/xen/xen/xennetback_xenbus.c:1.75	Sat Mar  9 08:42:25 2019
+++ src/sys/arch/xen/xen/xennetback_xenbus.c	Tue Feb 23 18:50:21 2021
@@ -1,4 +1,4 @@
-/*      $NetBSD: xennetback_xenbus.c,v 1.75 2019/03/09 08:42:25 maxv Exp $      */
+/*      $NetBSD: xennetback_xenbus.c,v 1.75.4.1 2021/02/23 18:50:21 martin Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.75 2019/03/09 08:42:25 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.75.4.1 2021/02/23 18:50:21 martin Exp $");
 
 #include "opt_xen.h"
 
@@ -129,7 +129,6 @@ struct xnetback_instance {
        void xvifattach(int);
 static int  xennetback_ifioctl(struct ifnet *, u_long, void *);
 static void xennetback_ifstart(struct ifnet *);
-static void xennetback_ifsoftstart_transfer(void *);
 static void xennetback_ifsoftstart_copy(void *);
 static void xennetback_ifwatchdog(struct ifnet *);
 static int  xennetback_ifinit(struct ifnet *);
@@ -160,35 +159,10 @@ static struct xenbus_backend_driver xvif
  */
 #define NB_XMIT_PAGES_BATCH 64
 
-/*
- * We will transfer a mapped page to the remote domain, and remap another
- * page in place immediately. For this we keep a list of pages available.
- * When the list is empty, we ask the hypervisor to give us
- * NB_XMIT_PAGES_BATCH pages back.
- */
-static unsigned long mcl_pages[NB_XMIT_PAGES_BATCH]; /* our physical pages */
-int mcl_pages_alloc; /* current index in mcl_pages */
-static int  xennetback_get_mcl_page(paddr_t *);
-static void xennetback_get_new_mcl_pages(void);
-
-/*
- * If we can't transfer the mbuf directly, we have to copy it to a page which
- * will be transferred to the remote domain. We use a pool_cache for this.
- */
-pool_cache_t xmit_pages_cache;
-
 /* arrays used in xennetback_ifstart(), too large to allocate on stack */
 /* XXXSMP */
-static mmu_update_t xstart_mmu[NB_XMIT_PAGES_BATCH];
-static multicall_entry_t xstart_mcl[NB_XMIT_PAGES_BATCH + 1];
-static gnttab_transfer_t xstart_gop_transfer[NB_XMIT_PAGES_BATCH];
 static gnttab_copy_t     xstart_gop_copy[NB_XMIT_PAGES_BATCH];
 static struct mbuf *mbufs_sent[NB_XMIT_PAGES_BATCH];
-static struct _pages_pool_free {
-	vaddr_t va;
-	paddr_t pa;
-} pages_pool_free[NB_XMIT_PAGES_BATCH];
-
 
 static inline void
 xni_pkt_unmap(struct xni_pkt *pkt, vaddr_t pkt_va)
@@ -200,31 +174,11 @@ xni_pkt_unmap(struct xni_pkt *pkt, vaddr
 void
 xvifattach(int n)
 {
-	int i;
-	struct pglist mlist;
-	struct vm_page *pg;
-
 	XENPRINTF(("xennetback_init\n"));
 
-	/*
-	 * steal some non-managed pages to the VM system, to replace
-	 * mbuf cluster or xmit_pages_pool pages given to foreign domains.
-	 */
-	if (uvm_pglistalloc(PAGE_SIZE * NB_XMIT_PAGES_BATCH, 0, 0xffffffff,
-	    0, 0, &mlist, NB_XMIT_PAGES_BATCH, 0) != 0)
-		panic("xennetback_init: uvm_pglistalloc");
-	for (i = 0, pg = mlist.tqh_first; pg != NULL;
-	    pg = pg->pageq.queue.tqe_next, i++)
-		mcl_pages[i] = xpmap_ptom(VM_PAGE_TO_PHYS(pg)) >> PAGE_SHIFT;
-	if (i != NB_XMIT_PAGES_BATCH)
-		panic("xennetback_init: %d mcl pages", i);
-	mcl_pages_alloc = NB_XMIT_PAGES_BATCH - 1;
-
 	/* initialise pools */
 	pool_init(&xni_pkt_pool, sizeof(struct xni_pkt), 0, 0, 0,
 	    "xnbpkt", NULL, IPL_VM);
-	xmit_pages_cache = pool_cache_init(PAGE_SIZE, 0, 0, 0, "xnbxm", NULL,
-	    IPL_VM, NULL, NULL, NULL);
 
 	SLIST_INIT(&xnetback_instances);
 	mutex_init(&xnetback_lock, MUTEX_DEFAULT, IPL_NONE);
@@ -342,14 +296,6 @@ xennetback_xenbus_create(struct xenbus_d
 			    xbusd->xbusd_path, err);
 			goto abort_xbt;
 		}
-		err = xenbus_printf(xbt, xbusd->xbusd_path,
-		    "feature-rx-flip", "%d", 1);
-		if (err) {
-			aprint_error_ifnet(ifp,
-			    "failed to write %s/feature-rx-flip: %d\n",
-			    xbusd->xbusd_path, err);
-			goto abort_xbt;
-		}
 	} while ((err = xenbus_transaction_end(xbt, 0)) == EAGAIN);
 	if (err) {
 		aprint_error_ifnet(ifp,
@@ -472,21 +418,19 @@ xennetback_connect(struct xnetback_insta
 	}
 	err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
 	    "request-rx-copy", &rx_copy, 10);
-	if (err == ENOENT)
-		rx_copy = 0;
-	else if (err) {
+	if (err == ENOENT || !rx_copy) {
+		xenbus_dev_fatal(xbusd, err,
+		    "%s/request-rx-copy not supported by frontend",
+		    xbusd->xbusd_otherend);
+		return -1;
+	} else if (err) {
 		xenbus_dev_fatal(xbusd, err, "reading %s/request-rx-copy",
 		    xbusd->xbusd_otherend);
 		return -1;
 	}
 
-	if (rx_copy)
-		xneti->xni_softintr = softint_establish(SOFTINT_NET,
-		    xennetback_ifsoftstart_copy, xneti);
-	else
-		xneti->xni_softintr = softint_establish(SOFTINT_NET,
-		    xennetback_ifsoftstart_transfer, xneti);
-
+	xneti->xni_softintr = softint_establish(SOFTINT_NET,
+	    xennetback_ifsoftstart_copy, xneti);
 	if (xneti->xni_softintr == NULL) {
 		err = ENOMEM;
 		xenbus_dev_fatal(xbusd, ENOMEM,
@@ -662,48 +606,6 @@ xnetif_lookup(domid_t dom , uint32_t han
 	return found;
 }
 
-/* get a page to replace a mbuf cluster page given to a domain */
-static int
-xennetback_get_mcl_page(paddr_t *map)
-{
-	if (mcl_pages_alloc < 0) {
-		/*
-		 * we exhausted our allocation. We can't allocate new ones yet
-		 * because the current pages may not have been loaned to
-		 * the remote domain yet. We have to let the caller do this.
-		 */
-		return -1;
-	}
-
-	*map = ((paddr_t)mcl_pages[mcl_pages_alloc]) << PAGE_SHIFT;
-	mcl_pages_alloc--;
-	return 0;
-}
-
-static void
-xennetback_get_new_mcl_pages(void)
-{
-	int nb_pages;
-	struct xen_memory_reservation res;
-
-	/* get some new pages. */
-	set_xen_guest_handle(res.extent_start, mcl_pages);
-	res.nr_extents = NB_XMIT_PAGES_BATCH;
-	res.extent_order = 0;
-	res.address_bits = 0;
-	res.domid = DOMID_SELF;
-
-	nb_pages = HYPERVISOR_memory_op(XENMEM_increase_reservation, &res);
-	if (nb_pages <= 0) {
-		printf("xennetback: can't get new mcl pages (%d)\n", nb_pages);
-		return;
-	}
-	if (nb_pages != NB_XMIT_PAGES_BATCH)
-		printf("xennetback: got only %d new mcl pages\n", nb_pages);
-
-	mcl_pages_alloc = nb_pages - 1;
-}
-
 static inline void
 xennetback_tx_response(struct xnetback_instance *xneti, int id, int status)
 {
@@ -965,255 +867,6 @@ xennetback_ifstart(struct ifnet *ifp)
 	softint_schedule(xneti->xni_softintr);
 }
 
-static void
-xennetback_ifsoftstart_transfer(void *arg)
-{
-	struct xnetback_instance *xneti = arg;
-	struct ifnet *ifp = &xneti->xni_if;
-	struct mbuf *m;
-	vaddr_t xmit_va;
-	paddr_t xmit_pa;
-	paddr_t xmit_ma;
-	paddr_t newp_ma = 0; /* XXX gcc */
-	int i, j, nppitems;
-	mmu_update_t *mmup;
-	multicall_entry_t *mclp;
-	netif_rx_response_t *rxresp;
-	netif_rx_request_t rxreq;
-	RING_IDX req_prod, resp_prod;
-	int do_event = 0;
-	gnttab_transfer_t *gop;
-	int id, offset;
-
-	XENPRINTF(("xennetback_ifsoftstart_transfer "));
-	int s = splnet();
-	if (__predict_false(
-	    (ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)) {
-		splx(s);
-		return;
-	}
-
-	while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
-		XENPRINTF(("pkt\n"));
-		req_prod = xneti->xni_rxring.sring->req_prod;
-		resp_prod = xneti->xni_rxring.rsp_prod_pvt;
-		xen_rmb();
-
-		mmup = xstart_mmu;
-		mclp = xstart_mcl;
-		gop = xstart_gop_transfer;
-		for (nppitems = 0, i = 0; !IFQ_IS_EMPTY(&ifp->if_snd);) {
-			XENPRINTF(("have a packet\n"));
-			IFQ_POLL(&ifp->if_snd, m);
-			if (__predict_false(m == NULL))
-				panic("xennetback_ifstart: IFQ_POLL");
-			if (__predict_false(
-			    req_prod == xneti->xni_rxring.req_cons ||
-			    xneti->xni_rxring.req_cons - resp_prod ==
-			    NET_RX_RING_SIZE)) {
-				/* out of ring space */
-				XENPRINTF(("xennetback_ifstart: ring full "
-				    "req_prod 0x%x req_cons 0x%x resp_prod "
-				    "0x%x\n",
-				    req_prod, xneti->xni_rxring.req_cons,
-				    resp_prod));
-				ifp->if_timer = 1;
-				break;
-			}
-			if (__predict_false(i == NB_XMIT_PAGES_BATCH))
-				break; /* we filled the array */
-			if (__predict_false(
-			    xennetback_get_mcl_page(&newp_ma) != 0))
-				break; /* out of memory */
-			if ((m->m_flags & M_EXT_CLUSTER) != 0 &&
-			    !M_READONLY(m) && MCLBYTES == PAGE_SIZE) {
-				/* we can give this page away */
-				xmit_pa = m->m_ext.ext_paddr;
-				xmit_ma = xpmap_ptom(xmit_pa);
-				xmit_va = (vaddr_t)m->m_ext.ext_buf;
-				KASSERT(xmit_pa != M_PADDR_INVALID);
-				KASSERT((xmit_va & PAGE_MASK) == 0);
-				offset = m->m_data - m->m_ext.ext_buf;
-			} else {
-				/* we have to copy the packet */
-				xmit_va = (vaddr_t)pool_cache_get_paddr(
-				    xmit_pages_cache, PR_NOWAIT, &xmit_pa);
-				if (__predict_false(xmit_va == 0))
-					break; /* out of memory */
-
-				KASSERT(xmit_pa != POOL_PADDR_INVALID);
-				xmit_ma = xpmap_ptom(xmit_pa);
-				XENPRINTF(("xennetback_get_xmit_page: got va "
-				    "0x%x ma 0x%x\n", (u_int)xmit_va,
-				    (u_int)xmit_ma));
-				m_copydata(m, 0, m->m_pkthdr.len,
-				    (char *)xmit_va + LINUX_REQUESTED_OFFSET);
-				offset = LINUX_REQUESTED_OFFSET;
-				pages_pool_free[nppitems].va = xmit_va;
-				pages_pool_free[nppitems].pa = xmit_pa;
-				nppitems++;
-			}
-			/* start filling ring */
-			RING_COPY_REQUEST(&xneti->xni_rxring,
-			    xneti->xni_rxring.req_cons, &rxreq);
-			gop->ref = rxreq.gref;
-			id = rxreq.id;
-			xen_rmb();
-			xneti->xni_rxring.req_cons++;
-			rxresp = RING_GET_RESPONSE(&xneti->xni_rxring,
-			    resp_prod);
-			rxresp->id = id;
-			rxresp->offset = offset;
-			rxresp->status = m->m_pkthdr.len;
-			if ((m->m_pkthdr.csum_flags &
-			    (M_CSUM_TCPv4 | M_CSUM_UDPv4)) != 0) {
-				rxresp->flags = NETRXF_csum_blank;
-			} else {
-				rxresp->flags = 0;
-			}
-			/*
-			 * transfers the page containing the packet to the
-			 * remote domain, and map newp in place.
-			 */
-			xpmap_ptom_map(xmit_pa, newp_ma);
-			MULTI_update_va_mapping(mclp, xmit_va,
-			    newp_ma | PTE_P | PTE_W | PTE_A | PTE_D | xpmap_pg_nx, 0);
-			mclp++;
-			gop->mfn = xmit_ma >> PAGE_SHIFT;
-			gop->domid = xneti->xni_domid;
-			gop++;
-
-			mmup->ptr = newp_ma | MMU_MACHPHYS_UPDATE;
-			mmup->val = xmit_pa >> PAGE_SHIFT;
-			mmup++;
-
-			/* done with this packet */
-			IFQ_DEQUEUE(&ifp->if_snd, m);
-			mbufs_sent[i] = m;
-			resp_prod++;
-			i++; /* this packet has been queued */
-			ifp->if_opackets++;
-			bpf_mtap(ifp, m, BPF_D_OUT);
-		}
-		if (i != 0) {
-			/*
-			 * We may have allocated buffers which have entries
-			 * outstanding in the page update queue -- make sure
-			 * we flush those first!
-			 */
-			int svm = splvm();
-			xpq_flush_queue();
-			splx(svm);
-			mclp[-1].args[MULTI_UVMFLAGS_INDEX] =
-			    UVMF_TLB_FLUSH|UVMF_ALL;
-			mclp->op = __HYPERVISOR_mmu_update;
-			mclp->args[0] = (unsigned long)xstart_mmu;
-			mclp->args[1] = i;
-			mclp->args[2] = 0;
-			mclp->args[3] = DOMID_SELF;
-			mclp++;
-			/* update the MMU */
-			if (HYPERVISOR_multicall(xstart_mcl, i + 1) != 0) {
-				panic("%s: HYPERVISOR_multicall failed",
-				    ifp->if_xname);
-			}
-			for (j = 0; j < i + 1; j++) {
-				if (xstart_mcl[j].result != 0) {
-					printf("%s: xstart_mcl[%d] "
-					    "failed (%lu)\n", ifp->if_xname,
-					    j, xstart_mcl[j].result);
-					printf("%s: req_prod %u req_cons "
-					    "%u rsp_prod %u rsp_prod_pvt %u "
-					    "i %u\n",
-					    ifp->if_xname,
-					    xneti->xni_rxring.sring->req_prod,
-					    xneti->xni_rxring.req_cons,
-					    xneti->xni_rxring.sring->rsp_prod,
-					    xneti->xni_rxring.rsp_prod_pvt,
-					    i);
-				}
-			}
-			if (HYPERVISOR_grant_table_op(GNTTABOP_transfer,
-			    xstart_gop_transfer, i) != 0) {
-				panic("%s: GNTTABOP_transfer failed",
-				    ifp->if_xname);
-			}
-
-			for (j = 0; j < i; j++) {
-				if (xstart_gop_transfer[j].status != GNTST_okay) {
-					printf("%s GNTTABOP_transfer[%d] %d\n",
-					    ifp->if_xname,
-					    j, xstart_gop_transfer[j].status);
-					printf("%s: req_prod %u req_cons "
-					    "%u rsp_prod %u rsp_prod_pvt %u "
-					    "i %d\n",
-					    ifp->if_xname,
-					    xneti->xni_rxring.sring->req_prod,
-					    xneti->xni_rxring.req_cons,
-					    xneti->xni_rxring.sring->rsp_prod,
-					    xneti->xni_rxring.rsp_prod_pvt,
-					    i);
-					rxresp = RING_GET_RESPONSE(
-					    &xneti->xni_rxring,
-					    xneti->xni_rxring.rsp_prod_pvt + j);
-					rxresp->status = NETIF_RSP_ERROR;
-				}
-			}
-
-			/* update pointer */
-			KASSERT(
-			    xneti->xni_rxring.rsp_prod_pvt + i == resp_prod);
-			xneti->xni_rxring.rsp_prod_pvt = resp_prod;
-			RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(
-			    &xneti->xni_rxring, j);
-			if (j)
-				do_event = 1;
-			/* now we can free the mbufs */
-			for (j = 0; j < i; j++) {
-				m_freem(mbufs_sent[j]);
-			}
-			for (j = 0; j < nppitems; j++) {
-				pool_cache_put_paddr(xmit_pages_cache,
-				    (void *)pages_pool_free[j].va,
-				    pages_pool_free[j].pa);
-			}
-		}
-		/* send event */
-		if (do_event) {
-			xen_rmb();
-			XENPRINTF(("%s receive event\n",
-			    xneti->xni_if.if_xname));
-			hypervisor_notify_via_evtchn(xneti->xni_evtchn);
-			do_event = 0;
-		}
-		/* check if we need to get back some pages */
-		if (mcl_pages_alloc < 0) {
-			xennetback_get_new_mcl_pages();
-			if (mcl_pages_alloc < 0) {
-				/*
-				 * setup the watchdog to try again, because
-				 * xennetback_ifstart() will never be called
-				 * again if queue is full.
-				 */
-				printf("xennetback_ifstart: no mcl_pages\n");
-				ifp->if_timer = 1;
-				break;
-			}
-		}
-		/*
-		 * note that we don't use RING_FINAL_CHECK_FOR_REQUESTS()
-		 * here, as the frontend doesn't notify when adding
-		 * requests anyway
-		 */
-		if (__predict_false(
-		    !RING_HAS_UNCONSUMED_REQUESTS(&xneti->xni_rxring))) {
-			/* ring full */
-			break;
-		}
-	}
-	splx(s);
-}
-
 /*
  * sighly different from m_dup(); for some reason m_dup() can return
  * a chain where the data area can cross a page boundary.

Reply via email to