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 in xennetback_evthandler() just copy the Do...



details:   https://anonhg.NetBSD.org/src/rev/406e41e24afa
branches:  trunk
changeset: 1008630:406e41e24afa
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Sun Mar 29 15:35:31 2020 +0000

description:
in xennetback_evthandler() just copy the DomU packet into destination
mbuf via hypervisor GNTTABOP_copy op instead of mapping the buffer into
Dom0 memory

no performance difference observed for now - it would probably make more
difference if Dom0 was MP, or when Dom0 is under VM pressure

this will eventually be updated to batch copy the DomU packets

diffstat:

 sys/arch/xen/xen/xennetback_xenbus.c |  121 +++++++++++++++-------------------
 1 files changed, 52 insertions(+), 69 deletions(-)

diffs (211 lines):

diff -r 523bb6d55fb4 -r 406e41e24afa sys/arch/xen/xen/xennetback_xenbus.c
--- a/sys/arch/xen/xen/xennetback_xenbus.c      Sun Mar 29 14:58:22 2020 +0000
+++ b/sys/arch/xen/xen/xennetback_xenbus.c      Sun Mar 29 15:35:31 2020 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: xennetback_xenbus.c,v 1.86 2020/03/27 18:37:30 jdolecek Exp $      */
+/*      $NetBSD: xennetback_xenbus.c,v 1.87 2020/03/29 15:35:31 jdolecek Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.86 2020/03/27 18:37:30 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.87 2020/03/29 15:35:31 jdolecek Exp $");
 
 #include "opt_xen.h"
 
@@ -79,16 +79,6 @@
 /* linux wants at last 16 bytes free in front of the packet */
 #define LINUX_REQUESTED_OFFSET 16
 
-/* hash list for TX requests */
-/* descriptor of a packet being handled by the kernel */
-struct xni_pkt {
-       int pkt_id; /* packet's ID */
-       grant_handle_t pkt_handle;
-       struct xnetback_instance *pkt_xneti; /* pointer back to our softc */
-};
-
-/* pools for xni_pkt */
-struct pool xni_pkt_pool;
 /* ratecheck(9) for pool allocation failures */
 static const struct timeval xni_pool_errintvl = { 30, 0 };  /* 30s, each */
 
@@ -141,6 +131,7 @@
 
 static inline void xennetback_tx_response(struct xnetback_instance *,
     int, int);
+static void xennetback_mbuf_addr(struct mbuf *, paddr_t *, int *);
 #if 0  /* XXX */
 static void xennetback_tx_free(struct mbuf * , void *, size_t, void *);
 #endif /* XXX */
@@ -192,13 +183,6 @@
 } pages_pool_free[NB_XMIT_PAGES_BATCH];
 
 
-static inline void
-xni_pkt_unmap(struct xni_pkt *pkt, vaddr_t pkt_va)
-{
-       xen_shm_unmap(pkt_va, 1, &pkt->pkt_handle);
-       pool_put(&xni_pkt_pool, pkt);
-}
-
 void
 xvifattach(int n)
 {
@@ -223,8 +207,6 @@
        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);
 
@@ -732,6 +714,10 @@
        if (__predict_false(txreq->size > maxlen))
                return "too big";
 
+       /* Somewhat duplicit, MCLBYTES is > ETHER_MAX_LEN */
+       if (__predict_false(txreq->size > MCLBYTES))
+               return "bigger than MCLBYTES";
+
        return NULL;
 }
 
@@ -741,11 +727,12 @@
        struct xnetback_instance *xneti = arg;
        struct ifnet *ifp = &xneti->xni_if;
        netif_tx_request_t txreq;
-       struct xni_pkt *pkt;
-       vaddr_t pkt_va;
        struct mbuf *m;
-       int receive_pending, err;
+       int receive_pending;
        RING_IDX req_cons;
+       gnttab_copy_t gop;
+       paddr_t pa;
+       int offset;
 
        XENPRINTF(("xennetback_evthandler "));
        req_cons = xneti->xni_txring.req_cons;
