NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/60182: ld@virtio sometimes hangs up
The following reply was made to PR kern/60182; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Tetsuya Isaki <isaki%pastel-flower.jp@localhost>
Cc: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Subject: Re: kern/60182: ld@virtio sometimes hangs up
Date: Wed, 8 Apr 2026 16:05:16 +0000
This is a multi-part message in MIME format.
--=_su1OON3HGWIM8fZuEZsawKeY4iHDSE1Z
Can you please try the attached patch?
--=_su1OON3HGWIM8fZuEZsawKeY4iHDSE1Z
Content-Type: text/plain; charset="ISO-8859-1"; name="pr60182-ldvirtiopollsync"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="pr60182-ldvirtiopollsync.patch"
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1775664088 0
# Wed Apr 08 16:01:28 2026 +0000
# Branch trunk
# Node ID e970b3afe31985e3cad7f63c90d2c597a34e3d31
# Parent ae9c36e69b645ddfc9547c15bc10f8ee5f7d8f8d
# EXP-Topic riastradh-pr60182-ldvirtiopollsync
ld@virtio: Guard virtio_dequeue by virtio_vq_is_enqueued.
After triggering the DMA operation, or any previous virtio_dequeue,
virtio_vq_is_enqueued issues the necessary bus_dmamap_sync for
virtio_dequeue to observe any potential (new) result.
Normally this happens inside virtio(4) (in virtio_vq_intr) between
interrupt delivery and calling the virtqueue's done callback. But
polling mode I/O operations (and dump operations) don't take that
path, so it is necessary to call virtio_vq_is_enqueued explicitly.
PR kern/60182: ld@virtio sometimes hangs up
diff -r ae9c36e69b64 -r e970b3afe319 sys/dev/pci/ld_virtio.c
--- a/sys/dev/pci/ld_virtio.c Tue Feb 24 03:50:28 2026 +0000
+++ b/sys/dev/pci/ld_virtio.c Wed Apr 08 16:01:28 2026 +0000
@@ -492,7 +492,8 @@ ld_virtio_info(struct ld_softc *ld, bool
while (sc->sc_sync_use !=3D SYNC_FREE) {
if (poll) {
mutex_exit(&sc->sc_sync_wait_lock);
- ld_virtio_vq_done(vq);
+ if (virtio_vq_is_enqueued(vq))
+ ld_virtio_vq_done(vq);
mutex_enter(&sc->sc_sync_wait_lock);
continue;
}
@@ -558,7 +559,8 @@ done:
while (sc->sc_sync_use !=3D SYNC_DONE) {
if (poll) {
mutex_exit(&sc->sc_sync_wait_lock);
- ld_virtio_vq_done(vq);
+ if (virtio_vq_is_enqueued(vq))
+ ld_virtio_vq_done(vq);
mutex_enter(&sc->sc_sync_wait_lock);
continue;
}
@@ -767,7 +769,8 @@ ld_virtio_dump(struct ld_softc *ld, void
r =3D virtio_enqueue_prep(vsc, vq, &slot);
if (r !=3D 0) {
if (r =3D=3D EAGAIN) { /* no free slot; dequeue first */
- delay(100);
+ while (!virtio_vq_is_enqueued(vq))
+ delay(100);
ld_virtio_vq_done(vq);
r =3D virtio_enqueue_prep(vsc, vq, &slot);
if (r !=3D 0)
@@ -820,6 +823,8 @@ ld_virtio_dump(struct ld_softc *ld, void
for ( ; ; ) {
int dslot;
=20
+ while (!virtio_vq_is_enqueued(vq))
+ continue;
r =3D virtio_dequeue(vsc, vq, &dslot, NULL);
if (r !=3D 0)
continue;
@@ -905,7 +910,8 @@ ld_virtio_flush(struct ld_softc *ld, boo
while (sc->sc_sync_use !=3D SYNC_FREE) {
if (poll) {
mutex_exit(&sc->sc_sync_wait_lock);
- ld_virtio_vq_done(vq);
+ if (virtio_vq_is_enqueued(vq))
+ ld_virtio_vq_done(vq);
mutex_enter(&sc->sc_sync_wait_lock);
continue;
}
@@ -953,7 +959,8 @@ ld_virtio_flush(struct ld_softc *ld, boo
while (sc->sc_sync_use !=3D SYNC_DONE) {
if (poll) {
mutex_exit(&sc->sc_sync_wait_lock);
- ld_virtio_vq_done(vq);
+ if (virtio_vq_is_enqueued(vq))
+ ld_virtio_vq_done(vq);
mutex_enter(&sc->sc_sync_wait_lock);
continue;
}
--=_su1OON3HGWIM8fZuEZsawKeY4iHDSE1Z--
Home |
Main Index |
Thread Index |
Old Index