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 xennetback(4): Fix xennetback_evthandler loop.
details: https://anonhg.NetBSD.org/src/rev/9987aaf6694a
branches: trunk
changeset: 373719:9987aaf6694a
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Feb 25 00:34:13 2023 +0000
description:
xennetback(4): Fix xennetback_evthandler loop.
- After observing the other side has produced pending tx requests by
reading sring->req_prod, must issue xen_rmb before touching them.
Despite all the effort to use the heavy-weight
RING_FINAL_CHECK_FOR_REQUESTS on each request in the loop, this
barrier was missing.
- No need to update req_cons at each iteration in the loop. It's
private. Just update it once at the end.
- After consuming requests, must issue xen_wmb before releasing the
slots with RING_FINAL_CHECK_FOR_REQUEST for the other side to
reuse.
XXX pullup-8 (requires patch; at least add xen_rmb between
RING_FINAL_CHECK_FOR_REQUESTS and RING_COPY_REQUEST)
XXX pullup-9 (requires patch; at least add xen_rmb between
RING_FINAL_CHECK_FOR_REQUESTS and RING_COPY_REQUEST)
XXX pullup-10
diffstat:
sys/arch/xen/xen/xennetback_xenbus.c | 25 +++++++++++++------------
1 files changed, 13 insertions(+), 12 deletions(-)
diffs (62 lines):
diff -r c416f9775bfe -r 9987aaf6694a sys/arch/xen/xen/xennetback_xenbus.c
--- a/sys/arch/xen/xen/xennetback_xenbus.c Sat Feb 25 00:34:01 2023 +0000
+++ b/sys/arch/xen/xen/xennetback_xenbus.c Sat Feb 25 00:34:13 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xennetback_xenbus.c,v 1.108 2022/09/02 23:48:10 thorpej Exp $ */
+/* $NetBSD: xennetback_xenbus.c,v 1.109 2023/02/25 00:34:13 riastradh Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.108 2022/09/02 23:48:10 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.109 2023/02/25 00:34:13 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -805,7 +805,7 @@
netif_tx_request_t txreq;
struct mbuf *m, *m0 = NULL, *mlast = NULL;
int receive_pending;
- RING_IDX req_cons;
+ RING_IDX req_cons, req_prod;
int queued = 0, m0_len = 0;
struct xnetback_xstate *xst;
const bool discard = ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
@@ -813,17 +813,12 @@
XENPRINTF(("xennetback_evthandler "));
req_cons = xneti->xni_txring.req_cons;
- while (1) {
- xen_rmb(); /* be sure to read the request before updating */
- xneti->xni_txring.req_cons = req_cons;
- xen_wmb();
- RING_FINAL_CHECK_FOR_REQUESTS(&xneti->xni_txring,
- receive_pending);
- if (receive_pending == 0)
- break;
+again:
+ req_prod = xneti->xni_txring.sring->req_prod;
+ xen_rmb();
+ while (req_cons != req_prod) {
RING_COPY_REQUEST(&xneti->xni_txring, req_cons,
&txreq);
- xen_rmb();
XENPRINTF(("%s pkt size %d\n", xneti->xni_if.if_xname,
txreq.size));
req_cons++;
@@ -962,6 +957,12 @@
queued = 0;
}
}
+ xen_wmb();
+ RING_FINAL_CHECK_FOR_REQUESTS(&xneti->xni_txring, receive_pending);
+ if (receive_pending)
+ goto again;
+ xneti->xni_txring.req_cons = req_cons;
+
if (m0) {
/* Queue empty, and still unfinished multi-fragment request */
printf("%s: dropped unfinished multi-fragment\n",
Home |
Main Index |
Thread Index |
Old Index