Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/xen/xen batch the GNTTABOP_copy hypervisor calls in...



details:   https://anonhg.NetBSD.org/src/rev/763de40d4405
branches:  trunk
changeset: 746397:763de40d4405
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Mon Mar 30 15:31:52 2020 +0000

description:
batch the GNTTABOP_copy hypervisor calls in xvif(4) when processing
DomU requests in xennetback_evthandler()

some 25% speed increase observed over the single-copy version

diffstat:

 sys/arch/xen/xen/xennetback_xenbus.c |  155 +++++++++++++++++++++-------------
 1 files changed, 97 insertions(+), 58 deletions(-)

diffs (206 lines):

diff -r ddc632f41667 -r 763de40d4405 sys/arch/xen/xen/xennetback_xenbus.c
--- a/sys/arch/xen/xen/xennetback_xenbus.c      Mon Mar 30 13:01:39 2020 +0000
+++ b/sys/arch/xen/xen/xennetback_xenbus.c      Mon Mar 30 15:31:52 2020 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: xennetback_xenbus.c,v 1.88 2020/03/29 15:38:29 jdolecek Exp $      */
+/*      $NetBSD: xennetback_xenbus.c,v 1.89 2020/03/30 15:31:52 jdolecek Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.88 2020/03/29 15:38:29 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.89 2020/03/30 15:31:52 jdolecek Exp $");
 
 #include "opt_xen.h"
 
@@ -178,6 +178,10 @@
        vaddr_t va;
        paddr_t pa;
 } pages_pool_free[NB_XMIT_PAGES_BATCH];
+static struct _req_info {
+       int id;
+       int flags;
+} xstart_req[NB_XMIT_PAGES_BATCH];
 
 
 void
@@ -718,6 +722,71 @@
        return NULL;
 }
 
+static void
+xennetback_tx_copy_process(struct ifnet *ifp, struct xnetback_instance *xneti,
+       int queued)
+{
+       int i = 0;
+       gnttab_copy_t *gop;
+       struct mbuf *m;
+       struct _req_info *req;
+
+       /*
+        * Copy the data and ack it. Delaying it until the mbuf is
+        * freed will stall transmit.
+        */
+       if (HYPERVISOR_grant_table_op(GNTTABOP_copy, xstart_gop_copy, queued)
+           != 0) {
+               printf("%s: GNTTABOP_copy failed", ifp->if_xname);
+               goto abort;
+       }
+
+       for (; i < queued; i++) {
+               gop = &xstart_gop_copy[i];
+               m = mbufs_sent[i];
+               req = &xstart_req[i];
+
+               if (gop->status != GNTST_okay) {
+                       printf("%s GNTTABOP_copy[%d] %d\n",
+                           ifp->if_xname, i, gop->status);
+                       goto abort;
+               }
+
+               xennetback_tx_response(xneti, req->id, NETIF_RSP_OKAY);
+
+               if ((ifp->if_flags & IFF_PROMISC) == 0) {
+                       struct ether_header *eh =
+                           mtod(m, struct ether_header *);
+                       if (ETHER_IS_MULTICAST(eh->ether_dhost) == 0 &&
+                           memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost,
+                           ETHER_ADDR_LEN) != 0) {
+                               m_freem(m);
+                               continue; /* packet is not for us */
+                       }
+               }
+
+               if (req->flags & NETTXF_csum_blank)
+                       xennet_checksum_fill(ifp, m);
+               else if (req->flags & NETTXF_data_validated)
+                       m->m_pkthdr.csum_flags = XN_M_CSUM_SUPPORTED;
+               m_set_rcvif(m, ifp);
+
+               if_percpuq_enqueue(ifp->if_percpuq, m);
+       }
+
+       return;
+
+abort:
+       for (; i < queued; i++) {
+               m = mbufs_sent[i];
+               req = &xstart_req[i];
+
+               m_freem(m);
+               xennetback_tx_response(xneti, req->id, NETIF_RSP_ERROR);
+               if_statinc(ifp, if_ierrors);
+       }
+}
+
 static int
 xennetback_evthandler(void *arg)
 {
@@ -727,9 +796,9 @@
        struct mbuf *m;
        int receive_pending;
        RING_IDX req_cons;
-       gnttab_copy_t gop;
+       gnttab_copy_t *gop;
        paddr_t pa;
-       int offset;
+       int offset, queued = 0;
 
        XENPRINTF(("xennetback_evthandler "));
        req_cons = xneti->xni_txring.req_cons;
@@ -796,68 +865,38 @@
                    xneti->xni_if.if_xname, txreq.offset,
                    txreq.size, txreq.id, MASK_NETIF_TX_IDX(req_cons)));
 