@@ -797,52 +784,64 @@
                        if_statinc(ifp, if_ierrors);
                        continue;
                }
+               if (txreq.size > MHLEN) {
+                       MCLGET(m, M_DONTWAIT);
+                       if (__predict_false(m->m_ext_storage.ext_buf == NULL)) {
+                               m_freem(m);
+                               xennetback_tx_response(xneti, txreq.id,
+                                   NETIF_RSP_DROPPED);
+                               if_statinc(ifp, if_ierrors);
+                               continue;
+                       }
+               }
 
                XENPRINTF(("%s pkt offset %d size %d id %d req_cons %d\n",
                    xneti->xni_if.if_xname, txreq.offset,
                    txreq.size, txreq.id, MASK_NETIF_TX_IDX(req_cons)));
 
-               pkt = pool_get(&xni_pkt_pool, PR_NOWAIT);
-               if (__predict_false(pkt == NULL)) {
-                       static struct timeval lasttime;
-                       if (ratecheck(&lasttime, &xni_pool_errintvl))
-                               printf("%s: xnbpkt alloc failed\n",
-                                   ifp->if_xname);
-                       xennetback_tx_response(xneti, txreq.id,
-                           NETIF_RSP_DROPPED);
-                       if_statinc(ifp, if_ierrors);
+               /*
+                * 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;
+
+               if (HYPERVISOR_grant_table_op(GNTTABOP_copy,
+                   &gop, 1) != 0) {
+                       printf("%s: GNTTABOP_copy failed",
+                           ifp->if_xname);
                        m_freem(m);
-                       continue;
-               }
-               err = xen_shm_map(1, xneti->xni_domid, &txreq.gref, &pkt_va,
-                   &pkt->pkt_handle, XSHM_RO);
-               if (__predict_false(err == ENOMEM)) {
-                       xennetback_tx_response(xneti, txreq.id,
-                           NETIF_RSP_DROPPED);
-                       if_statinc(ifp, if_ierrors);
-                       pool_put(&xni_pkt_pool, pkt);
-                       m_freem(m);
-                       continue;
-               }
-
-               if (__predict_false(err)) {
-                       printf("%s: mapping foreing page failed: %d\n",
-                           xneti->xni_if.if_xname, err);
                        xennetback_tx_response(xneti, txreq.id,
                            NETIF_RSP_ERROR);
                        if_statinc(ifp, if_ierrors);
-                       pool_put(&xni_pkt_pool, pkt);
+                       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;
                }
 
                if ((ifp->if_flags & IFF_PROMISC) == 0) {
                        struct ether_header *eh =
-                           (void*)(pkt_va + txreq.offset);
+                           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) {
-                               xni_pkt_unmap(pkt, pkt_va);
                                m_freem(m);
                                xennetback_tx_response(xneti, txreq.id,
                                    NETIF_RSP_OKAY);
@@ -850,23 +849,7 @@
                        }
                }
 
-               /*
-                * This is the last TX buffer. Copy the data and
-                * ack it. Delaying it until the mbuf is
-                * freed will stall transmit.
-                */
-               m->m_len = uimin(MHLEN, txreq.size);
-               m->m_pkthdr.len = 0;
-               m_copyback(m, 0, txreq.size,
-                   (void *)(pkt_va + txreq.offset));
-               xni_pkt_unmap(pkt, pkt_va);
-               if (m->m_pkthdr.len < txreq.size) {
-                       if_statinc(ifp, if_ierrors);
-                       m_freem(m);
-                       xennetback_tx_response(xneti, txreq.id,
-                           NETIF_RSP_DROPPED);
-                       continue;
-               }
+               m->m_len = m->m_pkthdr.len = txreq.size;
                xennetback_tx_response(xneti, txreq.id,
                    NETIF_RSP_OKAY);
 



Home | Main Index | Thread Index | Old Index