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