Module Name:    src
Committed By:   yamaguchi
Date:           Thu Mar 23 03:27:48 UTC 2023

Modified Files:
        src/sys/dev/pci: if_vioif.c ld_virtio.c vio9p.c viomb.c viornd.c
            vioscsi.c virtio.c virtio_pci.c virtiovar.h
        src/sys/dev/virtio: viocon.c

Log Message:
Set virtqueues in virtio_child_attach_finish

The number of virtqueue maybe change in a part of VirtIO devices
(e.g. vioif(4)). And it is fixed after negotiation of features.
So the configuration is moved into the function.


To generate a diff of this commit:
cvs rdiff -u -r1.102 -r1.103 src/sys/dev/pci/if_vioif.c
cvs rdiff -u -r1.30 -r1.31 src/sys/dev/pci/ld_virtio.c \
    src/sys/dev/pci/vioscsi.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/pci/vio9p.c
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/pci/viomb.c
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/pci/viornd.c
cvs rdiff -u -r1.65 -r1.66 src/sys/dev/pci/virtio.c
cvs rdiff -u -r1.38 -r1.39 src/sys/dev/pci/virtio_pci.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/pci/virtiovar.h
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/virtio/viocon.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/if_vioif.c
diff -u src/sys/dev/pci/if_vioif.c:1.102 src/sys/dev/pci/if_vioif.c:1.103
--- src/sys/dev/pci/if_vioif.c:1.102	Thu Mar 23 03:02:17 2023
+++ src/sys/dev/pci/if_vioif.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vioif.c,v 1.102 2023/03/23 03:02:17 yamaguchi Exp $	*/
+/*	$NetBSD: if_vioif.c,v 1.103 2023/03/23 03:27:48 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.102 2023/03/23 03:02:17 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.103 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -465,7 +465,7 @@ vioif_attach(device_t parent, device_t s
 	u_int softint_flags;
 	int r, i, req_flags;
 	char xnamebuf[MAXCOMLEN];
-	size_t netq_num;
+	size_t nvqs;
 
 	if (virtio_child(vsc) != NULL) {
 		aprint_normal(": child already attached for %s; "
@@ -509,11 +509,11 @@ vioif_attach(device_t parent, device_t s
 #ifdef VIOIF_MULTIQ
 	req_features |= VIRTIO_NET_F_MQ;
 #endif
-	virtio_child_attach_start(vsc, self, IPL_NET, NULL,
-	    vioif_config_change, virtio_vq_intrhand, req_flags,
-	    req_features, VIRTIO_NET_FLAG_BITS);
 
+	virtio_child_attach_start(vsc, self, IPL_NET,
+	    req_features, VIRTIO_NET_FLAG_BITS);
 	features = virtio_features(vsc);
+
 	if (features == 0)
 		goto err;
 
@@ -565,10 +565,12 @@ vioif_attach(device_t parent, device_t s
 
 		/* Limit the number of queue pairs to use */
 		sc->sc_req_nvq_pairs = MIN(sc->sc_max_nvq_pairs, ncpu);
+
+		if (sc->sc_max_nvq_pairs > 1)
+			req_flags |= VIRTIO_F_INTR_PERVQ;
 	}
 
 	vioif_alloc_queues(sc);
-	virtio_child_attach_set_vqs(vsc, sc->sc_vqs, sc->sc_req_nvq_pairs);
 
 #ifdef VIOIF_MPSAFE
 	softint_flags = SOFTINT_NET | SOFTINT_MPSAFE;
