summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2016-07-29 22:25:29 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2016-07-29 22:25:29 +0000
commit334d21078e591638e8e545ff0f28e787fa79b885 (patch)
treeca20947fd1dcb561652e3626bc2e5ad230706976 /sys/dev
parente16a4063b55e8a1da62de0375465f9f2a12d9214 (diff)
Add a periodic timer to workaround missing completion events
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pv/if_xnf.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/sys/dev/pv/if_xnf.c b/sys/dev/pv/if_xnf.c
index 15fa81e5499..ecea2b248b7 100644
--- a/sys/dev/pv/if_xnf.c
+++ b/sys/dev/pv/if_xnf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_xnf.c,v 1.28 2016/07/29 22:01:57 mikeb Exp $ */
+/* $OpenBSD: if_xnf.c,v 1.29 2016/07/29 22:25:28 mikeb Exp $ */
/*
* Copyright (c) 2015, 2016 Mike Belopuhov
@@ -158,6 +158,7 @@ struct xnf_softc {
struct ifmedia sc_media;
xen_intr_handle_t sc_xih;
+ struct timeout sc_timer;
int sc_caps;
#define XNF_CAP_SG 0x0001
@@ -176,7 +177,6 @@ struct xnf_softc {
struct mbuf *sc_rx_buf[XNF_RX_DESC];
bus_dmamap_t sc_rx_dmap[XNF_RX_DESC]; /* maps for packets */
struct mbuf *sc_rx_cbuf[2]; /* chain handling */
- struct timeout sc_rx_fill;
/* Tx ring */
struct xnf_tx_ring *sc_tx_ring;
@@ -201,6 +201,7 @@ void xnf_stop(struct xnf_softc *);
void xnf_start(struct ifnet *);
int xnf_encap(struct xnf_softc *, struct mbuf *, uint32_t *);
void xnf_intr(void *);
+void xnf_timer(void *);
void xnf_watchdog(struct ifnet *);
int xnf_txeof(struct xnf_softc *);
int xnf_rxeof(struct xnf_softc *);
@@ -309,7 +310,7 @@ xnf_attach(struct device *parent, struct device *self, void *aux)
if_attach(ifp);
ether_ifattach(ifp);
- timeout_set(&sc->sc_rx_fill, xnf_rx_ring_fill, sc);
+ timeout_set(&sc->sc_timer, xnf_timer, sc);
/* Kick out emulated em's and re's */
sc->sc_xen->sc_flags |= XSF_UNPLUG_NIC;
@@ -442,7 +443,7 @@ xnf_stop(struct xnf_softc *sc)
xen_intr_mask(sc->sc_xih);
- timeout_del(&sc->sc_rx_fill);
+ timeout_del(&sc->sc_timer);
ifp->if_timer = 0;
ifq_barrier(&ifp->if_snd);
@@ -611,10 +612,21 @@ xnf_intr(void *arg)
if (ifp->if_flags & IFF_RUNNING) {
xnf_rxeof(sc);
xnf_txeof(sc);
+ timeout_add(&sc->sc_timer, 10);
}
}
void
+xnf_timer(void *arg)
+{
+ struct xnf_softc *sc = arg;
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
+
+ if (ifp->if_flags & IFF_RUNNING)
+ xen_intr_schedule(sc->sc_xih);
+}
+
+void
xnf_watchdog(struct ifnet *ifp)
{
struct xnf_softc *sc = ifp->if_softc;
@@ -773,9 +785,7 @@ xnf_rx_ring_fill(void *arg)
bus_dmamap_t dmap;
struct mbuf *m;
uint32_t cons, prod, oprod;
- int i, flags, s;
-
- s = splnet();
+ int i, flags;
cons = rxr->rxr_cons;
prod = oprod = rxr->rxr_prod;
@@ -804,12 +814,10 @@ xnf_rx_ring_fill(void *arg)
bus_dmamap_sync(sc->sc_dmat, sc->sc_rx_rmap, 0, 0,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if ((prod - cons < XNF_RX_DESC) && (ifp->if_flags & IFF_RUNNING))
- timeout_add(&sc->sc_rx_fill, 10);
+ if ((prod - cons < XNF_RX_MIN) && (ifp->if_flags & IFF_RUNNING))
+ xen_intr_schedule(sc->sc_xih);
if (prod - rxr->rxr_prod_event < prod - oprod)
xen_intr_signal(sc->sc_xih);
-
- splx(s);
}
int