Message ID | CAP8WD_ZoJgrdsDZNR4uN8HWESO5MyuNc1xN_F2an8GfP8nKcLA@mail.gmail.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
Hello, On Mon, Dec 19, 2016 at 09:12:49PM -0500, tedheadster wrote: > Tejun, > apologies this took a while. Here is the patch I _think_ you were > asking me to test: > > diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c > index bce2a8c..bfa63d1 100644 > --- a/drivers/ata/pata_legacy.c > +++ b/drivers/ata/pata_legacy.c > @@ -1008,12 +1008,15 @@ static __init int legacy_init_one(struct > legacy_probe *probe) > if (!ata_dev_absent(dev)) { > legacy_host[probe->slot] = host; > ld->platform_dev = pdev; > + devres_remove_group(&pdev->dev, legacy_init_one); > return 0; > } > } > ata_host_detach(host); > fail: > platform_device_unregister(pdev); > + devres_release_group(&pdev->dev, legacy_init_one); > + printk("XXX pata_legacy: unregistering platform dev %p\n", pdev); > return ret; The thing I'm puzzled about and can't reproduce here is that the platform_device_unregister() call on the fail path should release the irq resources without the explicit devres group operations. I can write up tracking each step but it'd probably be easier on your side to track down why it's not getting called. So, pata_legacy doesn't need anything changed, but in the probe fail path, platform_device_unregister() should trigger driver/base/core.c::device_release() which calls devres_release_all() and release the irqs. Thanks.
Tejun, > > The thing I'm puzzled about and can't reproduce here is that the > platform_device_unregister() call on the fail path should release the > irq resources without the explicit devres group operations. I can > write up tracking each step but it'd probably be easier on your side > to track down why it's not getting called. > > So, pata_legacy doesn't need anything changed, but in the probe fail > path, platform_device_unregister() should trigger > driver/base/core.c::device_release() which calls devres_release_all() > and release the irqs. > It looks to me that when something is 'platform' it is not expected to ever go away, and that generally includes irqs. There are calls to platform_get_irq() but there isn't even a function called platform_put_irq() or platform_free_irq(). I do see some driver calls to failure conditions or 'remove' functions where it calls: free_irq(platform_get_irq(pdev, 0), var) See: drivers/mmc/host/atmel-mci.c drivers/usb/gadget/udc/fotg210-udc.c drivers/usb/gadget/udc/fusb300_udc.c drivers/usb/gadget/udc/m66592-udc.c drivers/video/fbdev/au1200fb.c drivers/virtio/virtio_mmio.c drivers/dma/at_hdmac.c drivers/input/keyboard/pxa930_rotary.c drivers/input/keyboard/sh_keysc.c I think this driver should either not be considered 'platform' or it should make a call to free_irq() on failures. - Matthew -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello, On Thu, Dec 22, 2016 at 12:14:43PM -0500, tedheadster wrote: > It looks to me that when something is 'platform' it is not expected to > ever go away, and that generally includes irqs. There are calls to > platform_get_irq() but there isn't even a function called > platform_put_irq() or platform_free_irq(). But it works fine if we open and release an explicit devres group, so the problem isn't there. The problem is why platform device destruction isn't triggering devres release of all associated resources. Thanks.
Greg, when calling drivers/ata/pata_legacy.c, it grabs four irq's even though those legacy device probes fail: root@i486:~# cat /proc/interrupts CPU0 0: 95630 XT-PIC timer 1: 1028 XT-PIC i8042 ... 10: 0 XT-PIC platform[pata_legacy.3] 11: 0 XT-PIC platform[pata_legacy.2] 12: 0 XT-PIC platform[pata_legacy.5] 14: 66786 XT-PIC platform[pata_legacy.0] 15: 0 XT-PIC platform[pata_legacy.1] Tejun believes that platform_device_unregister() should free the irqs: >> >> The thing I'm puzzled about and can't reproduce here is that the >> platform_device_unregister() call on the fail path should release the >> irq resources without the explicit devres group operations. I can >> write up tracking each step but it'd probably be easier on your side >> to track down why it's not getting called. >> >> So, pata_legacy doesn't need anything changed, but in the probe fail >> path, platform_device_unregister() should trigger >> driver/base/core.c::device_release() which calls devres_release_all() >> and release the irqs. >> > I ponder if the driver should instead release the irq's from the failed probe: > It looks to me that when something is 'platform' it is not expected to > ever go away, and that generally includes irqs. There are calls to > platform_get_irq() but there isn't even a function called > platform_put_irq() or platform_free_irq(). > ... > I think this driver should either not be considered 'platform' or it > should make a call to free_irq() on failures. > The question is: who is responsible to free an irq from a device registered using platform_device_register_simple()? Is it the driver or the platform code? - Matthew -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello, On Thu, Dec 22, 2016 at 01:30:23PM -0500, tedheadster wrote: > > I think this driver should either not be considered 'platform' or it > > should make a call to free_irq() on failures. > > > > The question is: who is responsible to free an irq from a device > registered using platform_device_register_simple()? Is it the driver > or the platform code? Sorry, I wasn't clear. There's a rudimentary garbage collector devm which tracks all the resources associated with a device. The previous patch that I sent you which created an explict resource group and released it uses the same mechanism. When any device gets destroyed, it should release all associated resources and I was wondering why that wasn't happening without the explicit group operations. I'll write up a debug patch to track down what's going on. Thanks.
On Thu, 22 Dec 2016 14:22:56 -0500 Tejun Heo <tj@kernel.org> wrote: > Hello, > > On Thu, Dec 22, 2016 at 01:30:23PM -0500, tedheadster wrote: > > > I think this driver should either not be considered 'platform' or it > > > should make a call to free_irq() on failures. > > > > > > > The question is: who is responsible to free an irq from a device > > registered using platform_device_register_simple()? Is it the driver > > or the platform code? > > Sorry, I wasn't clear. There's a rudimentary garbage collector devm > which tracks all the resources associated with a device. The previous > patch that I sent you which created an explict resource group and > released it uses the same mechanism. When any device gets destroyed, > it should release all associated resources and I was wondering why > that wasn't happening without the explicit group operations. I'll > write up a debug patch to track down what's going on. Almost certainly libata leaking a reference to the device so it doesn't think it's gone away. Alan -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index bce2a8c..bfa63d1 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -1008,12 +1008,15 @@ static __init int legacy_init_one(struct legacy_probe *probe) if (!ata_dev_absent(dev)) { legacy_host[probe->slot] = host; ld->platform_dev = pdev; + devres_remove_group(&pdev->dev, legacy_init_one); return 0; } } ata_host_detach(host); fail: platform_device_unregister(pdev); + devres_release_group(&pdev->dev, legacy_init_one); + printk("XXX pata_legacy: unregistering platform dev %p\n", pdev); return ret; }