Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
"The interrupt departement delivers this time:

- New infrastructure to manage NMIs on platforms which have a sane
NMI delivery, i.e. identifiable NMI vectors instead of a single
lump.

- Simplification of the interrupt affinity management so drivers
don't have to implement ugly loops around the PCI/MSI enablement.

- Speedup for interrupt statistics in /proc/stat

- Provide a function to retrieve the default irq domain

- A new interrupt controller for the Loongson LS1X platform

- Affinity support for the SiFive PLIC

- Better support for the iMX irqsteer driver

- NUMA aware memory allocations for GICv3

- The usual small fixes, improvements and cleanups all over the
place"

* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits)
irqchip/imx-irqsteer: Add multi output interrupts support
irqchip/imx-irqsteer: Change to use reg_num instead of irq_group
dt-bindings: irq: imx-irqsteer: Add multi output interrupts support
dt-binding: irq: imx-irqsteer: Use irq number instead of group number
irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code
irqchip/gicv3-its: Use NUMA aware memory allocation for ITS tables
irqdomain: Allow the default irq domain to be retrieved
irqchip/sifive-plic: Implement irq_set_affinity() for SMP host
irqchip/sifive-plic: Differentiate between PLIC handler and context
irqchip/sifive-plic: Add warning in plic_init() if handler already present
irqchip/sifive-plic: Pre-compute context hart base and enable base
PCI/MSI: Remove obsolete sanity checks for multiple interrupt sets
genirq/affinity: Remove the leftovers of the original set support
nvme-pci: Simplify interrupt allocation
genirq/affinity: Add new callback for (re)calculating interrupt sets
genirq/affinity: Store interrupt sets size in struct irq_affinity
genirq/affinity: Code consolidation
irqchip/irq-sifive-plic: Check and continue in case of an invalid cpuid.
irqchip/i8259: Fix shutdown order by moving syscore_ops registration
dt-bindings: interrupt-controller: loongson ls1x intc
...