-               /*
-                * Copy the data and ack it. Delaying it until the mbuf is
-                * freed will stall transmit.
-                */
                xennetback_mbuf_addr(m, &pa, &offset);
-               memset(&gop, 0, sizeof(gop));
-               gop.flags = GNTCOPY_source_gref;
-               gop.len = txreq.size;
 
-               gop.source.u.ref = txreq.gref;
-               gop.source.offset = txreq.offset;
-               gop.source.domid = xneti->xni_domid;
-
-               gop.dest.offset = offset;
-               gop.dest.domid = DOMID_SELF;
-               gop.dest.u.gmfn = xpmap_ptom(pa) >> PAGE_SHIFT;
+               /* Queue for the copy */
+               gop = &xstart_gop_copy[queued];
+               memset(gop, 0, sizeof(*gop));
+               gop->flags = GNTCOPY_source_gref;
+               gop->len = txreq.size;
 
-               if (HYPERVISOR_grant_table_op(GNTTABOP_copy,
-                   &gop, 1) != 0) {
-                       printf("%s: GNTTABOP_copy failed",
-                           ifp->if_xname);
-                       m_freem(m);
-                       xennetback_tx_response(xneti, txreq.id,
-                           NETIF_RSP_ERROR);
-                       if_statinc(ifp, if_ierrors);
-                       continue;
-               }
-               if (gop.status != GNTST_okay) {
-                       printf("%s GNTTABOP_copy %d\n",
-                           ifp->if_xname, gop.status);
-                       m_freem(m);
-                       xennetback_tx_response(xneti, txreq.id,
-                           NETIF_RSP_ERROR);
-                       if_statinc(ifp, if_ierrors);
-                       continue;
-               }
+               gop->source.u.ref = txreq.gref;
+               gop->source.offset = txreq.offset;
+               gop->source.domid = xneti->xni_domid;
 
-               if ((ifp->if_flags & IFF_PROMISC) == 0) {
-                       struct ether_header *eh =
-                           mtod(m, struct ether_header *);
-                       if (ETHER_IS_MULTICAST(eh->ether_dhost) == 0 &&
-                           memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost,
-                           ETHER_ADDR_LEN) != 0) {
-                               m_freem(m);
-                               xennetback_tx_response(xneti, txreq.id,
-                                   NETIF_RSP_OKAY);
-                               continue; /* packet is not for us */
-                       }
-               }
+               gop->dest.offset = offset;
+               gop->dest.domid = DOMID_SELF;
+               gop->dest.u.gmfn = xpmap_ptom(pa) >> PAGE_SHIFT;
 
                m->m_len = m->m_pkthdr.len = txreq.size;
-               xennetback_tx_response(xneti, txreq.id,
-                   NETIF_RSP_OKAY);
+               mbufs_sent[queued] = m;
+
+               xstart_req[queued].id = txreq.id;
+               xstart_req[queued].flags = txreq.flags;
+
+               queued++;
 
-               if (txreq.flags & NETTXF_csum_blank)
-                       xennet_checksum_fill(ifp, m);
-               else if (txreq.flags & NETTXF_data_validated)
-                       m->m_pkthdr.csum_flags = XN_M_CSUM_SUPPORTED;
-               m_set_rcvif(m, ifp);
-
-               if_percpuq_enqueue(ifp->if_percpuq, m);
+               KASSERT(queued <= NB_XMIT_PAGES_BATCH);
+               if (queued == NB_XMIT_PAGES_BATCH) {
+                       xennetback_tx_copy_process(ifp, xneti, queued);
+                       queued = 0;
+               }
        }
+       if (queued > 0)
+               xennetback_tx_copy_process(ifp, xneti, queued);
        xen_rmb(); /* be sure to read the request before updating pointer */
        xneti->xni_txring.req_cons = req_cons;
        xen_wmb();



Home | Main Index | Thread Index | Old Index