Skip to content

Commit 699fb50

Browse files
sulixgregkh
authored andcommitted
drivers: base: Free devm resources when unregistering a device
In the current code, devres_release_all() only gets called if the device has a bus and has been probed. This leads to issues when using bus-less or driver-less devices where the device might never get freed if a managed resource holds a reference to the device. This is happening in the DRM framework for example. We should thus call devres_release_all() in the device_del() function to make sure that the device-managed actions are properly executed when the device is unregistered, even if it has neither a bus nor a driver. This is effectively the same change than commit 2f8d16a ("devres: release resources on device_del()") that got reverted by commit a525a3d ("driver core: free devres in device_release") over memory leaks concerns. This patch effectively combines the two commits mentioned above to release the resources both on device_del() and device_release() and get the best of both worlds. Fixes: a525a3d ("driver core: free devres in device_release") Signed-off-by: David Gow <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> Link: https://lore.kernel.org/r/20230720-kunit-devm-inconsistencies-test-v3-3-6aa7e074f373@kernel.org Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b4cc443 commit 699fb50

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

drivers/base/core.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,6 +3817,17 @@ void device_del(struct device *dev)
38173817
device_platform_notify_remove(dev);
38183818
device_links_purge(dev);
38193819

3820+
/*
3821+
* If a device does not have a driver attached, we need to clean
3822+
* up any managed resources. We do this in device_release(), but
3823+
* it's never called (and we leak the device) if a managed
3824+
* resource holds a reference to the device. So release all
3825+
* managed resources here, like we do in driver_detach(). We
3826+
* still need to do so again in device_release() in case someone
3827+
* adds a new resource after this point, though.
3828+
*/
3829+
devres_release_all(dev);
3830+
38203831
bus_notify(dev, BUS_NOTIFY_REMOVED_DEVICE);
38213832
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
38223833
glue_dir = get_glue_dir(dev);

drivers/base/test/platform-device-test.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ static void platform_device_devm_register_get_unregister_with_devm_test(struct k
8787
struct test_priv *priv = test->priv;
8888
int ret;
8989

90-
kunit_skip(test, "This needs to be fixed in the core.");
91-
9290
pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);
9391
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
9492

drivers/base/test/root-device-test.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ static void root_device_devm_register_get_unregister_with_devm_test(struct kunit
7878
struct test_priv *priv = test->priv;
7979
int ret;
8080

81-
kunit_skip(test, "This needs to be fixed in the core.");
82-
8381
priv->dev = root_device_register(DEVICE_NAME);
8482
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
8583

0 commit comments

Comments
 (0)