Download raw body.
vio(4): fix control queue handling during reset
Hi,
at virtio_reset(), the features are reset, so we need to check for control
queue availability in a different way than virtio_has_feature().
After reset, we first need to re-enable the control-queue before we can
use it for configuring multiqueue. Due to the bug above, this has not been
a problem before.
ok?
Cheers,
Stefan
diff --git a/sys/dev/pv/if_vio.c b/sys/dev/pv/if_vio.c
index 8942b02857a..5a37f4b18f6 100644
--- a/sys/dev/pv/if_vio.c
+++ b/sys/dev/pv/if_vio.c
@@ -1097,38 +1097,42 @@ vio_stop(struct ifnet *ifp, int disable)
timeout_del(&sc->sc_rxtick);
/* only way to stop I/O and DMA is resetting... */
virtio_reset(vsc);
virtio_intr_barrier(vsc);
for (i = 0; i < sc->sc_nqueues; i++) {
mtx_enter(&sc->sc_q[i].viq_rxmtx);
vio_rxeof(&sc->sc_q[i]);
mtx_leave(&sc->sc_q[i].viq_rxmtx);
}
- if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
+ /*
+ * We cannot use virtio_has_feature() between virtio_reset and
+ * virtio_reinit_start()
+ */
+ if (sc->sc_ctl_vq != NULL)
vio_ctrl_wakeup(sc, RESET);
vio_tx_drain(sc);
if (disable)
vio_rx_drain(sc);
virtio_reinit_start(vsc);
for (i = 0; i < sc->sc_nqueues; i++) {
virtio_start_vq_intr(vsc, sc->sc_q[i].viq_rxvq);
virtio_stop_vq_intr(vsc, sc->sc_q[i].viq_txvq);
}
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
virtio_start_vq_intr(vsc, sc->sc_ctl_vq);
virtio_reinit_end(vsc);
- if (virtio_has_feature(vsc, VIRTIO_NET_F_MQ))
- vio_ctrl_mq(sc);
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
vio_ctrl_wakeup(sc, FREE);
+ if (virtio_has_feature(vsc, VIRTIO_NET_F_MQ))
+ vio_ctrl_mq(sc);
}
static inline uint16_t
vio_cksum_update(uint32_t cksum, uint16_t paylen)
{
/* Add payload length */
cksum += paylen;
/* Fold back to 16 bit */
cksum += cksum >> 16;
vio(4): fix control queue handling during reset