Module Name:    src
Committed By:   yamaguchi
Date:           Thu Oct 21 05:37:43 UTC 2021

Modified Files:
        src/sys/dev/pci: virtio.c virtio_pci.c virtiovar.h

Log Message:
virtio: reconfigure MSI-X vector on re-initialization

This may fix a problem that some interrupts, for example
link-state change of vioif(4) are not notified.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/dev/pci/virtio.c
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/pci/virtio_pci.c
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/pci/virtiovar.h

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.50 src/sys/dev/pci/virtio.c:1.51
--- src/sys/dev/pci/virtio.c:1.50	Thu Oct 21 05:32:27 2021
+++ src/sys/dev/pci/virtio.c	Thu Oct 21 05:37:43 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: virtio.c,v 1.50 2021/10/21 05:32:27 yamaguchi Exp $	*/
+/*	$NetBSD: virtio.c,v 1.51 2021/10/21 05:37:43 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.50 2021/10/21 05:32:27 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.51 2021/10/21 05:37:43 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -93,7 +93,7 @@ virtio_reset(struct virtio_softc *sc)
 void
 virtio_reinit_start(struct virtio_softc *sc)
 {
-	int i;
+	int i, r;
 
 	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
 	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
@@ -112,6 +112,12 @@ virtio_reinit_start(struct virtio_softc 
 		sc->sc_ops->setup_queue(sc, vq->vq_index,
 		    vq->vq_dmamap->dm_segs[0].ds_addr);
 	}
+
+	r = sc->sc_ops->setup_interrupts(sc, 1);
+	if (r != 0) {
+		printf("%s: failed to setup interrupts\n",
+		    device_xname(sc->sc_dev));
+	}
 }
 
 void
@@ -1205,7 +1211,7 @@ virtio_child_attach_finish(struct virtio
 		goto fail;
 	}
 
-	r = sc->sc_ops->setup_interrupts(sc);
+	r = sc->sc_ops->setup_interrupts(sc, 0);
 	if (r != 0) {
 		aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n");
 	}

Index: src/sys/dev/pci/virtio_pci.c
diff -u src/sys/dev/pci/virtio_pci.c:1.31 src/sys/dev/pci/virtio_pci.c:1.32
--- src/sys/dev/pci/virtio_pci.c:1.31	Thu Oct 21 05:32:27 2021
+++ src/sys/dev/pci/virtio_pci.c	Thu Oct 21 05:37:43 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: virtio_pci.c,v 1.31 2021/10/21 05:32:27 yamaguchi Exp $ */
+/* $NetBSD: virtio_pci.c,v 1.32 2021/10/21 05:37:43 yamaguchi Exp $ */
 
 /*
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.31 2021/10/21 05:32:27 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.32 2021/10/21 05:37:43 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -112,8 +112,8 @@ static int	virtio_pci_adjust_config_regi
 static int	virtio_pci_intr(void *arg);
 static int	virtio_pci_msix_queue_intr(void *);
 static int	virtio_pci_msix_config_intr(void *);
-static int	virtio_pci_setup_interrupts_09(struct virtio_softc *);
-static int	virtio_pci_setup_interrupts_10(struct virtio_softc *);
+static int	virtio_pci_setup_interrupts_09(struct virtio_softc *, int);
+static int	virtio_pci_setup_interrupts_10(struct virtio_softc *, int);
 static int	virtio_pci_establish_msix_interrupts(struct virtio_softc *,
 		    struct pci_attach_args *);
 static int	virtio_pci_establish_intx_interrupt(struct virtio_softc *,
@@ -805,7 +805,7 @@ virtio_pci_negotiate_features_10(struct 
  * -------------------------------------*/
 
 static int
-virtio_pci_setup_interrupts_10(struct virtio_softc *sc)
+virtio_pci_setup_interrupts_10(struct virtio_softc *sc, int reinit)
 {
 	struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
 	device_t self          =  sc->sc_dev;
@@ -821,7 +821,10 @@ virtio_pci_setup_interrupts_10(struct vi
 		VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR, vector);
 	ret = bus_space_read_2(iot, ioh, VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR);
 	if (ret != vector) {
-		aprint_error_dev(self, "can't set config msix vector\n");
+		if (reinit == 0) {
+			aprint_error_dev(self,
+			    "can't set config msix vector\n");
+		}
 		return -1;
 	}
 
@@ -836,8 +839,10 @@ virtio_pci_setup_interrupts_10(struct vi
 		ret = bus_space_read_2(iot, ioh,
 			VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR);
 		if (ret != vector) {
-			aprint_error_dev(self, "can't set queue %d "
-				"msix vector\n", qid);
+			if (reinit == 0) {
+				aprint_error_dev(self, "can't set queue %d "
+				    "msix vector\n", qid);
+			}
 			return -1;
 		}
 	}
@@ -846,7 +851,7 @@ virtio_pci_setup_interrupts_10(struct vi
 }
 
 static int
-virtio_pci_setup_interrupts_09(struct virtio_softc *sc)
+virtio_pci_setup_interrupts_09(struct virtio_softc *sc, int reinit)
 {
 	struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
 	device_t self = sc->sc_dev;
@@ -863,7 +868,10 @@ virtio_pci_setup_interrupts_09(struct vi
 	aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
 	    vector, ret);
 	if (ret != vector) {
-		aprint_error_dev(self, "can't set config msix vector\n");
+		if (reinit == 0) {
+			aprint_error_dev(self,
+			    "can't set config msix vector\n");
+		}
 		return -1;
 	}
 
@@ -882,8 +890,10 @@ virtio_pci_setup_interrupts_09(struct vi
 		aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
 		    vector, ret);
 		if (ret != vector) {
-			aprint_error_dev(self, "can't set queue %d "
-				"msix vector\n", qid);
+			if (reinit == 0) {
+				aprint_error_dev(self, "can't set queue %d "
+				    "msix vector\n", qid);
+			}
 			return -1;
 		}
 	}

Index: src/sys/dev/pci/virtiovar.h
diff -u src/sys/dev/pci/virtiovar.h:1.21 src/sys/dev/pci/virtiovar.h:1.22
--- src/sys/dev/pci/virtiovar.h:1.21	Thu Oct 21 05:32:27 2021
+++ src/sys/dev/pci/virtiovar.h	Thu Oct 21 05:37:43 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: virtiovar.h,v 1.21 2021/10/21 05:32:27 yamaguchi Exp $	*/
+/*	$NetBSD: virtiovar.h,v 1.22 2021/10/21 05:37:43 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -141,7 +141,7 @@ struct virtio_ops {
 	void		(*neg_features)(struct virtio_softc *, uint64_t);
 	int		(*alloc_interrupts)(struct virtio_softc *);
 	void		(*free_interrupts)(struct virtio_softc *);
-	int		(*setup_interrupts)(struct virtio_softc *);
+	int		(*setup_interrupts)(struct virtio_softc *, int);
 };
 
 struct virtio_softc {

Reply via email to