Module Name: src Committed By: martin Date: Fri Jan 13 19:11:31 UTC 2023
Modified Files: src/sys/dev/pci [netbsd-10]: virtio.c Log Message: Pull up following revision(s) (requested by jakllsch in ticket #48): sys/dev/pci/virtio.c: revision 1.64 sys/dev/pci/virtio.c: revision 1.65 Fix dmamap_syncs more; the number of ring elements is vq->vq_num, not sc->sc_nvqs. Subtly adjust criteria for notification of Virtio devices in VIRTIO_F_RING_EVENT_IDX mode. This fixes stalls in the vioif(4) transmit path that would happen sooner or later, depending on interface transmit utilization, and were particularly noticable with a NetBSD guest transmitting to its x86 KVM host at multi-gigabit speeds. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.63.2.1 src/sys/dev/pci/virtio.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/virtio.c diff -u src/sys/dev/pci/virtio.c:1.63 src/sys/dev/pci/virtio.c:1.63.2.1 --- src/sys/dev/pci/virtio.c:1.63 Mon Oct 31 13:00:34 2022 +++ src/sys/dev/pci/virtio.c Fri Jan 13 19:11:31 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: virtio.c,v 1.63 2022/10/31 13:00:34 simonb Exp $ */ +/* $NetBSD: virtio.c,v 1.63.2.1 2023/01/13 19:11:31 martin Exp $ */ /* * Copyright (c) 2020 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.63 2022/10/31 13:00:34 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.63.2.1 2023/01/13 19:11:31 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -450,7 +450,7 @@ static inline void vq_sync_aring_all(struct virtio_softc *sc, struct virtqueue *vq, int ops) { uint16_t hdrlen = offsetof(struct vring_avail, ring); - size_t payloadlen = sc->sc_nvqs * sizeof(uint16_t); + size_t payloadlen = vq->vq_num * sizeof(uint16_t); size_t usedlen = 0; if (sc->sc_active_features & VIRTIO_F_RING_EVENT_IDX) @@ -472,7 +472,7 @@ static inline void vq_sync_aring_payload(struct virtio_softc *sc, struct virtqueue *vq, int ops) { uint16_t hdrlen = offsetof(struct vring_avail, ring); - size_t payloadlen = sc->sc_nvqs * sizeof(uint16_t); + size_t payloadlen = vq->vq_num * sizeof(uint16_t); bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap, vq->vq_availoffset + hdrlen, payloadlen, ops); @@ -482,7 +482,7 @@ static inline void vq_sync_aring_used(struct virtio_softc *sc, struct virtqueue *vq, int ops) { uint16_t hdrlen = offsetof(struct vring_avail, ring); - size_t payloadlen = sc->sc_nvqs * sizeof(uint16_t); + size_t payloadlen = vq->vq_num * sizeof(uint16_t); size_t usedlen = sizeof(uint16_t); if ((sc->sc_active_features & VIRTIO_F_RING_EVENT_IDX) == 0) @@ -495,7 +495,7 @@ static inline void vq_sync_uring_all(struct virtio_softc *sc, struct virtqueue *vq, int ops) { uint16_t hdrlen = offsetof(struct vring_used, ring); - size_t payloadlen = sc->sc_nvqs * sizeof(struct vring_used_elem); + size_t payloadlen = vq->vq_num * sizeof(struct vring_used_elem); size_t availlen = 0; if (sc->sc_active_features & VIRTIO_F_RING_EVENT_IDX) @@ -517,7 +517,7 @@ static inline void vq_sync_uring_payload(struct virtio_softc *sc, struct virtqueue *vq, int ops) { uint16_t hdrlen = offsetof(struct vring_used, ring); - size_t payloadlen = sc->sc_nvqs * sizeof(struct vring_used_elem); + size_t payloadlen = vq->vq_num * sizeof(struct vring_used_elem); bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap, vq->vq_usedoffset + hdrlen, payloadlen, ops); @@ -527,7 +527,7 @@ static inline void vq_sync_uring_avail(struct virtio_softc *sc, struct virtqueue *vq, int ops) { uint16_t hdrlen = offsetof(struct vring_used, ring); - size_t payloadlen = sc->sc_nvqs * sizeof(struct vring_used_elem); + size_t payloadlen = vq->vq_num * sizeof(struct vring_used_elem); size_t availlen = sizeof(uint16_t); if ((sc->sc_active_features & VIRTIO_F_RING_EVENT_IDX) == 0) @@ -1148,7 +1148,7 @@ notify: uint16_t o, n, t; uint16_t flags; - o = virtio_rw16(sc, vq->vq_avail->idx); + o = virtio_rw16(sc, vq->vq_avail->idx) - 1; n = vq->vq_avail_idx; /*