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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'irq-urgent-2022-02-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fix from Thomas Gleixner:
"A single fix for a regression caused by the recent PCI/MSI rework
which resulted in a recursive locking problem in the VMD driver.

The cure is to cache the relevant information upfront instead of
retrieving it at runtime"

* tag 'irq-urgent-2022-02-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
PCI: vmd: Prevent recursive locking on interrupt allocation

+7 -7
+7 -7
drivers/pci/controller/vmd.c
··· 99 99 * @srcu: SRCU struct for local synchronization. 100 100 * @count: number of child IRQs assigned to this vector; used to track 101 101 * sharing. 102 + * @virq: The underlying VMD Linux interrupt number 102 103 */ 103 104 struct vmd_irq_list { 104 105 struct list_head irq_list; 105 106 struct srcu_struct srcu; 106 107 unsigned int count; 108 + unsigned int virq; 107 109 }; 108 110 109 111 struct vmd_dev { ··· 255 253 struct msi_desc *desc = arg->desc; 256 254 struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus); 257 255 struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); 258 - unsigned int index, vector; 259 256 260 257 if (!vmdirq) 261 258 return -ENOMEM; ··· 262 261 INIT_LIST_HEAD(&vmdirq->node); 263 262 vmdirq->irq = vmd_next_irq(vmd, desc); 264 263 vmdirq->virq = virq; 265 - index = index_from_irqs(vmd, vmdirq->irq); 266 - vector = pci_irq_vector(vmd->dev, index); 267 264 268 - irq_domain_set_info(domain, virq, vector, info->chip, vmdirq, 265 + irq_domain_set_info(domain, virq, vmdirq->irq->virq, info->chip, vmdirq, 269 266 handle_untracked_irq, vmd, NULL); 270 267 return 0; 271 268 } ··· 684 685 return err; 685 686 686 687 INIT_LIST_HEAD(&vmd->irqs[i].irq_list); 687 - err = devm_request_irq(&dev->dev, pci_irq_vector(dev, i), 688 + vmd->irqs[i].virq = pci_irq_vector(dev, i); 689 + err = devm_request_irq(&dev->dev, vmd->irqs[i].virq, 688 690 vmd_irq, IRQF_NO_THREAD, 689 691 vmd->name, &vmd->irqs[i]); 690 692 if (err) ··· 969 969 int i; 970 970 971 971 for (i = 0; i < vmd->msix_count; i++) 972 - devm_free_irq(dev, pci_irq_vector(pdev, i), &vmd->irqs[i]); 972 + devm_free_irq(dev, vmd->irqs[i].virq, &vmd->irqs[i]); 973 973 974 974 return 0; 975 975 } ··· 981 981 int err, i; 982 982 983 983 for (i = 0; i < vmd->msix_count; i++) { 984 - err = devm_request_irq(dev, pci_irq_vector(pdev, i), 984 + err = devm_request_irq(dev, vmd->irqs[i].virq, 985 985 vmd_irq, IRQF_NO_THREAD, 986 986 vmd->name, &vmd->irqs[i]); 987 987 if (err)