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;