Wed Aug 9 08:38:16 2023 UTC ()
xvif(4): Move expensive xen_mb out of xennetback_evthandler loop.

Use the cheaper RING_HAS_UNCONFIRMED_REQUESTS for most of the loop.

This should improve throughput without any impact on correctness.


(riastradh)
diff -r1.118 -r1.119 src/sys/arch/xen/xen/xennetback_xenbus.c

cvs diff -r1.118 -r1.119 src/sys/arch/xen/xen/xennetback_xenbus.c (expand / switch to unified diff)

--- src/sys/arch/xen/xen/xennetback_xenbus.c 2023/08/09 08:38:05 1.118
+++ src/sys/arch/xen/xen/xennetback_xenbus.c 2023/08/09 08:38:16 1.119
@@ -1,41 +1,41 @@ @@ -1,41 +1,41 @@
1/* $NetBSD: xennetback_xenbus.c,v 1.118 2023/08/09 08:38:05 riastradh Exp $ */ 1/* $NetBSD: xennetback_xenbus.c,v 1.119 2023/08/09 08:38:16 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Manuel Bouyer. 4 * Copyright (c) 2006 Manuel Bouyer.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27#include <sys/cdefs.h> 27#include <sys/cdefs.h>
28__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.118 2023/08/09 08:38:05 riastradh Exp $"); 28__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.119 2023/08/09 08:38:16 riastradh Exp $");
29 29
30#include <sys/types.h> 30#include <sys/types.h>
31#include <sys/param.h> 31#include <sys/param.h>
32#include <sys/systm.h> 32#include <sys/systm.h>
33#include <sys/kmem.h> 33#include <sys/kmem.h>
34#include <sys/queue.h> 34#include <sys/queue.h>
35#include <sys/kernel.h> 35#include <sys/kernel.h>
36#include <sys/mbuf.h> 36#include <sys/mbuf.h>
37#include <sys/protosw.h> 37#include <sys/protosw.h>
38#include <sys/socket.h> 38#include <sys/socket.h>
39#include <sys/ioctl.h> 39#include <sys/ioctl.h>
40#include <sys/errno.h> 40#include <sys/errno.h>
41#include <sys/device.h> 41#include <sys/device.h>
@@ -801,44 +801,36 @@ static int @@ -801,44 +801,36 @@ static int
801xennetback_evthandler(void *arg) 801xennetback_evthandler(void *arg)
802{ 802{
803 struct xnetback_instance *xneti = arg; 803 struct xnetback_instance *xneti = arg;
804 struct ifnet *ifp = &xneti->xni_if; 804 struct ifnet *ifp = &xneti->xni_if;
805 netif_tx_request_t txreq; 805 netif_tx_request_t txreq;
806 struct mbuf *m, *m0 = NULL, *mlast = NULL; 806 struct mbuf *m, *m0 = NULL, *mlast = NULL;
807 int receive_pending; 807 int receive_pending;
808 int queued = 0, m0_len = 0; 808 int queued = 0, m0_len = 0;
809 struct xnetback_xstate *xst; 809 struct xnetback_xstate *xst;
810 const bool discard = ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) != 810 const bool discard = ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
811 (IFF_UP | IFF_RUNNING)); 811 (IFF_UP | IFF_RUNNING));
812 812
813 XENPRINTF(("xennetback_evthandler ")); 813 XENPRINTF(("xennetback_evthandler "));
 814again:
814 while (1) { 815 while (1) {
815 /* 816 /*
816 * XXX The xen_rmb here and comment make no sense: 817 * XXX The xen_rmb here and comment make no sense:
817 * xneti->xni_txring.req_cons is a private variable. 818 * xneti->xni_txring.req_cons is a private variable.
818 */ 819 */
819 xen_rmb(); /* be sure to read the request before updating */ 820 xen_rmb(); /* be sure to read the request before updating */
820 /* XXX Unclear what this xen_wmb is for. */ 821 /* XXX Unclear what this xen_wmb is for. */
821 xen_wmb(); 822 xen_wmb();
822 /* 823 if (!RING_HAS_UNCONSUMED_REQUESTS(&xneti->xni_txring))
823 * XXX RING_FINAL_CHECK_FOR_REQUESTS issues the most 
824 * expensive memory barrier, xen_mb. This should be 
825 * used only at the end of the loop after we updating 
826 * the producer with the last index of the requests we 
827 * consumed in the queue. 
828 */ 
829 RING_FINAL_CHECK_FOR_REQUESTS(&xneti->xni_txring, 
830 receive_pending); 
831 if (receive_pending == 0) 
832 break; 824 break;
833 /* 825 /*
834 * Ensure we have read the producer's queue index in 826 * Ensure we have read the producer's queue index in
835 * RING_FINAL_CHECK_FOR_REQUESTS before we read the 827 * RING_FINAL_CHECK_FOR_REQUESTS before we read the
836 * content of the producer's next request in 828 * content of the producer's next request in
837 * RING_COPY_REQUEST. 829 * RING_COPY_REQUEST.
838 */ 830 */
839 xen_rmb(); 831 xen_rmb();
840 RING_COPY_REQUEST(&xneti->xni_txring, 832 RING_COPY_REQUEST(&xneti->xni_txring,
841 xneti->xni_txring.req_cons, 833 xneti->xni_txring.req_cons,
842 &txreq); 834 &txreq);
843 /* XXX Unclear what this xen_rmb is for. */ 835 /* XXX Unclear what this xen_rmb is for. */
844 xen_rmb(); 836 xen_rmb();
@@ -971,26 +963,29 @@ mbuf_fail: @@ -971,26 +963,29 @@ mbuf_fail:
971 963
972 KASSERT(queued <= NB_XMIT_PAGES_BATCH); 964 KASSERT(queued <= NB_XMIT_PAGES_BATCH);
973 if (__predict_false(m0 && 965 if (__predict_false(m0 &&
974 (txreq.flags & NETTXF_more_data) == 0)) { 966 (txreq.flags & NETTXF_more_data) == 0)) {
975 /* Last fragment, stop appending mbufs */ 967 /* Last fragment, stop appending mbufs */
976 m0 = NULL; 968 m0 = NULL;
977 } 969 }
978 if (queued == NB_XMIT_PAGES_BATCH) { 970 if (queued == NB_XMIT_PAGES_BATCH) {
979 KASSERT(m0 == NULL); 971 KASSERT(m0 == NULL);
980 xennetback_tx_copy_process(ifp, xneti, queued); 972 xennetback_tx_copy_process(ifp, xneti, queued);
981 queued = 0; 973 queued = 0;
982 } 974 }
983 } 975 }
 976 RING_FINAL_CHECK_FOR_REQUESTS(&xneti->xni_txring, receive_pending);
 977 if (receive_pending)
 978 goto again;
984 if (m0) { 979 if (m0) {
985 /* Queue empty, and still unfinished multi-fragment request */ 980 /* Queue empty, and still unfinished multi-fragment request */
986 printf("%s: dropped unfinished multi-fragment\n", 981 printf("%s: dropped unfinished multi-fragment\n",
987 ifp->if_xname); 982 ifp->if_xname);
988 xennetback_tx_copy_abort(ifp, xneti, queued); 983 xennetback_tx_copy_abort(ifp, xneti, queued);
989 queued = 0; 984 queued = 0;
990 m0 = NULL; 985 m0 = NULL;
991 } 986 }
992 if (queued > 0) 987 if (queued > 0)
993 xennetback_tx_copy_process(ifp, xneti, queued); 988 xennetback_tx_copy_process(ifp, xneti, queued);
994 989
995 /* check to see if we can transmit more packets */ 990 /* check to see if we can transmit more packets */
996 if_schedule_deferred_start(ifp); 991 if_schedule_deferred_start(ifp);