diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-11-11 18:45:25 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-11-11 18:45:25 +0000 |
commit | ddbc0cbc4f750587926b35b597bd3c1a0233d951 (patch) | |
tree | 7bc22035824572151d781ee55524d8b173e203e7 /sys/dev/pv | |
parent | df57cc472526807f446d178b1e134d54232f2907 (diff) |
Reorder atomic operations dealing with sc_tx_avail
The atomic decrement of the number of available descriptors must
be performed before sending the RNDIS message to the hypervisor
so that packet transmit completion that may execute in parallel
won't increase the value past the maximum.
Diffstat (limited to 'sys/dev/pv')
-rw-r--r-- | sys/dev/pv/if_hvn.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/sys/dev/pv/if_hvn.c b/sys/dev/pv/if_hvn.c index 42e70180b80..14cb3421037 100644 --- a/sys/dev/pv/if_hvn.c +++ b/sys/dev/pv/if_hvn.c @@ -120,7 +120,7 @@ TAILQ_HEAD(rndis_queue, rndis_cmd); struct hvn_tx_desc { uint32_t txd_id; - int txd_ready; + volatile int txd_ready; struct vmbus_gpa txd_sgl[HVN_TX_FRAGS + 1]; int txd_nsge; struct mbuf *txd_buf; @@ -485,9 +485,6 @@ hvn_start(struct ifnet *ifp) } sc->sc_tx_next++; - sc->sc_tx_next %= HVN_TX_DESC; - - atomic_dec_int(&sc->sc_tx_avail); ifp->if_opackets++; } @@ -524,12 +521,11 @@ hvn_encap(struct hvn_softc *sc, struct mbuf *m, struct hvn_tx_desc **txd0) size_t pktlen; int i, rv; - txd = &sc->sc_tx_desc[sc->sc_tx_next]; - while (!txd->txd_ready) { + do { + txd = &sc->sc_tx_desc[sc->sc_tx_next % HVN_TX_DESC]; sc->sc_tx_next++; - sc->sc_tx_next %= HVN_TX_DESC; - txd = &sc->sc_tx_desc[sc->sc_tx_next]; - } + } while (!txd->txd_ready); + txd->txd_ready = 0; pkt = txd->txd_req; memset(pkt, 0, sizeof(*pkt)); @@ -602,6 +598,9 @@ hvn_encap(struct hvn_softc *sc, struct mbuf *m, struct hvn_tx_desc **txd0) } *txd0 = txd; + + atomic_dec_int(&sc->sc_tx_avail); + return (0); } @@ -614,6 +613,7 @@ hvn_decap(struct hvn_softc *sc, struct hvn_tx_desc *txd) txd->txd_buf = NULL; txd->txd_nsge = 0; txd->txd_ready = 1; + atomic_inc_int(&sc->sc_tx_avail); } int |