Module Name: src Committed By: jdolecek Date: Sun Mar 29 15:35:31 UTC 2020
Modified Files: src/sys/arch/xen/xen: xennetback_xenbus.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.86 -r1.87 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.86 src/sys/arch/xen/xen/xennetback_xenbus.c:1.87 --- src/sys/arch/xen/xen/xennetback_xenbus.c:1.86 Fri Mar 27 18:37:30 2020 +++ src/sys/arch/xen/xen/xennetback_xenbus.c Sun Mar 29 15:35:31 2020 @@ -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 @@ extern pt_entry_t xpmap_pg_nx; /* 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 void xennetback_frontend_changed( 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 @@ static struct _pages_pool_free { } 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 @@ xvifattach(int n) 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 @@ xennetback_tx_check_packet(const netif_t 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 @@ xennetback_evthandler(void *arg) 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 @@ xennetback_evthandler(void *arg) 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); + NETIF_RSP_ERROR); 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); + 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); - pool_put(&xni_pkt_pool, pkt); - m_freem(m); 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 @@ xennetback_evthandler(void *arg) } } - /* - * 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);