From: sf Date: Mon, 2 Sep 2024 08:26:26 +0000 (+0000) Subject: virtio: Move interrupt setup into separate function X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=0e6436ede63d0b2b0d20985927c7f42ddcbaea8f;p=openbsd virtio: Move interrupt setup into separate function Put the MSIX vector into struct virtqueue and create a transport specific function that feeds the vectors to the device. This will allow child devices to influence which vectors are used for which virtqueues. This will be used by multi-queue vio(4) to route corresponding rx/tx queue interrupts to the same cpu. The setup_intrs() function also sets the config interrupt MSIX vector which fixes a bug that virtio_pci_set_msix_config_vector() would not be called after a device reset. OK bluhm@ --- diff --git a/sys/dev/fdt/virtio_mmio.c b/sys/dev/fdt/virtio_mmio.c index 212614f98ff..604ffcab570 100644 --- a/sys/dev/fdt/virtio_mmio.c +++ b/sys/dev/fdt/virtio_mmio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio_mmio.c,v 1.16 2024/08/27 19:01:11 sf Exp $ */ +/* $OpenBSD: virtio_mmio.c,v 1.17 2024/09/02 08:26:26 sf Exp $ */ /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ /* @@ -97,6 +97,7 @@ void virtio_mmio_write_device_config_4(struct virtio_softc *, int, uint32_t); void virtio_mmio_write_device_config_8(struct virtio_softc *, int, uint64_t); uint16_t virtio_mmio_read_queue_size(struct virtio_softc *, uint16_t); void virtio_mmio_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t); +void virtio_mmio_setup_intrs(struct virtio_softc *); int virtio_mmio_get_status(struct virtio_softc *); void virtio_mmio_set_status(struct virtio_softc *, int); int virtio_mmio_negotiate_features(struct virtio_softc *, @@ -145,6 +146,7 @@ const struct virtio_ops virtio_mmio_ops = { virtio_mmio_write_device_config_8, virtio_mmio_read_queue_size, virtio_mmio_setup_queue, + virtio_mmio_setup_intrs, virtio_mmio_get_status, virtio_mmio_set_status, virtio_mmio_negotiate_features, @@ -196,6 +198,11 @@ virtio_mmio_setup_queue(struct virtio_softc *vsc, struct virtqueue *vq, } } +void +virtio_mmio_setup_intrs(struct virtio_softc *vsc) +{ +} + int virtio_mmio_get_status(struct virtio_softc *vsc) { diff --git a/sys/dev/pci/virtio_pci.c b/sys/dev/pci/virtio_pci.c index fe137db8632..4a0c9037cf7 100644 --- a/sys/dev/pci/virtio_pci.c +++ b/sys/dev/pci/virtio_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio_pci.c,v 1.41 2024/09/02 08:22:08 sf Exp $ */ +/* $OpenBSD: virtio_pci.c,v 1.42 2024/09/02 08:26:26 sf Exp $ */ /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ /* @@ -73,6 +73,7 @@ void virtio_pci_write_device_config_4(struct virtio_softc *, int, uint32_t); void virtio_pci_write_device_config_8(struct virtio_softc *, int, uint64_t); uint16_t virtio_pci_read_queue_size(struct virtio_softc *, uint16_t); void virtio_pci_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t); +void virtio_pci_setup_intrs(struct virtio_softc *); int virtio_pci_get_status(struct virtio_softc *); void virtio_pci_set_status(struct virtio_softc *, int); int virtio_pci_negotiate_features(struct virtio_softc *, const struct virtio_feature_name *); @@ -169,6 +170,7 @@ const struct virtio_ops virtio_pci_ops = { virtio_pci_write_device_config_8, virtio_pci_read_queue_size, virtio_pci_setup_queue, + virtio_pci_setup_intrs, virtio_pci_get_status, virtio_pci_set_status, virtio_pci_negotiate_features, @@ -271,23 +273,23 @@ virtio_pci_setup_queue(struct virtio_softc *vsc, struct virtqueue *vq, bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_ADDRESS, addr / VIRTIO_PAGE_SIZE); } +} - /* - * This path is only executed if this function is called after - * the child's attach function has finished. In other cases, - * it's done in virtio_pci_setup_msix(). - */ - if (sc->sc_irq_type != IRQ_NO_MSIX) { - int vec = 1; - if (sc->sc_irq_type == IRQ_MSIX_PER_VQ) - vec += vq->vq_index; - if (sc->sc_sc.sc_version_1) { - CWRITE(sc, queue_msix_vector, vec); - } else { - bus_space_write_2(sc->sc_iot, sc->sc_ioh, - VIRTIO_MSI_QUEUE_VECTOR, vec); - } +void +virtio_pci_setup_intrs(struct virtio_softc *vsc) +{ + struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; + int i; + + if (sc->sc_irq_type == IRQ_NO_MSIX) + return; + + for (i = 0; i <= vsc->sc_nvqs; i++) { + unsigned vec = vsc->sc_vqs[i].vq_intr_vec; + virtio_pci_set_msix_queue_vector(sc, i, vec); } + if (vsc->sc_config_change) + virtio_pci_set_msix_config_vector(sc, 0); } int @@ -699,6 +701,7 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux) goto fail_2; } } + virtio_pci_setup_intrs(vsc); printf("%s: %s\n", vsc->sc_dev.dv_xname, intrstr); return; @@ -1029,7 +1032,6 @@ virtio_pci_setup_msix(struct virtio_pci_softc *sc, return 1; sc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI; virtio_pci_adjust_config_region(sc); - virtio_pci_set_msix_config_vector(sc, 0); if (shared) { if (virtio_pci_msix_establish(sc, vpa, 1, @@ -1038,14 +1040,14 @@ virtio_pci_setup_msix(struct virtio_pci_softc *sc, } for (i = 0; i < vsc->sc_nvqs; i++) - virtio_pci_set_msix_queue_vector(sc, i, 1); + vsc->sc_vqs[i].vq_intr_vec = 1; } else { for (i = 0; i < vsc->sc_nvqs; i++) { if (virtio_pci_msix_establish(sc, vpa, i + 1, virtio_pci_queue_intr, &vsc->sc_vqs[i])) { goto fail; } - virtio_pci_set_msix_queue_vector(sc, i, i + 1); + vsc->sc_vqs[i].vq_intr_vec = i + 1; } } diff --git a/sys/dev/pv/virtio.c b/sys/dev/pv/virtio.c index 394546ecf7f..6d9fe06d645 100644 --- a/sys/dev/pv/virtio.c +++ b/sys/dev/pv/virtio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio.c,v 1.31 2024/08/27 18:44:12 sf Exp $ */ +/* $OpenBSD: virtio.c,v 1.32 2024/09/02 08:26:26 sf Exp $ */ /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ /* @@ -175,6 +175,7 @@ virtio_reinit_start(struct virtio_softc *sc) virtio_init_vq(sc, vq); virtio_setup_queue(sc, vq, vq->vq_dmamap->dm_segs[0].ds_addr); } + sc->sc_ops->setup_intrs(sc); } void diff --git a/sys/dev/pv/virtiovar.h b/sys/dev/pv/virtiovar.h index 367e166f2bb..193a0b5862d 100644 --- a/sys/dev/pv/virtiovar.h +++ b/sys/dev/pv/virtiovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: virtiovar.h,v 1.21 2024/08/27 19:01:11 sf Exp $ */ +/* $OpenBSD: virtiovar.h,v 1.22 2024/09/02 08:26:26 sf Exp $ */ /* $NetBSD: virtiovar.h,v 1.1 2011/10/30 12:12:21 hannken Exp $ */ /* @@ -137,6 +137,7 @@ struct virtqueue { int (*vq_done)(struct virtqueue*); /* 1.x only: offset for notify address calculation */ uint32_t vq_notify_off; + int vq_intr_vec; }; struct virtio_feature_name { @@ -156,6 +157,7 @@ struct virtio_ops { void (*write_dev_cfg_8)(struct virtio_softc *, int, uint64_t); uint16_t (*read_queue_size)(struct virtio_softc *, uint16_t); void (*setup_queue)(struct virtio_softc *, struct virtqueue *, uint64_t); + void (*setup_intrs)(struct virtio_softc *); int (*get_status)(struct virtio_softc *); void (*set_status)(struct virtio_softc *, int); int (*neg_features)(struct virtio_softc *, const struct virtio_feature_name *);