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



At Wed, 8 Apr 2026 16:05:16 +0000,
Taylor R Campbell wrote:
> Can you please try the attached patch?

Thank you for looking into it.

(By the way, the patch had syntax errors.
 - virtio_vq_is_enqueued(vq)
 + virtio_vq_is_enqueued(vsc, vq)
But it's trivial and doesn't matter.  I attached the correct one.)

Let's get back to the main topic.
It still hanged up.

virtio_vq_is_enqueued() issues POSTREAD for vq->vq_used region
((mainly?) in order to invalidate the cache),
But, on 68030, POSTREAD is nop (and PREREAD invalidates the cache).
See _bus_dmamap_sync_30() in sys/arch/m68k/m68k/bus_dma.c .
---
Tetsuya Isaki <isaki%pastel-flower.jp@localhost / isaki%NetBSD.org@localhost>

--- sys/dev/pci/ld_virtio.c
+++ sys/dev/pci/ld_virtio.c
@@ -502,7 +502,8 @@ ld_virtio_info(struct ld_softc *ld, bool poll)
 	while (sc->sc_sync_use != SYNC_FREE) {
 		if (poll) {
 			mutex_exit(&sc->sc_sync_wait_lock);
-			ld_virtio_vq_done(vq);
+			if (virtio_vq_is_enqueued(vsc, vq))
+				ld_virtio_vq_done(vq);
 			mutex_enter(&sc->sc_sync_wait_lock);
 			continue;
 		}
@@ -568,7 +569,8 @@ done:
 	while (sc->sc_sync_use != SYNC_DONE) {
 		if (poll) {
 			mutex_exit(&sc->sc_sync_wait_lock);
-			ld_virtio_vq_done(vq);
+			if (virtio_vq_is_enqueued(vsc, vq))
+				ld_virtio_vq_done(vq);
 			mutex_enter(&sc->sc_sync_wait_lock);
 			continue;
 		}
@@ -777,7 +779,8 @@ ld_virtio_dump(struct ld_softc *ld, void *data, daddr_t blkno, int blkcnt)
 	r = virtio_enqueue_prep(vsc, vq, &slot);
 	if (r != 0) {
 		if (r == EAGAIN) { /* no free slot; dequeue first */
-			delay(100);
+			while (!virtio_vq_is_enqueued(vsc, vq))
+				delay(100);
 			ld_virtio_vq_done(vq);
 			r = virtio_enqueue_prep(vsc, vq, &slot);
 			if (r != 0)
@@ -830,6 +833,8 @@ ld_virtio_dump(struct ld_softc *ld, void *data, daddr_t blkno, int blkcnt)
 	for ( ; ; ) {
 		int dslot;
 
+		while (!virtio_vq_is_enqueued(vsc, vq))
+			continue;
 		r = virtio_dequeue(vsc, vq, &dslot, NULL);
 		if (r != 0)
 			continue;
@@ -915,7 +920,8 @@ ld_virtio_flush(struct ld_softc *ld, bool poll)
 	while (sc->sc_sync_use != SYNC_FREE) {
 		if (poll) {
 			mutex_exit(&sc->sc_sync_wait_lock);
-			ld_virtio_vq_done(vq);
+			if (virtio_vq_is_enqueued(vsc, vq))
+				ld_virtio_vq_done(vq);
 			mutex_enter(&sc->sc_sync_wait_lock);
 			continue;
 		}
@@ -963,7 +969,8 @@ ld_virtio_flush(struct ld_softc *ld, bool poll)
 	while (sc->sc_sync_use != SYNC_DONE) {
 		if (poll) {
 			mutex_exit(&sc->sc_sync_wait_lock);
-			ld_virtio_vq_done(vq);
+			if (virtio_vq_is_enqueued(vsc, vq))
+				ld_virtio_vq_done(vq);
 			mutex_enter(&sc->sc_sync_wait_lock);
 			continue;
 		}



Home | Main Index | Thread Index | Old Index