@@ -579,15 +581,17 @@ vioif_attach(device_t parent, device_t s
 	/*
 	 * Initialize network queues
 	 */
-	netq_num = sc->sc_max_nvq_pairs * 2;
-	for (i = 0; i < netq_num; i++) {
+	nvqs = sc->sc_max_nvq_pairs * 2;
+	for (i = 0; i < nvqs; i++) {
 		r = vioif_netqueue_init(sc, vsc, i, softint_flags);
 		if (r != 0)
 			goto err;
 	}
 
 	if (sc->sc_has_ctrl) {
-		int ctrlq_idx = sc->sc_max_nvq_pairs * 2;
+		int ctrlq_idx = nvqs;
+
+		nvqs++;
 		/*
 		 * Allocating a virtqueue for control channel
 		 */
@@ -618,7 +622,9 @@ vioif_attach(device_t parent, device_t s
 	if (vioif_alloc_mems(sc) < 0)
 		goto err;
 
-	if (virtio_child_attach_finish(vsc) != 0)
+	r = virtio_child_attach_finish(vsc, sc->sc_vqs, nvqs,
+	    vioif_config_change, virtio_vq_intrhand, req_flags);
+	if (r != 0)
 		goto err;
 
 	if (vioif_setup_sysctl(sc) != 0) {
@@ -656,8 +662,8 @@ vioif_attach(device_t parent, device_t s
 	return;
 
 err:
-	netq_num = sc->sc_max_nvq_pairs * 2;
-	for (i = 0; i < netq_num; i++) {
+	nvqs = sc->sc_max_nvq_pairs * 2;
+	for (i = 0; i < nvqs; i++) {
 		vioif_netqueue_teardown(sc, vsc, i);
 	}
 

Index: src/sys/dev/pci/ld_virtio.c
diff -u src/sys/dev/pci/ld_virtio.c:1.30 src/sys/dev/pci/ld_virtio.c:1.31
--- src/sys/dev/pci/ld_virtio.c:1.30	Wed Apr 13 10:42:12 2022
+++ src/sys/dev/pci/ld_virtio.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_virtio.c,v 1.30 2022/04/13 10:42:12 uwe Exp $	*/
+/*	$NetBSD: ld_virtio.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.30 2022/04/13 10:42:12 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -275,8 +275,7 @@ ld_virtio_attach(device_t parent, device
 	sc->sc_dev = self;
 	sc->sc_virtio = vsc;
 
-	virtio_child_attach_start(vsc, self, IPL_BIO, &sc->sc_vq,
-	    NULL, virtio_vq_intr, VIRTIO_F_INTR_MSIX,
+	virtio_child_attach_start(vsc, self, IPL_BIO,
 	    (VIRTIO_BLK_F_SIZE_MAX | VIRTIO_BLK_F_SEG_MAX |
 	     VIRTIO_BLK_F_GEOMETRY | VIRTIO_BLK_F_RO | VIRTIO_BLK_F_BLK_SIZE |
 	     VIRTIO_BLK_F_FLUSH | VIRTIO_BLK_F_CONFIG_WCE),
@@ -340,7 +339,8 @@ ld_virtio_attach(device_t parent, device
 	qsize = sc->sc_vq.vq_num;
 	sc->sc_vq.vq_done = ld_virtio_vq_done;
 
-	if (virtio_child_attach_finish(vsc) != 0)
+	if (virtio_child_attach_finish(vsc, &sc->sc_vq, 1,
+	    NULL, virtio_vq_intr, VIRTIO_F_INTR_MSIX) != 0)
 		goto err;
 
 	ld->sc_dv = self;
Index: src/sys/dev/pci/vioscsi.c
diff -u src/sys/dev/pci/vioscsi.c:1.30 src/sys/dev/pci/vioscsi.c:1.31
--- src/sys/dev/pci/vioscsi.c:1.30	Tue Oct 11 22:03:37 2022
+++ src/sys/dev/pci/vioscsi.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: vioscsi.c,v 1.30 2022/10/11 22:03:37 andvar Exp $	*/
+/*	$NetBSD: vioscsi.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $	*/
 /*	$OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $	*/
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.30 2022/10/11 22:03:37 andvar Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -128,8 +128,7 @@ vioscsi_attach(device_t parent, device_t
 
 	sc->sc_dev = self;
 
-	virtio_child_attach_start(vsc, self, ipl, sc->sc_vqs,
-	    NULL, virtio_vq_intr, VIRTIO_F_INTR_MSIX,
+	virtio_child_attach_start(vsc, self, ipl,
 	    0, VIRTIO_COMMON_FLAG_BITS);
 
 	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, ipl);
@@ -171,7 +170,9 @@ vioscsi_attach(device_t parent, device_t
 	    " max_lun %u\n",
 	    cmd_per_lun, qsize, seg_max, max_target, max_lun);
 
-	if (virtio_child_attach_finish(vsc) != 0)
+	if (virtio_child_attach_finish(vsc, sc->sc_vqs,
+	    __arraycount(sc->sc_vqs), NULL, virtio_vq_intr,
+	    VIRTIO_F_INTR_MSIX) != 0)
 		goto err;
 
 	/*

Index: src/sys/dev/pci/vio9p.c
diff -u src/sys/dev/pci/vio9p.c:1.9 src/sys/dev/pci/vio9p.c:1.10
--- src/sys/dev/pci/vio9p.c:1.9	Wed Apr 20 22:08:10 2022
+++ src/sys/dev/pci/vio9p.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: vio9p.c,v 1.9 2022/04/20 22:08:10 uwe Exp $	*/
+/*	$NetBSD: vio9p.c,v 1.10 2023/03/23 03:27:48 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2019 Internet Initiative Japan, Inc.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vio9p.c,v 1.9 2022/04/20 22:08:10 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vio9p.c,v 1.10 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -500,11 +500,8 @@ vio9p_attach(device_t parent, device_t s
 	sc->sc_dev = self;
 	sc->sc_virtio = vsc;
 
-	virtio_child_attach_start(vsc, self, IPL_VM, sc->sc_vq,
-	    NULL, virtio_vq_intr,
-	    VIRTIO_F_INTR_MPSAFE | VIRTIO_F_INTR_SOFTINT,
-	    VIO9P_F_MOUNT_TAG,
-	    VIO9P_FLAG_BITS);
+	virtio_child_attach_start(vsc, self, IPL_VM,
+	    VIO9P_F_MOUNT_TAG, VIO9P_FLAG_BITS);
 
 	features = virtio_features(vsc);
 	if ((features & VIO9P_F_MOUNT_TAG) == 0)
@@ -517,8 +514,6 @@ vio9p_attach(device_t parent, device_t s
 
 	sc->sc_vq[0].vq_done = vio9p_request_done;
 
-	virtio_child_attach_set_vqs(vsc, sc->sc_vq, 1);
-
 	sc->sc_buf_tx = kmem_alloc(VIO9P_MAX_REQLEN, KM_SLEEP);
 	sc->sc_buf_rx = kmem_alloc(VIO9P_MAX_REQLEN, KM_SLEEP);
 
@@ -559,7 +554,9 @@ vio9p_attach(device_t parent, device_t s
 	vio9p_read_config(sc);
 	aprint_normal_dev(self, "tagged as %s\n", sc->sc_tag);
 
-	error = virtio_child_attach_finish(vsc);
+	error = virtio_child_attach_finish(vsc, sc->sc_vq,
+	    __arraycount(sc->sc_vq), NULL, virtio_vq_intr,
+	    VIRTIO_F_INTR_MPSAFE | VIRTIO_F_INTR_SOFTINT);
 	if (error != 0)
 		goto err_mutex;
 

Index: src/sys/dev/pci/viomb.c
diff -u src/sys/dev/pci/viomb.c:1.13 src/sys/dev/pci/viomb.c:1.14
--- src/sys/dev/pci/viomb.c:1.13	Wed Apr 13 10:42:12 2022
+++ src/sys/dev/pci/viomb.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: viomb.c,v 1.13 2022/04/13 10:42:12 uwe Exp $	*/
+/*	$NetBSD: viomb.c,v 1.14 2023/03/23 03:27:48 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.13 2022/04/13 10:42:12 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.14 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -148,8 +148,7 @@ viomb_attach(device_t parent, device_t s
 	sc->sc_dev = self;
 	sc->sc_virtio = vsc;
 
-	virtio_child_attach_start(vsc, self, IPL_VM, sc->sc_vq,
-	    viomb_config_change, virtio_vq_intr, 0,
+	virtio_child_attach_start(vsc, self, IPL_VM,
 	    VIRTIO_BALLOON_F_MUST_TELL_HOST, VIRTIO_BALLOON_FLAG_BITS);
 
 	features = virtio_features(vsc);
@@ -190,7 +189,8 @@ viomb_attach(device_t parent, device_t s
 		goto err_dmamap;
 	}
 
-	if (virtio_child_attach_finish(vsc) != 0)
+	if (virtio_child_attach_finish(vsc, sc->sc_vq, __arraycount(sc->sc_vq),
+	    viomb_config_change, virtio_vq_intr, 0) != 0)
 		goto err_out;
 
 	if (kthread_create(PRI_IDLE, KTHREAD_MPSAFE, NULL,

Index: src/sys/dev/pci/viornd.c
diff -u src/sys/dev/pci/viornd.c:1.18 src/sys/dev/pci/viornd.c:1.19
--- src/sys/dev/pci/viornd.c:1.18	Thu Apr 14 19:47:14 2022
+++ src/sys/dev/pci/viornd.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/* 	$NetBSD: viornd.c,v 1.18 2022/04/14 19:47:14 riastradh Exp $ */
+/* 	$NetBSD: viornd.c,v 1.19 2023/03/23 03:27:48 yamaguchi Exp $ */
 /*	$OpenBSD: viornd.c,v 1.1 2014/01/21 21:14:58 sf Exp $	*/
 
 /*
@@ -176,8 +176,7 @@ viornd_attach(device_t parent, device_t 
 		goto load_failed;
 	}
 
-	virtio_child_attach_start(vsc, self, IPL_NET, &sc->sc_vq,
-	    NULL, virtio_vq_intr, 0,
+	virtio_child_attach_start(vsc, self, IPL_NET,
 	    0, VIRTIO_COMMON_FLAG_BITS);
 
 	error = virtio_alloc_vq(vsc, &sc->sc_vq, 0, VIORND_BUFSIZE, 1,
@@ -189,7 +188,9 @@ viornd_attach(device_t parent, device_t 
 	}
 	sc->sc_vq.vq_done = viornd_vq_done;
 
-	if (virtio_child_attach_finish(vsc) != 0) {
+	error = virtio_child_attach_finish(vsc, &sc->sc_vq, 1,
+	    NULL, virtio_vq_intr, 0);
+	if (error) {
 		virtio_free_vq(vsc, &sc->sc_vq);
 		goto vio_failed;
 	}

Index: src/sys/dev/pci/virtio.c
diff -u src/sys/dev/pci/virtio.c:1.65 src/sys/dev/pci/virtio.c:1.66
--- src/sys/dev/pci/virtio.c:1.65	Tue Jan  3 19:33:31 2023
+++ src/sys/dev/pci/virtio.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: virtio.c,v 1.65 2023/01/03 19:33:31 jakllsch Exp $	*/
+/*	$NetBSD: virtio.c,v 1.66 2023/03/23 03:27:48 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.65 2023/01/03 19:33:31 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.66 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -762,9 +762,6 @@ virtio_alloc_vq(struct virtio_softc *sc,
 	int rsegs, r, hdrlen;
 #define VIRTQUEUE_ALIGN(n)	roundup(n, VIRTIO_PAGE_SIZE)
 
-	/* Make sure callers allocate vqs in order */
-	KASSERT(sc->sc_nvqs == index);
-
 	memset(vq, 0, sizeof(*vq));
 
 	vq_size = sc->sc_ops->read_queue_size(sc, index);
@@ -864,8 +861,6 @@ virtio_alloc_vq(struct virtio_softc *sc,
 		    "using %d byte (%d entries) indirect descriptors\n",
 		    allocsize3, maxnsegs * vq_size);
 
-	sc->sc_nvqs++;
-
 	return 0;
 
 err:
@@ -913,8 +908,6 @@ virtio_free_vq(struct virtio_softc *sc, 
 	mutex_destroy(&vq->vq_aring_lock);
 	memset(vq, 0, sizeof(*vq));
 
-	sc->sc_nvqs--;
-
 	return 0;
 }
 
@@ -1270,19 +1263,12 @@ virtio_dequeue_commit(struct virtio_soft
  */
 void
 virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl,
-    struct virtqueue *vqs,
-    virtio_callback config_change,
-    virtio_callback intr_hand,
-    int req_flags, int req_features, const char *feat_bits)
+    uint64_t req_features, const char *feat_bits)
 {
 	char buf[1024];
 
 	sc->sc_child = child;
 	sc->sc_ipl = ipl;
-	sc->sc_vqs = vqs;
-	sc->sc_config_change = config_change;
-	sc->sc_intrhand = intr_hand;
-	sc->sc_flags = req_flags;
 
 	virtio_negotiate_features(sc, req_features);
 	snprintb(buf, sizeof(buf), feat_bits, sc->sc_active_features);
@@ -1290,25 +1276,35 @@ virtio_child_attach_start(struct virtio_
 	aprint_naive("\n");
 }
 
-void
-virtio_child_attach_set_vqs(struct virtio_softc *sc,
-    struct virtqueue *vqs, int nvq_pairs)
-{
-
-	KASSERT(nvq_pairs == 1 ||
-	    (sc->sc_flags & VIRTIO_F_INTR_SOFTINT) == 0);
-	if (nvq_pairs > 1)
-		sc->sc_child_mq = true;
-
-	sc->sc_vqs = vqs;
-}
-
 int
-virtio_child_attach_finish(struct virtio_softc *sc)
+virtio_child_attach_finish(struct virtio_softc *sc,
+    struct virtqueue *vqs, size_t nvqs,
+    virtio_callback config_change, virtio_callback intr_hand,
+    int req_flags)
 {
 	int r;
 
+#ifdef DIAGNOSTIC
+	KASSERT(nvqs > 0);
+#define VIRTIO_ASSERT_FLAGS	(VIRTIO_F_INTR_SOFTINT | VIRTIO_F_INTR_PERVQ)
+	KASSERT((req_flags & VIRTIO_ASSERT_FLAGS) != VIRTIO_ASSERT_FLAGS);
+#undef VIRTIO_ASSERT_FLAGS
+
+	for (size_t _i = 0; _i < nvqs; _i++){
+		KASSERT(vqs[_i].vq_index == _i);
+		KASSERT((req_flags & VIRTIO_F_INTR_PERVQ) == 0 ||
+		    vqs[_i].vq_intrhand != NULL);
+	}
+#endif
+
 	sc->sc_finished_called = true;
+
+	sc->sc_vqs = vqs;
+	sc->sc_nvqs = nvqs;
+	sc->sc_config_change = config_change;
+	sc->sc_intrhand = intr_hand;
+	sc->sc_flags = req_flags;
+
 	r = sc->sc_ops->alloc_interrupts(sc);
 	if (r != 0) {
 		aprint_error_dev(sc->sc_dev,

Index: src/sys/dev/pci/virtio_pci.c
diff -u src/sys/dev/pci/virtio_pci.c:1.38 src/sys/dev/pci/virtio_pci.c:1.39
--- src/sys/dev/pci/virtio_pci.c:1.38	Mon May 30 20:28:18 2022
+++ src/sys/dev/pci/virtio_pci.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: virtio_pci.c,v 1.38 2022/05/30 20:28:18 riastradh Exp $ */
+/* $NetBSD: virtio_pci.c,v 1.39 2023/03/23 03:27:48 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.38 2022/05/30 20:28:18 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.39 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -73,6 +73,7 @@ static int	virtio_pci_detach(device_t, i
 				sizeof(pcireg_t))
 struct virtio_pci_softc {
 	struct virtio_softc	sc_sc;
+	bool			sc_intr_pervq;
 
 	/* IO space */
 	bus_space_tag_t		sc_iot;
@@ -629,7 +630,7 @@ virtio_pci_setup_queue_09(struct virtio_
 
 	if (psc->sc_ihs_num > 1) {
 		int vec = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-		if (sc->sc_child_mq)
+		if (psc->sc_intr_pervq)
 			vec += idx;
 		bus_space_write_2(psc->sc_iot, psc->sc_ioh,
 		    VIRTIO_CONFIG_MSI_QUEUE_VECTOR, vec);
@@ -751,7 +752,7 @@ virtio_pci_setup_queue_10(struct virtio_
 
 	if (psc->sc_ihs_num > 1) {
 		int vec = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-		if (sc->sc_child_mq)
+		if (psc->sc_intr_pervq)
 			vec += idx;
 		bus_space_write_2(iot, ioh,
 			VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR, vec);
@@ -849,7 +850,7 @@ virtio_pci_setup_interrupts_10(struct vi
 	for (qid = 0; qid < sc->sc_nvqs; qid++) {
 		vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
 
-		if (sc->sc_child_mq)
+		if (psc->sc_intr_pervq)
 			vector += qid;
 		bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_SELECT, qid);
 		bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR,
@@ -895,7 +896,7 @@ virtio_pci_setup_interrupts_09(struct vi
 		offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR;
 		vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
 
-		if (sc->sc_child_mq)
+		if (psc->sc_intr_pervq)
 			vector += qid;
 
 		bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, vector);
@@ -941,7 +942,7 @@ virtio_pci_establish_msix_interrupts(str
 	}
 
 	idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-	if (sc->sc_child_mq) {
+	if (psc->sc_intr_pervq) {
 		for (qid = 0; qid < sc->sc_nvqs; qid++) {
 			n = idx + qid;
 			vq = &sc->sc_vqs[qid];
@@ -979,7 +980,7 @@ virtio_pci_establish_msix_interrupts(str
 	intrstr = pci_intr_string(pc, psc->sc_ihp[idx], intrbuf, sizeof(intrbuf));
 	aprint_normal_dev(self, "config interrupting at %s\n", intrstr);
 	idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-	if (sc->sc_child_mq) {
+	if (psc->sc_intr_pervq) {
 		kcpuset_t *affinity;
 		int affinity_to, r;
 
@@ -1019,7 +1020,7 @@ error:
 	if (psc->sc_ihs[idx] != NULL)
 		pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[idx]);
 	idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-	if (sc->sc_child_mq) {
+	if (psc->sc_intr_pervq) {
 		for (qid = 0; qid < sc->sc_nvqs; qid++) {
 			n = idx + qid;
 			if (psc->sc_ihs[n] == NULL)
@@ -1085,13 +1086,10 @@ virtio_pci_alloc_interrupts(struct virti
 		counts[PCI_INTR_TYPE_INTX] = 1;
 	} else {
 		/* Try MSI-X first and INTx second */
-		if (sc->sc_nvqs + VIRTIO_MSIX_QUEUE_VECTOR_INDEX <= nmsix) {
+		if (ISSET(sc->sc_flags, VIRTIO_F_INTR_PERVQ) &&
+		    sc->sc_nvqs + VIRTIO_MSIX_QUEUE_VECTOR_INDEX <= nmsix) {
 			nmsix = sc->sc_nvqs + VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
 		} else {
-			sc->sc_child_mq = false;
-		}
-
-		if (sc->sc_child_mq == false) {
 			nmsix = 2;
 		}
 
@@ -1109,6 +1107,7 @@ retry:
 	}
 
 	if (pci_intr_type(pc, psc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX) {
+		psc->sc_intr_pervq = nmsix > 2 ? true : false;
 		psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * nmsix,
 		    KM_SLEEP);
 
@@ -1127,6 +1126,7 @@ retry:
 		psc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI;
 		virtio_pci_adjust_config_region(psc);
 	} else if (pci_intr_type(pc, psc->sc_ihp[0]) == PCI_INTR_TYPE_INTX) {
+		psc->sc_intr_pervq = false;
 		psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * 1,
 		    KM_SLEEP);
 
@@ -1149,6 +1149,8 @@ retry:
 		}
 	}
 
+	if (!psc->sc_intr_pervq)
+		CLR(sc->sc_flags, VIRTIO_F_INTR_PERVQ);
 	return 0;
 }
 

Index: src/sys/dev/pci/virtiovar.h
diff -u src/sys/dev/pci/virtiovar.h:1.24 src/sys/dev/pci/virtiovar.h:1.25
--- src/sys/dev/pci/virtiovar.h:1.24	Thu Mar 24 08:08:05 2022
+++ src/sys/dev/pci/virtiovar.h	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: virtiovar.h,v 1.24 2022/03/24 08:08:05 andvar Exp $	*/
+/*	$NetBSD: virtiovar.h,v 1.25 2023/03/23 03:27:48 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -171,7 +171,6 @@ struct virtio_softc {
 
 	int			sc_childdevid;
 	device_t		sc_child; 		/* set by child */
-	bool			sc_child_mq;
 	virtio_callback		sc_config_change; 	/* set by child */
 	virtio_callback		sc_intrhand;		/* set by child */
 };
@@ -184,6 +183,7 @@ struct virtio_softc;
 #define VIRTIO_F_INTR_MPSAFE	(1 << 0)
 #define VIRTIO_F_INTR_SOFTINT	(1 << 1)
 #define VIRTIO_F_INTR_MSIX	(1 << 2)
+#define VIRTIO_F_INTR_PERVQ	(1 << 3)
 
 
 #define	VIRTIO_CHILD_FAILED		((void *)1)
@@ -211,12 +211,10 @@ void virtio_reset(struct virtio_softc *)
 int virtio_reinit_start(struct virtio_softc *);
 void virtio_reinit_end(struct virtio_softc *);
 void virtio_child_attach_start(struct virtio_softc *, device_t, int,
-                    struct virtqueue *,
-                    virtio_callback, virtio_callback, int,
-		    int, const char *);
-void virtio_child_attach_set_vqs(struct virtio_softc *,
-                    struct virtqueue *, int);
-int virtio_child_attach_finish(struct virtio_softc *);
+		    uint64_t, const char *);
+int virtio_child_attach_finish(struct virtio_softc *,
+		    struct virtqueue *, size_t,
+		    virtio_callback, virtio_callback, int);
 void virtio_child_attach_failed(struct virtio_softc *);
 void virtio_child_detach(struct virtio_softc *);
 

Index: src/sys/dev/virtio/viocon.c
diff -u src/sys/dev/virtio/viocon.c:1.5 src/sys/dev/virtio/viocon.c:1.6
--- src/sys/dev/virtio/viocon.c:1.5	Sat Aug 13 17:31:32 2022
+++ src/sys/dev/virtio/viocon.c	Thu Mar 23 03:27:48 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: viocon.c,v 1.5 2022/08/13 17:31:32 riastradh Exp $	*/
+/*	$NetBSD: viocon.c,v 1.6 2023/03/23 03:27:48 yamaguchi Exp $	*/
 /*	$OpenBSD: viocon.c,v 1.8 2021/11/05 11:38:29 mpi Exp $	*/
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: viocon.c,v 1.5 2022/08/13 17:31:32 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: viocon.c,v 1.6 2023/03/23 03:27:48 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -209,10 +209,8 @@ viocon_attach(struct device *parent, str
 	sc->sc_ports = kmem_zalloc(maxports * sizeof(sc->sc_ports[0]),
 	    KM_SLEEP);
 
-	virtio_child_attach_start(vsc, self, IPL_TTY, sc->sc_vqs,
-	    /*config_change*/NULL, virtio_vq_intr,
-	    /*req_flags*/0, /*req_features*/VIRTIO_CONSOLE_F_SIZE,
-	    VIRTIO_CONSOLE_FLAG_BITS);
+	virtio_child_attach_start(vsc, self, IPL_TTY,
+	    /*req_features*/VIRTIO_CONSOLE_F_SIZE, VIRTIO_CONSOLE_FLAG_BITS);
 
 	DPRINTF("%s: softc: %p\n", __func__, sc);
 	if (viocon_port_create(sc, 0) != 0) {
@@ -221,7 +219,8 @@ viocon_attach(struct device *parent, str
 	}
 	viocon_rx_fill(sc->sc_ports[0]);
 
-	if (virtio_child_attach_finish(vsc) != 0)
+	if (virtio_child_attach_finish(vsc, sc->sc_vqs, sc->sc_max_ports * 2,
+	    /*config_change*/NULL, virtio_vq_intr, /*req_flags*/0) != 0)
 		goto err;
 
 	return;

Reply via email to