+1177 -281
+6 -5
Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt
··· 6 6 - "fsl,imx8m-irqsteer" 7 7 - "fsl,imx-irqsteer" 8 8 - reg: Physical base address and size of registers. 9 - - interrupts: Should contain the parent interrupt line used to multiplex the 10 - input interrupts. 9 + - interrupts: Should contain the up to 8 parent interrupt lines used to 10 + multiplex the input interrupts. They should be specified sequentially 11 + from output 0 to 7. 11 12 - clocks: Should contain one clock for entry in clock-names 12 13 see Documentation/devicetree/bindings/clock/clock-bindings.txt 13 14 - clock-names: ··· 17 16 - #interrupt-cells: Specifies the number of cells needed to encode an 18 17 interrupt source. The value must be 1. 19 18 - fsl,channel: The output channel that all input IRQs should be steered into. 20 - - fsl,irq-groups: Number of IRQ groups managed by this controller instance. 21 - Each group manages 64 input interrupts. 19 + - fsl,num-irqs: Number of input interrupts of this channel. 20 + Should be multiple of 32 input interrupts and up to 512 interrupts. 22 21 23 22 Example: 24 23 ··· 29 28 clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>; 30 29 clock-names = "ipg"; 31 30 fsl,channel = <0>; 32 - fsl,irq-groups = <1>; 31 + fsl,num-irqs = <64>; 33 32 interrupt-controller; 34 33 #interrupt-cells = <1>; 35 34 };
+24
Documentation/devicetree/bindings/interrupt-controller/loongson,ls1x-intc.txt
··· 1 + Loongson ls1x Interrupt Controller 2 + 3 + Required properties: 4 + 5 + - compatible : should be "loongson,ls1x-intc". Valid strings are: 6 + 7 + - reg : Specifies base physical address and size of the registers. 8 + - interrupt-controller : Identifies the node as an interrupt controller 9 + - #interrupt-cells : Specifies the number of cells needed to encode an 10 + interrupt source. The value shall be 2. 11 + - interrupts : Specifies the CPU interrupt the controller is connected to. 12 + 13 + Example: 14 + 15 + intc: interrupt-controller@1fd01040 { 16 + compatible = "loongson,ls1x-intc"; 17 + reg = <0x1fd01040 0x18>; 18 + 19 + interrupt-controller; 20 + #interrupt-cells = <2>; 21 + 22 + interrupt-parent = <&cpu_intc>; 23 + interrupts = <2>; 24 + };
+9
drivers/irqchip/Kconfig
··· 406 406 help 407 407 Support for the i.MX IRQSTEER interrupt multiplexer/remapper. 408 408 409 + config LS1X_IRQ 410 + bool "Loongson-1 Interrupt Controller" 411 + depends on MACH_LOONGSON32 412 + default y 413 + select IRQ_DOMAIN 414 + select GENERIC_IRQ_CHIP 415 + help 416 + Support for the Loongson-1 platform Interrupt Controller. 417 + 409 418 endmenu 410 419 411 420 config SIFIVE_PLIC
+1
drivers/irqchip/Makefile
··· 94 94 obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o 95 95 obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o 96 96 obj-$(CONFIG_MADERA_IRQ) += irq-madera.o 97 + obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o
+6 -4
drivers/irqchip/irq-brcmstb-l2.c
··· 129 129 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 130 130 struct irq_chip_type *ct = irq_data_get_chip_type(d); 131 131 struct brcmstb_l2_intc_data *b = gc->private; 132 + unsigned long flags; 132 133 133 - irq_gc_lock(gc); 134 + irq_gc_lock_irqsave(gc, flags); 134 135 /* Save the current mask */ 135 136 b->saved_mask = irq_reg_readl(gc, ct->regs.mask); 136 137 ··· 140 139 irq_reg_writel(gc, ~gc->wake_active, ct->regs.disable); 141 140 irq_reg_writel(gc, gc->wake_active, ct->regs.enable); 142 141 } 143 - irq_gc_unlock(gc); 142 + irq_gc_unlock_irqrestore(gc, flags); 144 143 } 145 144 146 145 static void brcmstb_l2_intc_resume(struct irq_data *d) ··· 148 147 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 149 148 struct irq_chip_type *ct = irq_data_get_chip_type(d); 150 149 struct brcmstb_l2_intc_data *b = gc->private; 150 + unsigned long flags; 151 151 152 - irq_gc_lock(gc); 152 + irq_gc_lock_irqsave(gc, flags); 153 153 if (ct->chip.irq_ack) { 154 154 /* Clear unmasked non-wakeup interrupts */ 155 155 irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active, ··· 160 158 /* Restore the saved mask */ 161 159 irq_reg_writel(gc, b->saved_mask, ct->regs.disable); 162 160 irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable); 163 - irq_gc_unlock(gc); 161 + irq_gc_unlock_irqrestore(gc, flags); 164 162 } 165 163 166 164 static int __init brcmstb_l2_intc_of_init(struct device_node *np,
+18 -10
drivers/irqchip/irq-gic-v3-its.c
··· 1746 1746 u64 type = GITS_BASER_TYPE(val); 1747 1747 u64 baser_phys, tmp; 1748 1748 u32 alloc_pages; 1749 + struct page *page; 1749 1750 void *base; 1750 1751 1751 1752 retry_alloc_baser: ··· 1759 1758 order = get_order(GITS_BASER_PAGES_MAX * psz); 1760 1759 } 1761 1760 1762 - base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); 1763 - if (!base) 1761 + page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order); 1762 + if (!page) 1764 1763 return -ENOMEM; 1765 1764 1765 + base = (void *)page_address(page); 1766 1766 baser_phys = virt_to_phys(base); 1767 1767 1768 1768 /* Check if the physical address of the memory is above 48bits */ ··· 1957 1955 indirect = its_parse_indirect_baser(its, baser, 1958 1956 psz, &order, 1959 1957 its->device_ids); 1958 + break; 1959 + 1960 1960 case GITS_BASER_TYPE_VCPU: 1961 1961 indirect = its_parse_indirect_baser(its, baser, 1962 1962 psz, &order, ··· 2296 2292 return NULL; 2297 2293 } 2298 2294 2299 - static bool its_alloc_table_entry(struct its_baser *baser, u32 id) 2295 + static bool its_alloc_table_entry(struct its_node *its, 2296 + struct its_baser *baser, u32 id) 2300 2297 { 2301 2298 struct page *page; 2302 2299 u32 esz, idx; ··· 2317 2312 2318 2313 /* Allocate memory for 2nd level table */ 2319 2314 if (!table[idx]) { 2320 - page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(baser->psz)); 2315 + page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, 2316 + get_order(baser->psz)); 2321 2317 if (!page) 2322 2318 return false; 2323 2319 ··· 2349 2343 if (!baser) 2350 2344 return (ilog2(dev_id) < its->device_ids); 2351 2345 2352 - return its_alloc_table_entry(baser, dev_id); 2346 + return its_alloc_table_entry(its, baser, dev_id); 2353 2347 } 2354 2348 2355 2349 static bool its_alloc_vpe_table(u32 vpe_id) ··· 2373 2367 if (!baser) 2374 2368 return false; 2375 2369 2376 - if (!its_alloc_table_entry(baser, vpe_id)) 2370 + if (!its_alloc_table_entry(its, baser, vpe_id)) 2377 2371 return false; 2378 2372 } 2379 2373 ··· 2407 2401 nr_ites = max(2, nvecs); 2408 2402 sz = nr_ites * its->ite_size; 2409 2403 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; 2410 - itt = kzalloc(sz, GFP_KERNEL); 2404 + itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node); 2411 2405 if (alloc_lpis) { 2412 2406 lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis); 2413 2407 if (lpi_map) ··· 3549 3543 void __iomem *its_base; 3550 3544 u32 val, ctlr; 3551 3545 u64 baser, tmp, typer; 3546 + struct page *page; 3552 3547 int err; 3553 3548 3554 3549 its_base = ioremap(res->start, resource_size(res)); ··· 3606 3599 3607 3600 its->numa_node = numa_node; 3608 3601 3609 - its->cmd_base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3610 - get_order(ITS_CMD_QUEUE_SZ)); 3611 - if (!its->cmd_base) { 3602 + page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, 3603 + get_order(ITS_CMD_QUEUE_SZ)); 3604 + if (!page) { 3612 3605 err = -ENOMEM; 3613 3606 goto out_free_its; 3614 3607 } 3608 + its->cmd_base = (void *)page_address(page); 3615 3609 its->cmd_write = its->cmd_base; 3616 3610 its->fwnode_handle = handle; 3617 3611 its->get_msi_base = its_irq_get_msi_base;
+1 -8
drivers/irqchip/irq-i8259.c
··· 225 225 .shutdown = i8259A_shutdown, 226 226 }; 227 227 228 - static int __init i8259A_init_sysfs(void) 229 - { 230 - register_syscore_ops(&i8259_syscore_ops); 231 - return 0; 232 - } 233 - 234 - device_initcall(i8259A_init_sysfs); 235 - 236 228 static void init_8259A(int auto_eoi) 237 229 { 238 230 unsigned long flags; ··· 324 332 panic("Failed to add i8259 IRQ domain"); 325 333 326 334 setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); 335 + register_syscore_ops(&i8259_syscore_ops); 327 336 return domain; 328 337 } 329 338
+83 -32
drivers/irqchip/irq-imx-irqsteer.c
··· 10 10 #include <linux/irqchip/chained_irq.h> 11 11 #include <linux/irqdomain.h> 12 12 #include <linux/kernel.h> 13 + #include <linux/of_irq.h> 13 14 #include <linux/of_platform.h> 14 15 #include <linux/spinlock.h> 15 16 16 - #define CTRL_STRIDE_OFF(_t, _r) (_t * 8 * _r) 17 + #define CTRL_STRIDE_OFF(_t, _r) (_t * 4 * _r) 17 18 #define CHANCTRL 0x0 18 19 #define CHANMASK(n, t) (CTRL_STRIDE_OFF(t, 0) + 0x4 * (n) + 0x4) 19 20 #define CHANSET(n, t) (CTRL_STRIDE_OFF(t, 1) + 0x4 * (n) + 0x4) ··· 22 21 #define CHAN_MINTDIS(t) (CTRL_STRIDE_OFF(t, 3) + 0x4) 23 22 #define CHAN_MASTRSTAT(t) (CTRL_STRIDE_OFF(t, 3) + 0x8) 24 23 24 + #define CHAN_MAX_OUTPUT_INT 0x8 25 + 25 26 struct irqsteer_data { 26 27 void __iomem *regs; 27 28 struct clk *ipg_clk; 28 - int irq; 29 + int irq[CHAN_MAX_OUTPUT_INT]; 30 + int irq_count; 29 31 raw_spinlock_t lock; 30 - int irq_groups; 32 + int reg_num; 31 33 int channel; 32 34 struct irq_domain *domain; 33 35 u32 *saved_reg; ··· 39 35 static int imx_irqsteer_get_reg_index(struct irqsteer_data *data, 40 36 unsigned long irqnum) 41 37 { 42 - return (data->irq_groups * 2 - irqnum / 32 - 1); 38 + return (data->reg_num - irqnum / 32 - 1); 43 39 } 44 40 45 41 static void imx_irqsteer_irq_unmask(struct irq_data *d) ··· 50 46 u32 val; 51 47 52 48 raw_spin_lock_irqsave(&data->lock, flags); 53 - val = readl_relaxed(data->regs + CHANMASK(idx, data->irq_groups)); 49 + val = readl_relaxed(data->regs + CHANMASK(idx, data->reg_num)); 54 50 val |= BIT(d->hwirq % 32); 55 - writel_relaxed(val, data->regs + CHANMASK(idx, data->irq_groups)); 51 + writel_relaxed(val, data->regs + CHANMASK(idx, data->reg_num)); 56 52 raw_spin_unlock_irqrestore(&data->lock, flags); 57 53 } 58 54 ··· 64 60 u32 val; 65 61 66 62 raw_spin_lock_irqsave(&data->lock, flags); 67 - val = readl_relaxed(data->regs + CHANMASK(idx, data->irq_groups)); 63 + val = readl_relaxed(data->regs + CHANMASK(idx, data->reg_num)); 68 64 val &= ~BIT(d->hwirq % 32); 69 - writel_relaxed(val, data->regs + CHANMASK(idx, data->irq_groups)); 65 + writel_relaxed(val, data->regs + CHANMASK(idx, data->reg_num)); 70 66 raw_spin_unlock_irqrestore(&data->lock, flags); 71 67 } 72 68 ··· 91 87 .xlate = irq_domain_xlate_onecell, 92 88 }; 93 89 90 + static int imx_irqsteer_get_hwirq_base(struct irqsteer_data *data, u32 irq) 91 + { 92 + int i; 93 + 94 + for (i = 0; i < data->irq_count; i++) { 95 + if (data->irq[i] == irq) 96 + return i * 64; 97 + } 98 + 99 + return -EINVAL; 100 + } 101 + 94 102 static void imx_irqsteer_irq_handler(struct irq_desc *desc) 95 103 { 96 104 struct irqsteer_data *data = irq_desc_get_handler_data(desc); 97 - int i; 105 + int hwirq; 106 + int irq, i; 98 107 99 108 chained_irq_enter(irq_desc_get_chip(desc), desc); 100 109 101 - for (i = 0; i < data->irq_groups * 64; i += 32) { 102 - int idx = imx_irqsteer_get_reg_index(data, i); 110 + irq = irq_desc_get_irq(desc); 111 + hwirq = imx_irqsteer_get_hwirq_base(data, irq); 112 + if (hwirq < 0) { 113 + pr_warn("%s: unable to get hwirq base for irq %d\n", 114 + __func__, irq); 115 + return; 116 + } 117 + 118 + for (i = 0; i < 2; i++, hwirq += 32) { 119 + int idx = imx_irqsteer_get_reg_index(data, hwirq); 103 120 unsigned long irqmap; 104 121 int pos, virq; 105 122 123 + if (hwirq >= data->reg_num * 32) 124 + break; 125 + 106 126 irqmap = readl_relaxed(data->regs + 107 - CHANSTATUS(idx, data->irq_groups)); 127 + CHANSTATUS(idx, data->reg_num)); 108 128 109 129 for_each_set_bit(pos, &irqmap, 32) { 110 - virq = irq_find_mapping(data->domain, pos + i); 130 + virq = irq_find_mapping(data->domain, pos + hwirq); 111 131 if (virq) 112 132 generic_handle_irq(virq); 113 133 } ··· 145 117 struct device_node *np = pdev->dev.of_node; 146 118 struct irqsteer_data *data; 147 119 struct resource *res; 148 - int ret; 120 + u32 irqs_num; 121 + int i, ret; 149 122 150 123 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 151 124 if (!data) ··· 159 130 return PTR_ERR(data->regs); 160 131 } 161 132 162 - data->irq = platform_get_irq(pdev, 0); 163 - if (data->irq <= 0) { 164 - dev_err(&pdev->dev, "failed to get irq\n"); 165 - return -ENODEV; 166 - } 167 - 168 133 data->ipg_clk = devm_clk_get(&pdev->dev, "ipg"); 169 134 if (IS_ERR(data->ipg_clk)) { 170 135 ret = PTR_ERR(data->ipg_clk); ··· 169 146 170 147 raw_spin_lock_init(&data->lock); 171 148 172 - of_property_read_u32(np, "fsl,irq-groups", &data->irq_groups); 149 + of_property_read_u32(np, "fsl,num-irqs", &irqs_num); 173 150 of_property_read_u32(np, "fsl,channel", &data->channel); 151 + 152 + /* 153 + * There is one output irq for each group of 64 inputs. 154 + * One register bit map can represent 32 input interrupts. 155 + */ 156 + data->irq_count = DIV_ROUND_UP(irqs_num, 64); 157 + data->reg_num = irqs_num / 32; 174 158 175 159 if (IS_ENABLED(CONFIG_PM_SLEEP)) { 176 160 data->saved_reg = devm_kzalloc(&pdev->dev, 177 - sizeof(u32) * data->irq_groups * 2, 161 + sizeof(u32) * data->reg_num, 178 162 GFP_KERNEL); 179 163 if (!data->saved_reg) 180 164 return -ENOMEM; ··· 196 166 /* steer all IRQs into configured channel */ 197 167 writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); 198 168 199 - data->domain = irq_domain_add_linear(np, data->irq_groups * 64, 169 + data->domain = irq_domain_add_linear(np, data->reg_num * 32, 200 170 &imx_irqsteer_domain_ops, data); 201 171 if (!data->domain) { 202 172 dev_err(&pdev->dev, "failed to create IRQ domain\n"); 203 - clk_disable_unprepare(data->ipg_clk); 204 - return -ENOMEM; 173 + ret = -ENOMEM; 174 + goto out; 205 175 } 206 176 207 - irq_set_chained_handler_and_data(data->irq, imx_irqsteer_irq_handler, 208 - data); 177 + if (!data->irq_count || data->irq_count > CHAN_MAX_OUTPUT_INT) { 178 + ret = -EINVAL; 179 + goto out; 180 + } 181 + 182 + for (i = 0; i < data->irq_count; i++) { 183 + data->irq[i] = irq_of_parse_and_map(np, i); 184 + if (!data->irq[i]) { 185 + ret = -EINVAL; 186 + goto out; 187 + } 188 + 189 + irq_set_chained_handler_and_data(data->irq[i], 190 + imx_irqsteer_irq_handler, 191 + data); 192 + } 209 193 210 194 platform_set_drvdata(pdev, data); 211 195 212 196 return 0; 197 + out: 198 + clk_disable_unprepare(data->ipg_clk); 199 + return ret; 213 200 } 214 201 215 202 static int imx_irqsteer_remove(struct platform_device *pdev) 216 203 { 217 204 struct irqsteer_data *irqsteer_data = platform_get_drvdata(pdev); 205 + int i; 218 206 219 - irq_set_chained_handler_and_data(irqsteer_data->irq, NULL, NULL); 207 + for (i = 0; i < irqsteer_data->irq_count; i++) 208 + irq_set_chained_handler_and_data(irqsteer_data->irq[i], 209 + NULL, NULL); 210 + 220 211 irq_domain_remove(irqsteer_data->domain); 221 212 222 213 clk_disable_unprepare(irqsteer_data->ipg_clk); ··· 250 199 { 251 200 int i; 252 201 253 - for (i = 0; i < data->irq_groups * 2; i++) 202 + for (i = 0; i < data->reg_num; i++) 254 203 data->saved_reg[i] = readl_relaxed(data->regs + 255 - CHANMASK(i, data->irq_groups)); 204 + CHANMASK(i, data->reg_num)); 256 205 } 257 206 258 207 static void imx_irqsteer_restore_regs(struct irqsteer_data *data) ··· 260 209 int i; 261 210 262 211 writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); 263 - for (i = 0; i < data->irq_groups * 2; i++) 212 + for (i = 0; i < data->reg_num; i++) 264 213 writel_relaxed(data->saved_reg[i], 265 - data->regs + CHANMASK(i, data->irq_groups)); 214 + data->regs + CHANMASK(i, data->reg_num)); 266 215 } 267 216 268 217 static int imx_irqsteer_suspend(struct device *dev)
+192
drivers/irqchip/irq-ls1x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2019, Jiaxun Yang <jiaxun.yang@flygoat.com> 4 + * Loongson-1 platform IRQ support 5 + */ 6 + 7 + #include <linux/errno.h> 8 + #include <linux/init.h> 9 + #include <linux/types.h> 10 + #include <linux/interrupt.h> 11 + #include <linux/ioport.h> 12 + #include <linux/irqchip.h> 13 + #include <linux/of_address.h> 14 + #include <linux/of_irq.h> 15 + #include <linux/io.h> 16 + #include <linux/irqchip/chained_irq.h> 17 + 18 + #define LS_REG_INTC_STATUS 0x00 19 + #define LS_REG_INTC_EN 0x04 20 + #define LS_REG_INTC_SET 0x08 21 + #define LS_REG_INTC_CLR 0x0c 22 + #define LS_REG_INTC_POL 0x10 23 + #define LS_REG_INTC_EDGE 0x14 24 + 25 + /** 26 + * struct ls1x_intc_priv - private ls1x-intc data. 27 + * @domain: IRQ domain. 28 + * @intc_base: IO Base of intc registers. 29 + */ 30 + 31 + struct ls1x_intc_priv { 32 + struct irq_domain *domain; 33 + void __iomem *intc_base; 34 + }; 35 + 36 + 37 + static void ls1x_chained_handle_irq(struct irq_desc *desc) 38 + { 39 + struct ls1x_intc_priv *priv = irq_desc_get_handler_data(desc); 40 + struct irq_chip *chip = irq_desc_get_chip(desc); 41 + u32 pending; 42 + 43 + chained_irq_enter(chip, desc); 44 + pending = readl(priv->intc_base + LS_REG_INTC_STATUS) & 45 + readl(priv->intc_base + LS_REG_INTC_EN); 46 + 47 + if (!pending) 48 + spurious_interrupt(); 49 + 50 + while (pending) { 51 + int bit = __ffs(pending); 52 + 53 + generic_handle_irq(irq_find_mapping(priv->domain, bit)); 54 + pending &= ~BIT(bit); 55 + } 56 + 57 + chained_irq_exit(chip, desc); 58 + } 59 + 60 + static void ls_intc_set_bit(struct irq_chip_generic *gc, 61 + unsigned int offset, 62 + u32 mask, bool set) 63 + { 64 + if (set) 65 + writel(readl(gc->reg_base + offset) | mask, 66 + gc->reg_base + offset); 67 + else 68 + writel(readl(gc->reg_base + offset) & ~mask, 69 + gc->reg_base + offset); 70 + } 71 + 72 + static int ls_intc_set_type(struct irq_data *data, unsigned int type) 73 + { 74 + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); 75 + u32 mask = data->mask; 76 + 77 + switch (type) { 78 + case IRQ_TYPE_LEVEL_HIGH: 79 + ls_intc_set_bit(gc, LS_REG_INTC_EDGE, mask, false); 80 + ls_intc_set_bit(gc, LS_REG_INTC_POL, mask, true); 81 + break; 82 + case IRQ_TYPE_LEVEL_LOW: 83 + ls_intc_set_bit(gc, LS_REG_INTC_EDGE, mask, false); 84 + ls_intc_set_bit(gc, LS_REG_INTC_POL, mask, false); 85 + break; 86 + case IRQ_TYPE_EDGE_RISING: 87 + ls_intc_set_bit(gc, LS_REG_INTC_EDGE, mask, true); 88 + ls_intc_set_bit(gc, LS_REG_INTC_POL, mask, true); 89 + break; 90 + case IRQ_TYPE_EDGE_FALLING: 91 + ls_intc_set_bit(gc, LS_REG_INTC_EDGE, mask, true); 92 + ls_intc_set_bit(gc, LS_REG_INTC_POL, mask, false); 93 + break; 94 + default: 95 + return -EINVAL; 96 + } 97 + 98 + irqd_set_trigger_type(data, type); 99 + return irq_setup_alt_chip(data, type); 100 + } 101 + 102 + 103 + static int __init ls1x_intc_of_init(struct device_node *node, 104 + struct device_node *parent) 105 + { 106 + struct irq_chip_generic *gc; 107 + struct irq_chip_type *ct; 108 + struct ls1x_intc_priv *priv; 109 + int parent_irq, err = 0; 110 + 111 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 112 + if (!priv) 113 + return -ENOMEM; 114 + 115 + priv->intc_base = of_iomap(node, 0); 116 + if (!priv->intc_base) { 117 + err = -ENODEV; 118 + goto out_free_priv; 119 + } 120 + 121 + parent_irq = irq_of_parse_and_map(node, 0); 122 + if (!parent_irq) { 123 + pr_err("ls1x-irq: unable to get parent irq\n"); 124 + err = -ENODEV; 125 + goto out_iounmap; 126 + } 127 + 128 + /* Set up an IRQ domain */ 129 + priv->domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops, 130 + NULL); 131 + if (!priv->domain) { 132 + pr_err("ls1x-irq: cannot add IRQ domain\n"); 133 + goto out_iounmap; 134 + } 135 + 136 + err = irq_alloc_domain_generic_chips(priv->domain, 32, 2, 137 + node->full_name, handle_level_irq, 138 + IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN, 0, 139 + IRQ_GC_INIT_MASK_CACHE); 140 + if (err) { 141 + pr_err("ls1x-irq: unable to register IRQ domain\n"); 142 + goto out_free_domain; 143 + } 144 + 145 + /* Mask all irqs */ 146 + writel(0x0, priv->intc_base + LS_REG_INTC_EN); 147 + 148 + /* Ack all irqs */ 149 + writel(0xffffffff, priv->intc_base + LS_REG_INTC_CLR); 150 + 151 + /* Set all irqs to high level triggered */ 152 + writel(0xffffffff, priv->intc_base + LS_REG_INTC_POL); 153 + 154 + gc = irq_get_domain_generic_chip(priv->domain, 0); 155 + 156 + gc->reg_base = priv->intc_base; 157 + 158 + ct = gc->chip_types; 159 + ct[0].type = IRQ_TYPE_LEVEL_MASK; 160 + ct[0].regs.mask = LS_REG_INTC_EN; 161 + ct[0].regs.ack = LS_REG_INTC_CLR; 162 + ct[0].chip.irq_unmask = irq_gc_mask_set_bit; 163 + ct[0].chip.irq_mask = irq_gc_mask_clr_bit; 164 + ct[0].chip.irq_ack = irq_gc_ack_set_bit; 165 + ct[0].chip.irq_set_type = ls_intc_set_type; 166 + ct[0].handler = handle_level_irq; 167 + 168 + ct[1].type = IRQ_TYPE_EDGE_BOTH; 169 + ct[1].regs.mask = LS_REG_INTC_EN; 170 + ct[1].regs.ack = LS_REG_INTC_CLR; 171 + ct[1].chip.irq_unmask = irq_gc_mask_set_bit; 172 + ct[1].chip.irq_mask = irq_gc_mask_clr_bit; 173 + ct[1].chip.irq_ack = irq_gc_ack_set_bit; 174 + ct[1].chip.irq_set_type = ls_intc_set_type; 175 + ct[1].handler = handle_edge_irq; 176 + 177 + irq_set_chained_handler_and_data(parent_irq, 178 + ls1x_chained_handle_irq, priv); 179 + 180 + return 0; 181 + 182 + out_free_domain: 183 + irq_domain_remove(priv->domain); 184 + out_iounmap: 185 + iounmap(priv->intc_base); 186 + out_free_priv: 187 + kfree(priv); 188 + 189 + return err; 190 + } 191 + 192 + IRQCHIP_DECLARE(ls1x_intc, "loongson,ls1x-intc", ls1x_intc_of_init);
+77 -39
drivers/irqchip/irq-sifive-plic.c
··· 59 59 60 60 struct plic_handler { 61 61 bool present; 62 - int ctxid; 62 + void __iomem *hart_base; 63 + /* 64 + * Protect mask operations on the registers given that we can't 65 + * assume atomic memory operations work on them. 66 + */ 67 + raw_spinlock_t enable_lock; 68 + void __iomem *enable_base; 63 69 }; 64 70 static DEFINE_PER_CPU(struct plic_handler, plic_handlers); 65 71 66 - static inline void __iomem *plic_hart_offset(int ctxid) 72 + static inline void plic_toggle(struct plic_handler *handler, 73 + int hwirq, int enable) 67 74 { 68 - return plic_regs + CONTEXT_BASE + ctxid * CONTEXT_PER_HART; 69 - } 70 - 71 - static inline u32 __iomem *plic_enable_base(int ctxid) 72 - { 73 - return plic_regs + ENABLE_BASE + ctxid * ENABLE_PER_HART; 74 - } 75 - 76 - /* 77 - * Protect mask operations on the registers given that we can't assume that 78 - * atomic memory operations work on them. 79 - */ 80 - static DEFINE_RAW_SPINLOCK(plic_toggle_lock); 81 - 82 - static inline void plic_toggle(int ctxid, int hwirq, int enable) 83 - { 84 - u32 __iomem *reg = plic_enable_base(ctxid) + (hwirq / 32); 75 + u32 __iomem *reg = handler->enable_base + (hwirq / 32) * sizeof(u32); 85 76 u32 hwirq_mask = 1 << (hwirq % 32); 86 77 87 - raw_spin_lock(&plic_toggle_lock); 78 + raw_spin_lock(&handler->enable_lock); 88 79 if (enable) 89 80 writel(readl(reg) | hwirq_mask, reg); 90 81 else 91 82 writel(readl(reg) & ~hwirq_mask, reg); 92 - raw_spin_unlock(&plic_toggle_lock); 83 + raw_spin_unlock(&handler->enable_lock); 93 84 } 94 85 95 - static inline void plic_irq_toggle(struct irq_data *d, int enable) 86 + static inline void plic_irq_toggle(const struct cpumask *mask, 87 + int hwirq, int enable) 96 88 { 97 89 int cpu; 98 90 99 - writel(enable, plic_regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); 100 - for_each_cpu(cpu, irq_data_get_affinity_mask(d)) { 91 + writel(enable, plic_regs + PRIORITY_BASE + hwirq * PRIORITY_PER_ID); 92 + for_each_cpu(cpu, mask) { 101 93 struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu); 102 94 103 95 if (handler->present) 104 - plic_toggle(handler->ctxid, d->hwirq, enable); 96 + plic_toggle(handler, hwirq, enable); 105 97 } 106 98 } 107 99 108 100 static void plic_irq_enable(struct irq_data *d) 109 101 { 110 - plic_irq_toggle(d, 1); 102 + unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d), 103 + cpu_online_mask); 104 + if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) 105 + return; 106 + plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); 111 107 } 112 108 113 109 static void plic_irq_disable(struct irq_data *d) 114 110 { 115 - plic_irq_toggle(d, 0); 111 + plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); 116 112 } 113 + 114 + #ifdef CONFIG_SMP 115 + static int plic_set_affinity(struct irq_data *d, 116 + const struct cpumask *mask_val, bool force) 117 + { 118 + unsigned int cpu; 119 + 120 + if (force) 121 + cpu = cpumask_first(mask_val); 122 + else 123 + cpu = cpumask_any_and(mask_val, cpu_online_mask); 124 + 125 + if (cpu >= nr_cpu_ids) 126 + return -EINVAL; 127 + 128 + if (!irqd_irq_disabled(d)) { 129 + plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); 130 + plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); 131 + } 132 + 133 + irq_data_update_effective_affinity(d, cpumask_of(cpu)); 134 + 135 + return IRQ_SET_MASK_OK_DONE; 136 + } 137 + #endif 117 138 118 139 static struct irq_chip plic_chip = { 119 140 .name = "SiFive PLIC", ··· 144 123 */ 145 124 .irq_enable = plic_irq_enable, 146 125 .irq_disable = plic_irq_disable, 126 + #ifdef CONFIG_SMP 127 + .irq_set_affinity = plic_set_affinity, 128 + #endif 147 129 }; 148 130 149 131 static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, ··· 174 150 static void plic_handle_irq(struct pt_regs *regs) 175 151 { 176 152 struct plic_handler *handler = this_cpu_ptr(&plic_handlers); 177 - void __iomem *claim = plic_hart_offset(handler->ctxid) + CONTEXT_CLAIM; 153 + void __iomem *claim = handler->hart_base + CONTEXT_CLAIM; 178 154 irq_hw_number_t hwirq; 179 155 180 156 WARN_ON_ONCE(!handler->present); ··· 210 186 static int __init plic_init(struct device_node *node, 211 187 struct device_node *parent) 212 188 { 213 - int error = 0, nr_handlers, nr_mapped = 0, i; 189 + int error = 0, nr_contexts, nr_handlers = 0, i; 214 190 u32 nr_irqs; 215 191 216 192 if (plic_regs) { ··· 227 203 if (WARN_ON(!nr_irqs)) 228 204 goto out_iounmap; 229 205 230 - nr_handlers = of_irq_count(node); 231 - if (WARN_ON(!nr_handlers)) 206 + nr_contexts = of_irq_count(node); 207 + if (WARN_ON(!nr_contexts)) 232 208 goto out_iounmap; 233 - if (WARN_ON(nr_handlers < num_possible_cpus())) 209 + if (WARN_ON(nr_contexts < num_possible_cpus())) 234 210 goto out_iounmap; 235 211 236 212 error = -ENOMEM; ··· 239 215 if (WARN_ON(!plic_irqdomain)) 240 216 goto out_iounmap; 241 217 242 - for (i = 0; i < nr_handlers; i++) { 218 + for (i = 0; i < nr_contexts; i++) { 243 219 struct of_phandle_args parent; 244 220 struct plic_handler *handler; 245 221 irq_hw_number_t hwirq; ··· 261 237 } 262 238 263 239 cpu = riscv_hartid_to_cpuid(hartid); 240 + if (cpu < 0) { 241 + pr_warn("Invalid cpuid for context %d\n", i); 242 + continue; 243 + } 244 + 264 245 handler = per_cpu_ptr(&plic_handlers, cpu); 246 + if (handler->present) { 247 + pr_warn("handler already present for context %d.\n", i); 248 + continue; 249 + } 250 + 265 251 handler->present = true; 266 - handler->ctxid = i; 252 + handler->hart_base = 253 + plic_regs + CONTEXT_BASE + i * CONTEXT_PER_HART; 254 + raw_spin_lock_init(&handler->enable_lock); 255 + handler->enable_base = 256 + plic_regs + ENABLE_BASE + i * ENABLE_PER_HART; 267 257 268 258 /* priority must be > threshold to trigger an interrupt */ 269 - writel(0, plic_hart_offset(i) + CONTEXT_THRESHOLD); 259 + writel(0, handler->hart_base + CONTEXT_THRESHOLD); 270 260 for (hwirq = 1; hwirq <= nr_irqs; hwirq++) 271 - plic_toggle(i, hwirq, 0); 272 - nr_mapped++; 261 + plic_toggle(handler, hwirq, 0); 262 + nr_handlers++; 273 263 } 274 264 275 - pr_info("mapped %d interrupts to %d (out of %d) handlers.\n", 276 - nr_irqs, nr_mapped, nr_handlers); 265 + pr_info("mapped %d interrupts with %d handlers for %d contexts.\n", 266 + nr_irqs, nr_handlers, nr_contexts); 277 267 set_handle_irq(plic_handle_irq); 278 268 return 0; 279 269
+39 -78
drivers/nvme/host/pci.c
··· 2041 2041 return ret; 2042 2042 } 2043 2043 2044 - /* irq_queues covers admin queue */ 2045 - static void nvme_calc_io_queues(struct nvme_dev *dev, unsigned int irq_queues) 2044 + /* 2045 + * nirqs is the number of interrupts available for write and read 2046 + * queues. The core already reserved an interrupt for the admin queue. 2047 + */ 2048 + static void nvme_calc_irq_sets(struct irq_affinity *affd, unsigned int nrirqs) 2046 2049 { 2047 - unsigned int this_w_queues = write_queues; 2048 - 2049 - WARN_ON(!irq_queues); 2050 - 2051 - /* 2052 - * Setup read/write queue split, assign admin queue one independent 2053 - * irq vector if irq_queues is > 1. 2054 - */ 2055 - if (irq_queues <= 2) { 2056 - dev->io_queues[HCTX_TYPE_DEFAULT] = 1; 2057 - dev->io_queues[HCTX_TYPE_READ] = 0; 2058 - return; 2059 - } 2050 + struct nvme_dev *dev = affd->priv; 2051 + unsigned int nr_read_queues; 2060 2052 2061 2053 /* 2062 - * If 'write_queues' is set, ensure it leaves room for at least 2063 - * one read queue and one admin queue 2054 + * If there is no interupt available for queues, ensure that 2055 + * the default queue is set to 1. The affinity set size is 2056 + * also set to one, but the irq core ignores it for this case. 2057 + * 2058 + * If only one interrupt is available or 'write_queue' == 0, combine 2059 + * write and read queues. 2060 + * 2061 + * If 'write_queues' > 0, ensure it leaves room for at least one read 2062 + * queue. 2064 2063 */ 2065 - if (this_w_queues >= irq_queues) 2066 - this_w_queues = irq_queues - 2; 2067 - 2068 - /* 2069 - * If 'write_queues' is set to zero, reads and writes will share 2070 - * a queue set. 2071 - */ 2072 - if (!this_w_queues) { 2073 - dev->io_queues[HCTX_TYPE_DEFAULT] = irq_queues - 1; 2074 - dev->io_queues[HCTX_TYPE_READ] = 0; 2064 + if (!nrirqs) { 2065 + nrirqs = 1; 2066 + nr_read_queues = 0; 2067 + } else if (nrirqs == 1 || !write_queues) { 2068 + nr_read_queues = 0; 2069 + } else if (write_queues >= nrirqs) { 2070 + nr_read_queues = 1; 2075 2071 } else { 2076 - dev->io_queues[HCTX_TYPE_DEFAULT] = this_w_queues; 2077 - dev->io_queues[HCTX_TYPE_READ] = irq_queues - this_w_queues - 1; 2072 + nr_read_queues = nrirqs - write_queues; 2078 2073 } 2074 + 2075 + dev->io_queues[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; 2076 + affd->set_size[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; 2077 + dev->io_queues[HCTX_TYPE_READ] = nr_read_queues; 2078 + affd->set_size[HCTX_TYPE_READ] = nr_read_queues; 2079 + affd->nr_sets = nr_read_queues ? 2 : 1; 2079 2080 } 2080 2081 2081 2082 static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues) 2082 2083 { 2083 2084 struct pci_dev *pdev = to_pci_dev(dev->dev); 2084 - int irq_sets[2]; 2085 2085 struct irq_affinity affd = { 2086 - .pre_vectors = 1, 2087 - .nr_sets = ARRAY_SIZE(irq_sets), 2088 - .sets = irq_sets, 2086 + .pre_vectors = 1, 2087 + .calc_sets = nvme_calc_irq_sets, 2088 + .priv = dev, 2089 2089 }; 2090 - int result = 0; 2091 2090 unsigned int irq_queues, this_p_queues; 2092 2091 2093 2092 /* ··· 2102 2103 } 2103 2104 dev->io_queues[HCTX_TYPE_POLL] = this_p_queues; 2104 2105 2105 - /* 2106 - * For irq sets, we have to ask for minvec == maxvec. This passes 2107 - * any reduction back to us, so we can adjust our queue counts and 2108 - * IRQ vector needs. 2109 - */ 2110 - do { 2111 - nvme_calc_io_queues(dev, irq_queues); 2112 - irq_sets[0] = dev->io_queues[HCTX_TYPE_DEFAULT]; 2113 - irq_sets[1] = dev->io_queues[HCTX_TYPE_READ]; 2114 - if (!irq_sets[1]) 2115 - affd.nr_sets = 1; 2106 + /* Initialize for the single interrupt case */ 2107 + dev->io_queues[HCTX_TYPE_DEFAULT] = 1; 2108 + dev->io_queues[HCTX_TYPE_READ] = 0; 2116 2109 2117 - /* 2118 - * If we got a failure and we're down to asking for just 2119 - * 1 + 1 queues, just ask for a single vector. We'll share 2120 - * that between the single IO queue and the admin queue. 2121 - * Otherwise, we assign one independent vector to admin queue. 2122 - */ 2123 - if (irq_queues > 1) 2124 - irq_queues = irq_sets[0] + irq_sets[1] + 1; 2125 - 2126 - result = pci_alloc_irq_vectors_affinity(pdev, irq_queues, 2127 - irq_queues, 2128 - PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd); 2129 - 2130 - /* 2131 - * Need to reduce our vec counts. If we get ENOSPC, the 2132 - * platform should support mulitple vecs, we just need 2133 - * to decrease our ask. If we get EINVAL, the platform 2134 - * likely does not. Back down to ask for just one vector. 2135 - */ 2136 - if (result == -ENOSPC) { 2137 - irq_queues--; 2138 - if (!irq_queues) 2139 - return result; 2140 - continue; 2141 - } else if (result == -EINVAL) { 2142 - irq_queues = 1; 2143 - continue; 2144 - } else if (result <= 0) 2145 - return -EIO; 2146 - break; 2147 - } while (1); 2148 - 2149 - return result; 2110 + return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues, 2111 + PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd); 2150 2112 } 2151 2113 2152 2114 static void nvme_disable_io_queues(struct nvme_dev *dev) ··· 2984 3024 2985 3025 static int __init nvme_init(void) 2986 3026 { 3027 + BUILD_BUG_ON(IRQ_AFFINITY_MAX_SETS < 2); 2987 3028 return pci_register_driver(&nvme_driver); 2988 3029 } 2989 3030
+16 -23
drivers/pci/msi.c
··· 532 532 } 533 533 534 534 static struct msi_desc * 535 - msi_setup_entry(struct pci_dev *dev, int nvec, const struct irq_affinity *affd) 535 + msi_setup_entry(struct pci_dev *dev, int nvec, struct irq_affinity *affd) 536 536 { 537 537 struct irq_affinity_desc *masks = NULL; 538 538 struct msi_desc *entry; ··· 597 597 * which could have been allocated. 598 598 */ 599 599 static int msi_capability_init(struct pci_dev *dev, int nvec, 600 - const struct irq_affinity *affd) 600 + struct irq_affinity *affd) 601 601 { 602 602 struct msi_desc *entry; 603 603 int ret; ··· 669 669 670 670 static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, 671 671 struct msix_entry *entries, int nvec, 672 - const struct irq_affinity *affd) 672 + struct irq_affinity *affd) 673 673 { 674 674 struct irq_affinity_desc *curmsk, *masks = NULL; 675 675 struct msi_desc *entry; ··· 736 736 * requested MSI-X entries with allocated irqs or non-zero for otherwise. 737 737 **/ 738 738 static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, 739 - int nvec, const struct irq_affinity *affd) 739 + int nvec, struct irq_affinity *affd) 740 740 { 741 741 int ret; 742 742 u16 control; ··· 932 932 EXPORT_SYMBOL(pci_msix_vec_count); 933 933 934 934 static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, 935 - int nvec, const struct irq_affinity *affd) 935 + int nvec, struct irq_affinity *affd) 936 936 { 937 937 int nr_entries; 938 938 int i, j; ··· 1018 1018 EXPORT_SYMBOL(pci_msi_enabled); 1019 1019 1020 1020 static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, 1021 - const struct irq_affinity *affd) 1021 + struct irq_affinity *affd) 1022 1022 { 1023 1023 int nvec; 1024 1024 int rc; ··· 1034 1034 1035 1035 if (maxvec < minvec) 1036 1036 return -ERANGE; 1037 - 1038 - /* 1039 - * If the caller is passing in sets, we can't support a range of 1040 - * vectors. The caller needs to handle that. 1041 - */ 1042 - if (affd && affd->nr_sets && minvec != maxvec) 1043 - return -EINVAL; 1044 1037 1045 1038 if (WARN_ON_ONCE(dev->msi_enabled)) 1046 1039 return -EINVAL; ··· 1079 1086 1080 1087 static int __pci_enable_msix_range(struct pci_dev *dev, 1081 1088 struct msix_entry *entries, int minvec, 1082 - int maxvec, const struct irq_affinity *affd) 1089 + int maxvec, struct irq_affinity *affd) 1083 1090 { 1084 1091 int rc, nvec = maxvec; 1085 1092 1086 1093 if (maxvec < minvec) 1087 1094 return -ERANGE; 1088 - 1089 - /* 1090 - * If the caller is passing in sets, we can't support a range of 1091 - * supported vectors. The caller needs to handle that. 1092 - */ 1093 - if (affd && affd->nr_sets && minvec != maxvec) 1094 - return -EINVAL; 1095 1095 1096 1096 if (WARN_ON_ONCE(dev->msix_enabled)) 1097 1097 return -EINVAL; ··· 1151 1165 */ 1152 1166 int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, 1153 1167 unsigned int max_vecs, unsigned int flags, 1154 - const struct irq_affinity *affd) 1168 + struct irq_affinity *affd) 1155 1169 { 1156 - static const struct irq_affinity msi_default_affd; 1170 + struct irq_affinity msi_default_affd = {0}; 1157 1171 int msix_vecs = -ENOSPC; 1158 1172 int msi_vecs = -ENOSPC; 1159 1173 ··· 1182 1196 /* use legacy irq if allowed */ 1183 1197 if (flags & PCI_IRQ_LEGACY) { 1184 1198 if (min_vecs == 1 && dev->irq) { 1199 + /* 1200 + * Invoke the affinity spreading logic to ensure that 1201 + * the device driver can adjust queue configuration 1202 + * for the single interrupt case. 1203 + */ 1204 + if (affd) 1205 + irq_create_affinity_masks(1, affd); 1185 1206 pci_intx(dev, 1); 1186 1207 return 1; 1187 1208 }
+1 -1
drivers/scsi/be2iscsi/be_main.c
··· 3566 3566 3567 3567 /* if eqid_count == 1 fall back to INTX */ 3568 3568 if (enable_msix && nvec > 1) { 3569 - const struct irq_affinity desc = { .post_vectors = 1 }; 3569 + struct irq_affinity desc = { .post_vectors = 1 }; 3570 3570 3571 3571 if (pci_alloc_irq_vectors_affinity(phba->pcidev, 2, nvec, 3572 3572 PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc) < 0) {
+26 -3
fs/proc/stat.c
··· 79 79 80 80 #endif 81 81 82 + static void show_irq_gap(struct seq_file *p, unsigned int gap) 83 + { 84 + static const char zeros[] = " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; 85 + 86 + while (gap > 0) { 87 + unsigned int inc; 88 + 89 + inc = min_t(unsigned int, gap, ARRAY_SIZE(zeros) / 2); 90 + seq_write(p, zeros, 2 * inc); 91 + gap -= inc; 92 + } 93 + } 94 + 95 + static void show_all_irqs(struct seq_file *p) 96 + { 97 + unsigned int i, next = 0; 98 + 99 + for_each_active_irq(i) { 100 + show_irq_gap(p, i - next); 101 + seq_put_decimal_ull(p, " ", kstat_irqs_usr(i)); 102 + next = i + 1; 103 + } 104 + show_irq_gap(p, nr_irqs - next); 105 + } 106 + 82 107 static int show_stat(struct seq_file *p, void *v) 83 108 { 84 109 int i, j; ··· 181 156 } 182 157 seq_put_decimal_ull(p, "intr ", (unsigned long long)sum); 183 158 184 - /* sum again ? it could be updated? */ 185 - for_each_irq_nr(j) 186 - seq_put_decimal_ull(p, " ", kstat_irqs_usr(j)); 159 + show_all_irqs(p); 187 160 188 161 seq_printf(p, 189 162 "\nctxt %llu\n"
+40 -11
include/linux/interrupt.h
··· 156 156 unsigned long flags, const char *devname, 157 157 void __percpu *percpu_dev_id); 158 158 159 + extern int __must_check 160 + request_nmi(unsigned int irq, irq_handler_t handler, unsigned long flags, 161 + const char *name, void *dev); 162 + 159 163 static inline int __must_check 160 164 request_percpu_irq(unsigned int irq, irq_handler_t handler, 161 165 const char *devname, void __percpu *percpu_dev_id) ··· 168 164 devname, percpu_dev_id); 169 165 } 170 166 167 + extern int __must_check 168 + request_percpu_nmi(unsigned int irq, irq_handler_t handler, 169 + const char *devname, void __percpu *dev); 170 + 171 171 extern const void *free_irq(unsigned int, void *); 172 172 extern void free_percpu_irq(unsigned int, void __percpu *); 173 + 174 + extern const void *free_nmi(unsigned int irq, void *dev_id); 175 + extern void free_percpu_nmi(unsigned int irq, void __percpu *percpu_dev_id); 173 176 174 177 struct device; 175 178 ··· 228 217 extern bool irq_percpu_is_enabled(unsigned int irq); 229 218 extern void irq_wake_thread(unsigned int irq, void *dev_id); 230 219 220 + extern void disable_nmi_nosync(unsigned int irq); 221 + extern void disable_percpu_nmi(unsigned int irq); 222 + extern void enable_nmi(unsigned int irq); 223 + extern void enable_percpu_nmi(unsigned int irq, unsigned int type); 224 + extern int prepare_percpu_nmi(unsigned int irq); 225 + extern void teardown_percpu_nmi(unsigned int irq); 226 + 231 227 /* The following three functions are for the core kernel use only. */ 232 228 extern void suspend_device_irqs(void); 233 229 extern void resume_device_irqs(void); ··· 259 241 void (*release)(struct kref *ref); 260 242 }; 261 243 244 + #define IRQ_AFFINITY_MAX_SETS 4 245 + 262 246 /** 263 247 * struct irq_affinity - Description for automatic irq affinity assignements 264 248 * @pre_vectors: Don't apply affinity to @pre_vectors at beginning of 265 249 * the MSI(-X) vector space 266 250 * @post_vectors: Don't apply affinity to @post_vectors at end of 267 251 * the MSI(-X) vector space 268 - * @nr_sets: Length of passed in *sets array 269 - * @sets: Number of affinitized sets 252 + * @nr_sets: The number of interrupt sets for which affinity 253 + * spreading is required 254 + * @set_size: Array holding the size of each interrupt set 255 + * @calc_sets: Callback for calculating the number and size 256 + * of interrupt sets 257 + * @priv: Private data for usage by @calc_sets, usually a 258 + * pointer to driver/device specific data. 270 259 */ 271 260 struct irq_affinity { 272 - int pre_vectors; 273 - int post_vectors; 274 - int nr_sets; 275 - int *sets; 261 + unsigned int pre_vectors; 262 + unsigned int post_vectors; 263 + unsigned int nr_sets; 264 + unsigned int set_size[IRQ_AFFINITY_MAX_SETS]; 265 + void (*calc_sets)(struct irq_affinity *, unsigned int nvecs); 266 + void *priv; 276 267 }; 277 268 278 269 /** ··· 341 314 irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify); 342 315 343 316 struct irq_affinity_desc * 344 - irq_create_affinity_masks(int nvec, const struct irq_affinity *affd); 317 + irq_create_affinity_masks(unsigned int nvec, struct irq_affinity *affd); 345 318 346 - int irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd); 319 + unsigned int irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec, 320 + const struct irq_affinity *affd); 347 321 348 322 #else /* CONFIG_SMP */ 349 323 ··· 378 350 } 379 351 380 352 static inline struct irq_affinity_desc * 381 - irq_create_affinity_masks(int nvec, const struct irq_affinity *affd) 353 + irq_create_affinity_masks(unsigned int nvec, struct irq_affinity *affd) 382 354 { 383 355 return NULL; 384 356 } 385 357 386 - static inline int 387 - irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd) 358 + static inline unsigned int 359 + irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec, 360 + const struct irq_affinity *affd) 388 361 { 389 362 return maxvec; 390 363 }
+10
include/linux/irq.h
··· 442 442 * @irq_set_vcpu_affinity: optional to target a vCPU in a virtual machine 443 443 * @ipi_send_single: send a single IPI to destination cpus 444 444 * @ipi_send_mask: send an IPI to destination cpus in cpumask 445 + * @irq_nmi_setup: function called from core code before enabling an NMI 446 + * @irq_nmi_teardown: function called from core code after disabling an NMI 445 447 * @flags: chip specific flags 446 448 */ 447 449 struct irq_chip { ··· 492 490 void (*ipi_send_single)(struct irq_data *data, unsigned int cpu); 493 491 void (*ipi_send_mask)(struct irq_data *data, const struct cpumask *dest); 494 492 493 + int (*irq_nmi_setup)(struct irq_data *data); 494 + void (*irq_nmi_teardown)(struct irq_data *data); 495 + 495 496 unsigned long flags; 496 497 }; 497 498 ··· 510 505 * IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask 511 506 * IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode 512 507 * IRQCHIP_SUPPORTS_LEVEL_MSI Chip can provide two doorbells for Level MSIs 508 + * IRQCHIP_SUPPORTS_NMI: Chip can deliver NMIs, only for root irqchips 513 509 */ 514 510 enum { 515 511 IRQCHIP_SET_TYPE_MASKED = (1 << 0), ··· 521 515 IRQCHIP_ONESHOT_SAFE = (1 << 5), 522 516 IRQCHIP_EOI_THREADED = (1 << 6), 523 517 IRQCHIP_SUPPORTS_LEVEL_MSI = (1 << 7), 518 + IRQCHIP_SUPPORTS_NMI = (1 << 8), 524 519 }; 525 520 526 521 #include <linux/irqdesc.h> ··· 600 593 extern void handle_percpu_devid_irq(struct irq_desc *desc); 601 594 extern void handle_bad_irq(struct irq_desc *desc); 602 595 extern void handle_nested_irq(unsigned int irq); 596 + 597 + extern void handle_fasteoi_nmi(struct irq_desc *desc); 598 + extern void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc); 603 599 604 600 extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); 605 601 extern int irq_chip_pm_get(struct irq_data *data);
+7
include/linux/irqdesc.h
··· 28 28 * @core_internal_state__do_not_mess_with_it: core internal status information 29 29 * @depth: disable-depth, for nested irq_disable() calls 30 30 * @wake_depth: enable depth, for multiple irq_set_irq_wake() callers 31 + * @tot_count: stats field for non-percpu irqs 31 32 * @irq_count: stats field to detect stalled irqs 32 33 * @last_unhandled: aging timer for unhandled count 33 34 * @irqs_unhandled: stats field for spurious unhandled interrupts ··· 66 65 unsigned int core_internal_state__do_not_mess_with_it; 67 66 unsigned int depth; /* nested irq disables */ 68 67 unsigned int wake_depth; /* nested wake enables */ 68 + unsigned int tot_count; 69 69 unsigned int irq_count; /* For detecting broken IRQs */ 70 70 unsigned long last_unhandled; /* Aging timer for unhandled count */ 71 71 unsigned int irqs_unhandled; ··· 173 171 { 174 172 return __handle_domain_irq(domain, hwirq, true, regs); 175 173 } 174 + 175 + #ifdef CONFIG_IRQ_DOMAIN 176 + int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, 177 + struct pt_regs *regs); 178 + #endif 176 179 #endif 177 180 178 181 /* Test to see if a driver has successfully requested an irq */
+1
include/linux/irqdomain.h
··· 265 265 enum irq_domain_bus_token bus_token); 266 266 extern bool irq_domain_check_msi_remap(void); 267 267 extern void irq_set_default_host(struct irq_domain *host); 268 + extern struct irq_domain *irq_get_default_host(void); 268 269 extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs, 269 270 irq_hw_number_t hwirq, int node, 270 271 const struct irq_affinity_desc *affinity);
+1
include/linux/kthread.h
··· 56 56 int kthread_stop(struct task_struct *k); 57 57 bool kthread_should_stop(void); 58 58 bool kthread_should_park(void); 59 + bool __kthread_should_park(struct task_struct *k); 59 60 bool kthread_freezable_should_stop(bool *was_frozen); 60 61 void *kthread_data(struct task_struct *k); 61 62 void *kthread_probe_data(struct task_struct *k);
+2 -2
include/linux/pci.h
··· 1393 1393 } 1394 1394 int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, 1395 1395 unsigned int max_vecs, unsigned int flags, 1396 - const struct irq_affinity *affd); 1396 + struct irq_affinity *affd); 1397 1397 1398 1398 void pci_free_irq_vectors(struct pci_dev *dev); 1399 1399 int pci_irq_vector(struct pci_dev *dev, unsigned int nr); ··· 1419 1419 static inline int 1420 1420 pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, 1421 1421 unsigned int max_vecs, unsigned int flags, 1422 - const struct irq_affinity *aff_desc) 1422 + struct irq_affinity *aff_desc) 1423 1423 { 1424 1424 if ((flags & PCI_IRQ_LEGACY) && min_vecs == 1 && dev->irq) 1425 1425 return 1;
+70 -51
kernel/irq/affinity.c
··· 9 9 #include <linux/cpu.h> 10 10 11 11 static void irq_spread_init_one(struct cpumask *irqmsk, struct cpumask *nmsk, 12 - int cpus_per_vec) 12 + unsigned int cpus_per_vec) 13 13 { 14 14 const struct cpumask *siblmsk; 15 15 int cpu, sibl; ··· 95 95 } 96 96 97 97 static int __irq_build_affinity_masks(const struct irq_affinity *affd, 98 - int startvec, int numvecs, int firstvec, 98 + unsigned int startvec, 99 + unsigned int numvecs, 100 + unsigned int firstvec, 99 101 cpumask_var_t *node_to_cpumask, 100 102 const struct cpumask *cpu_mask, 101 103 struct cpumask *nmsk, 102 104 struct irq_affinity_desc *masks) 103 105 { 104 - int n, nodes, cpus_per_vec, extra_vecs, done = 0; 105 - int last_affv = firstvec + numvecs; 106 - int curvec = startvec; 106 + unsigned int n, nodes, cpus_per_vec, extra_vecs, done = 0; 107 + unsigned int last_affv = firstvec + numvecs; 108 + unsigned int curvec = startvec; 107 109 nodemask_t nodemsk = NODE_MASK_NONE; 108 110 109 111 if (!cpumask_weight(cpu_mask)) ··· 119 117 */ 120 118 if (numvecs <= nodes) { 121 119 for_each_node_mask(n, nodemsk) { 122 - cpumask_or(&masks[curvec].mask, 123 - &masks[curvec].mask, 124 - node_to_cpumask[n]); 120 + cpumask_or(&masks[curvec].mask, &masks[curvec].mask, 121 + node_to_cpumask[n]); 125 122 if (++curvec == last_affv) 126 123 curvec = firstvec; 127 124 } 128 - done = numvecs; 129 - goto out; 125 + return numvecs; 130 126 } 131 127 132 128 for_each_node_mask(n, nodemsk) { 133 - int ncpus, v, vecs_to_assign, vecs_per_node; 129 + unsigned int ncpus, v, vecs_to_assign, vecs_per_node; 134 130 135 131 /* Spread the vectors per node */ 136 132 vecs_per_node = (numvecs - (curvec - firstvec)) / nodes; ··· 163 163 curvec = firstvec; 164 164 --nodes; 165 165 } 166 - 167 - out: 168 166 return done; 169 167 } 170 168 ··· 172 174 * 2) spread other possible CPUs on these vectors 173 175 */ 174 176 static int irq_build_affinity_masks(const struct irq_affinity *affd, 175 - int startvec, int numvecs, int firstvec, 176 - cpumask_var_t *node_to_cpumask, 177 + unsigned int startvec, unsigned int numvecs, 178 + unsigned int firstvec, 177 179 struct irq_affinity_desc *masks) 178 180 { 179 - int curvec = startvec, nr_present, nr_others; 180 - int ret = -ENOMEM; 181 + unsigned int curvec = startvec, nr_present, nr_others; 182 + cpumask_var_t *node_to_cpumask; 181 183 cpumask_var_t nmsk, npresmsk; 184 + int ret = -ENOMEM; 182 185 183 186 if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL)) 184 187 return ret; 185 188 186 189 if (!zalloc_cpumask_var(&npresmsk, GFP_KERNEL)) 187 - goto fail; 190 + goto fail_nmsk; 191 + 192 + node_to_cpumask = alloc_node_to_cpumask(); 193 + if (!node_to_cpumask) 194 + goto fail_npresmsk; 188 195 189 196 ret = 0; 190 197 /* Stabilize the cpumasks */ ··· 220 217 if (nr_present < numvecs) 221 218 WARN_ON(nr_present + nr_others < numvecs); 222 219 220 + free_node_to_cpumask(node_to_cpumask); 221 + 222 + fail_npresmsk: 223 223 free_cpumask_var(npresmsk); 224 224 225 - fail: 225 + fail_nmsk: 226 226 free_cpumask_var(nmsk); 227 227 return ret; 228 + } 229 + 230 + static void default_calc_sets(struct irq_affinity *affd, unsigned int affvecs) 231 + { 232 + affd->nr_sets = 1; 233 + affd->set_size[0] = affvecs; 228 234 } 229 235 230 236 /** ··· 244 232 * Returns the irq_affinity_desc pointer or NULL if allocation failed. 245 233 */ 246 234 struct irq_affinity_desc * 247 - irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) 235 + irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd) 248 236 { 249 - int affvecs = nvecs - affd->pre_vectors - affd->post_vectors; 250 - int curvec, usedvecs; 251 - cpumask_var_t *node_to_cpumask; 237 + unsigned int affvecs, curvec, usedvecs, i; 252 238 struct irq_affinity_desc *masks = NULL; 253 - int i, nr_sets; 254 239 255 240 /* 256 - * If there aren't any vectors left after applying the pre/post 257 - * vectors don't bother with assigning affinity. 241 + * Determine the number of vectors which need interrupt affinities 242 + * assigned. If the pre/post request exhausts the available vectors 243 + * then nothing to do here except for invoking the calc_sets() 244 + * callback so the device driver can adjust to the situation. If there 245 + * is only a single vector, then managing the queue is pointless as 246 + * well. 258 247 */ 259 - if (nvecs == affd->pre_vectors + affd->post_vectors) 248 + if (nvecs > 1 && nvecs > affd->pre_vectors + affd->post_vectors) 249 + affvecs = nvecs - affd->pre_vectors - affd->post_vectors; 250 + else 251 + affvecs = 0; 252 + 253 + /* 254 + * Simple invocations do not provide a calc_sets() callback. Install 255 + * the generic one. 256 + */ 257 + if (!affd->calc_sets) 258 + affd->calc_sets = default_calc_sets; 259 + 260 + /* Recalculate the sets */ 261 + affd->calc_sets(affd, affvecs); 262 + 263 + if (WARN_ON_ONCE(affd->nr_sets > IRQ_AFFINITY_MAX_SETS)) 260 264 return NULL; 261 265 262 - node_to_cpumask = alloc_node_to_cpumask(); 263 - if (!node_to_cpumask) 266 + /* Nothing to assign? */ 267 + if (!affvecs) 264 268 return NULL; 265 269 266 270 masks = kcalloc(nvecs, sizeof(*masks), GFP_KERNEL); 267 271 if (!masks) 268 - goto outnodemsk; 272 + return NULL; 269 273 270 274 /* Fill out vectors at the beginning that don't need affinity */ 271 275 for (curvec = 0; curvec < affd->pre_vectors; curvec++) 272 276 cpumask_copy(&masks[curvec].mask, irq_default_affinity); 277 + 273 278 /* 274 279 * Spread on present CPUs starting from affd->pre_vectors. If we 275 280 * have multiple sets, build each sets affinity mask separately. 276 281 */ 277 - nr_sets = affd->nr_sets; 278 - if (!nr_sets) 279 - nr_sets = 1; 280 - 281 - for (i = 0, usedvecs = 0; i < nr_sets; i++) { 282 - int this_vecs = affd->sets ? affd->sets[i] : affvecs; 282 + for (i = 0, usedvecs = 0; i < affd->nr_sets; i++) { 283 + unsigned int this_vecs = affd->set_size[i]; 283 284 int ret; 284 285 285 286 ret = irq_build_affinity_masks(affd, curvec, this_vecs, 286 - curvec, node_to_cpumask, masks); 287 + curvec, masks); 287 288 if (ret) { 288 289 kfree(masks); 289 - masks = NULL; 290 - goto outnodemsk; 290 + return NULL; 291 291 } 292 292 curvec += this_vecs; 293 293 usedvecs += this_vecs; ··· 317 293 for (i = affd->pre_vectors; i < nvecs - affd->post_vectors; i++) 318 294 masks[i].is_managed = 1; 319 295 320 - outnodemsk: 321 - free_node_to_cpumask(node_to_cpumask); 322 296 return masks; 323 297 } 324 298 ··· 326 304 * @maxvec: The maximum number of vectors available 327 305 * @affd: Description of the affinity requirements 328 306 */ 329 - int irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd) 307 + unsigned int irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec, 308 + const struct irq_affinity *affd) 330 309 { 331 - int resv = affd->pre_vectors + affd->post_vectors; 332 - int vecs = maxvec - resv; 333 - int set_vecs; 310 + unsigned int resv = affd->pre_vectors + affd->post_vectors; 311 + unsigned int set_vecs; 334 312 335 313 if (resv > minvec) 336 314 return 0; 337 315 338 - if (affd->nr_sets) { 339 - int i; 340 - 341 - for (i = 0, set_vecs = 0; i < affd->nr_sets; i++) 342 - set_vecs += affd->sets[i]; 316 + if (affd->calc_sets) { 317 + set_vecs = maxvec - resv; 343 318 } else { 344 319 get_online_cpus(); 345 320 set_vecs = cpumask_weight(cpu_possible_mask); 346 321 put_online_cpus(); 347 322 } 348 323 349 - return resv + min(set_vecs, vecs); 324 + return resv + min(set_vecs, maxvec - resv); 350 325 }
+64 -2
kernel/irq/chip.c
··· 730 730 EXPORT_SYMBOL_GPL(handle_fasteoi_irq); 731 731 732 732 /** 733 + * handle_fasteoi_nmi - irq handler for NMI interrupt lines 734 + * @desc: the interrupt description structure for this irq 735 + * 736 + * A simple NMI-safe handler, considering the restrictions 737 + * from request_nmi. 738 + * 739 + * Only a single callback will be issued to the chip: an ->eoi() 740 + * call when the interrupt has been serviced. This enables support 741 + * for modern forms of interrupt handlers, which handle the flow 742 + * details in hardware, transparently. 743 + */ 744 + void handle_fasteoi_nmi(struct irq_desc *desc) 745 + { 746 + struct irq_chip *chip = irq_desc_get_chip(desc); 747 + struct irqaction *action = desc->action; 748 + unsigned int irq = irq_desc_get_irq(desc); 749 + irqreturn_t res; 750 + 751 + trace_irq_handler_entry(irq, action); 752 + /* 753 + * NMIs cannot be shared, there is only one action. 754 + */ 755 + res = action->handler(irq, action->dev_id); 756 + trace_irq_handler_exit(irq, action, res); 757 + 758 + if (chip->irq_eoi) 759 + chip->irq_eoi(&desc->irq_data); 760 + } 761 + EXPORT_SYMBOL_GPL(handle_fasteoi_nmi); 762 + 763 + /** 733 764 * handle_edge_irq - edge type IRQ handler 734 765 * @desc: the interrupt description structure for this irq 735 766 * ··· 886 855 { 887 856 struct irq_chip *chip = irq_desc_get_chip(desc); 888 857 889 - kstat_incr_irqs_this_cpu(desc); 858 + /* 859 + * PER CPU interrupts are not serialized. Do not touch 860 + * desc->tot_count. 861 + */ 862 + __kstat_incr_irqs_this_cpu(desc); 890 863 891 864 if (chip->irq_ack) 892 865 chip->irq_ack(&desc->irq_data); ··· 919 884 unsigned int irq = irq_desc_get_irq(desc); 920 885 irqreturn_t res; 921 886 922 - kstat_incr_irqs_this_cpu(desc); 887 + /* 888 + * PER CPU interrupts are not serialized. Do not touch 889 + * desc->tot_count. 890 + */ 891 + __kstat_incr_irqs_this_cpu(desc); 923 892 924 893 if (chip->irq_ack) 925 894 chip->irq_ack(&desc->irq_data); ··· 942 903 pr_err_once("Spurious%s percpu IRQ%u on CPU%u\n", 943 904 enabled ? " and unmasked" : "", irq, cpu); 944 905 } 906 + 907 + if (chip->irq_eoi) 908 + chip->irq_eoi(&desc->irq_data); 909 + } 910 + 911 + /** 912 + * handle_percpu_devid_fasteoi_nmi - Per CPU local NMI handler with per cpu 913 + * dev ids 914 + * @desc: the interrupt description structure for this irq 915 + * 916 + * Similar to handle_fasteoi_nmi, but handling the dev_id cookie 917 + * as a percpu pointer. 918 + */ 919 + void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc) 920 + { 921 + struct irq_chip *chip = irq_desc_get_chip(desc); 922 + struct irqaction *action = desc->action; 923 + unsigned int irq = irq_desc_get_irq(desc); 924 + irqreturn_t res; 925 + 926 + trace_irq_handler_entry(irq, action); 927 + res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id)); 928 + trace_irq_handler_exit(irq, action, res); 945 929 946 930 if (chip->irq_eoi) 947 931 chip->irq_eoi(&desc->irq_data);
+4 -4
kernel/irq/debugfs.c
··· 56 56 BIT_MASK_DESCR(IRQCHIP_ONESHOT_SAFE), 57 57 BIT_MASK_DESCR(IRQCHIP_EOI_THREADED), 58 58 BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI), 59 + BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI), 59 60 }; 60 61 61 62 static void ··· 141 140 BIT_MASK_DESCR(IRQS_WAITING), 142 141 BIT_MASK_DESCR(IRQS_PENDING), 143 142 BIT_MASK_DESCR(IRQS_SUSPENDED), 143 + BIT_MASK_DESCR(IRQS_NMI), 144 144 }; 145 145 146 146 ··· 205 203 chip_bus_lock(desc); 206 204 raw_spin_lock_irqsave(&desc->lock, flags); 207 205 208 - if (irq_settings_is_level(desc)) { 209 - /* Can't do level, sorry */ 206 + if (irq_settings_is_level(desc) || desc->istate & IRQS_NMI) { 207 + /* Can't do level nor NMIs, sorry */ 210 208 err = -EINVAL; 211 209 } else { 212 210 desc->istate |= IRQS_PENDING; ··· 258 256 int irq; 259 257 260 258 root_dir = debugfs_create_dir("irq", NULL); 261 - if (!root_dir) 262 - return -ENOMEM; 263 259 264 260 irq_domain_debugfs_init(root_dir); 265 261
+1 -1
kernel/irq/handle.c
··· 166 166 167 167 __irq_wake_thread(desc, action); 168 168 169 - /* Fall through to add to randomness */ 169 + /* Fall through - to add to randomness */ 170 170 case IRQ_HANDLED: 171 171 *flags |= action->flags; 172 172 break;
+9 -1
kernel/irq/internals.h
··· 49 49 * IRQS_WAITING - irq is waiting 50 50 * IRQS_PENDING - irq is pending and replayed later 51 51 * IRQS_SUSPENDED - irq is suspended 52 + * IRQS_NMI - irq line is used to deliver NMIs 52 53 */ 53 54 enum { 54 55 IRQS_AUTODETECT = 0x00000001, ··· 61 60 IRQS_PENDING = 0x00000200, 62 61 IRQS_SUSPENDED = 0x00000800, 63 62 IRQS_TIMINGS = 0x00001000, 63 + IRQS_NMI = 0x00002000, 64 64 }; 65 65 66 66 #include "debug.h" ··· 244 242 245 243 #undef __irqd_to_state 246 244 247 - static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc) 245 + static inline void __kstat_incr_irqs_this_cpu(struct irq_desc *desc) 248 246 { 249 247 __this_cpu_inc(*desc->kstat_irqs); 250 248 __this_cpu_inc(kstat.irqs_sum); 249 + } 250 + 251 + static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc) 252 + { 253 + __kstat_incr_irqs_this_cpu(desc); 254 + desc->tot_count++; 251 255 } 252 256 253 257 static inline int irq_desc_get_node(struct irq_desc *desc)
+41 -1
kernel/irq/irqdesc.c
··· 119 119 desc->depth = 1; 120 120 desc->irq_count = 0; 121 121 desc->irqs_unhandled = 0; 122 + desc->tot_count = 0; 122 123 desc->name = NULL; 123 124 desc->owner = owner; 124 125 for_each_possible_cpu(cpu) ··· 670 669 set_irq_regs(old_regs); 671 670 return ret; 672 671 } 672 + 673 + #ifdef CONFIG_IRQ_DOMAIN 674 + /** 675 + * handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain 676 + * @domain: The domain where to perform the lookup 677 + * @hwirq: The HW irq number to convert to a logical one 678 + * @regs: Register file coming from the low-level handling code 679 + * 680 + * Returns: 0 on success, or -EINVAL if conversion has failed 681 + */ 682 + int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, 683 + struct pt_regs *regs) 684 + { 685 + struct pt_regs *old_regs = set_irq_regs(regs); 686 + unsigned int irq; 687 + int ret = 0; 688 + 689 + nmi_enter(); 690 + 691 + irq = irq_find_mapping(domain, hwirq); 692 + 693 + /* 694 + * ack_bad_irq is not NMI-safe, just report 695 + * an invalid interrupt. 696 + */ 697 + if (likely(irq)) 698 + generic_handle_irq(irq); 699 + else 700 + ret = -EINVAL; 701 + 702 + nmi_exit(); 703 + set_irq_regs(old_regs); 704 + return ret; 705 + } 706 + #endif 673 707 #endif 674 708 675 709 /* Dynamic interrupt handling */ ··· 955 919 unsigned int kstat_irqs(unsigned int irq) 956 920 { 957 921 struct irq_desc *desc = irq_to_desc(irq); 958 - int cpu; 959 922 unsigned int sum = 0; 923 + int cpu; 960 924 961 925 if (!desc || !desc->kstat_irqs) 962 926 return 0; 927 + if (!irq_settings_is_per_cpu_devid(desc) && 928 + !irq_settings_is_per_cpu(desc)) 929 + return desc->tot_count; 930 + 963 931 for_each_possible_cpu(cpu) 964 932 sum += *per_cpu_ptr(desc->kstat_irqs, cpu); 965 933 return sum;
+14 -2
kernel/irq/irqdomain.c
··· 458 458 } 459 459 EXPORT_SYMBOL_GPL(irq_set_default_host); 460 460 461 + /** 462 + * irq_get_default_host() - Retrieve the "default" irq domain 463 + * 464 + * Returns: the default domain, if any. 465 + * 466 + * Modern code should never use this. This should only be used on 467 + * systems that cannot implement a firmware->fwnode mapping (which 468 + * both DT and ACPI provide). 469 + */ 470 + struct irq_domain *irq_get_default_host(void) 471 + { 472 + return irq_default_domain; 473 + } 474 + 461 475 static void irq_domain_clear_mapping(struct irq_domain *domain, 462 476 irq_hw_number_t hwirq) 463 477 { ··· 1763 1749 struct irq_domain *d; 1764 1750 1765 1751 domain_dir = debugfs_create_dir("domains", root); 1766 - if (!domain_dir) 1767 - return; 1768 1752 1769 1753 debugfs_create_file("default", 0444, domain_dir, NULL, 1770 1754 &irq_domain_debug_fops);
+405 -1
kernel/irq/manage.c
··· 341 341 /* The release function is promised process context */ 342 342 might_sleep(); 343 343 344 - if (!desc) 344 + if (!desc || desc->istate & IRQS_NMI) 345 345 return -EINVAL; 346 346 347 347 /* Complete initialisation of *notify */ ··· 553 553 } 554 554 EXPORT_SYMBOL_GPL(disable_hardirq); 555 555 556 + /** 557 + * disable_nmi_nosync - disable an nmi without waiting 558 + * @irq: Interrupt to disable 559 + * 560 + * Disable the selected interrupt line. Disables and enables are 561 + * nested. 562 + * The interrupt to disable must have been requested through request_nmi. 563 + * Unlike disable_nmi(), this function does not ensure existing 564 + * instances of the IRQ handler have completed before returning. 565 + */ 566 + void disable_nmi_nosync(unsigned int irq) 567 + { 568 + disable_irq_nosync(irq); 569 + } 570 + 556 571 void __enable_irq(struct irq_desc *desc) 557 572 { 558 573 switch (desc->depth) { ··· 624 609 } 625 610 EXPORT_SYMBOL(enable_irq); 626 611 612 + /** 613 + * enable_nmi - enable handling of an nmi 614 + * @irq: Interrupt to enable 615 + * 616 + * The interrupt to enable must have been requested through request_nmi. 617 + * Undoes the effect of one call to disable_nmi(). If this 618 + * matches the last disable, processing of interrupts on this 619 + * IRQ line is re-enabled. 620 + */ 621 + void enable_nmi(unsigned int irq) 622 + { 623 + enable_irq(irq); 624 + } 625 + 627 626 static int set_irq_wake_real(unsigned int irq, unsigned int on) 628 627 { 629 628 struct irq_desc *desc = irq_to_desc(irq); ··· 673 644 if (!desc) 674 645 return -EINVAL; 675 646 647 + /* Don't use NMIs as wake up interrupts please */ 648 + if (desc->istate & IRQS_NMI) { 649 + ret = -EINVAL; 650 + goto out_unlock; 651 + } 652 + 676 653 /* wakeup-capable irqs can be shared between drivers that 677 654 * don't need to have the same sleep mode behaviors. 678 655 */ ··· 701 666 irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE); 702 667 } 703 668 } 669 + 670 + out_unlock: 704 671 irq_put_desc_busunlock(desc, flags); 705 672 return ret; 706 673 } ··· 763 726 case IRQ_SET_MASK_OK_DONE: 764 727 irqd_clear(&desc->irq_data, IRQD_TRIGGER_MASK); 765 728 irqd_set(&desc->irq_data, flags); 729 + /* fall through */ 766 730 767 731 case IRQ_SET_MASK_OK_NOCOPY: 768 732 flags = irqd_get_trigger_type(&desc->irq_data); ··· 1166 1128 c->irq_release_resources(d); 1167 1129 } 1168 1130 1131 + static bool irq_supports_nmi(struct irq_desc *desc) 1132 + { 1133 + struct irq_data *d = irq_desc_get_irq_data(desc); 1134 + 1135 + #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 1136 + /* Only IRQs directly managed by the root irqchip can be set as NMI */ 1137 + if (d->parent_data) 1138 + return false; 1139 + #endif 1140 + /* Don't support NMIs for chips behind a slow bus */ 1141 + if (d->chip->irq_bus_lock || d->chip->irq_bus_sync_unlock) 1142 + return false; 1143 + 1144 + return d->chip->flags & IRQCHIP_SUPPORTS_NMI; 1145 + } 1146 + 1147 + static int irq_nmi_setup(struct irq_desc *desc) 1148 + { 1149 + struct irq_data *d = irq_desc_get_irq_data(desc); 1150 + struct irq_chip *c = d->chip; 1151 + 1152 + return c->irq_nmi_setup ? c->irq_nmi_setup(d) : -EINVAL; 1153 + } 1154 + 1155 + static void irq_nmi_teardown(struct irq_desc *desc) 1156 + { 1157 + struct irq_data *d = irq_desc_get_irq_data(desc); 1158 + struct irq_chip *c = d->chip; 1159 + 1160 + if (c->irq_nmi_teardown) 1161 + c->irq_nmi_teardown(d); 1162 + } 1163 + 1169 1164 static int 1170 1165 setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary) 1171 1166 { ··· 1373 1302 * fields must have IRQF_SHARED set and the bits which 1374 1303 * set the trigger type must match. Also all must 1375 1304 * agree on ONESHOT. 1305 + * Interrupt lines used for NMIs cannot be shared. 1376 1306 */ 1377 1307 unsigned int oldtype; 1308 + 1309 + if (desc->istate & IRQS_NMI) { 1310 + pr_err("Invalid attempt to share NMI for %s (irq %d) on irqchip %s.\n", 1311 + new->name, irq, desc->irq_data.chip->name); 1312 + ret = -EINVAL; 1313 + goto out_unlock; 1314 + } 1378 1315 1379 1316 /* 1380 1317 * If nobody did set the configuration before, inherit ··· 1835 1756 } 1836 1757 EXPORT_SYMBOL(free_irq); 1837 1758 1759 + /* This function must be called with desc->lock held */ 1760 + static const void *__cleanup_nmi(unsigned int irq, struct irq_desc *desc) 1761 + { 1762 + const char *devname = NULL; 1763 + 1764 + desc->istate &= ~IRQS_NMI; 1765 + 1766 + if (!WARN_ON(desc->action == NULL)) { 1767 + irq_pm_remove_action(desc, desc->action); 1768 + devname = desc->action->name; 1769 + unregister_handler_proc(irq, desc->action); 1770 + 1771 + kfree(desc->action); 1772 + desc->action = NULL; 1773 + } 1774 + 1775 + irq_settings_clr_disable_unlazy(desc); 1776 + irq_shutdown(desc); 1777 + 1778 + irq_release_resources(desc); 1779 + 1780 + irq_chip_pm_put(&desc->irq_data); 1781 + module_put(desc->owner); 1782 + 1783 + return devname; 1784 + } 1785 + 1786 + const void *free_nmi(unsigned int irq, void *dev_id) 1787 + { 1788 + struct irq_desc *desc = irq_to_desc(irq); 1789 + unsigned long flags; 1790 + const void *devname; 1791 + 1792 + if (!desc || WARN_ON(!(desc->istate & IRQS_NMI))) 1793 + return NULL; 1794 + 1795 + if (WARN_ON(irq_settings_is_per_cpu_devid(desc))) 1796 + return NULL; 1797 + 1798 + /* NMI still enabled */ 1799 + if (WARN_ON(desc->depth == 0)) 1800 + disable_nmi_nosync(irq); 1801 + 1802 + raw_spin_lock_irqsave(&desc->lock, flags); 1803 + 1804 + irq_nmi_teardown(desc); 1805 + devname = __cleanup_nmi(irq, desc); 1806 + 1807 + raw_spin_unlock_irqrestore(&desc->lock, flags); 1808 + 1809 + return devname; 1810 + } 1811 + 1838 1812 /** 1839 1813 * request_threaded_irq - allocate an interrupt line 1840 1814 * @irq: Interrupt line to allocate ··· 2057 1925 } 2058 1926 EXPORT_SYMBOL_GPL(request_any_context_irq); 2059 1927 1928 + /** 1929 + * request_nmi - allocate an interrupt line for NMI delivery 1930 + * @irq: Interrupt line to allocate 1931 + * @handler: Function to be called when the IRQ occurs. 1932 + * Threaded handler for threaded interrupts. 1933 + * @irqflags: Interrupt type flags 1934 + * @name: An ascii name for the claiming device 1935 + * @dev_id: A cookie passed back to the handler function 1936 + * 1937 + * This call allocates interrupt resources and enables the 1938 + * interrupt line and IRQ handling. It sets up the IRQ line 1939 + * to be handled as an NMI. 1940 + * 1941 + * An interrupt line delivering NMIs cannot be shared and IRQ handling 1942 + * cannot be threaded. 1943 + * 1944 + * Interrupt lines requested for NMI delivering must produce per cpu 1945 + * interrupts and have auto enabling setting disabled. 1946 + * 1947 + * Dev_id must be globally unique. Normally the address of the 1948 + * device data structure is used as the cookie. Since the handler 1949 + * receives this value it makes sense to use it. 1950 + * 1951 + * If the interrupt line cannot be used to deliver NMIs, function 1952 + * will fail and return a negative value. 1953 + */ 1954 + int request_nmi(unsigned int irq, irq_handler_t handler, 1955 + unsigned long irqflags, const char *name, void *dev_id) 1956 + { 1957 + struct irqaction *action; 1958 + struct irq_desc *desc; 1959 + unsigned long flags; 1960 + int retval; 1961 + 1962 + if (irq == IRQ_NOTCONNECTED) 1963 + return -ENOTCONN; 1964 + 1965 + /* NMI cannot be shared, used for Polling */ 1966 + if (irqflags & (IRQF_SHARED | IRQF_COND_SUSPEND | IRQF_IRQPOLL)) 1967 + return -EINVAL; 1968 + 1969 + if (!(irqflags & IRQF_PERCPU)) 1970 + return -EINVAL; 1971 + 1972 + if (!handler) 1973 + return -EINVAL; 1974 + 1975 + desc = irq_to_desc(irq); 1976 + 1977 + if (!desc || irq_settings_can_autoenable(desc) || 1978 + !irq_settings_can_request(desc) || 1979 + WARN_ON(irq_settings_is_per_cpu_devid(desc)) || 1980 + !irq_supports_nmi(desc)) 1981 + return -EINVAL; 1982 + 1983 + action = kzalloc(sizeof(struct irqaction), GFP_KERNEL); 1984 + if (!action) 1985 + return -ENOMEM; 1986 + 1987 + action->handler = handler; 1988 + action->flags = irqflags | IRQF_NO_THREAD | IRQF_NOBALANCING; 1989 + action->name = name; 1990 + action->dev_id = dev_id; 1991 + 1992 + retval = irq_chip_pm_get(&desc->irq_data); 1993 + if (retval < 0) 1994 + goto err_out; 1995 + 1996 + retval = __setup_irq(irq, desc, action); 1997 + if (retval) 1998 + goto err_irq_setup; 1999 + 2000 + raw_spin_lock_irqsave(&desc->lock, flags); 2001 + 2002 + /* Setup NMI state */ 2003 + desc->istate |= IRQS_NMI; 2004 + retval = irq_nmi_setup(desc); 2005 + if (retval) { 2006 + __cleanup_nmi(irq, desc); 2007 + raw_spin_unlock_irqrestore(&desc->lock, flags); 2008 + return -EINVAL; 2009 + } 2010 + 2011 + raw_spin_unlock_irqrestore(&desc->lock, flags); 2012 + 2013 + return 0; 2014 + 2015 + err_irq_setup: 2016 + irq_chip_pm_put(&desc->irq_data); 2017 + err_out: 2018 + kfree(action); 2019 + 2020 + return retval; 2021 + } 2022 + 2060 2023 void enable_percpu_irq(unsigned int irq, unsigned int type) 2061 2024 { 2062 2025 unsigned int cpu = smp_processor_id(); ··· 2185 1958 irq_put_desc_unlock(desc, flags); 2186 1959 } 2187 1960 EXPORT_SYMBOL_GPL(enable_percpu_irq); 1961 + 1962 + void enable_percpu_nmi(unsigned int irq, unsigned int type) 1963 + { 1964 + enable_percpu_irq(irq, type); 1965 + } 2188 1966 2189 1967 /** 2190 1968 * irq_percpu_is_enabled - Check whether the per cpu irq is enabled ··· 2230 1998 } 2231 1999 EXPORT_SYMBOL_GPL(disable_percpu_irq); 2232 2000 2001 + void disable_percpu_nmi(unsigned int irq) 2002 + { 2003 + disable_percpu_irq(irq); 2004 + } 2005 + 2233 2006 /* 2234 2007 * Internal function to unregister a percpu irqaction. 2235 2008 */ ··· 2265 2028 2266 2029 /* Found it - now remove it from the list of entries: */ 2267 2030 desc->action = NULL; 2031 + 2032 + desc->istate &= ~IRQS_NMI; 2268 2033 2269 2034 raw_spin_unlock_irqrestore(&desc->lock, flags); 2270 2035 ··· 2320 2081 chip_bus_sync_unlock(desc); 2321 2082 } 2322 2083 EXPORT_SYMBOL_GPL(free_percpu_irq); 2084 + 2085 + void free_percpu_nmi(unsigned int irq, void __percpu *dev_id) 2086 + { 2087 + struct irq_desc *desc = irq_to_desc(irq); 2088 + 2089 + if (!desc || !irq_settings_is_per_cpu_devid(desc)) 2090 + return; 2091 + 2092 + if (WARN_ON(!(desc->istate & IRQS_NMI))) 2093 + return; 2094 + 2095 + kfree(__free_percpu_irq(irq, dev_id)); 2096 + } 2323 2097 2324 2098 /** 2325 2099 * setup_percpu_irq - setup a per-cpu interrupt ··· 2422 2170 return retval; 2423 2171 } 2424 2172 EXPORT_SYMBOL_GPL(__request_percpu_irq); 2173 + 2174 + /** 2175 + * request_percpu_nmi - allocate a percpu interrupt line for NMI delivery 2176 + * @irq: Interrupt line to allocate 2177 + * @handler: Function to be called when the IRQ occurs. 2178 + * @name: An ascii name for the claiming device 2179 + * @dev_id: A percpu cookie passed back to the handler function 2180 + * 2181 + * This call allocates interrupt resources for a per CPU NMI. Per CPU NMIs 2182 + * have to be setup on each CPU by calling prepare_percpu_nmi() before 2183 + * being enabled on the same CPU by using enable_percpu_nmi(). 2184 + * 2185 + * Dev_id must be globally unique. It is a per-cpu variable, and 2186 + * the handler gets called with the interrupted CPU's instance of 2187 + * that variable. 2188 + * 2189 + * Interrupt lines requested for NMI delivering should have auto enabling 2190 + * setting disabled. 2191 + * 2192 + * If the interrupt line cannot be used to deliver NMIs, function 2193 + * will fail returning a negative value. 2194 + */ 2195 + int request_percpu_nmi(unsigned int irq, irq_handler_t handler, 2196 + const char *name, void __percpu *dev_id) 2197 + { 2198 + struct irqaction *action; 2199 + struct irq_desc *desc; 2200 + unsigned long flags; 2201 + int retval; 2202 + 2203 + if (!handler) 2204 + return -EINVAL; 2205 + 2206 + desc = irq_to_desc(irq); 2207 + 2208 + if (!desc || !irq_settings_can_request(desc) || 2209 + !irq_settings_is_per_cpu_devid(desc) || 2210 + irq_settings_can_autoenable(desc) || 2211 + !irq_supports_nmi(desc)) 2212 + return -EINVAL; 2213 + 2214 + /* The line cannot already be NMI */ 2215 + if (desc->istate & IRQS_NMI) 2216 + return -EINVAL; 2217 + 2218 + action = kzalloc(sizeof(struct irqaction), GFP_KERNEL); 2219 + if (!action) 2220 + return -ENOMEM; 2221 + 2222 + action->handler = handler; 2223 + action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND | IRQF_NO_THREAD 2224 + | IRQF_NOBALANCING; 2225 + action->name = name; 2226 + action->percpu_dev_id = dev_id; 2227 + 2228 + retval = irq_chip_pm_get(&desc->irq_data); 2229 + if (retval < 0) 2230 + goto err_out; 2231 + 2232 + retval = __setup_irq(irq, desc, action); 2233 + if (retval) 2234 + goto err_irq_setup; 2235 + 2236 + raw_spin_lock_irqsave(&desc->lock, flags); 2237 + desc->istate |= IRQS_NMI; 2238 + raw_spin_unlock_irqrestore(&desc->lock, flags); 2239 + 2240 + return 0; 2241 + 2242 + err_irq_setup: 2243 + irq_chip_pm_put(&desc->irq_data); 2244 + err_out: 2245 + kfree(action); 2246 + 2247 + return retval; 2248 + } 2249 + 2250 + /** 2251 + * prepare_percpu_nmi - performs CPU local setup for NMI delivery 2252 + * @irq: Interrupt line to prepare for NMI delivery 2253 + * 2254 + * This call prepares an interrupt line to deliver NMI on the current CPU, 2255 + * before that interrupt line gets enabled with enable_percpu_nmi(). 2256 + * 2257 + * As a CPU local operation, this should be called from non-preemptible 2258 + * context. 2259 + * 2260 + * If the interrupt line cannot be used to deliver NMIs, function 2261 + * will fail returning a negative value. 2262 + */ 2263 + int prepare_percpu_nmi(unsigned int irq) 2264 + { 2265 + unsigned long flags; 2266 + struct irq_desc *desc; 2267 + int ret = 0; 2268 + 2269 + WARN_ON(preemptible()); 2270 + 2271 + desc = irq_get_desc_lock(irq, &flags, 2272 + IRQ_GET_DESC_CHECK_PERCPU); 2273 + if (!desc) 2274 + return -EINVAL; 2275 + 2276 + if (WARN(!(desc->istate & IRQS_NMI), 2277 + KERN_ERR "prepare_percpu_nmi called for a non-NMI interrupt: irq %u\n", 2278 + irq)) { 2279 + ret = -EINVAL; 2280 + goto out; 2281 + } 2282 + 2283 + ret = irq_nmi_setup(desc); 2284 + if (ret) { 2285 + pr_err("Failed to setup NMI delivery: irq %u\n", irq); 2286 + goto out; 2287 + } 2288 + 2289 + out: 2290 + irq_put_desc_unlock(desc, flags); 2291 + return ret; 2292 + } 2293 + 2294 + /** 2295 + * teardown_percpu_nmi - undoes NMI setup of IRQ line 2296 + * @irq: Interrupt line from which CPU local NMI configuration should be 2297 + * removed 2298 + * 2299 + * This call undoes the setup done by prepare_percpu_nmi(). 2300 + * 2301 + * IRQ line should not be enabled for the current CPU. 2302 + * 2303 + * As a CPU local operation, this should be called from non-preemptible 2304 + * context. 2305 + */ 2306 + void teardown_percpu_nmi(unsigned int irq) 2307 + { 2308 + unsigned long flags; 2309 + struct irq_desc *desc; 2310 + 2311 + WARN_ON(preemptible()); 2312 + 2313 + desc = irq_get_desc_lock(irq, &flags, 2314 + IRQ_GET_DESC_CHECK_PERCPU); 2315 + if (!desc) 2316 + return; 2317 + 2318 + if (WARN_ON(!(desc->istate & IRQS_NMI))) 2319 + goto out; 2320 + 2321 + irq_nmi_teardown(desc); 2322 + out: 2323 + irq_put_desc_unlock(desc, flags); 2324 + } 2425 2325 2426 2326 /** 2427 2327 * irq_get_irqchip_state - returns the irqchip state of a interrupt.
+7 -1
kernel/kthread.c
··· 101 101 } 102 102 EXPORT_SYMBOL(kthread_should_stop); 103 103 104 + bool __kthread_should_park(struct task_struct *k) 105 + { 106 + return test_bit(KTHREAD_SHOULD_PARK, &to_kthread(k)->flags); 107 + } 108 + EXPORT_SYMBOL_GPL(__kthread_should_park); 109 + 104 110 /** 105 111 * kthread_should_park - should this kthread park now? 106 112 * ··· 120 114 */ 121 115 bool kthread_should_park(void) 122 116 { 123 - return test_bit(KTHREAD_SHOULD_PARK, &to_kthread(current)->flags); 117 + return __kthread_should_park(current); 124 118 } 125 119 EXPORT_SYMBOL_GPL(kthread_should_park); 126 120
+2 -1
kernel/softirq.c
··· 89 89 90 90 if (pending & SOFTIRQ_NOW_MASK) 91 91 return false; 92 - return tsk && (tsk->state == TASK_RUNNING); 92 + return tsk && (tsk->state == TASK_RUNNING) && 93 + !__kthread_should_park(tsk); 93 94 } 94 95 95 96 /*