aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Russell <brian.russell@brocade.com>2015-03-19 13:55:26 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-20 08:18:16 -0400
commita087146c72bad795bcab80e5987c5b80fa225000 (patch)
treec39771b658ac6befec0ab6ca552c6ad533d03ea9
parent03b225b16d75bccf9bc4d82607964a08148adf61 (diff)
uio: Request/free irq separate from dev lifecycle
Separate irq request/free from the device lifecycle. After device unregister the parent module can call pci_disable_msi. >From the PCI MSI how to: "Before calling this function, a device driver must always call free_irq() on any interrupt for which it previously called request_irq(). Failure to do so results in a BUG_ON(), leaving the device with MSI enabled and thus leaking its vector." So we need to separately free the irq at unregister to allow the device to be kept around in the case of it still having open FDs. Signed-off-by: Brian Russell <brussell@brocade.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/uio/uio.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 6276f13e9e12..65bf0676d54a 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -835,7 +835,15 @@ int __uio_register_device(struct module *owner,
835 info->uio_dev = idev; 835 info->uio_dev = idev;
836 836
837 if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { 837 if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
838 ret = devm_request_irq(idev->dev, info->irq, uio_interrupt, 838 /*
839 * Note that we deliberately don't use devm_request_irq
840 * here. The parent module can unregister the UIO device
841 * and call pci_disable_msi, which requires that this
842 * irq has been freed. However, the device may have open
843 * FDs at the time of unregister and therefore may not be
844 * freed until they are released.
845 */
846 ret = request_irq(info->irq, uio_interrupt,
839 info->irq_flags, info->name, idev); 847 info->irq_flags, info->name, idev);
840 if (ret) 848 if (ret)
841 goto err_request_irq; 849 goto err_request_irq;
@@ -871,6 +879,8 @@ void uio_unregister_device(struct uio_info *info)
871 879
872 uio_dev_del_attributes(idev); 880 uio_dev_del_attributes(idev);
873 881
882 free_irq(idev->info->irq, idev);
883
874 device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); 884 device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
875 885
876 return; 886 return;