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/a5e8dbeb32d1
branches: trunk
changeset: 970636:a5e8dbeb32d1
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 67a6d8f4b688 -r a5e8dbeb32d1 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