[Intel-gfx] [PATCH 01/44] drivers/base: Always release devres on device_del

Daniel Vetter daniel.vetter at ffwll.ch
Fri Apr 3 13:57:45 UTC 2020


In drm we've added nice drm_device (the main gpu driver thing, which
also represents the userspace interfaces and has everything else
dangling off it) init functions using devres, devm_drm_dev_init and
soon devm_drm_dev_alloc (this patch series adds that).

A slight trouble is that drm_device itself holds a reference on the
struct device it's sitting on top (for sysfs links and dmesg debug and
lots of other things), so there's a reference loop. For real drivers
this is broken at remove/unplug time, where all devres resources are
released device_release_driver(), before the final device reference is
dropped. So far so good.

There's 2 exceptions:
- drm/vkms|vgem: Virtual drivers for which we create a fake/virtual
  platform device to make them look more like normal devices to
  userspace. These aren't drivers in the driver model sense, we simple
  create a platform_device and register it.

- drm/i915/selftests, where we create minimal mock devices, and again
  the selftests aren't proper drivers in the driver model sense.

For these two cases the reference loop isn't broken, because devres is
only cleaned up when the last device reference is dropped. But that's
not happening, because the drm_device holds that last struct device
reference.

Thus far this wasn't a problem since the above cases simply
hand-rolled their cleanup code. But I want to convert all drivers over
to the devm_ versions, hence it would be really nice if these
virtual/fake/mock uses-cases could also be managed with devres
cleanup.

I see three possible approaches:

- Clean up devres from device_del (or platform_device_unregister) even
  when no driver is bound. This seems like the simplest solution, but
  also the one with the widest impact, and what this patch implements.
  We might want to include more of the cleanup than just
  devres_release_all, but this is all I need to get my use case going.

- Create a devres group and release that when we unbind. The code in
  virtual drivers gets a bit ugly, since every error case has a
  different cleanup code until we've chained everything
  (platform_device, devres group and then drm_device) together and a
  devres_release_group takes care of everything. Doable, but a bit
  confusing when I typed it out.

- Convert the virtual drivers to real (in the device model sense)
  drivers. Feels like too much boilerplate for not much gain. And
  especially with the mock objects minimal mocking is kinda the goal,
  to limit the amount of accidentally pulled in code into our unit
  tests as much as possible.

Either way I think time to discuss this a bit and figure out what's
the recommended approach here.

Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael at kernel.org>
---
 drivers/base/dd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index b25bcab2a26b..1bcfb0ff5f44 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -1155,6 +1155,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 						     dev);
 
 		kobject_uevent(&dev->kobj, KOBJ_UNBIND);
+	} else {
+		devres_release_all(dev);
 	}
 }
 
-- 
2.25.1



More information about the Intel-gfx mailing list