diff options
author | Ming Lei <tom.leiming@gmail.com> | 2012-07-25 01:42:29 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-08-16 10:32:07 -0700 |
commit | a525a3ddeaca69f405d98442ab3c0746e53168dc (patch) | |
tree | 51198c610f85622549fd679bb3cf3e1940844829 /drivers/base/core.c | |
parent | 2221f6ef71d4b89ed56a233cc0200bbe9b84a385 (diff) | |
download | lwn-a525a3ddeaca69f405d98442ab3c0746e53168dc.tar.gz lwn-a525a3ddeaca69f405d98442ab3c0746e53168dc.zip |
driver core: free devres in device_release
device_del can happen anytime, so once it happens,
the devres of the device will be freed inside device_del, but
drivers can't know it has been deleted and may still add
resources into the device, so memory leak is caused.
This patch moves the devres_release_all to fix the problem.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index f338037a4f3d..c8fe4a563866 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -184,6 +184,17 @@ static void device_release(struct kobject *kobj) struct device *dev = kobj_to_dev(kobj); struct device_private *p = dev->p; + /* + * Some platform devices are driven without driver attached + * and managed resources may have been acquired. Make sure + * all resources are released. + * + * Drivers still can add resources into device after device + * is deleted but alive, so release devres here to avoid + * possible memory leak. + */ + devres_release_all(dev); + if (dev->release) dev->release(dev); else if (dev->type && dev->type->release) @@ -1196,13 +1207,6 @@ void device_del(struct device *dev) bus_remove_device(dev); driver_deferred_probe_del(dev); - /* - * Some platform devices are driven without driver attached - * and managed resources may have been acquired. Make sure - * all resources are released. - */ - devres_release_all(dev); - /* Notify the platform of the removal, in case they * need to do anything... */ |