From c9af4663f334ab01bb83d796611cb14e1c6b75d2 Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Sat, 22 Jun 2024 13:10:26 -0700 Subject: [PATCH 1/7] tegra: remove duplicate enabling/disabling of interrupts INTRNG will call the enable/disable functions immediately after the first handler is added, or the last is removed. As a result there is no need for setup/teardown functions to handle this task. The teardown functions were doing nothing else. Remove the PCIe teardown function, the GPIO teardown function can be repurposed. The PCIe setup function might still have some value in a debugging kernel. --- sys/arm/nvidia/tegra_gpio.c | 5 ++--- sys/arm/nvidia/tegra_pcie.c | 23 ++++------------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/sys/arm/nvidia/tegra_gpio.c b/sys/arm/nvidia/tegra_gpio.c index 29bc8624e27ad5..920acf15fd69ac 100644 --- a/sys/arm/nvidia/tegra_gpio.c +++ b/sys/arm/nvidia/tegra_gpio.c @@ -677,7 +677,6 @@ tegra_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, tgi->cfgreg = cfgreg; intr_write_modify(sc, GPIO_INT_LVL, tgi, cfgreg, GPIO_INT_LVL_MASK); - tegra_gpio_pic_enable_intr(dev, isrc); return (0); } @@ -686,14 +685,14 @@ static int tegra_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, struct resource *res, struct intr_map_data *data) { +#if 0 struct tegra_gpio_softc *sc; struct tegra_gpio_irqsrc *tgi; sc = device_get_softc(dev); tgi = (struct tegra_gpio_irqsrc *)isrc; +#endif - if (isrc->isrc_handlers == 0) - tegra_gpio_isrc_mask(sc, tgi, 0); return (0); } diff --git a/sys/arm/nvidia/tegra_pcie.c b/sys/arm/nvidia/tegra_pcie.c index 2a91a81d40a913..e368768965a44a 100644 --- a/sys/arm/nvidia/tegra_pcie.c +++ b/sys/arm/nvidia/tegra_pcie.c @@ -709,6 +709,7 @@ tegra_pcib_msi_pre_ithread(device_t dev, struct intr_irqsrc *isrc) { } +#if defined(WITNESS) || defined(INVARIANTS) static int tegra_pcib_msi_setup_intr(device_t dev, struct intr_irqsrc *isrc, struct resource *res, struct intr_map_data *data) @@ -716,26 +717,9 @@ tegra_pcib_msi_setup_intr(device_t dev, struct intr_irqsrc *isrc, if (data == NULL || data->type != INTR_MAP_DATA_MSI) return (ENOTSUP); - if (isrc->isrc_handlers == 0) - tegra_pcib_msi_enable_intr(dev, isrc); - - return (0); -} - -static int -tegra_pcib_msi_teardown_intr(device_t dev, struct intr_irqsrc *isrc, - struct resource *res, struct intr_map_data *data) -{ - struct tegra_pcib_softc *sc; - struct tegra_pcib_irqsrc *tgi; - - sc = device_get_softc(dev); - tgi = (struct tegra_pcib_irqsrc *)isrc; - - if (isrc->isrc_handlers == 0) - tegra_pcib_isrc_mask(sc, tgi, 0); return (0); } +#endif static int tegra_pcib_msi_alloc_msi(device_t dev, device_t child, int count, int maxcount, @@ -1602,8 +1586,9 @@ static device_method_t tegra_pcib_methods[] = { /* Interrupt controller interface */ DEVMETHOD(pic_disable_intr, tegra_pcib_msi_disable_intr), DEVMETHOD(pic_enable_intr, tegra_pcib_msi_enable_intr), +#if defined(WITNESS) || defined(INVARIANTS) DEVMETHOD(pic_setup_intr, tegra_pcib_msi_setup_intr), - DEVMETHOD(pic_teardown_intr, tegra_pcib_msi_teardown_intr), +#endif DEVMETHOD(pic_post_filter, tegra_pcib_msi_post_filter), DEVMETHOD(pic_post_ithread, tegra_pcib_msi_post_ithread), DEVMETHOD(pic_pre_ithread, tegra_pcib_msi_pre_ithread), From 753b5a03a6e61b716d28c2994f97ba9f53114cfe Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Fri, 21 Jun 2024 18:47:18 -0700 Subject: [PATCH 2/7] sys: add *_INVALID values for interrupt and gpio constants Create invalid value constants for intr_polarity and GPIO pin/interrupts. These are meant for internal use by drivers. --- sys/sys/bus.h | 1 + sys/sys/gpio.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 1f5e074cfe5a04..4dd28babf84710 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -291,6 +291,7 @@ enum intr_trigger { }; enum intr_polarity { + INTR_POLARITY_INVALID = -1, INTR_POLARITY_CONFORM = 0, INTR_POLARITY_HIGH = 1, INTR_POLARITY_LOW = 2 diff --git a/sys/sys/gpio.h b/sys/sys/gpio.h index 1a9e998a0e5692..f3b9919f72ff58 100644 --- a/sys/sys/gpio.h +++ b/sys/sys/gpio.h @@ -63,6 +63,7 @@ #define GPIOMAXNAME 64 /* GPIO pin configuration flags */ +#define GPIO_PIN_INVALID 0x0000FFFF /* invalid pin value */ #define GPIO_PIN_INPUT 0x00000001 /* input direction */ #define GPIO_PIN_OUTPUT 0x00000002 /* output direction */ #define GPIO_PIN_OPENDRAIN 0x00000004 /* open-drain output */ @@ -77,6 +78,7 @@ #define GPIO_PIN_PRESET_HIGH 0x00000800 /* low before enabling output */ /* GPIO interrupt capabilities */ #define GPIO_INTR_NONE 0x00000000 /* no interrupt support */ +#define GPIO_INTR_INVALID 0xFFFF0000 /* invalid interrupt value */ #define GPIO_INTR_LEVEL_LOW 0x00010000 /* level trigger, low */ #define GPIO_INTR_LEVEL_HIGH 0x00020000 /* level trigger, high */ #define GPIO_INTR_EDGE_RISING 0x00040000 /* edge trigger, rising */ From 9c63963ed20b68d0c481cedddd589c1320a71aba Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Fri, 21 Jun 2024 21:15:33 -0700 Subject: [PATCH 3/7] arm/arm64: use PIC settings for first handler instead of INTRNG internals Using PIC-private variables is superior as it keeps the PIC implementation better separated from INTRNG's internals. In turn this eases changes to INTRNG. --- sys/arm/allwinner/aw_nmi.c | 11 ++++++----- sys/arm/arm/gic.c | 11 ++++++----- sys/arm/broadcom/bcm2835/bcm2835_gpio.c | 4 ++-- sys/arm/freescale/imx/imx_gpio.c | 6 +++--- sys/arm/mv/mvebu_gpio.c | 9 +++++++-- sys/arm/nvidia/tegra_gpio.c | 13 +++++++------ sys/arm64/arm64/gic_v3.c | 11 ++++++----- sys/arm64/rockchip/rk_gpio.c | 6 +++--- sys/dev/gpio/pl061.c | 6 +++--- 9 files changed, 43 insertions(+), 34 deletions(-) diff --git a/sys/arm/allwinner/aw_nmi.c b/sys/arm/allwinner/aw_nmi.c index febf970c7ffbc2..516a0633938aa2 100644 --- a/sys/arm/allwinner/aw_nmi.c +++ b/sys/arm/allwinner/aw_nmi.c @@ -255,7 +255,8 @@ aw_nmi_setup_intr(device_t dev, struct intr_irqsrc *isrc, return (EINVAL); /* Compare config if this is not first setup. */ - if (isrc->isrc_handlers != 0) { + if (nmi_intr->pol != INTR_POLARITY_INVALID || + nmi_intr->tri != INTR_TRIGGER_INVALID) { if (pol != nmi_intr->pol || trig != nmi_intr->tri) return (EINVAL); else @@ -291,8 +292,8 @@ aw_nmi_teardown_intr(device_t dev, struct intr_irqsrc *isrc, sc = device_get_softc(dev); if (isrc->isrc_handlers == 0) { - sc->intr.pol = INTR_POLARITY_CONFORM; - sc->intr.tri = INTR_TRIGGER_CONFORM; + sc->intr.pol = INTR_POLARITY_INVALID; + sc->intr.tri = INTR_TRIGGER_INVALID; SC_NMI_WRITE(sc, sc->cfg->enable_reg, ~NMI_IRQ_ENABLE); } @@ -371,8 +372,8 @@ aw_nmi_attach(device_t dev) xref = OF_xref_from_node(ofw_bus_get_node(dev)); /* Register our isrc */ sc->intr.irq = 0; - sc->intr.pol = INTR_POLARITY_CONFORM; - sc->intr.tri = INTR_TRIGGER_CONFORM; + sc->intr.pol = INTR_POLARITY_INVALID; + sc->intr.tri = INTR_TRIGGER_INVALID; if (intr_isrc_register(&sc->intr.isrc, sc->dev, 0, "%s,%u", device_get_nameunit(sc->dev), sc->intr.irq) != 0) goto error; diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index b1b7aacd63abb2..568ecae0e00b83 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -254,8 +254,8 @@ arm_gic_register_isrcs(struct arm_gic_softc *sc, uint32_t num) name = device_get_nameunit(sc->gic_dev); for (irq = 0; irq < num; irq++) { irqs[irq].gi_irq = irq; - irqs[irq].gi_pol = INTR_POLARITY_CONFORM; - irqs[irq].gi_trig = INTR_TRIGGER_CONFORM; + irqs[irq].gi_pol = INTR_POLARITY_INVALID; + irqs[irq].gi_trig = INTR_TRIGGER_INVALID; isrc = &irqs[irq].gi_isrc; if (irq <= GIC_LAST_SGI) { @@ -867,7 +867,8 @@ arm_gic_setup_intr(device_t dev, struct intr_irqsrc *isrc, } /* Compare config if this is not first setup. */ - if (isrc->isrc_handlers != 0) { + if (gi->gi_pol != INTR_POLARITY_INVALID || + gi->gi_trig != INTR_TRIGGER_INVALID) { if ((pol != INTR_POLARITY_CONFORM && pol != gi->gi_pol) || (trig != INTR_TRIGGER_CONFORM && trig != gi->gi_trig)) return (EINVAL); @@ -912,8 +913,8 @@ arm_gic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; if (isrc->isrc_handlers == 0 && (gi->gi_flags & GI_FLAG_MSI) == 0) { - gi->gi_pol = INTR_POLARITY_CONFORM; - gi->gi_trig = INTR_TRIGGER_CONFORM; + gi->gi_pol = INTR_POLARITY_INVALID; + gi->gi_trig = INTR_TRIGGER_INVALID; } return (0); } diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index e4fc57b79ba58a..521726b072731d 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -998,7 +998,7 @@ bcm_gpio_pic_attach(struct bcm_gpio_softc *sc) for (irq = 0; irq < sc->sc_maxpins; irq++) { sc->sc_isrcs[irq].bgi_irq = irq; sc->sc_isrcs[irq].bgi_mask = BCM_GPIO_MASK(irq); - sc->sc_isrcs[irq].bgi_mode = GPIO_INTR_CONFORM; + sc->sc_isrcs[irq].bgi_mode = GPIO_INTR_INVALID; error = intr_isrc_register(&sc->sc_isrcs[irq].bgi_isrc, sc->sc_dev, 0, "%s,%u", name, irq); @@ -1211,7 +1211,7 @@ bcm_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, * If this is a setup for another handler, * only check that its configuration match. */ - if (isrc->isrc_handlers != 0) + if (bgi->bgi_mode == GPIO_INTR_INVALID) return (bgi->bgi_mode == mode ? 0 : EINVAL); bcm_gpio_pic_config_intr(sc, bgi, mode); diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c index 7610d28af90e99..1093cb565348e4 100644 --- a/sys/arm/freescale/imx/imx_gpio.c +++ b/sys/arm/freescale/imx/imx_gpio.c @@ -303,7 +303,7 @@ gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, sc = device_get_softc(dev); if (isrc->isrc_handlers == 0) { gi = (struct gpio_irqsrc *)isrc; - gi->gi_mode = GPIO_INTR_CONFORM; + gi->gi_mode = GPIO_INTR_INVALID; // XXX Not sure this is necessary mtx_lock_spin(&sc->sc_mtx); @@ -338,7 +338,7 @@ gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, return (EINVAL); /* Compare config if this is not first setup. */ - if (isrc->isrc_handlers != 0) + if (gi->gi_mode == GPIO_INTR_INVALID) return (gi->gi_mode == mode ? 0 : EINVAL); gi->gi_mode = mode; @@ -497,7 +497,7 @@ gpio_pic_register_isrcs(struct imx51_gpio_softc *sc) name = device_get_nameunit(sc->dev); for (irq = 0; irq < NGPIO; irq++) { sc->gpio_pic_irqsrc[irq].gi_irq = irq; - sc->gpio_pic_irqsrc[irq].gi_mode = GPIO_INTR_CONFORM; + sc->gpio_pic_irqsrc[irq].gi_mode = GPIO_INTR_INVALID; error = intr_isrc_register(&sc->gpio_pic_irqsrc[irq].gi_isrc, sc->dev, 0, "%s,%u", name, irq); diff --git a/sys/arm/mv/mvebu_gpio.c b/sys/arm/mv/mvebu_gpio.c index a2001589867c0b..59b448da24755d 100644 --- a/sys/arm/mv/mvebu_gpio.c +++ b/sys/arm/mv/mvebu_gpio.c @@ -86,6 +86,7 @@ struct mvebu_gpio_irqsrc { u_int irq; bool is_level; bool is_inverted; + bool is_setup; }; struct mvebu_gpio_softc; @@ -359,6 +360,7 @@ mvebu_gpio_pic_attach(struct mvebu_gpio_softc *sc) sc->isrcs[irq].irq = irq; sc->isrcs[irq].is_level = false; sc->isrcs[irq].is_inverted = false; + sc->isrcs[irq].is_setup = false; rv = intr_isrc_register(&sc->isrcs[irq].isrc, sc->dev, 0, "%s,%u", name, irq); if (rv != 0) @@ -597,13 +599,14 @@ mvebu_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, * If this is a setup for another handler, * only check that its configuration match. */ - if (isrc->isrc_handlers != 0) + if (mgi->is_setup) return ( mgi->is_level == level && mgi->is_inverted == inverted ? 0 : EINVAL); mgi->is_level = level; mgi->is_inverted = inverted; + mgi->is_setup = true; GPIO_LOCK(sc); intr_modify(sc, GPIO_DATA_IN_POL, mgi, inverted ? 1 : 0); @@ -623,8 +626,10 @@ mvebu_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; - if (isrc->isrc_handlers == 0) + if (isrc->isrc_handlers == 0) { mvebu_gpio_isrc_mask(sc, mgi, 0); + mgi->is_setup = false; + } return (0); } diff --git a/sys/arm/nvidia/tegra_gpio.c b/sys/arm/nvidia/tegra_gpio.c index 920acf15fd69ac..3e2bcb0d4f53c4 100644 --- a/sys/arm/nvidia/tegra_gpio.c +++ b/sys/arm/nvidia/tegra_gpio.c @@ -97,6 +97,8 @@ #define GPIO_MSK_INT_ENB 0xD0 #define GPIO_MSK_INT_LVL 0xE0 +#define GPIO_UNSET 0xFFFFFFFF + char *tegra_gpio_port_names[] = { "A", "B", "C", "D", /* Bank 0 */ "E", "F", "G", "H", /* Bank 1 */ @@ -443,7 +445,7 @@ tegra_gpio_pic_attach(struct tegra_gpio_softc *sc) name = device_get_nameunit(sc->dev); for (irq = 0; irq < sc->gpio_npins; irq++) { sc->isrcs[irq].irq = irq; - sc->isrcs[irq].cfgreg = 0; + sc->isrcs[irq].cfgreg = GPIO_UNSET; error = intr_isrc_register(&sc->isrcs[irq].isrc, sc->dev, 0, "%s,%u", name, irq); if (error != 0) @@ -672,7 +674,7 @@ tegra_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, * If this is a setup for another handler, * only check that its configuration match. */ - if (isrc->isrc_handlers != 0) + if (tgi->cfgreg != GPIO_UNSET) return (tgi->cfgreg == cfgreg ? 0 : EINVAL); tgi->cfgreg = cfgreg; @@ -685,13 +687,12 @@ static int tegra_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, struct resource *res, struct intr_map_data *data) { -#if 0 - struct tegra_gpio_softc *sc; struct tegra_gpio_irqsrc *tgi; - sc = device_get_softc(dev); tgi = (struct tegra_gpio_irqsrc *)isrc; -#endif + + if (isrc->isrc_handlers == 0) + tgi->cfgreg = GPIO_UNSET; return (0); } diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index 964a129111e274..a89fc8ba2fcb4a 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -360,8 +360,8 @@ gic_v3_attach(device_t dev) struct intr_irqsrc *isrc; sc->gic_irqs[irq].gi_irq = irq; - sc->gic_irqs[irq].gi_pol = INTR_POLARITY_CONFORM; - sc->gic_irqs[irq].gi_trig = INTR_TRIGGER_CONFORM; + sc->gic_irqs[irq].gi_pol = INTR_POLARITY_INVALID; + sc->gic_irqs[irq].gi_trig = INTR_TRIGGER_INVALID; isrc = &sc->gic_irqs[irq].gi_isrc; if (irq <= GIC_LAST_SGI) { @@ -913,7 +913,8 @@ gic_v3_setup_intr(device_t dev, struct intr_irqsrc *isrc, return (EINVAL); /* Compare config if this is not first setup. */ - if (isrc->isrc_handlers != 0) { + if (gi->gi_pol != INTR_POLARITY_INVALID || + gi->gi_trig != INTR_TRIGGER_INVALID) { if (pol != gi->gi_pol || trig != gi->gi_trig) return (EINVAL); else @@ -951,8 +952,8 @@ gic_v3_teardown_intr(device_t dev, struct intr_irqsrc *isrc, struct gic_v3_irqsrc *gi = (struct gic_v3_irqsrc *)isrc; if (isrc->isrc_handlers == 0 && (gi->gi_flags & GI_FLAG_MSI) == 0) { - gi->gi_pol = INTR_POLARITY_CONFORM; - gi->gi_trig = INTR_TRIGGER_CONFORM; + gi->gi_pol = INTR_POLARITY_INVALID; + gi->gi_trig = INTR_TRIGGER_INVALID; } return (0); diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c index a86392f1662406..e391f96805171f 100644 --- a/sys/arm64/rockchip/rk_gpio.c +++ b/sys/arm64/rockchip/rk_gpio.c @@ -347,7 +347,7 @@ rk_gpio_attach(device_t dev) for (i = 0; i < RK_GPIO_MAX_PINS; i++) { sc->isrcs[i].irq = i; - sc->isrcs[i].mode = GPIO_INTR_CONFORM; + sc->isrcs[i].mode = GPIO_INTR_INVALID; if ((err = intr_isrc_register(RK_GPIO_ISRC(sc, i), dev, 0, "%s", device_get_nameunit(dev)))) { device_printf(dev, "Can not register isrc %d\n", err); @@ -697,7 +697,7 @@ rk_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, return (EINVAL); } - if (isrc->isrc_handlers != 0) { + if (rkisrc->mode == GPIO_INTR_INVALID) { device_printf(dev, "Handler already attached\n"); return (rkisrc->mode == mode ? 0 : EINVAL); } @@ -763,7 +763,7 @@ rk_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, irqsrc = (struct rk_pin_irqsrc *)isrc; if (isrc->isrc_handlers == 0) { - irqsrc->mode = GPIO_INTR_CONFORM; + irqsrc->mode = GPIO_INTR_INVALID; RK_GPIO_LOCK(sc); rk_gpio_write_bit(sc, RK_GPIO_INTEN, irqsrc->irq, 0); rk_gpio_write_bit(sc, RK_GPIO_INTMASK, irqsrc->irq, 0); diff --git a/sys/dev/gpio/pl061.c b/sys/dev/gpio/pl061.c index cc39790322b6b1..81a920d03e5a00 100644 --- a/sys/dev/gpio/pl061.c +++ b/sys/dev/gpio/pl061.c @@ -318,7 +318,7 @@ pl061_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, return (EINVAL); } - if (isrc->isrc_handlers != 0) { + if (irqsrc->mode == GPIO_INTR_INVALID) { dprintf("%s: handler already attached\n", __func__); return (irqsrc->mode == mode ? 0 : EINVAL); } @@ -364,7 +364,7 @@ pl061_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, sc = device_get_softc(dev); if (isrc->isrc_handlers == 0) { - irqsrc->mode = GPIO_INTR_CONFORM; + irqsrc->mode = GPIO_INTR_INVALID; PL061_LOCK(sc); mask_and_set(sc, PL061_INTMASK, mask, 0); PL061_UNLOCK(sc); @@ -478,7 +478,7 @@ pl061_attach(device_t dev) "trying to register pin %d name %s\n", irq, name); } sc->sc_isrcs[irq].irq = irq; - sc->sc_isrcs[irq].mode = GPIO_INTR_CONFORM; + sc->sc_isrcs[irq].mode = GPIO_INTR_INVALID; ret = intr_isrc_register(PIC_INTR_ISRC(sc, irq), dev, 0, "%s", name); if (ret) { From 30bc93eb305b94029c765dbcf8f1ce5233843864 Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Wed, 19 Jun 2024 22:03:16 -0700 Subject: [PATCH 4/7] intrng: add helper macro for use with ->isrc_handlers field Add macros for future development. Instead of always using `== 0` everywhere, create a macro for testing for existance of handler(s). --- sys/arm/allwinner/aw_nmi.c | 2 +- sys/arm/arm/gic.c | 4 ++-- sys/arm/broadcom/bcm2835/bcm2835_gpio.c | 2 +- sys/arm/broadcom/bcm2835/bcm2836.c | 2 +- sys/arm/freescale/imx/imx_gpio.c | 2 +- sys/arm/mv/mvebu_gpio.c | 2 +- sys/arm/nvidia/tegra_gpio.c | 2 +- sys/arm64/arm64/gic_v3.c | 4 ++-- sys/arm64/qoriq/qoriq_gpio_pic.c | 2 +- sys/arm64/rockchip/rk_gpio.c | 2 +- sys/dev/gpio/pl061.c | 2 +- sys/kern/subr_intr.c | 17 ++++++++++------- sys/sys/intr.h | 3 +++ 13 files changed, 26 insertions(+), 20 deletions(-) diff --git a/sys/arm/allwinner/aw_nmi.c b/sys/arm/allwinner/aw_nmi.c index 516a0633938aa2..466d12ac725c1e 100644 --- a/sys/arm/allwinner/aw_nmi.c +++ b/sys/arm/allwinner/aw_nmi.c @@ -291,7 +291,7 @@ aw_nmi_teardown_intr(device_t dev, struct intr_irqsrc *isrc, sc = device_get_softc(dev); - if (isrc->isrc_handlers == 0) { + if (ISRC_NO_HANDLER(isrc)) { sc->intr.pol = INTR_POLARITY_INVALID; sc->intr.tri = INTR_TRIGGER_INVALID; diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index 568ecae0e00b83..1015e9f7de090c 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -291,7 +291,7 @@ arm_gic_reserve_msi_range(device_t dev, u_int start, u_int count) ("%s: Trying to allocate too many MSI IRQs: %d + %d > %d", __func__, start, count, sc->nirqs)); for (i = 0; i < count; i++) { - KASSERT(sc->gic_irqs[start + i].gi_isrc.isrc_handlers == 0, + KASSERT(ISRC_NO_HANDLER(&sc->gic_irqs[start + i].gi_isrc), ("%s: MSI interrupt %d already has a handler", __func__, count + i)); KASSERT(sc->gic_irqs[start + i].gi_pol == INTR_POLARITY_CONFORM, @@ -912,7 +912,7 @@ arm_gic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, { struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; - if (isrc->isrc_handlers == 0 && (gi->gi_flags & GI_FLAG_MSI) == 0) { + if (ISRC_NO_HANDLER(isrc) && (gi->gi_flags & GI_FLAG_MSI) == 0) { gi->gi_pol = INTR_POLARITY_INVALID; gi->gi_trig = INTR_TRIGGER_INVALID; } diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index 521726b072731d..52d27905d64b27 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -1225,7 +1225,7 @@ bcm_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, struct bcm_gpio_softc *sc = device_get_softc(dev); struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc; - if (isrc->isrc_handlers == 0) + if (ISRC_NO_HANDLER(isrc)) bcm_gpio_pic_config_intr(sc, bgi, GPIO_INTR_CONFORM); return (0); } diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c index 7ed9dedaa77ebb..889745031b82da 100644 --- a/sys/arm/broadcom/bcm2835/bcm2836.c +++ b/sys/arm/broadcom/bcm2835/bcm2836.c @@ -506,7 +506,7 @@ bcm_lintc_setup_intr(device_t dev, struct intr_irqsrc *isrc, { struct bcm_lintc_softc *sc; - if (isrc->isrc_handlers == 0 && isrc->isrc_flags & INTR_ISRCF_PPI) { + if (ISRC_NO_HANDLER(isrc) && isrc->isrc_flags & INTR_ISRCF_PPI) { sc = device_get_softc(dev); BCM_LINTC_LOCK(sc); CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu); diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c index 1093cb565348e4..cab3f68496967f 100644 --- a/sys/arm/freescale/imx/imx_gpio.c +++ b/sys/arm/freescale/imx/imx_gpio.c @@ -301,7 +301,7 @@ gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, struct gpio_irqsrc *gi; sc = device_get_softc(dev); - if (isrc->isrc_handlers == 0) { + if (ISRC_NO_HANDLER(isrc)) { gi = (struct gpio_irqsrc *)isrc; gi->gi_mode = GPIO_INTR_INVALID; diff --git a/sys/arm/mv/mvebu_gpio.c b/sys/arm/mv/mvebu_gpio.c index 59b448da24755d..cef27050434766 100644 --- a/sys/arm/mv/mvebu_gpio.c +++ b/sys/arm/mv/mvebu_gpio.c @@ -626,7 +626,7 @@ mvebu_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; - if (isrc->isrc_handlers == 0) { + if (ISRC_NO_HANDLER(isrc)) { mvebu_gpio_isrc_mask(sc, mgi, 0); mgi->is_setup = false; } diff --git a/sys/arm/nvidia/tegra_gpio.c b/sys/arm/nvidia/tegra_gpio.c index 3e2bcb0d4f53c4..e55170fe23828c 100644 --- a/sys/arm/nvidia/tegra_gpio.c +++ b/sys/arm/nvidia/tegra_gpio.c @@ -691,7 +691,7 @@ tegra_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, tgi = (struct tegra_gpio_irqsrc *)isrc; - if (isrc->isrc_handlers == 0) + if (ISRC_NO_HANDLER(isrc)) tgi->cfgreg = GPIO_UNSET; return (0); diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index a89fc8ba2fcb4a..1bfac900e5ccb3 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -276,7 +276,7 @@ gic_v3_reserve_msi_range(device_t dev, u_int start, u_int count) ("%s: Trying to allocate too many MSI IRQs: %d + %d > %d", __func__, start, count, sc->gic_nirqs)); for (i = 0; i < count; i++) { - KASSERT(sc->gic_irqs[start + i].gi_isrc.isrc_handlers == 0, + KASSERT(ISRC_NO_HANDLER(&sc->gic_irqs[start + i].gi_isrc), ("%s: MSI interrupt %d already has a handler", __func__, count + i)); KASSERT(sc->gic_irqs[start + i].gi_pol == INTR_POLARITY_CONFORM, @@ -951,7 +951,7 @@ gic_v3_teardown_intr(device_t dev, struct intr_irqsrc *isrc, { struct gic_v3_irqsrc *gi = (struct gic_v3_irqsrc *)isrc; - if (isrc->isrc_handlers == 0 && (gi->gi_flags & GI_FLAG_MSI) == 0) { + if (ISRC_NO_HANDLER(isrc) && (gi->gi_flags & GI_FLAG_MSI) == 0) { gi->gi_pol = INTR_POLARITY_INVALID; gi->gi_trig = INTR_TRIGGER_INVALID; } diff --git a/sys/arm64/qoriq/qoriq_gpio_pic.c b/sys/arm64/qoriq/qoriq_gpio_pic.c index ec84d2a14ae7ae..570d6ee78d30bb 100644 --- a/sys/arm64/qoriq/qoriq_gpio_pic.c +++ b/sys/arm64/qoriq/qoriq_gpio_pic.c @@ -266,7 +266,7 @@ qoriq_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, sc = device_get_softc(dev); qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; - if (isrc->isrc_handlers > 0) + if (!ISRC_NO_HANDLER(isrc)) return (0); GPIO_LOCK(&sc->base); diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c index e391f96805171f..dd60898963c51f 100644 --- a/sys/arm64/rockchip/rk_gpio.c +++ b/sys/arm64/rockchip/rk_gpio.c @@ -762,7 +762,7 @@ rk_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, irqsrc = (struct rk_pin_irqsrc *)isrc; - if (isrc->isrc_handlers == 0) { + if (ISRC_NO_HANDLER(isrc)) { irqsrc->mode = GPIO_INTR_INVALID; RK_GPIO_LOCK(sc); rk_gpio_write_bit(sc, RK_GPIO_INTEN, irqsrc->irq, 0); diff --git a/sys/dev/gpio/pl061.c b/sys/dev/gpio/pl061.c index 81a920d03e5a00..ac2c7368caa446 100644 --- a/sys/dev/gpio/pl061.c +++ b/sys/dev/gpio/pl061.c @@ -363,7 +363,7 @@ pl061_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, dprintf("%s: calling teardown interrupt %#x\n", __func__, mask); sc = device_get_softc(dev); - if (isrc->isrc_handlers == 0) { + if (ISRC_NO_HANDLER(isrc)) { irqsrc->mode = GPIO_INTR_INVALID; PL061_LOCK(sc); mask_and_set(sc, PL061_INTMASK, mask, 0); diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index b8d85bf20f289b..685648215a7811 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -568,7 +568,7 @@ bool intr_isrc_init_on_cpu(struct intr_irqsrc *isrc, u_int cpu) { - if (isrc->isrc_handlers == 0) + if (ISRC_NO_HANDLER(isrc)) return (false); if ((isrc->isrc_flags & (INTR_ISRCF_PPI | INTR_ISRCF_IPI)) == 0) return (false); @@ -1091,6 +1091,7 @@ intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt, struct intr_irqsrc *isrc; const char *name; u_int res_id; + bool startempty; KASSERT(rman_get_start(res) == rman_get_end(res), ("%s: more interrupts in resource", __func__)); @@ -1105,6 +1106,8 @@ intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt, data = rman_get_virtual(res); name = device_get_nameunit(dev); + startempty = ISRC_NO_HANDLER(isrc); + #ifdef INTR_SOLO /* * Standard handling is done through MI interrupt framework. However, @@ -1140,7 +1143,7 @@ intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt, error = PIC_SETUP_INTR(isrc->isrc_dev, isrc, res, data); if (error == 0) { isrc->isrc_handlers++; - if (isrc->isrc_handlers == 1) + if (startempty) PIC_ENABLE_INTR(isrc->isrc_dev, isrc); } mtx_unlock(&isrc_table_lock); @@ -1162,7 +1165,7 @@ intr_teardown_irq(device_t dev, struct resource *res, void *cookie) res_id = (u_int)rman_get_start(res); isrc = intr_map_get_isrc(res_id); - if (isrc == NULL || isrc->isrc_handlers == 0) + if (isrc == NULL || ISRC_NO_HANDLER(isrc)) return (EINVAL); data = rman_get_virtual(res); @@ -1190,7 +1193,7 @@ intr_teardown_irq(device_t dev, struct resource *res, void *cookie) if (error == 0) { mtx_lock(&isrc_table_lock); isrc->isrc_handlers--; - if (isrc->isrc_handlers == 0) + if (ISRC_NO_HANDLER(isrc)) PIC_DISABLE_INTR(isrc->isrc_dev, isrc); PIC_TEARDOWN_INTR(isrc->isrc_dev, isrc, res, data); intrcnt_updatename(isrc); @@ -1212,7 +1215,7 @@ intr_describe_irq(device_t dev, struct resource *res, void *cookie, res_id = (u_int)rman_get_start(res); isrc = intr_map_get_isrc(res_id); - if (isrc == NULL || isrc->isrc_handlers == 0) + if (isrc == NULL || ISRC_NO_HANDLER(isrc)) return (EINVAL); #ifdef INTR_SOLO if (isrc->isrc_filter != NULL) { @@ -1246,7 +1249,7 @@ intr_bind_irq(device_t dev, struct resource *res, int cpu) res_id = (u_int)rman_get_start(res); isrc = intr_map_get_isrc(res_id); - if (isrc == NULL || isrc->isrc_handlers == 0) + if (isrc == NULL || ISRC_NO_HANDLER(isrc)) return (EINVAL); #ifdef INTR_SOLO if (isrc->isrc_filter != NULL) @@ -1300,7 +1303,7 @@ intr_irq_shuffle(void *arg __unused) irq_assign_cpu = true; for (i = 0; i < intr_nirq; i++) { isrc = irq_sources[i]; - if (isrc == NULL || isrc->isrc_handlers == 0 || + if (isrc == NULL || ISRC_NO_HANDLER(isrc) || isrc->isrc_flags & (INTR_ISRCF_PPI | INTR_ISRCF_IPI)) continue; diff --git a/sys/sys/intr.h b/sys/sys/intr.h index f11e96777927a9..bd511baad95488 100644 --- a/sys/sys/intr.h +++ b/sys/sys/intr.h @@ -100,6 +100,9 @@ struct intr_irqsrc { void * isrc_iommu; }; +/* Macros for PIC usage. */ +#define ISRC_NO_HANDLER(isrc) ((isrc)->isrc_handlers == 0) + /* Intr interface for PIC. */ int intr_isrc_deregister(struct intr_irqsrc *); int intr_isrc_register(struct intr_irqsrc *, device_t, u_int, const char *, ...) From 48366eef2f314f04313eb37539388e5ecbebca34 Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Fri, 28 Jun 2024 06:51:49 -0700 Subject: [PATCH 5/7] intrng: create stray handler for IPI interrupts We most certainly don't want the shared interrupt system to mask IPI interrupts. As such report them to `dmesg` and indicate they're being handled. --- sys/kern/subr_intr.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index 685648215a7811..ba6157dba2c637 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -1874,6 +1874,21 @@ intr_ipi_pic_register(device_t dev, u_int priority) return (0); } +/* + * Handler for flagging IPIs called via intr_event_handle() as stray. + */ +static int +isrc_ipi_strayfunc(void *_isrc) +{ + struct intr_irqsrc *isrc = _isrc; + + printf("ERROR: %s(): IPI for \"%s\" called via intr_event_handle()!\n", + __func__, isrc->isrc_event->ie_name); + + /* ensure PIC_DISABLE_INTR() is NOT called */ + return (FILTER_HANDLED); +} + /* * Setup IPI handler on interrupt controller. * @@ -1901,6 +1916,9 @@ intr_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand, if (error != 0) return; + intr_event_add_handler(isrc->isrc_event, name, isrc_ipi_strayfunc, + NULL, isrc, PI_INTR, 0, NULL); + isrc->isrc_handlers++; ii = intr_ipi_lookup(ipi); From ac66e52a04339dd45a643dc4cbbaf615c87bce01 Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Wed, 19 Jun 2024 22:03:16 -0700 Subject: [PATCH 6/7] intrng: purge ->isrc_handlers value The information is already available on the event, via a different means. Therefore retrieve it from there, rather than duplicating the information. Should be mild space savings, perhaps trivial speed due to cache savings. Should improve in future due to increasing numbers of interrupts on recent systems. --- sys/kern/subr_intr.c | 4 ---- sys/sys/intr.h | 5 +++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index ba6157dba2c637..9477d997ba1e25 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -1142,7 +1142,6 @@ intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt, mtx_lock(&isrc_table_lock); error = PIC_SETUP_INTR(isrc->isrc_dev, isrc, res, data); if (error == 0) { - isrc->isrc_handlers++; if (startempty) PIC_ENABLE_INTR(isrc->isrc_dev, isrc); } @@ -1192,7 +1191,6 @@ intr_teardown_irq(device_t dev, struct resource *res, void *cookie) error = intr_event_remove_handler(cookie); if (error == 0) { mtx_lock(&isrc_table_lock); - isrc->isrc_handlers--; if (ISRC_NO_HANDLER(isrc)) PIC_DISABLE_INTR(isrc->isrc_dev, isrc); PIC_TEARDOWN_INTR(isrc->isrc_dev, isrc, res, data); @@ -1919,8 +1917,6 @@ intr_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand, intr_event_add_handler(isrc->isrc_event, name, isrc_ipi_strayfunc, NULL, isrc, PI_INTR, 0, NULL); - isrc->isrc_handlers++; - ii = intr_ipi_lookup(ipi); KASSERT(ii->ii_count == NULL, ("%s: ipi %u reused", __func__, ipi)); diff --git a/sys/sys/intr.h b/sys/sys/intr.h index bd511baad95488..e0bff6546f5146 100644 --- a/sys/sys/intr.h +++ b/sys/sys/intr.h @@ -34,6 +34,8 @@ #endif #include +#include +#include #include @@ -90,7 +92,6 @@ struct intr_irqsrc { cpuset_t isrc_cpu; /* on which CPUs is enabled */ u_int isrc_index; u_long * isrc_count; - u_int isrc_handlers; struct intr_event * isrc_event; #ifdef INTR_SOLO intr_irq_filter_t * isrc_filter; @@ -101,7 +102,7 @@ struct intr_irqsrc { }; /* Macros for PIC usage. */ -#define ISRC_NO_HANDLER(isrc) ((isrc)->isrc_handlers == 0) +#define ISRC_NO_HANDLER(isrc) CK_SLIST_EMPTY(&(isrc)->isrc_event->ie_handlers) /* Intr interface for PIC. */ int intr_isrc_deregister(struct intr_irqsrc *); From 2d231c9f3a65e8d16f4647c7603e87fee512c9a3 Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Mon, 1 Jul 2024 08:26:43 -0700 Subject: [PATCH 7/7] intr/x86: purge ->is_handlers value Use of the macro CK_SLIST_EMPTY() on ->is_event->ie_handlers readily substitues for the value ->is_handlers. While only minor shrinkage of struct intsrc, small reductions do accumulate. Update the i8254 hack to work with this setup. --- sys/x86/include/intr_machdep.h | 1 - sys/x86/isa/clock.c | 19 ++++++++++++++++--- sys/x86/x86/intr_machdep.c | 8 +++----- sys/x86/x86/io_apic.c | 6 ++++-- sys/x86/x86/msi.c | 7 +++++-- sys/x86/xen/xen_arch_intr.c | 4 ++-- 6 files changed, 30 insertions(+), 15 deletions(-) diff --git a/sys/x86/include/intr_machdep.h b/sys/x86/include/intr_machdep.h index d7bfcdc126a9e4..89859804e0ff7f 100644 --- a/sys/x86/include/intr_machdep.h +++ b/sys/x86/include/intr_machdep.h @@ -111,7 +111,6 @@ struct intsrc { u_long *is_count; u_long *is_straycount; u_int is_index; - u_int is_handlers; u_int is_domain; u_int is_cpu; }; diff --git a/sys/x86/isa/clock.c b/sys/x86/isa/clock.c index 68d6085d5891e0..419a32aa50e620 100644 --- a/sys/x86/isa/clock.c +++ b/sys/x86/isa/clock.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -557,6 +558,15 @@ attimer_probe(device_t dev) return (result); } +/* Dirty hack, to make bus_setup_intr to not enable source. */ +static int +empty_handler(void *unused) +{ + + /* ensure disable is NOT called */ + return (FILTER_HANDLED); +} + static int attimer_attach(device_t dev) { @@ -586,6 +596,8 @@ attimer_attach(device_t dev) } if (resource_int_value(device_get_name(dev), device_get_unit(dev), "clock", &i) != 0 || i != 0) { + void *cookie; + sc->intr_rid = 0; while (bus_get_resource(dev, SYS_RES_IRQ, sc->intr_rid, &s, NULL) == 0 && s != 0) @@ -596,16 +608,17 @@ attimer_attach(device_t dev) return (0); } /* Dirty hack, to make bus_setup_intr to not enable source. */ - i8254_intsrc->is_handlers++; + intr_event_add_handler(i8254_intsrc->is_event, "", + empty_handler, NULL, NULL, PI_INTR, 0, &cookie); if ((bus_setup_intr(dev, sc->intr_res, INTR_MPSAFE | INTR_TYPE_CLK, (driver_filter_t *)clkintr, NULL, sc, &sc->intr_handler))) { device_printf(dev, "Can't setup interrupt.\n"); - i8254_intsrc->is_handlers--; + intr_event_remove_handler(cookie); return (0); } - i8254_intsrc->is_handlers--; + intr_event_remove_handler(cookie); i8254_intsrc->is_pic->pic_enable_intr(i8254_intsrc); sc->et.et_name = "i8254"; sc->et.et_flags = ET_FLAGS_PERIODIC; diff --git a/sys/x86/x86/intr_machdep.c b/sys/x86/x86/intr_machdep.c index 023c3df22580de..9a9b479b56239f 100644 --- a/sys/x86/x86/intr_machdep.c +++ b/sys/x86/x86/intr_machdep.c @@ -240,7 +240,6 @@ intr_register_source(struct intsrc *isrc) } intrcnt_register(isrc); interrupt_sources[vector] = isrc; - isrc->is_handlers = 0; sx_xunlock(&intrsrc_lock); return (0); } @@ -259,6 +258,7 @@ intr_add_handler(struct intsrc *isrc, const char *name, driver_filter_t filter, driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep, int domain) { + bool startempty = CK_SLIST_EMPTY(&isrc->is_event->ie_handlers); int error; error = intr_event_add_handler(isrc->is_event, name, filter, handler, @@ -266,8 +266,7 @@ intr_add_handler(struct intsrc *isrc, const char *name, driver_filter_t filter, if (error == 0) { sx_xlock(&intrsrc_lock); intrcnt_updatename(isrc); - isrc->is_handlers++; - if (isrc->is_handlers == 1) { + if (startempty) { isrc->is_domain = domain; isrc->is_pic->pic_enable_intr(isrc); isrc->is_pic->pic_enable_source(isrc); @@ -287,8 +286,7 @@ intr_remove_handler(void *cookie) error = intr_event_remove_handler(cookie); if (error == 0) { sx_xlock(&intrsrc_lock); - isrc->is_handlers--; - if (isrc->is_handlers == 0) { + if (CK_SLIST_EMPTY(&isrc->is_event->ie_handlers)) { isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI); isrc->is_pic->pic_disable_intr(isrc); } diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c index 525547f9482a91..6c12ee1baa0d92 100644 --- a/sys/x86/x86/io_apic.c +++ b/sys/x86/x86/io_apic.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -473,7 +475,7 @@ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id) intpin->io_cpu = apic_id; intpin->io_vector = new_vector; - if (isrc->is_handlers > 0) + if (!CK_SLIST_EMPTY(&isrc->is_event->ie_handlers)) apic_enable_vector(intpin->io_cpu, intpin->io_vector); if (bootverbose) { printf("ioapic%u: routing intpin %u (", io->io_id, @@ -490,7 +492,7 @@ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id) * to prevent races where we could miss an interrupt. */ if (old_vector) { - if (isrc->is_handlers > 0) + if (!CK_SLIST_EMPTY(&isrc->is_event->ie_handlers)) apic_disable_vector(old_id, old_vector); apic_free_vector(old_id, old_vector, intpin->io_irq); } diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c index 9d5a51f9753c2b..5cfc7406216a06 100644 --- a/sys/x86/x86/msi.c +++ b/sys/x86/x86/msi.c @@ -42,6 +42,8 @@ #include #include +#include +#include #include #include #include @@ -502,7 +504,7 @@ msi_alloc(device_t dev, int count, int maxcount, int *irqs) "msi: routing MSI IRQ %d to local APIC %u vector %u\n", msi->msi_irq, msi->msi_cpu, msi->msi_vector); msi->msi_first = fsrc; - KASSERT(msi->msi_intsrc.is_handlers == 0, + KASSERT(CK_SLIST_EMPTY(&msi->msi_intsrc.is_event->ie_handlers), ("dead MSI has handlers")); } fsrc->msi_count = count; @@ -742,7 +744,8 @@ msix_alloc(device_t dev, int *irq) msi->msi_maxcount = 1; msi->msi_irqs = NULL; - KASSERT(msi->msi_intsrc.is_handlers == 0, ("dead MSI-X has handlers")); + KASSERT(CK_SLIST_EMPTY(&msi->msi_intsrc.is_event->ie_handlers), + ("dead MSI-X has handlers")); mtx_unlock(&msi_lock); *irq = i; diff --git a/sys/x86/xen/xen_arch_intr.c b/sys/x86/xen/xen_arch_intr.c index dcf8b4aa35f160..0125641905196c 100644 --- a/sys/x86/xen/xen_arch_intr.c +++ b/sys/x86/xen/xen_arch_intr.c @@ -330,7 +330,7 @@ xen_arch_intr_alloc(void) KASSERT(isrc->xi_arch.intsrc.is_pic == &xen_intr_pic, ("interrupt not owned by Xen code?")); - KASSERT(isrc->xi_arch.intsrc.is_handlers == 0, + KASSERT(CK_SLIST_EMPTY(&isrc->xi_arch.intsrc.is_event->ie_handlers), ("Free evtchn still has handlers")); return (isrc); @@ -367,7 +367,7 @@ void xen_arch_intr_release(struct xenisrc *isrc) { - KASSERT(isrc->xi_arch.intsrc.is_handlers == 0, + KASSERT(CK_SLIST_EMPTY(&isrc->xi_arch.intsrc.is_event->ie_handlers), ("Release called, but xenisrc still in use")); _Static_assert(sizeof(struct xenisrc) >= sizeof(struct avail_list),