From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756858AbbCSRzu (ORCPT ); Thu, 19 Mar 2015 13:55:50 -0400 Received: from mx0b-000f0801.pphosted.com ([67.231.152.113]:3301 "EHLO mx0b-000f0801.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755374AbbCSRzl (ORCPT ); Thu, 19 Mar 2015 13:55:41 -0400 Message-ID: <550B0D8E.1010200@brocade.com> Date: Thu, 19 Mar 2015 17:55:26 +0000 From: Brian Russell User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.5.0 MIME-Version: 1.0 To: "Hans J. Koch" , Greg Kroah-Hartman CC: Subject: [PATCH 1/2] uio: Request/free irq separate from dev lifecycle Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.13.68,1.0.33,0.0.0000 definitions=2015-03-19_06:2015-03-19,2015-03-19,1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=2 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1503190159 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/uio/uio.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 6276f13..65bf067 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -835,7 +835,15 @@ int __uio_register_device(struct module *owner, info->uio_dev = idev; if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { - ret = devm_request_irq(idev->dev, info->irq, uio_interrupt, + /* + * Note that we deliberately don't use devm_request_irq + * here. The parent module can unregister the UIO device + * and call pci_disable_msi, which requires that this + * irq has been freed. However, the device may have open + * FDs at the time of unregister and therefore may not be + * freed until they are released. + */ + ret = request_irq(info->irq, uio_interrupt, info->irq_flags, info->name, idev); if (ret) goto err_request_irq; @@ -871,6 +879,8 @@ void uio_unregister_device(struct uio_info *info) uio_dev_del_attributes(idev); + free_irq(idev->info->irq, idev); + device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); return; -- 2.1.4