Message ID | 20230814093621.23209-3-brgl@bgdev.pl |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b824:0:b0:3f2:4152:657d with SMTP id z4csp2639369vqi; Mon, 14 Aug 2023 03:10:12 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGjM2piY/+95jzwhm73cmlFO++6A5GQJgQkiGDLSNci5V2w1mfjzlMX9DA1XjoPaP85DLIJ X-Received: by 2002:a05:6a00:1ad1:b0:687:6288:783d with SMTP id f17-20020a056a001ad100b006876288783dmr9581962pfv.7.1692007812185; Mon, 14 Aug 2023 03:10:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692007812; cv=none; d=google.com; s=arc-20160816; b=pPX2ItvO/yyBmyuCpdkgyc3HcmhEXcKnzKh7KxKQ3XqiwSe6PL6HvFmh/aHL7Mdo1k 6vBUyrrZTF962FrXReKYK/COqrpXCLFzX5n1/BXzHjxlzRC/w9y/AKjCcjUfMpzGT8BB Bf/Fo/SuYmRpRqAYmkQgACTiDhwnKQh7lYUzJNc8dnHrr8y2ColBt2EZPGP9F202vRjR iu9A3G3FUzeEVFZjlPTTl9MQZc/DjvR2TAqUKH9zQM4+VjjEGR3l/KOyibfts/qUTPt0 7NcBwBuyJ3Taq3qp53TSW3y2m58CwvGPo0sWJpz8KSzYXFv+4nNWxEua7SFVUikY1Kb9 oJ9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=x9GIkI+02jFm9GaovqHGnU7H+AqY3jsX4KEby4kRqP0=; fh=5VnmXmoZBR4+6qVIfQDiLcsiW+SDqIu0KJ6MYk3TKH8=; b=z8+wh4V/lI2I5FF6xTPavaIVPv8lprY046T6gr1xg0KruBdrtNQ8K8PedXTI5D4gFw 3TXYWRiAVWQ8C5zVf+yQcKJpSlJo643IMFWzKkeC8IwsKptDhYsybZ+mFZP4ZxiZYl9v Cs92IPIstMxwFC2toPIk/iFcvEfFcI+9/5AxaaIxz6QTXEt/ULZRK7RgAFSGDOPkRMxq 166aJcfjsgNcQ7uIBB7PR7qpeLSmr+l8XgB/hU1zZ/Aqlar5naOrCAph06jKiY/a6XXn buxnSJqum+Cs4M5qvWekOD8VU1CHofbmesu9GBs7ZwRrAKx3l8RoR26U1gQbugR7RZ/j n83A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bgdev-pl.20221208.gappssmtp.com header.s=20221208 header.b=uitaqFVv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d4-20020a056a0010c400b00686da99493bsi8181123pfu.221.2023.08.14.03.09.58; Mon, 14 Aug 2023 03:10:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@bgdev-pl.20221208.gappssmtp.com header.s=20221208 header.b=uitaqFVv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234870AbjHNJhD (ORCPT <rfc822;274620705z@gmail.com> + 99 others); Mon, 14 Aug 2023 05:37:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234699AbjHNJgq (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 14 Aug 2023 05:36:46 -0400 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E0E2E73 for <linux-kernel@vger.kernel.org>; Mon, 14 Aug 2023 02:36:29 -0700 (PDT) Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-3fe2048c910so37656665e9.1 for <linux-kernel@vger.kernel.org>; Mon, 14 Aug 2023 02:36:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20221208.gappssmtp.com; s=20221208; t=1692005788; x=1692610588; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=x9GIkI+02jFm9GaovqHGnU7H+AqY3jsX4KEby4kRqP0=; b=uitaqFVvR6wG+2WZxZnkMJsbIyf80+jIPR57rXBxpxxKezVlMzJKTeUBYqcHrfaKlO hrp7aqI4YGAn8CplW3KnRMOYvF/HPhiP+ar40CrfhJrKkBOjD5jjozVwn5GvtfmZmra8 +jsuiDnH//FbniWJ0t5T8gOYrPGZC4L43txWOhyP6azrObVGJ7n2KsXvfZqGY46CPBjk 9ODpZZejIlfw9nq6gj1CG1oHAWUtAcj6hTOaZrZgvCVmdwiB0H70LwcApl+a1DHwGXmY GB7hp0lceP+YVqEbga7HVcupnwQjyha4U0713nOcu2uf7hPGZKH1lT5Dll/XwMtfa2AW e+9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692005788; x=1692610588; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=x9GIkI+02jFm9GaovqHGnU7H+AqY3jsX4KEby4kRqP0=; b=isPFth6x4mbjCK/YNinKaptx0XJu+Db41qmauxE2rxjG1Lln6khfXskDwpYBxw8fzw 9pBSkUJVMokgAIKK5jwTX8UZuWyMCiwLcAjtDqTurvOlII9Q/Ti11cr5vsshnTlb/JsA gkFnpZh97qhTKtI552UckbV80kHrdVmHHSOdM+UUZ6PYSayqhAct0NwJV60VErT4o6vC 6Xobi6T9TI+N+3iSB6JGIPrj5AzEd7E9MHYLrHcORiZ30Yk32pj2ghfnQIic+nkomv1s nzspttHvEy1lunVC8anRiRSVr+pqHNkj8/P9Wjedd/IKlzSHHPea0DrukxGESiK6KsDk qpgQ== X-Gm-Message-State: AOJu0YygtAIFaT7HNSieMVJlQGMXl0rAGKnVbmcBuew2Vuyr0lg31UQc SQv2RuDy/6I88h1iO1E0INiv7Q== X-Received: by 2002:adf:ff92:0:b0:317:ed01:dc48 with SMTP id j18-20020adfff92000000b00317ed01dc48mr6349175wrr.9.1692005788084; Mon, 14 Aug 2023 02:36:28 -0700 (PDT) Received: from brgl-uxlite.home ([2a01:cb1d:334:ac00:d0cb:d23e:f2fb:62b4]) by smtp.gmail.com with ESMTPSA id d17-20020adfe851000000b003197839d68asm2422140wrn.97.2023.08.14.02.36.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Aug 2023 02:36:27 -0700 (PDT) From: Bartosz Golaszewski <brgl@bgdev.pl> To: Thomas Gleixner <tglx@linutronix.de>, Marc Zyngier <marc.zyngier@arm.com> Cc: linux-kernel@vger.kernel.org, Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Subject: [PATCH 2/2] genirq: proc: fix a procfs entry leak Date: Mon, 14 Aug 2023 11:36:21 +0200 Message-Id: <20230814093621.23209-3-brgl@bgdev.pl> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230814093621.23209-1-brgl@bgdev.pl> References: <20230814093621.23209-1-brgl@bgdev.pl> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1774198784066327532 X-GMAIL-MSGID: 1774198784066327532 |
Series |
genirq: don't leak handler procfs entries
|
|
Commit Message
Bartosz Golaszewski
Aug. 14, 2023, 9:36 a.m. UTC
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> When removing the proc entry for a desc that still has active users, we will leak the irqaction entries. Let's remove them in unregister_irq_proc(). Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> --- kernel/irq/proc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
Comments
On Wed, Sep 06 2023 at 16:54, Bartosz Golaszewski wrote: > On Wed, Aug 30, 2023 at 12:29 AM Thomas Gleixner <tglx@linutronix.de> wrote: >> usb disconnect >> ... >> cp2112_remove() >> i2c_del_adapter() >> i2c_unregister_device(client) >> ... >> device_unregister() >> device_del() >> bus_notify() // Mechanism #1 >> i2c_device_remove() >> if (dev->remove) >> dev->remove() >> ... >> device_unbind_cleanup() >> devres_release_all() // Mechanism #2 >> >> gpiochip_remove() >> >> There are very well notifications to the drivers about unplug of a >> device. Otherwise this would end up in a complete disaster and a lot >> more stale data and state than just a procfs file or a requested >> interrupt. > > I'm not sure how either of the two helps here. #2 just releases > managed resources owned by cp2112. It can remove the domain with an > appropriate devm action but it won't do anything for the users of > interrupts. #1 is a bus notification emitted when the I2C adapter > exposed by cp2112 has been deleted. No. The domain is not yet gone at the point where the I2C bus notification happens. Look at the above invocation chain. The removal of the attached I2C devices happens _before_ the domain is removed. Anything else does not make sense at all. So the cleanup of those devices should free the interrupt, in the same way it frees other resources, no? i2c_device_remove() if (driver->remove) driver->remove() // Driver specific cleanup // Devres cleanup operating on the to be removed I2C device devres_release_group(&client->dev, client->devres_group_id); So again: cp2112_remove() i2c_del_adapter() // Cleans up all I2C users gpiochip_remove() // Removes the interrupt domain. So you do not need any magic bus notififications and whatever. It's all there already. > This one in particular doesn't help us, the domain is long gone by now > but if I get what you mean correctly, you'd want the driver to call > request_irq() and then set up a notifier block for the > BUS_NOTIFY_UNBIND_DRIVER notification of the provider of that > interrupt? Doesn't that break like half a dozen of abstraction layers? > Because now the device driver which is the GPIO consumer needs to know > where it gets its interrupts from? Again. It does not. The point is that the device is removed in the hotplug event chain, which cleans up the associated resources. devm_request_irq() already takes care of that. > You would think that plug-and-play works well in the kernel and it's > true for certain parts but it really isn't the case for subsystems > that were not considered as very plug-and-play until people started > putting them on a stick. Some devices that are not typically > hot-pluggable - like serial - have been used with USB for so long that > they do handle unplugging very well. But as soon as you put i2c on > USB, you'll see what a mess it is. If you have an I2C device on a USB > I2C expander and it's being used, when you pull the plug, you'll see > that the kernel thread removing the device will block on a call to > wait_for_completion() until all users release their i2c adapter > references. They (the users) are not however notified in any generic > way about the provider of their resources being gone. So why aren't you fixing this and instead trying to implement force unplug mechanisms which require a pile of unholy hacks all over the place? >> All hotpluggable consumers have at least one mechanism to mop up the >> resources they allocated. There are a lot of resources in the kernel >> which do not clean themself up magically. >> > > Yeah, hotpluggable consumers are fine. The problem here is > hotpluggable *providers* with consumers who don't know that. Then these consumers have to be fixed and made aware of the new world order of hotplug, no? >> Your idea of tracking request_irq()/free_irq() at some subsystem level >> is not going to work either simply because it requires that such muck is >> sprinkled all over the place. >> > I was thinking more about tracking it at the irq domain level so that > when a domain is destroyed with interrupts requested, these interrupts > are freed. I admit I still don't have enough in-depth knowledge about > linux interrupts to understand why it can't work, I need to spend > more time on this. I'll be back. There is no need for special tracking. The core can figure out today whether an interrupt which is mapped by the domain is requested or not. That's not the problem at all. The problems are the life time rules, references, concurrency etc. They are not magically going away by some new form of tracking. It's amazing that you insist on solving the problem at the wrong end. The real problem is that there are device drivers and subsystems which are not prepared for hotplug, right? As interrupts are only a small part of the overall problem, I'm absolutely not seeing how adding heuristics all over the place is a sensible design principle. What's so problematic about teaching the affected subsystems and drivers that hotplug exists? Thanks, tglx
On Tue, Sep 12, 2023 at 8:17 PM Thomas Gleixner <tglx@linutronix.de> wrote: > > On Wed, Sep 06 2023 at 16:54, Bartosz Golaszewski wrote: > > On Wed, Aug 30, 2023 at 12:29 AM Thomas Gleixner <tglx@linutronix.de> wrote: > >> usb disconnect > >> ... > >> cp2112_remove() > >> i2c_del_adapter() > >> i2c_unregister_device(client) > >> ... > >> device_unregister() > >> device_del() > >> bus_notify() // Mechanism #1 > >> i2c_device_remove() > >> if (dev->remove) > >> dev->remove() > >> ... > >> device_unbind_cleanup() > >> devres_release_all() // Mechanism #2 > >> > >> gpiochip_remove() > >> > >> There are very well notifications to the drivers about unplug of a > >> device. Otherwise this would end up in a complete disaster and a lot > >> more stale data and state than just a procfs file or a requested > >> interrupt. > > > > I'm not sure how either of the two helps here. #2 just releases > > managed resources owned by cp2112. It can remove the domain with an > > appropriate devm action but it won't do anything for the users of > > interrupts. #1 is a bus notification emitted when the I2C adapter > > exposed by cp2112 has been deleted. > > No. The domain is not yet gone at the point where the I2C bus > notification happens. Look at the above invocation chain. > > The removal of the attached I2C devices happens _before_ the domain is > removed. Anything else does not make sense at all. > > So the cleanup of those devices should free the interrupt, in the same > way it frees other resources, no? > > i2c_device_remove() > if (driver->remove) > driver->remove() // Driver specific cleanup > > // Devres cleanup operating on the to be removed I2C device > devres_release_group(&client->dev, client->devres_group_id); > > So again: > > cp2112_remove() > i2c_del_adapter() // Cleans up all I2C users > > gpiochip_remove() // Removes the interrupt domain. > > So you do not need any magic bus notififications and whatever. It's all > there already. > You're only talking about a situation in which the users of the interrupts from the cp2112 GPIO chip's are I2C devices on its I2C adapter. We can have consumers of those interrupts elsewhere. We can have user-space watching interrupts on GPIOs (see below). They won't get removed before the cp2112 GPIO chip, so their remove paths freeing interrupts will not be triggered as you describe it. > > This one in particular doesn't help us, the domain is long gone by now > > but if I get what you mean correctly, you'd want the driver to call > > request_irq() and then set up a notifier block for the > > BUS_NOTIFY_UNBIND_DRIVER notification of the provider of that > > interrupt? Doesn't that break like half a dozen of abstraction layers? > > Because now the device driver which is the GPIO consumer needs to know > > where it gets its interrupts from? > > Again. It does not. The point is that the device is removed in the > hotplug event chain, which cleans up the associated resources. > devm_request_irq() already takes care of that. > That's not always necessary. Imagine you have an interrupt handler set up on a GPIO that is now gone. Your driver may do lots of other things and remain functional even though this interrupt will never fire. > > You would think that plug-and-play works well in the kernel and it's > > true for certain parts but it really isn't the case for subsystems > > that were not considered as very plug-and-play until people started > > putting them on a stick. Some devices that are not typically > > hot-pluggable - like serial - have been used with USB for so long that > > they do handle unplugging very well. But as soon as you put i2c on > > USB, you'll see what a mess it is. If you have an I2C device on a USB > > I2C expander and it's being used, when you pull the plug, you'll see > > that the kernel thread removing the device will block on a call to > > wait_for_completion() until all users release their i2c adapter > > references. They (the users) are not however notified in any generic > > way about the provider of their resources being gone. > > So why aren't you fixing this and instead trying to implement force > unplug mechanisms which require a pile of unholy hacks all over the > place? > That's not what I'm suggesting. I've described the general model I'm postulating. If this patch is an unholy hack, it's because I didn't know better. Now I do, I've abandoned it two weeks ago. > >> All hotpluggable consumers have at least one mechanism to mop up the > >> resources they allocated. There are a lot of resources in the kernel > >> which do not clean themself up magically. > >> > > > > Yeah, hotpluggable consumers are fine. The problem here is > > hotpluggable *providers* with consumers who don't know that. > > Then these consumers have to be fixed and made aware of the new world order > of hotplug, no? > I've asked that question in my previous email. What do you think we should do when a provider of a resource we're using in a driver is gone? Let's assume, the consumer device will not get removed in the hot-unplug chain - which is perfectly reasonable. I'm arguing that it should receive an error code on the next call to that provider. The alternatives I see are: force-unbind the device or notify it by some other unspecified means and have it do what exactly? > >> Your idea of tracking request_irq()/free_irq() at some subsystem level > >> is not going to work either simply because it requires that such muck is > >> sprinkled all over the place. > >> > > I was thinking more about tracking it at the irq domain level so that > > when a domain is destroyed with interrupts requested, these interrupts > > are freed. I admit I still don't have enough in-depth knowledge about > > linux interrupts to understand why it can't work, I need to spend > > more time on this. I'll be back. > > There is no need for special tracking. The core can figure out today > whether an interrupt which is mapped by the domain is requested or > not. That's not the problem at all. > > The problems are the life time rules, references, concurrency etc. They > are not magically going away by some new form of tracking. > > It's amazing that you insist on solving the problem at the wrong end. > Is it really the wrong end though? Let me give you an analogy with a driver consuming a resource replaced by a user-space process. Let's take a user process requesting some kernel resource by opening a character device file. The handle the process gets will now be the file descriptor number. The resource can be a GPIO (or even an interrupt on that GPIO - as user-space can watch interrupts via the GPIO character device). Let's now assume the GPIO is on a USB expander. We now unplug it. Should the user-space get informed about this fact with some side-channel other than the descriptor? Or sent a signal/killed (analogy to the removal of the device in the hot-unplug path)? Should we set up some entirely different notification mechanism? No, the only sane thing to do is: next time the process calls into the kernel via a system call referencing that descriptor, it should return an error - typically -ENODEV. If a poll() is in process, it should be woken up with EPOLLERR. The process should then call close() on that descriptor, putting its reference to the resource. If it doesn't, then all it'll see will be errors. The process however can keep on living and doing other stuff. What should happen in the kernel is: on the unplug event we clean everything up, leaving just the user-facing, reference-counted outer shell. Once the last reference to struct file is put, it'll be released. Of course not everyone does it and so user-space can crash the kernel just by opening a character device exposed by vulnerable subsystems, unbinding the device over sysfs and calling ioctl() or otherwise. My point is: the same rule should apply to in-kernel consumers. When they request a resource, they get a reference to it. The resource is managed by its provider. If the provider is going down, it frees the resource. The consumer tries to use it -> it gets an error. I'm not convinced by the life-time rules argument. The consumer is not CREATING a resource. It's REQUESTING it for usage. IMO this means it REFERENCES it, not OWNS it. And so is only responsible for putting the reference. Bartosz > The real problem is that there are device drivers and subsystems which > are not prepared for hotplug, right? > > As interrupts are only a small part of the overall problem, I'm > absolutely not seeing how adding heuristics all over the place is a > sensible design principle. > > What's so problematic about teaching the affected subsystems and drivers > that hotplug exists? > > Thanks, > > tglx >
On Fri, Sep 15, 2023 at 9:50 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote: > [snip] > > My point is: the same rule should apply to in-kernel consumers. When > they request a resource, they get a reference to it. The resource is > managed by its provider. If the provider is going down, it frees the > resource. The consumer tries to use it -> it gets an error. I'm not > convinced by the life-time rules argument. The consumer is not > CREATING a resource. It's REQUESTING it for usage. IMO this means it > REFERENCES it, not OWNS it. And so is only responsible for putting the > reference. > > Bartosz > Hi Thomas, Greg et al, I am at LPC and will present a talk on Wednesday 5:15pm at the kernel summit about object life-time issues. I'll reference this problem among others. Please consider it in your schedules, I think it'll be useful to discuss it in person as it's a generic problem in many driver subsystems. Bartosz
On Mon, Nov 13, 2023 at 09:53:47PM +0100, Bartosz Golaszewski wrote: > On Fri, Sep 15, 2023 at 9:50 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote: > > > > [snip] > > > > > My point is: the same rule should apply to in-kernel consumers. When > > they request a resource, they get a reference to it. The resource is > > managed by its provider. If the provider is going down, it frees the > > resource. The consumer tries to use it -> it gets an error. I'm not > > convinced by the life-time rules argument. The consumer is not > > CREATING a resource. It's REQUESTING it for usage. IMO this means it > > REFERENCES it, not OWNS it. And so is only responsible for putting the > > reference. > > > > Bartosz > > > > Hi Thomas, Greg et al, > > I am at LPC and will present a talk on Wednesday 5:15pm at the kernel > summit about object life-time issues. I'll reference this problem > among others. Please consider it in your schedules, I think it'll be > useful to discuss it in person as it's a generic problem in many > driver subsystems. Sounds great, I'll try to make it there! greg k-h
On Mon, Nov 13, 2023 at 9:53 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote: > I am at LPC and will present a talk on Wednesday 5:15pm at the kernel > summit about object life-time issues. I'll reference this problem > among others. Please consider it in your schedules, I think it'll be > useful to discuss it in person as it's a generic problem in many > driver subsystems. I'm sadly not at LPC, but this sounds very relevant and I'd love to know what you conclude (if we're lucky maybe LWN catches it in a writeup). Yours, Linus Walleij
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 83ed403991c6..b284604a091a 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -390,6 +390,15 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) mutex_unlock(®ister_lock); } +static void unregister_action_proc(struct irqaction *action) +{ + if (!action) + return; + + unregister_action_proc(action->secondary); + unregister_handler_proc(action); +} + void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) { char name [MAX_NAMELEN]; @@ -408,6 +417,12 @@ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) #endif remove_proc_entry("spurious", desc->dir); + /* + * If at this point, this irq desc is still requested, we need to + * remove the proc handler entries or we'll leak them. + */ + unregister_action_proc(desc->action); + sprintf(name, "%u", irq); remove_proc_entry(name, root_irq_dir); }