Hi all,
Here's the promised follow-up to get rid of the drmm_add_final_kfree calls from drivers. I've also sprinkled in a bunch of cleanups for the drivers I've had to touch anyway. I think with devm_drm_dev_alloc we now have a very neat and clean way to init the drm_device, and all the interim stage with drm_dev_init and devm_drm_dev_init are unexported.
For reading, documenation changes are all concentrated in the last patch, because the interim state would result in way too much shuffling and readjusting.
The driver core patch is only required for vkms, vgem and i915/selftest patches, everything else only needs the patch to add devm_drm_dev_alloc. Once that's landed we can merge driver patches in any order, only the final patch needs to wait until everything has landed.
As usual, review, testing and comments very much appreciated.
Cheers, Daniel
Daniel Vetter (44): drivers/base: Always release devres on device_del drm: Add devm_drm_dev_alloc macro drm/device: Deprecate dev_private harder drm/vgem: Use devm_drm_dev_alloc drm/vkms: Use devm_drm_dev_alloc drm/vboxvideo: drop DRM_MTRR_WC #define drm/vboxvideo: Use devm_drm_dev_alloc drm/vboxvideo: Stop using drm_device->dev_private drm/vboxvidoe: use managed pci functions drm/vboxvideo: Use devm_gen_pool_create drm/v3d: Don't set drm_device->dev_private drm/v3d: Use devm_drm_dev_alloc drm/v3d: Delete v3d_dev->dev drm/v3d: Delete v3d_dev->pdev drm/udl: Use demv_drm_dev_alloc drm/udl: don't set drm_device->dev_private drm/st7735r: Use devm_drm_dev_alloc drm/st7586: Use devm_drm_dev_alloc drm/repaper: Use devm_drm_dev_alloc drm/mi0283qt: Use devm_drm_dev_alloc drm/ili9486: Use devm_drm_dev_alloc drm/ili9341: Use devm_drm_dev_alloc drm/ili9225: Use devm_drm_dev_alloc drm/hx8357d: Use devm_drm_dev_alloc drm/gm12u320: Use devm_drm_dev_alloc drm/gm12u320: Don't use drm_device->dev_private drm/tidss: Use devm_drm_dev_alloc drm/tidss: Don't use drm_device->dev_private drm/tidss: Delete tidss->saved_state drm/qxl: Use devm_drm_dev_alloc drm/qxl: Don't use drm_device->dev_private drm/mcde: Use devm_drm_dev_alloc drm/mcde: Don't use drm_device->dev_private drm/ingenic: Use devm_drm_dev_alloc drm/ingenic: Don't set drm_device->dev_private drm/komeda: use devm_drm_dev_alloc drm/armada: Use devm_drm_dev_alloc drm/armada: Don't use drm_device->dev_private drm/cirrus: Use devm_drm_dev_alloc drm/cirrus: Don't use drm_device->dev_private drm/i915: Use devm_drm_dev_alloc drm/i915/selftest: Create mock_destroy_device drm/i915/selftests: align more to real device lifetimes drm/managed: Cleanup of unused functions and polishing docs
.../driver-api/driver-model/devres.rst | 2 +- drivers/base/dd.c | 2 + .../gpu/drm/arm/display/komeda/komeda_kms.c | 16 +- drivers/gpu/drm/armada/armada_crtc.c | 4 +- drivers/gpu/drm/armada/armada_debugfs.c | 2 +- drivers/gpu/drm/armada/armada_drm.h | 2 + drivers/gpu/drm/armada/armada_drv.c | 30 +--- drivers/gpu/drm/armada/armada_fbdev.c | 4 +- drivers/gpu/drm/armada/armada_gem.c | 4 +- drivers/gpu/drm/armada/armada_overlay.c | 8 +- drivers/gpu/drm/cirrus/cirrus.c | 22 ++- drivers/gpu/drm/drm_drv.c | 142 ++++++------------ drivers/gpu/drm/drm_internal.h | 1 + drivers/gpu/drm/drm_managed.c | 15 +- .../gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- .../drm/i915/gem/selftests/i915_gem_context.c | 2 +- .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 2 +- .../drm/i915/gem/selftests/i915_gem_object.c | 2 +- .../drm/i915/gem/selftests/i915_gem_phys.c | 2 +- drivers/gpu/drm/i915/gt/selftest_timeline.c | 2 +- drivers/gpu/drm/i915/i915_drv.c | 17 +-- drivers/gpu/drm/i915/i915_pci.c | 2 - .../gpu/drm/i915/selftests/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 2 +- drivers/gpu/drm/i915/selftests/i915_request.c | 2 +- drivers/gpu/drm/i915/selftests/i915_vma.c | 2 +- .../drm/i915/selftests/intel_memory_region.c | 2 +- .../gpu/drm/i915/selftests/mock_gem_device.c | 33 ++-- .../gpu/drm/i915/selftests/mock_gem_device.h | 5 + drivers/gpu/drm/ingenic/ingenic-drm.c | 15 +- drivers/gpu/drm/mcde/mcde_display.c | 10 +- drivers/gpu/drm/mcde/mcde_drm.h | 2 + drivers/gpu/drm/mcde/mcde_drv.c | 21 +-- drivers/gpu/drm/mcde/mcde_dsi.c | 2 +- drivers/gpu/drm/qxl/qxl_debugfs.c | 7 +- drivers/gpu/drm/qxl/qxl_display.c | 32 ++-- drivers/gpu/drm/qxl/qxl_drv.c | 23 +-- drivers/gpu/drm/qxl/qxl_drv.h | 7 +- drivers/gpu/drm/qxl/qxl_dumb.c | 2 +- drivers/gpu/drm/qxl/qxl_gem.c | 2 +- drivers/gpu/drm/qxl/qxl_ioctl.c | 14 +- drivers/gpu/drm/qxl/qxl_irq.c | 2 +- drivers/gpu/drm/qxl/qxl_kms.c | 13 +- drivers/gpu/drm/qxl/qxl_object.c | 2 +- drivers/gpu/drm/qxl/qxl_release.c | 2 +- drivers/gpu/drm/qxl/qxl_ttm.c | 2 +- drivers/gpu/drm/tidss/tidss_crtc.c | 16 +- drivers/gpu/drm/tidss/tidss_drv.c | 17 +-- drivers/gpu/drm/tidss/tidss_drv.h | 4 +- drivers/gpu/drm/tidss/tidss_irq.c | 12 +- drivers/gpu/drm/tidss/tidss_kms.c | 2 +- drivers/gpu/drm/tidss/tidss_plane.c | 6 +- drivers/gpu/drm/tiny/gm12u320.c | 24 ++- drivers/gpu/drm/tiny/hx8357d.c | 13 +- drivers/gpu/drm/tiny/ili9225.c | 13 +- drivers/gpu/drm/tiny/ili9341.c | 13 +- drivers/gpu/drm/tiny/ili9486.c | 13 +- drivers/gpu/drm/tiny/mi0283qt.c | 13 +- drivers/gpu/drm/tiny/repaper.c | 14 +- drivers/gpu/drm/tiny/st7586.c | 13 +- drivers/gpu/drm/tiny/st7735r.c | 13 +- drivers/gpu/drm/udl/udl_connector.c | 4 +- drivers/gpu/drm/udl/udl_drv.c | 37 ++--- drivers/gpu/drm/udl/udl_modeset.c | 6 +- drivers/gpu/drm/v3d/v3d_debugfs.c | 12 +- drivers/gpu/drm/v3d/v3d_drv.c | 47 +++--- drivers/gpu/drm/v3d/v3d_drv.h | 7 +- drivers/gpu/drm/v3d/v3d_gem.c | 17 ++- drivers/gpu/drm/v3d/v3d_irq.c | 16 +- drivers/gpu/drm/v3d/v3d_mmu.c | 10 +- drivers/gpu/drm/v3d/v3d_sched.c | 10 +- drivers/gpu/drm/vboxvideo/vbox_drv.c | 26 +--- drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_irq.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_main.c | 29 ++-- drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +- drivers/gpu/drm/vboxvideo/vbox_ttm.c | 12 -- drivers/gpu/drm/vgem/vgem_drv.c | 51 ++----- drivers/gpu/drm/vkms/vkms_drv.c | 48 ++---- include/drm/drm_device.h | 9 +- include/drm/drm_drv.h | 51 +++++-- 81 files changed, 422 insertions(+), 660 deletions(-)
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@intel.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@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); } }
On Fri, Apr 03, 2020 at 03:57:45PM +0200, Daniel Vetter wrote:
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.
That's a horrid abuse of platform devices, just use a "virtual" device please, create/remove it when you need it, and all should be fine.
- drm/i915/selftests, where we create minimal mock devices, and again the selftests aren't proper drivers in the driver model sense.
Again, virtual devices are best to use for this.
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.
After device_del, you should never be using that structure again anyway. So why is there any "resource leak"? You can't recycle the structure, and you can't assign it to anything else, so eventually you have to do a final put on the thing, which will free up the resources.
And then all should be fine, right? But, by putting the freeing here, you can still have a "live" device that thinks it has resources availble that it can access, but yet they are now gone. Yeah, it's probably not ever going to really happen, but the lifecycles of dynamic devices are tough to "prove" at times, and I worry that freeing things this early is going to cause odd disconnect issues.
thanks,
greg k-h
On Fri, Apr 3, 2020 at 4:17 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 03:57:45PM +0200, Daniel Vetter wrote:
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.
That's a horrid abuse of platform devices, just use a "virtual" device please, create/remove it when you need it, and all should be fine.
- drm/i915/selftests, where we create minimal mock devices, and again the selftests aren't proper drivers in the driver model sense.
Again, virtual devices are best to use for this.
Hm yeah, I guess we should fix that. i915 selftests do use raw struct device though, and it's not really the problem.
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.
After device_del, you should never be using that structure again anyway. So why is there any "resource leak"? You can't recycle the structure, and you can't assign it to anything else, so eventually you have to do a final put on the thing, which will free up the resources.
I guess I should have spent more time explaining this. There's two references involved:
- drm_device->dev points at the underlying struct device. The drm_device holds a reference until it's fully cleaned up, so that we can do nice stuff like use dev_ versions of printk functions, and you always know that there's not going to be a use-after free.
- now the other dependency is that as long as the device exists (not just in memory, but in the device model, i.e. between device_add() and device_del()) the drm_device should exist. So what we do in the bus-specific remove/disconnect callback is that we call drm_dev_unregister(). This drops the drm_device refcount that the drm chardev was holding, to make sure that an open() on the chardev can actually get at the memory without going boom. Then after the drm_dev_unregister, again in the remove/disconnect callback of th driver, there's a drm_dev_put(). Which might or might not be the final drm_dev_put(), since if there's currently some open fd we keep the refcount elevated, to avoid oopses and fun stuff like that. And drm_device pointers get shared very widely, thanks to fun stuff like dma_buf buffer sharing and dma_fence hw syncpt sharing across processes and drivers.
Once the final drm_dev_put() is called we also end up calling put_device() and everything is happy.
So far so good.
Now the problem is that refcount is hard, and most drm drivers get it wrong in some fashion or another, so I'm trying to solve all this with more magic.
Since all drivers need to have a drm_dev_put() at the end of their driver's remove/disconnect callback we've added a devm_drm_dev_init function which registers a devres action to do that drm_dev_put() at device_del time (which might or might not be the final drm_dev_put()). Nothing has changed thus far.
Now this works really well because when you have a real driver model driver attached, then device_del ends up calling devres_release_all(), which ends up triggering the multi-stage cleanup of drm_devices. But if you do _not_ have a real driver attached, then device_del does nothing wrt devres cleanup. Instead this is delayed until the final put_device().
Unfortunately that final put_device() will never happen, because drm_device is still holding a reference to the struct device. And the final drm_dev_put of that drm_device will never happen, because that drm_dev_put call is in a devres actions, which wont ever get called.
This is the only case where this reference loop happens and doesn't get broken. By calling devres_release_all at device_del time, irrespective of whether a driver is bound or not, we make both cases work the same. And at both cases the devres cleanup happens device_del time, and not when the final put_device is called.
Aside: The final put_device has another devres_release_all() call, which given your explanation sounds very wrong - at that point the physical device is long gone, and cleaning up devres actions at that point is way too late. I think a good cleanup patch on top of this would be to remove that call, and replace it with an assert that no one managed to sneak in a devres_add_action between device_del and the final put_device().
And then all should be fine, right? But, by putting the freeing here, you can still have a "live" device that thinks it has resources availble that it can access, but yet they are now gone. Yeah, it's probably not ever going to really happen, but the lifecycles of dynamic devices are tough to "prove" at times, and I worry that freeing things this early is going to cause odd disconnect issues.
Not exactly sure what you mean here, but trying to fix all the driver bugs we have in drm is why I'm doing this. We have a massive amount of gaps still, but we're slowly closing them all off with stuff like drm_dev_enter/exit, to make sure there's no races possible between driver hotunplug and concurrent access by userspace.
The additional trouble is that users are really pissed when we crash their compositor just because they unplugged an usb display dongle or an usb projector thing. So the failure mode we're aiming for in drm for hotunplug is to be very graceful to userspace - experience says that userspace is even less likely to handle this correctly than the kernel. That's why we're refcounting drm_device and everything hanging off it, so that it sticks around and we can pretend to userspace that it's all still there (but disconnected from hw and the driver). Until userspace has gone around and managed to process the udev events and closed all open fds.
Cheers, Daniel
On Fri, Apr 3, 2020 at 4:47 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
On Fri, Apr 3, 2020 at 4:17 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 03:57:45PM +0200, Daniel Vetter wrote:
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.
That's a horrid abuse of platform devices, just use a "virtual" device please, create/remove it when you need it, and all should be fine.
- drm/i915/selftests, where we create minimal mock devices, and again the selftests aren't proper drivers in the driver model sense.
Again, virtual devices are best to use for this.
Hm yeah, I guess we should fix that. i915 selftests do use raw struct device though, and it's not really the problem.
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.
After device_del, you should never be using that structure again anyway. So why is there any "resource leak"? You can't recycle the structure, and you can't assign it to anything else, so eventually you have to do a final put on the thing, which will free up the resources.
I guess I should have spent more time explaining this. There's two references involved:
- drm_device->dev points at the underlying struct device. The
drm_device holds a reference until it's fully cleaned up, so that we can do nice stuff like use dev_ versions of printk functions, and you always know that there's not going to be a use-after free.
- now the other dependency is that as long as the device exists (not
just in memory, but in the device model, i.e. between device_add() and device_del()) the drm_device should exist. So what we do in the bus-specific remove/disconnect callback is that we call drm_dev_unregister(). This drops the drm_device refcount that the drm chardev was holding, to make sure that an open() on the chardev can actually get at the memory without going boom. Then after the drm_dev_unregister, again in the remove/disconnect callback of th driver, there's a drm_dev_put(). Which might or might not be the final drm_dev_put(), since if there's currently some open fd we keep the refcount elevated, to avoid oopses and fun stuff like that. And drm_device pointers get shared very widely, thanks to fun stuff like dma_buf buffer sharing and dma_fence hw syncpt sharing across processes and drivers.
Once the final drm_dev_put() is called we also end up calling put_device() and everything is happy.
So far so good.
Now the problem is that refcount is hard, and most drm drivers get it wrong in some fashion or another, so I'm trying to solve all this with more magic.
Since all drivers need to have a drm_dev_put() at the end of their driver's remove/disconnect callback we've added a devm_drm_dev_init function which registers a devres action to do that drm_dev_put() at device_del time (which might or might not be the final drm_dev_put()). Nothing has changed thus far.
Now this works really well because when you have a real driver model driver attached, then device_del ends up calling devres_release_all(), which ends up triggering the multi-stage cleanup of drm_devices. But if you do _not_ have a real driver attached, then device_del does nothing wrt devres cleanup. Instead this is delayed until the final put_device().
Unfortunately that final put_device() will never happen, because drm_device is still holding a reference to the struct device. And the final drm_dev_put of that drm_device will never happen, because that drm_dev_put call is in a devres actions, which wont ever get called.
This is the only case where this reference loop happens and doesn't get broken. By calling devres_release_all at device_del time, irrespective of whether a driver is bound or not, we make both cases work the same. And at both cases the devres cleanup happens device_del time, and not when the final put_device is called.
Aside: The final put_device has another devres_release_all() call, which given your explanation sounds very wrong - at that point the physical device is long gone, and cleaning up devres actions at that point is way too late. I think a good cleanup patch on top of this would be to remove that call, and replace it with an assert that no one managed to sneak in a devres_add_action between device_del and the final put_device().
I've done a bit more digging, and found this commit:
commit a525a3ddeaca69f405d98442ab3c0746e53168dc Author: Ming Lei tom.leiming@gmail.com Date: Wed Jul 25 01:42:29 2012 +0800
driver core: free devres in device_release
Before this devres_release_all was called at device_del() time, unconditionally whether a driver was bound or not. Which seems to have been the intention at least back then. So in a way my patch simply restores that behaviour for the case where no driver has been bound to a device structure, but we still have devres resources hanging off it. -Daniel
And then all should be fine, right? But, by putting the freeing here, you can still have a "live" device that thinks it has resources availble that it can access, but yet they are now gone. Yeah, it's probably not ever going to really happen, but the lifecycles of dynamic devices are tough to "prove" at times, and I worry that freeing things this early is going to cause odd disconnect issues.
Not exactly sure what you mean here, but trying to fix all the driver bugs we have in drm is why I'm doing this. We have a massive amount of gaps still, but we're slowly closing them all off with stuff like drm_dev_enter/exit, to make sure there's no races possible between driver hotunplug and concurrent access by userspace.
The additional trouble is that users are really pissed when we crash their compositor just because they unplugged an usb display dongle or an usb projector thing. So the failure mode we're aiming for in drm for hotunplug is to be very graceful to userspace - experience says that userspace is even less likely to handle this correctly than the kernel. That's why we're refcounting drm_device and everything hanging off it, so that it sticks around and we can pretend to userspace that it's all still there (but disconnected from hw and the driver). Until userspace has gone around and managed to process the udev events and closed all open fds.
Cheers, Daniel
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
On Fri, Apr 03, 2020 at 04:51:33PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 4:47 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
On Fri, Apr 3, 2020 at 4:17 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 03:57:45PM +0200, Daniel Vetter wrote:
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.
That's a horrid abuse of platform devices, just use a "virtual" device please, create/remove it when you need it, and all should be fine.
- drm/i915/selftests, where we create minimal mock devices, and again the selftests aren't proper drivers in the driver model sense.
Again, virtual devices are best to use for this.
Hm yeah, I guess we should fix that. i915 selftests do use raw struct device though, and it's not really the problem.
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.
After device_del, you should never be using that structure again anyway. So why is there any "resource leak"? You can't recycle the structure, and you can't assign it to anything else, so eventually you have to do a final put on the thing, which will free up the resources.
I guess I should have spent more time explaining this. There's two references involved:
- drm_device->dev points at the underlying struct device. The
drm_device holds a reference until it's fully cleaned up, so that we can do nice stuff like use dev_ versions of printk functions, and you always know that there's not going to be a use-after free.
- now the other dependency is that as long as the device exists (not
just in memory, but in the device model, i.e. between device_add() and device_del()) the drm_device should exist. So what we do in the bus-specific remove/disconnect callback is that we call drm_dev_unregister(). This drops the drm_device refcount that the drm chardev was holding, to make sure that an open() on the chardev can actually get at the memory without going boom. Then after the drm_dev_unregister, again in the remove/disconnect callback of th driver, there's a drm_dev_put(). Which might or might not be the final drm_dev_put(), since if there's currently some open fd we keep the refcount elevated, to avoid oopses and fun stuff like that. And drm_device pointers get shared very widely, thanks to fun stuff like dma_buf buffer sharing and dma_fence hw syncpt sharing across processes and drivers.
Once the final drm_dev_put() is called we also end up calling put_device() and everything is happy.
So far so good.
Now the problem is that refcount is hard, and most drm drivers get it wrong in some fashion or another, so I'm trying to solve all this with more magic.
Since all drivers need to have a drm_dev_put() at the end of their driver's remove/disconnect callback we've added a devm_drm_dev_init function which registers a devres action to do that drm_dev_put() at device_del time (which might or might not be the final drm_dev_put()). Nothing has changed thus far.
Now this works really well because when you have a real driver model driver attached, then device_del ends up calling devres_release_all(), which ends up triggering the multi-stage cleanup of drm_devices. But if you do _not_ have a real driver attached, then device_del does nothing wrt devres cleanup. Instead this is delayed until the final put_device().
Unfortunately that final put_device() will never happen, because drm_device is still holding a reference to the struct device. And the final drm_dev_put of that drm_device will never happen, because that drm_dev_put call is in a devres actions, which wont ever get called.
This is the only case where this reference loop happens and doesn't get broken. By calling devres_release_all at device_del time, irrespective of whether a driver is bound or not, we make both cases work the same. And at both cases the devres cleanup happens device_del time, and not when the final put_device is called.
Aside: The final put_device has another devres_release_all() call, which given your explanation sounds very wrong - at that point the physical device is long gone, and cleaning up devres actions at that point is way too late. I think a good cleanup patch on top of this would be to remove that call, and replace it with an assert that no one managed to sneak in a devres_add_action between device_del and the final put_device().
I've done a bit more digging, and found this commit:
commit a525a3ddeaca69f405d98442ab3c0746e53168dc Author: Ming Lei tom.leiming@gmail.com Date: Wed Jul 25 01:42:29 2012 +0800
driver core: free devres in device_release
Before this devres_release_all was called at device_del() time, unconditionally whether a driver was bound or not. Which seems to have been the intention at least back then. So in a way my patch simply restores that behaviour for the case where no driver has been bound to a device structure, but we still have devres resources hanging off it.
Hey, I was right, I guessed well :)
I'll respond to the parent email, but it looks like you can't do this, sorry.
greg k-h
On Fri, Apr 03, 2020 at 04:47:04PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 4:17 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 03:57:45PM +0200, Daniel Vetter wrote:
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.
That's a horrid abuse of platform devices, just use a "virtual" device please, create/remove it when you need it, and all should be fine.
- drm/i915/selftests, where we create minimal mock devices, and again the selftests aren't proper drivers in the driver model sense.
Again, virtual devices are best to use for this.
Hm yeah, I guess we should fix that. i915 selftests do use raw struct device though, and it's not really the problem.
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.
After device_del, you should never be using that structure again anyway. So why is there any "resource leak"? You can't recycle the structure, and you can't assign it to anything else, so eventually you have to do a final put on the thing, which will free up the resources.
I guess I should have spent more time explaining this. There's two references involved:
- drm_device->dev points at the underlying struct device. The
drm_device holds a reference until it's fully cleaned up, so that we can do nice stuff like use dev_ versions of printk functions, and you always know that there's not going to be a use-after free.
- now the other dependency is that as long as the device exists (not
just in memory, but in the device model, i.e. between device_add() and device_del()) the drm_device should exist. So what we do in the bus-specific remove/disconnect callback is that we call drm_dev_unregister(). This drops the drm_device refcount that the drm chardev was holding, to make sure that an open() on the chardev can actually get at the memory without going boom. Then after the drm_dev_unregister, again in the remove/disconnect callback of th driver, there's a drm_dev_put(). Which might or might not be the final drm_dev_put(), since if there's currently some open fd we keep the refcount elevated, to avoid oopses and fun stuff like that. And drm_device pointers get shared very widely, thanks to fun stuff like dma_buf buffer sharing and dma_fence hw syncpt sharing across processes and drivers.
Once the final drm_dev_put() is called we also end up calling put_device() and everything is happy.
So far so good.
Now the problem is that refcount is hard, and most drm drivers get it wrong in some fashion or another, so I'm trying to solve all this with more magic.
Wait, no. Fix the drivers. Seriously, don't try to "bust" the reference count logic here.
Since all drivers need to have a drm_dev_put() at the end of their driver's remove/disconnect callback we've added a devm_drm_dev_init function which registers a devres action to do that drm_dev_put() at device_del time (which might or might not be the final drm_dev_put()). Nothing has changed thus far.
Now this works really well because when you have a real driver model driver attached, then device_del ends up calling devres_release_all(), which ends up triggering the multi-stage cleanup of drm_devices. But if you do _not_ have a real driver attached, then device_del does nothing wrt devres cleanup. Instead this is delayed until the final put_device().
Unfortunately that final put_device() will never happen, because drm_device is still holding a reference to the struct device. And the final drm_dev_put of that drm_device will never happen, because that drm_dev_put call is in a devres actions, which wont ever get called.
True, so fix the logic to do the final put_device() :)
This is the only case where this reference loop happens and doesn't get broken. By calling devres_release_all at device_del time, irrespective of whether a driver is bound or not, we make both cases work the same. And at both cases the devres cleanup happens device_del time, and not when the final put_device is called.
So what is so odd about these random drivers that the normal process does not work for them?
Along these lines, you might look into how the v4l developers finally fixed this as they had much the same type of issues that you do with regards to reference counting and resources and userspace file handles.
Aside: The final put_device has another devres_release_all() call, which given your explanation sounds very wrong - at that point the physical device is long gone, and cleaning up devres actions at that point is way too late. I think a good cleanup patch on top of this would be to remove that call, and replace it with an assert that no one managed to sneak in a devres_add_action between device_del and the final put_device().
The physical device might be gone, but an open handle to the device might still be around, keeping the structure in place and the driver thinking it still has access to it's memory structures.
And then all should be fine, right? But, by putting the freeing here, you can still have a "live" device that thinks it has resources availble that it can access, but yet they are now gone. Yeah, it's probably not ever going to really happen, but the lifecycles of dynamic devices are tough to "prove" at times, and I worry that freeing things this early is going to cause odd disconnect issues.
Not exactly sure what you mean here, but trying to fix all the driver bugs we have in drm is why I'm doing this. We have a massive amount of gaps still, but we're slowly closing them all off with stuff like drm_dev_enter/exit, to make sure there's no races possible between driver hotunplug and concurrent access by userspace.
Again, look at what v4l did, I think it might work out for you all as well.
thanks,
greg k-h
On Fri, Apr 3, 2020 at 5:06 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 04:47:04PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 4:17 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 03:57:45PM +0200, Daniel Vetter wrote:
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.
That's a horrid abuse of platform devices, just use a "virtual" device please, create/remove it when you need it, and all should be fine.
- drm/i915/selftests, where we create minimal mock devices, and again the selftests aren't proper drivers in the driver model sense.
Again, virtual devices are best to use for this.
Hm yeah, I guess we should fix that. i915 selftests do use raw struct device though, and it's not really the problem.
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.
After device_del, you should never be using that structure again anyway. So why is there any "resource leak"? You can't recycle the structure, and you can't assign it to anything else, so eventually you have to do a final put on the thing, which will free up the resources.
I guess I should have spent more time explaining this. There's two references involved:
- drm_device->dev points at the underlying struct device. The
drm_device holds a reference until it's fully cleaned up, so that we can do nice stuff like use dev_ versions of printk functions, and you always know that there's not going to be a use-after free.
- now the other dependency is that as long as the device exists (not
just in memory, but in the device model, i.e. between device_add() and device_del()) the drm_device should exist. So what we do in the bus-specific remove/disconnect callback is that we call drm_dev_unregister(). This drops the drm_device refcount that the drm chardev was holding, to make sure that an open() on the chardev can actually get at the memory without going boom. Then after the drm_dev_unregister, again in the remove/disconnect callback of th driver, there's a drm_dev_put(). Which might or might not be the final drm_dev_put(), since if there's currently some open fd we keep the refcount elevated, to avoid oopses and fun stuff like that. And drm_device pointers get shared very widely, thanks to fun stuff like dma_buf buffer sharing and dma_fence hw syncpt sharing across processes and drivers.
Once the final drm_dev_put() is called we also end up calling put_device() and everything is happy.
So far so good.
Now the problem is that refcount is hard, and most drm drivers get it wrong in some fashion or another, so I'm trying to solve all this with more magic.
Wait, no. Fix the drivers. Seriously, don't try to "bust" the reference count logic here.
I guess still not clear. What I'm doing is fixing the drivers. But because they all get it wrong, I'm trying to hide as much of the refcounting as possible behind functions which do the right thing.
Which works great for the epic pile of real hw drivers that we have.
The problem I have is is _only_ with those drm drivers which run on fake hw. For those forcing them to use the exact same functions as the real hw drivers has some challenges, because they're not really real drivers. Now the original patch had 3 ideas for how to make things work for those fake drivers too, with one of them implemented in this patch (the one that required the least amount of typing on my part).
You harping that I'm getting the refcounting wrong is kinda totally missing the point, because that's what I'm doing.
Since all drivers need to have a drm_dev_put() at the end of their driver's remove/disconnect callback we've added a devm_drm_dev_init function which registers a devres action to do that drm_dev_put() at device_del time (which might or might not be the final drm_dev_put()). Nothing has changed thus far.
Now this works really well because when you have a real driver model driver attached, then device_del ends up calling devres_release_all(), which ends up triggering the multi-stage cleanup of drm_devices. But if you do _not_ have a real driver attached, then device_del does nothing wrt devres cleanup. Instead this is delayed until the final put_device().
Unfortunately that final put_device() will never happen, because drm_device is still holding a reference to the struct device. And the final drm_dev_put of that drm_device will never happen, because that drm_dev_put call is in a devres actions, which wont ever get called.
True, so fix the logic to do the final put_device() :)
This is the only case where this reference loop happens and doesn't get broken. By calling devres_release_all at device_del time, irrespective of whether a driver is bound or not, we make both cases work the same. And at both cases the devres cleanup happens device_del time, and not when the final put_device is called.
So what is so odd about these random drivers that the normal process does not work for them?
They're not drivers in the driver model sense.
Along these lines, you might look into how the v4l developers finally fixed this as they had much the same type of issues that you do with regards to reference counting and resources and userspace file handles.
We have a pile of v4l developers on dri-devel, they've been reviewing the stuff we've been doing in drm over the past 2-3 years already ...
Aside: The final put_device has another devres_release_all() call, which given your explanation sounds very wrong - at that point the physical device is long gone, and cleaning up devres actions at that point is way too late. I think a good cleanup patch on top of this would be to remove that call, and replace it with an assert that no one managed to sneak in a devres_add_action between device_del and the final put_device().
The physical device might be gone, but an open handle to the device might still be around, keeping the structure in place and the driver thinking it still has access to it's memory structures.
I understand that. This is not the problem I'm having here, we've fixed that problem a while ago (at least in drm core, but the drivers have a bit a harder time picking up the correct coding patterns, mostly because there's overwhelming code in existing drivers that's just plain broken).
And then all should be fine, right? But, by putting the freeing here, you can still have a "live" device that thinks it has resources availble that it can access, but yet they are now gone. Yeah, it's probably not ever going to really happen, but the lifecycles of dynamic devices are tough to "prove" at times, and I worry that freeing things this early is going to cause odd disconnect issues.
Not exactly sure what you mean here, but trying to fix all the driver bugs we have in drm is why I'm doing this. We have a massive amount of gaps still, but we're slowly closing them all off with stuff like drm_dev_enter/exit, to make sure there's no races possible between driver hotunplug and concurrent access by userspace.
Again, look at what v4l did, I think it might work out for you all as well.
I think we're talking past each another quite badly here ... -Daniel
On Fri, Apr 3, 2020 at 5:15 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
On Fri, Apr 3, 2020 at 5:06 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 04:47:04PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 4:17 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Apr 03, 2020 at 03:57:45PM +0200, Daniel Vetter wrote:
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.
That's a horrid abuse of platform devices, just use a "virtual" device please, create/remove it when you need it, and all should be fine.
- drm/i915/selftests, where we create minimal mock devices, and again the selftests aren't proper drivers in the driver model sense.
Again, virtual devices are best to use for this.
Hm yeah, I guess we should fix that. i915 selftests do use raw struct device though, and it's not really the problem.
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.
After device_del, you should never be using that structure again anyway. So why is there any "resource leak"? You can't recycle the structure, and you can't assign it to anything else, so eventually you have to do a final put on the thing, which will free up the resources.
I guess I should have spent more time explaining this. There's two references involved:
- drm_device->dev points at the underlying struct device. The
drm_device holds a reference until it's fully cleaned up, so that we can do nice stuff like use dev_ versions of printk functions, and you always know that there's not going to be a use-after free.
- now the other dependency is that as long as the device exists (not
just in memory, but in the device model, i.e. between device_add() and device_del()) the drm_device should exist. So what we do in the bus-specific remove/disconnect callback is that we call drm_dev_unregister(). This drops the drm_device refcount that the drm chardev was holding, to make sure that an open() on the chardev can actually get at the memory without going boom. Then after the drm_dev_unregister, again in the remove/disconnect callback of th driver, there's a drm_dev_put(). Which might or might not be the final drm_dev_put(), since if there's currently some open fd we keep the refcount elevated, to avoid oopses and fun stuff like that. And drm_device pointers get shared very widely, thanks to fun stuff like dma_buf buffer sharing and dma_fence hw syncpt sharing across processes and drivers.
Once the final drm_dev_put() is called we also end up calling put_device() and everything is happy.
So far so good.
Now the problem is that refcount is hard, and most drm drivers get it wrong in some fashion or another, so I'm trying to solve all this with more magic.
Wait, no. Fix the drivers. Seriously, don't try to "bust" the reference count logic here.
I guess still not clear. What I'm doing is fixing the drivers. But because they all get it wrong, I'm trying to hide as much of the refcounting as possible behind functions which do the right thing.
Which works great for the epic pile of real hw drivers that we have.
The problem I have is is _only_ with those drm drivers which run on fake hw. For those forcing them to use the exact same functions as the real hw drivers has some challenges, because they're not really real drivers. Now the original patch had 3 ideas for how to make things work for those fake drivers too, with one of them implemented in this patch (the one that required the least amount of typing on my part).
You harping that I'm getting the refcounting wrong is kinda totally missing the point, because that's what I'm doing.
Since all drivers need to have a drm_dev_put() at the end of their driver's remove/disconnect callback we've added a devm_drm_dev_init function which registers a devres action to do that drm_dev_put() at device_del time (which might or might not be the final drm_dev_put()). Nothing has changed thus far.
Now this works really well because when you have a real driver model driver attached, then device_del ends up calling devres_release_all(), which ends up triggering the multi-stage cleanup of drm_devices. But if you do _not_ have a real driver attached, then device_del does nothing wrt devres cleanup. Instead this is delayed until the final put_device().
Unfortunately that final put_device() will never happen, because drm_device is still holding a reference to the struct device. And the final drm_dev_put of that drm_device will never happen, because that drm_dev_put call is in a devres actions, which wont ever get called.
True, so fix the logic to do the final put_device() :)
This is the only case where this reference loop happens and doesn't get broken. By calling devres_release_all at device_del time, irrespective of whether a driver is bound or not, we make both cases work the same. And at both cases the devres cleanup happens device_del time, and not when the final put_device is called.
So what is so odd about these random drivers that the normal process does not work for them?
They're not drivers in the driver model sense.
Along these lines, you might look into how the v4l developers finally fixed this as they had much the same type of issues that you do with regards to reference counting and resources and userspace file handles.
We have a pile of v4l developers on dri-devel, they've been reviewing the stuff we've been doing in drm over the past 2-3 years already ...
Aside: The final put_device has another devres_release_all() call, which given your explanation sounds very wrong - at that point the physical device is long gone, and cleaning up devres actions at that point is way too late. I think a good cleanup patch on top of this would be to remove that call, and replace it with an assert that no one managed to sneak in a devres_add_action between device_del and the final put_device().
The physical device might be gone, but an open handle to the device might still be around, keeping the structure in place and the driver thinking it still has access to it's memory structures.
I understand that. This is not the problem I'm having here, we've fixed that problem a while ago (at least in drm core, but the drivers have a bit a harder time picking up the correct coding patterns, mostly because there's overwhelming code in existing drivers that's just plain broken).
And then all should be fine, right? But, by putting the freeing here, you can still have a "live" device that thinks it has resources availble that it can access, but yet they are now gone. Yeah, it's probably not ever going to really happen, but the lifecycles of dynamic devices are tough to "prove" at times, and I worry that freeing things this early is going to cause odd disconnect issues.
Not exactly sure what you mean here, but trying to fix all the driver bugs we have in drm is why I'm doing this. We have a massive amount of gaps still, but we're slowly closing them all off with stuff like drm_dev_enter/exit, to make sure there's no races possible between driver hotunplug and concurrent access by userspace.
Again, look at what v4l did, I think it might work out for you all as well.
I think we're talking past each another quite badly here ...
So I've read through the v4l register/unregister code for the cdev, and in spirit it matches what we're doing with drm_device. In practice the drm version is a lot more complicated, mostly because our uapi is kinda hilarious and our single userspace-facing object is exposed through an entire set of of different cdev (the one I have here has like at 5 different cdev registered ...).
The other big difference that I'm seeing is that our equivalent of video_unregister_device is split up, i.e. we're not using the equivalent of device_unregister, but the device_del and put_device that one boils down is split up, with some things happening in between. Mostly because developers insist that when they remove/unbind a driver, we're supposed to shut down the display hardware, instead of just continuing to scan out garbage. Otherwise we could just use the merged device_unregister().
tldr; I'm not seeing what we're doing totally wrong compared to v4l ... -Daniel
On Fri, Apr 3, 2020 at 3:58 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
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:
Restarting this at the top level, because the discussion thus far just ended in a long "you're doing it wrong", despite that I think we're doing what v4l is doing (plus/minus that we can't do an exact matching handling in drm because our uapi has a lot more warts, which we can't change because no breaking userspace).
So which one of the three below is the right approach?
Aside, looking at the v4l solution I think there's also a confusion about struct device representing a char device (which v4l directly uses as its userspace interface refcounted thing, and which drm does _not_ directly). And a struct device embedded into something like platform_device or a virtual device, where a driver can bind to. My question here is about the former, I don't care how cdev struct device are cleaned up one bit. Now if other subsystems relies on the devres cleanup behaviour we currently have because of such cdev usage, then yeah first approach doesn't work (and I have a big surprised that use case, but hey would actually learn something).
End of aside, since again I want to figure out which of the tree approaches it the right one. Not about how wrong one of them is, ignoring the other three I laid out. And maybe there's even more options for this. -Daniel
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@intel.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@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
On Mon, Apr 06, 2020 at 02:32:51PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 3:58 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
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:
Restarting this at the top level, because the discussion thus far just ended in a long "you're doing it wrong", despite that I think we're doing what v4l is doing (plus/minus that we can't do an exact matching handling in drm because our uapi has a lot more warts, which we can't change because no breaking userspace).
So which one of the three below is the right approach?
Aside, looking at the v4l solution I think there's also a confusion about struct device representing a char device (which v4l directly uses as its userspace interface refcounted thing, and which drm does _not_ directly). And a struct device embedded into something like platform_device or a virtual device, where a driver can bind to. My question here is about the former, I don't care how cdev struct device are cleaned up one bit. Now if other subsystems relies on the devres cleanup behaviour we currently have because of such cdev usage, then yeah first approach doesn't work (and I have a big surprised that use case, but hey would actually learn something).
End of aside, since again I want to figure out which of the tree approaches it the right one. Not about how wrong one of them is, ignoring the other three I laid out. And maybe there's even more options for this.
Sorry, been swamped with other things, give me a few days to get back to this, I need to dig into how you all are dealing with the virtual drivers.
Doing this in the middle of the merge window is a bit rough :)
thanks,
greg k-h
On Mon, Apr 6, 2020 at 3:38 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Mon, Apr 06, 2020 at 02:32:51PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 3:58 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
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:
Restarting this at the top level, because the discussion thus far just ended in a long "you're doing it wrong", despite that I think we're doing what v4l is doing (plus/minus that we can't do an exact matching handling in drm because our uapi has a lot more warts, which we can't change because no breaking userspace).
So which one of the three below is the right approach?
Aside, looking at the v4l solution I think there's also a confusion about struct device representing a char device (which v4l directly uses as its userspace interface refcounted thing, and which drm does _not_ directly). And a struct device embedded into something like platform_device or a virtual device, where a driver can bind to. My question here is about the former, I don't care how cdev struct device are cleaned up one bit. Now if other subsystems relies on the devres cleanup behaviour we currently have because of such cdev usage, then yeah first approach doesn't work (and I have a big surprised that use case, but hey would actually learn something).
End of aside, since again I want to figure out which of the tree approaches it the right one. Not about how wrong one of them is, ignoring the other three I laid out. And maybe there's even more options for this.
Sorry, been swamped with other things, give me a few days to get back to this, I need to dig into how you all are dealing with the virtual drivers.
Sure, no problem.
Doing this in the middle of the merge window is a bit rough :)
Ah I always forget ... we freeze drm at -rc6, so merge window is actually my most relaxed time since everyone is busy and no one has time to report drm bugs :-)
Thanks, Daniel
On Mon, Apr 06, 2020 at 03:55:28PM +0200, Daniel Vetter wrote:
On Mon, Apr 6, 2020 at 3:38 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Mon, Apr 06, 2020 at 02:32:51PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 3:58 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
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:
Restarting this at the top level, because the discussion thus far just ended in a long "you're doing it wrong", despite that I think we're doing what v4l is doing (plus/minus that we can't do an exact matching handling in drm because our uapi has a lot more warts, which we can't change because no breaking userspace).
So which one of the three below is the right approach?
Aside, looking at the v4l solution I think there's also a confusion about struct device representing a char device (which v4l directly uses as its userspace interface refcounted thing, and which drm does _not_ directly). And a struct device embedded into something like platform_device or a virtual device, where a driver can bind to. My question here is about the former, I don't care how cdev struct device are cleaned up one bit. Now if other subsystems relies on the devres cleanup behaviour we currently have because of such cdev usage, then yeah first approach doesn't work (and I have a big surprised that use case, but hey would actually learn something).
End of aside, since again I want to figure out which of the tree approaches it the right one. Not about how wrong one of them is, ignoring the other three I laid out. And maybe there's even more options for this.
Sorry, been swamped with other things, give me a few days to get back to this, I need to dig into how you all are dealing with the virtual drivers.
Sure, no problem.
Doing this in the middle of the merge window is a bit rough :)
Ah I always forget ... we freeze drm at -rc6, so merge window is actually my most relaxed time since everyone is busy and no one has time to report drm bugs :-)
Hi Greg,
Since -rc3 is out, had any to ponder this? Otherwise we'll be right back in the next merge window ...
Cheers, Daniel
On Tue, Apr 28, 2020 at 03:15:12PM +0200, Daniel Vetter wrote:
On Mon, Apr 06, 2020 at 03:55:28PM +0200, Daniel Vetter wrote:
On Mon, Apr 6, 2020 at 3:38 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Mon, Apr 06, 2020 at 02:32:51PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 3:58 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
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:
Restarting this at the top level, because the discussion thus far just ended in a long "you're doing it wrong", despite that I think we're doing what v4l is doing (plus/minus that we can't do an exact matching handling in drm because our uapi has a lot more warts, which we can't change because no breaking userspace).
So which one of the three below is the right approach?
Aside, looking at the v4l solution I think there's also a confusion about struct device representing a char device (which v4l directly uses as its userspace interface refcounted thing, and which drm does _not_ directly). And a struct device embedded into something like platform_device or a virtual device, where a driver can bind to. My question here is about the former, I don't care how cdev struct device are cleaned up one bit. Now if other subsystems relies on the devres cleanup behaviour we currently have because of such cdev usage, then yeah first approach doesn't work (and I have a big surprised that use case, but hey would actually learn something).
End of aside, since again I want to figure out which of the tree approaches it the right one. Not about how wrong one of them is, ignoring the other three I laid out. And maybe there's even more options for this.
Sorry, been swamped with other things, give me a few days to get back to this, I need to dig into how you all are dealing with the virtual drivers.
Sure, no problem.
Doing this in the middle of the merge window is a bit rough :)
Ah I always forget ... we freeze drm at -rc6, so merge window is actually my most relaxed time since everyone is busy and no one has time to report drm bugs :-)
Hi Greg,
Since -rc3 is out, had any to ponder this? Otherwise we'll be right back in the next merge window ...
I owe you a response to this. I'm going to try to carve out some time on Monday to do this, sorry for the delay :(
greg k-h
On Fri, May 15, 2020 at 02:55:38PM +0200, Greg Kroah-Hartman wrote:
On Tue, Apr 28, 2020 at 03:15:12PM +0200, Daniel Vetter wrote:
On Mon, Apr 06, 2020 at 03:55:28PM +0200, Daniel Vetter wrote:
On Mon, Apr 6, 2020 at 3:38 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Mon, Apr 06, 2020 at 02:32:51PM +0200, Daniel Vetter wrote:
On Fri, Apr 3, 2020 at 3:58 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
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:
Restarting this at the top level, because the discussion thus far just ended in a long "you're doing it wrong", despite that I think we're doing what v4l is doing (plus/minus that we can't do an exact matching handling in drm because our uapi has a lot more warts, which we can't change because no breaking userspace).
So which one of the three below is the right approach?
Aside, looking at the v4l solution I think there's also a confusion about struct device representing a char device (which v4l directly uses as its userspace interface refcounted thing, and which drm does _not_ directly). And a struct device embedded into something like platform_device or a virtual device, where a driver can bind to. My question here is about the former, I don't care how cdev struct device are cleaned up one bit. Now if other subsystems relies on the devres cleanup behaviour we currently have because of such cdev usage, then yeah first approach doesn't work (and I have a big surprised that use case, but hey would actually learn something).
End of aside, since again I want to figure out which of the tree approaches it the right one. Not about how wrong one of them is, ignoring the other three I laid out. And maybe there's even more options for this.
Sorry, been swamped with other things, give me a few days to get back to this, I need to dig into how you all are dealing with the virtual drivers.
Sure, no problem.
Doing this in the middle of the merge window is a bit rough :)
Ah I always forget ... we freeze drm at -rc6, so merge window is actually my most relaxed time since everyone is busy and no one has time to report drm bugs :-)
Hi Greg,
Since -rc3 is out, had any to ponder this? Otherwise we'll be right back in the next merge window ...
I owe you a response to this. I'm going to try to carve out some time on Monday to do this, sorry for the delay :(
No worries, I got myself plenty occupied with other fun stuff in graphics for now. And the part of the series which doesn't need this here is all landed, so new drivers already look a notch cleaner in their code.
I'd have poked you earlier, but ofc very much appreciated if you can look into this a bit before the next merge window.
Thanks, Daniel
The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc.
Cc: Paul Kocialkowski paul.kocialkowski@bootlin.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/drm_drv.c | 23 +++++++++++++++++++++++ include/drm/drm_drv.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 1bb4f636b83c..9e60b784b3ac 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -739,6 +739,29 @@ int devm_drm_dev_init(struct device *parent, } EXPORT_SYMBOL(devm_drm_dev_init);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, + size_t size, size_t offset) +{ + void *container; + struct drm_device *drm; + int ret; + + container = kzalloc(size, GFP_KERNEL); + if (!container) + return ERR_PTR(-ENOMEM); + + drm = container + offset; + ret = devm_drm_dev_init(parent, drm, driver); + if (ret) { + kfree(container); + return ERR_PTR(ret); + } + drmm_add_final_kfree(drm, container); + + return container; +} +EXPORT_SYMBOL(__devm_drm_dev_alloc); + /** * drm_dev_alloc - Allocate new DRM device * @driver: DRM driver to allocate device for diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e7c6ea261ed1..26776be5a21e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -626,6 +626,39 @@ int devm_drm_dev_init(struct device *parent, struct drm_device *dev, struct drm_driver *driver);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, + size_t size, size_t offset); + +/** + * devm_drm_dev_alloc - Resource managed allocation of a &drm_device instance + * @parent: Parent device object + * @driver: DRM driver + * @type: the type of the struct which contains struct &drm_device + * @member: the name of the &drm_device within @type. + * + * This allocates and initialize a new DRM device. No device registration is done. + * Call drm_dev_register() to advertice the device to user space and register it + * with other core subsystems. This should be done last in the device + * initialization sequence to make sure userspace can't access an inconsistent + * state. + * + * The initial ref-count of the object is 1. Use drm_dev_get() and + * drm_dev_put() to take and drop further ref-counts. + * + * It is recommended that drivers embed &struct drm_device into their own device + * structure. + * + * Note that this manages the lifetime of the resulting &drm_device + * automatically using devres. The DRM device initialized with this function is + * automatically put on driver detach using drm_dev_put(). + * + * RETURNS: + * Pointer to new DRM device, or ERR_PTR on failure. + */ +#define devm_drm_dev_alloc(parent, driver, type, member) \ + ((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \ + offsetof(type, member))) + struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags);
Den 03.04.2020 15.57, skrev Daniel Vetter:
The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc.
Cc: Paul Kocialkowski paul.kocialkowski@bootlin.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Acked-by: Noralf Trønnes noralf@tronnes.org
Hi Daniel,
Thank you for the patch.
On Fri, Apr 03, 2020 at 03:57:46PM +0200, Daniel Vetter wrote:
The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc.
How about drivers that expose another interface towards userspace ? If the other related subsystem also required allocation of the driver private structure through its corresponding API, we'd be stuck. As stated before, I want this API to be optional.
Cc: Paul Kocialkowski paul.kocialkowski@bootlin.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_drv.c | 23 +++++++++++++++++++++++ include/drm/drm_drv.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 1bb4f636b83c..9e60b784b3ac 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -739,6 +739,29 @@ int devm_drm_dev_init(struct device *parent, } EXPORT_SYMBOL(devm_drm_dev_init);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset)
+{
- void *container;
- struct drm_device *drm;
- int ret;
- container = kzalloc(size, GFP_KERNEL);
- if (!container)
return ERR_PTR(-ENOMEM);
- drm = container + offset;
- ret = devm_drm_dev_init(parent, drm, driver);
- if (ret) {
kfree(container);
return ERR_PTR(ret);
- }
- drmm_add_final_kfree(drm, container);
- return container;
+} +EXPORT_SYMBOL(__devm_drm_dev_alloc);
/**
- drm_dev_alloc - Allocate new DRM device
- @driver: DRM driver to allocate device for
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e7c6ea261ed1..26776be5a21e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -626,6 +626,39 @@ int devm_drm_dev_init(struct device *parent, struct drm_device *dev, struct drm_driver *driver);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset);
+/**
- devm_drm_dev_alloc - Resource managed allocation of a &drm_device instance
- @parent: Parent device object
- @driver: DRM driver
- @type: the type of the struct which contains struct &drm_device
- @member: the name of the &drm_device within @type.
- This allocates and initialize a new DRM device. No device registration is done.
- Call drm_dev_register() to advertice the device to user space and register it
- with other core subsystems. This should be done last in the device
- initialization sequence to make sure userspace can't access an inconsistent
- state.
- The initial ref-count of the object is 1. Use drm_dev_get() and
- drm_dev_put() to take and drop further ref-counts.
- It is recommended that drivers embed &struct drm_device into their own device
- structure.
- Note that this manages the lifetime of the resulting &drm_device
- automatically using devres. The DRM device initialized with this function is
- automatically put on driver detach using drm_dev_put().
- RETURNS:
- Pointer to new DRM device, or ERR_PTR on failure.
- */
+#define devm_drm_dev_alloc(parent, driver, type, member) \
- ((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \
offsetof(type, member)))
struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags);
On Mon, Apr 6, 2020 at 2:01 PM Laurent Pinchart laurent.pinchart@ideasonboard.com wrote:
Hi Daniel,
Thank you for the patch.
On Fri, Apr 03, 2020 at 03:57:46PM +0200, Daniel Vetter wrote:
The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc.
How about drivers that expose another interface towards userspace ? If the other related subsystem also required allocation of the driver private structure through its corresponding API, we'd be stuck. As stated before, I want this API to be optional.
So maybe we need to import a little bit more of our epic irc discussion here, because this is leaving out all the context. There's a few more things:
- Since the merging of the previous patch series this is already mandatory, because the kfree(drm_device.managed.final_kfree) is the last thing that will run. So I already killed your use-case (and it seems to work just fine for all the drivers in-tree, and we have a lot).
- As part of doing all these patches here and in the previous series and in a next one I've seen that drivers just get this wrong. I'm extremely hesitant to give that rope back to drivers, so I really don't want to merge anything until we're ready to merge a driver that needs it. I've set myself a goal to fix up all 40 odd drivers still using drm_dev_alloc(), and that's itself already pretty stupid idea. It's definitely not going to work if new drivers keep adding bad usage patterns.
- Now I'm not opposed to allowing this, if/when we actually need it. I think a very clean long-term solution would be to have a struct kref_res, which augments a kref with automatic resource cleanup. We'd probably need to fully demidlayer that, i.e. if you supply your own ->release hook then it's your job to call kref_release_all() at the right point in there. With that we could then do a devm_drm_dev_init() again, which would take that kref_res structure and the drm_device, both embedded somewhere in your overall driver struture, and use your drivers kref_res to attach all drm related auto-cleanup. In that case it would then also be that kref_res' responsibility to do the final kfree, hence drm wouldn't insist on doing that either. Prototype would be something like:
devm_drm_dev_init(struct device *dev, struct drm_device *drm, struct drm_driver *driver, struct kref_res *kref);
The trouble with the above idea is that it assumes I have endless amounts of time and that I can convince Greg KH that I understand driver unload lifetime issues. The former is atm the more realistic looking one of these two, so interim solution would be to add some hack or another meanwhile to do this within drm only. Or as an alternative solution, easy to convert over to an eventual kref_res world:
#define kref_res_get() drm_dev_get() #define kref_res_put() drm_dev_put()
With suitable amounts of casting to make this work out correctly like the real kref_res solution.
Until we do have such drivers though I really don't want to open the barn door again to all the bugs that'll bring, while I'm trying to get the other barn doors closed down and fixed meanwhile. -Daniel
Cc: Paul Kocialkowski paul.kocialkowski@bootlin.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_drv.c | 23 +++++++++++++++++++++++ include/drm/drm_drv.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 1bb4f636b83c..9e60b784b3ac 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -739,6 +739,29 @@ int devm_drm_dev_init(struct device *parent, } EXPORT_SYMBOL(devm_drm_dev_init);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset)
+{
void *container;
struct drm_device *drm;
int ret;
container = kzalloc(size, GFP_KERNEL);
if (!container)
return ERR_PTR(-ENOMEM);
drm = container + offset;
ret = devm_drm_dev_init(parent, drm, driver);
if (ret) {
kfree(container);
return ERR_PTR(ret);
}
drmm_add_final_kfree(drm, container);
return container;
+} +EXPORT_SYMBOL(__devm_drm_dev_alloc);
/**
- drm_dev_alloc - Allocate new DRM device
- @driver: DRM driver to allocate device for
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e7c6ea261ed1..26776be5a21e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -626,6 +626,39 @@ int devm_drm_dev_init(struct device *parent, struct drm_device *dev, struct drm_driver *driver);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset);
+/**
- devm_drm_dev_alloc - Resource managed allocation of a &drm_device instance
- @parent: Parent device object
- @driver: DRM driver
- @type: the type of the struct which contains struct &drm_device
- @member: the name of the &drm_device within @type.
- This allocates and initialize a new DRM device. No device registration is done.
- Call drm_dev_register() to advertice the device to user space and register it
- with other core subsystems. This should be done last in the device
- initialization sequence to make sure userspace can't access an inconsistent
- state.
- The initial ref-count of the object is 1. Use drm_dev_get() and
- drm_dev_put() to take and drop further ref-counts.
- It is recommended that drivers embed &struct drm_device into their own device
- structure.
- Note that this manages the lifetime of the resulting &drm_device
- automatically using devres. The DRM device initialized with this function is
- automatically put on driver detach using drm_dev_put().
- RETURNS:
- Pointer to new DRM device, or ERR_PTR on failure.
- */
+#define devm_drm_dev_alloc(parent, driver, type, member) \
((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \
offsetof(type, member)))
struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags);
-- Regards,
Laurent Pinchart
Hi Daniel.
Finally managed to dive into this..
Maybe I need more coffee, it is still morning here. But alas this patch triggered a few comments.
Sam
On Fri, Apr 03, 2020 at 03:57:46PM +0200, Daniel Vetter wrote:
The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc.
This changelog entry does a poor job describing what the purpose of this change is. Try to read it outside context.
Cc: Paul Kocialkowski paul.kocialkowski@bootlin.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_drv.c | 23 +++++++++++++++++++++++ include/drm/drm_drv.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 1bb4f636b83c..9e60b784b3ac 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -739,6 +739,29 @@ int devm_drm_dev_init(struct device *parent, } EXPORT_SYMBOL(devm_drm_dev_init);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset)
+{
- void *container;
- struct drm_device *drm;
- int ret;
- container = kzalloc(size, GFP_KERNEL);
- if (!container)
return ERR_PTR(-ENOMEM);
- drm = container + offset;
- ret = devm_drm_dev_init(parent, drm, driver);
- if (ret) {
kfree(container);
return ERR_PTR(ret);
- }
- drmm_add_final_kfree(drm, container);
- return container;
+} +EXPORT_SYMBOL(__devm_drm_dev_alloc);
/**
- drm_dev_alloc - Allocate new DRM device
- @driver: DRM driver to allocate device for
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e7c6ea261ed1..26776be5a21e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -626,6 +626,39 @@ int devm_drm_dev_init(struct device *parent, struct drm_device *dev, struct drm_driver *driver);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset);
+/**
- devm_drm_dev_alloc - Resource managed allocation of a &drm_device instance
- @parent: Parent device object
- @driver: DRM driver
- @type: the type of the struct which contains struct &drm_device
- @member: the name of the &drm_device within @type.
I am confused about the naming here. devm_ implies we allocate something with a lifetime equal that of a driver. So when the driver are gone what we allocate is also gone. Like everythign else devm_ prefixed.
But the lifetime of a drm_device is until the last userspace reference is gone (final drm_dev_put() is called).
- This allocates and initialize a new DRM device. No device registration is done.
- Call drm_dev_register() to advertice the device to user space and register it
- with other core subsystems. This should be done last in the device
s/This/Calling drm_dev_register()/ will make this sentence a bit more explicit.
- initialization sequence to make sure userspace can't access an inconsistent
- state.
- The initial ref-count of the object is 1. Use drm_dev_get() and
- drm_dev_put() to take and drop further ref-counts.
- It is recommended that drivers embed &struct drm_device into their own device
- structure.
- Note that this manages the lifetime of the resulting &drm_device
- automatically using devres.
Hmm, no this is managed by drmres???
- The DRM device initialized with this function is
- automatically put on driver detach using drm_dev_put().
- RETURNS:
- Pointer to new DRM device, or ERR_PTR on failure.
- */
+#define devm_drm_dev_alloc(parent, driver, type, member) \
- ((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \
offsetof(type, member)))
struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags); -- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On Wed, Apr 08, 2020 at 08:57:14AM +0200, Sam Ravnborg wrote:
Hi Daniel.
Finally managed to dive into this..
Maybe I need more coffee, it is still morning here. But alas this patch triggered a few comments.
Sam
On Fri, Apr 03, 2020 at 03:57:46PM +0200, Daniel Vetter wrote:
The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc.
This changelog entry does a poor job describing what the purpose of this change is. Try to read it outside context.
Something like:
Add a new macro helper to combine the usual init sequence in drivers, consisting of a kzalloc + devm_drm_dev_init + drmm_add_final_kfree triplet. This allows us to remove the rather unsightly drmm_add_final_kfree from all currently merged drivers.
This good enough, as an intro paragraph?
Cc: Paul Kocialkowski paul.kocialkowski@bootlin.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_drv.c | 23 +++++++++++++++++++++++ include/drm/drm_drv.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 1bb4f636b83c..9e60b784b3ac 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -739,6 +739,29 @@ int devm_drm_dev_init(struct device *parent, } EXPORT_SYMBOL(devm_drm_dev_init);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset)
+{
- void *container;
- struct drm_device *drm;
- int ret;
- container = kzalloc(size, GFP_KERNEL);
- if (!container)
return ERR_PTR(-ENOMEM);
- drm = container + offset;
- ret = devm_drm_dev_init(parent, drm, driver);
- if (ret) {
kfree(container);
return ERR_PTR(ret);
- }
- drmm_add_final_kfree(drm, container);
- return container;
+} +EXPORT_SYMBOL(__devm_drm_dev_alloc);
/**
- drm_dev_alloc - Allocate new DRM device
- @driver: DRM driver to allocate device for
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e7c6ea261ed1..26776be5a21e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -626,6 +626,39 @@ int devm_drm_dev_init(struct device *parent, struct drm_device *dev, struct drm_driver *driver);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset);
+/**
- devm_drm_dev_alloc - Resource managed allocation of a &drm_device instance
- @parent: Parent device object
- @driver: DRM driver
- @type: the type of the struct which contains struct &drm_device
- @member: the name of the &drm_device within @type.
I am confused about the naming here. devm_ implies we allocate something with a lifetime equal that of a driver. So when the driver are gone what we allocate is also gone. Like everythign else devm_ prefixed.
But the lifetime of a drm_device is until the last userspace reference is gone (final drm_dev_put() is called).
The kerneldoc for this is largely copied from the existing devm_drm_dev_init. And yes the lifetime is bound to the device, we do the drm_dev_put() when that disappears. Now other users of drm_device might still hold references and delay cleanup, but "cleanup is done as a devres action" is very much what devm_ signifies. "
- This allocates and initialize a new DRM device. No device registration is done.
- Call drm_dev_register() to advertice the device to user space and register it
- with other core subsystems. This should be done last in the device
s/This/Calling drm_dev_register()/ will make this sentence a bit more explicit.
- initialization sequence to make sure userspace can't access an inconsistent
- state.
- The initial ref-count of the object is 1. Use drm_dev_get() and
- drm_dev_put() to take and drop further ref-counts.
- It is recommended that drivers embed &struct drm_device into their own device
- structure.
- Note that this manages the lifetime of the resulting &drm_device
- automatically using devres.
Hmm, no this is managed by drmres???
Yup, the next sentence explains how. And note that we're already using this in the form of devm_drm_dev_init. So not clear what's unclear here ...
Thanks for your comments. -Daniel
- The DRM device initialized with this function is
- automatically put on driver detach using drm_dev_put().
- RETURNS:
- Pointer to new DRM device, or ERR_PTR on failure.
- */
+#define devm_drm_dev_alloc(parent, driver, type, member) \
- ((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \
offsetof(type, member)))
struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags); -- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Hi Daniel.
On Wed, Apr 08, 2020 at 02:11:47PM +0200, Daniel Vetter wrote:
On Wed, Apr 08, 2020 at 08:57:14AM +0200, Sam Ravnborg wrote:
Hi Daniel.
Finally managed to dive into this..
Maybe I need more coffee, it is still morning here. But alas this patch triggered a few comments.
Sam
On Fri, Apr 03, 2020 at 03:57:46PM +0200, Daniel Vetter wrote:
The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc.
This changelog entry does a poor job describing what the purpose of this change is. Try to read it outside context.
Something like:
Add a new macro helper to combine the usual init sequence in drivers, consisting of a kzalloc + devm_drm_dev_init + drmm_add_final_kfree triplet. This allows us to remove the rather unsightly drmm_add_final_kfree from all currently merged drivers.
Much better - thanks!
This good enough, as an intro paragraph?
Cc: Paul Kocialkowski paul.kocialkowski@bootlin.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_drv.c | 23 +++++++++++++++++++++++ include/drm/drm_drv.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 1bb4f636b83c..9e60b784b3ac 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -739,6 +739,29 @@ int devm_drm_dev_init(struct device *parent, } EXPORT_SYMBOL(devm_drm_dev_init);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset)
+{
- void *container;
- struct drm_device *drm;
- int ret;
- container = kzalloc(size, GFP_KERNEL);
- if (!container)
return ERR_PTR(-ENOMEM);
- drm = container + offset;
- ret = devm_drm_dev_init(parent, drm, driver);
- if (ret) {
kfree(container);
return ERR_PTR(ret);
- }
- drmm_add_final_kfree(drm, container);
- return container;
+} +EXPORT_SYMBOL(__devm_drm_dev_alloc);
/**
- drm_dev_alloc - Allocate new DRM device
- @driver: DRM driver to allocate device for
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e7c6ea261ed1..26776be5a21e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -626,6 +626,39 @@ int devm_drm_dev_init(struct device *parent, struct drm_device *dev, struct drm_driver *driver);
+void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
size_t size, size_t offset);
+/**
- devm_drm_dev_alloc - Resource managed allocation of a &drm_device instance
- @parent: Parent device object
- @driver: DRM driver
- @type: the type of the struct which contains struct &drm_device
- @member: the name of the &drm_device within @type.
I am confused about the naming here. devm_ implies we allocate something with a lifetime equal that of a driver. So when the driver are gone what we allocate is also gone. Like everythign else devm_ prefixed.
But the lifetime of a drm_device is until the last userspace reference is gone (final drm_dev_put() is called).
The kerneldoc for this is largely copied from the existing devm_drm_dev_init. And yes the lifetime is bound to the device, we do the drm_dev_put() when that disappears. Now other users of drm_device might still hold references and delay cleanup, but "cleanup is done as a devres action" is very much what devm_ signifies.
After discussing this on IRC I took one more look at the code.
We have something like this:
devm_drm_dev_alloc() | +-> devm_drm_dev_init() | | | +-> drm_dev_init() | | | | | +- kref_init(&dev->ref) | | | | | +- drmm_add_action(drm_dev_init_release) | | | +-> devm_add_action(devm_drm_dev_init_release) | +-> drmm_add_final_kfree()
drm_dev_init_release() - does all the release stuff devm_drm_dev_init_release() do a simple drm_dev_put()
In other words we use the devres functionality to keep track of the reference count for the structure allocated by devm_drm_dev_alloc() So the naming makes some sense anyway.
When there are no users left of drm_dev_init() outside drm_drv.c this can be simplified a little.
After re-reading the code it made sense again.
With the updated changelog:
Reviewed-by: Sam Ravnborg sam@ravnborg.org
PS. There is a few trivial checkpatch warnings to look at before pushing out.
Sam
"
- This allocates and initialize a new DRM device. No device registration is done.
- Call drm_dev_register() to advertice the device to user space and register it
- with other core subsystems. This should be done last in the device
s/This/Calling drm_dev_register()/ will make this sentence a bit more explicit.
- initialization sequence to make sure userspace can't access an inconsistent
- state.
- The initial ref-count of the object is 1. Use drm_dev_get() and
- drm_dev_put() to take and drop further ref-counts.
- It is recommended that drivers embed &struct drm_device into their own device
- structure.
- Note that this manages the lifetime of the resulting &drm_device
- automatically using devres.
Hmm, no this is managed by drmres???
Yup, the next sentence explains how. And note that we're already using this in the form of devm_drm_dev_init. So not clear what's unclear here ...
Thanks for your comments. -Daniel
- The DRM device initialized with this function is
- automatically put on driver detach using drm_dev_put().
- RETURNS:
- Pointer to new DRM device, or ERR_PTR on failure.
- */
+#define devm_drm_dev_alloc(parent, driver, type, member) \
- ((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \
offsetof(type, member)))
struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags); -- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
-- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
We've had lots of conversions to embeddeding, but didn't stop using ->dev_private. Which defeats the point of this.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- include/drm/drm_device.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index d39132b477dd..a55874db9dd4 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -88,9 +88,12 @@ struct drm_device { /** * @dev_private: * - * DRM driver private data. Instead of using this pointer it is - * recommended that drivers use drm_dev_init() and embed struct - * &drm_device in their larger per-device structure. + * DRM driver private data. This is deprecated and should be left set to + * NULL. + * + * Instead of using this pointer it is recommended that drivers use + * drm_dev_init() and embed struct &drm_device in their larger + * per-device structure. */ void *dev_private;
On Fri, Apr 03, 2020 at 03:57:47PM +0200, Daniel Vetter wrote:
We've had lots of conversions to embeddeding, but didn't stop using ->dev_private. Which defeats the point of this.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Reviewed-by: Sam Ravnborg sam@ravnborg.org
include/drm/drm_device.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index d39132b477dd..a55874db9dd4 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -88,9 +88,12 @@ struct drm_device { /** * @dev_private: *
* DRM driver private data. Instead of using this pointer it is
* recommended that drivers use drm_dev_init() and embed struct
* &drm_device in their larger per-device structure.
* DRM driver private data. This is deprecated and should be left set to
* NULL.
*
* Instead of using this pointer it is recommended that drivers use
* drm_dev_init() and embed struct &drm_device in their larger
*/ void *dev_private;* per-device structure.
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On Wed, Apr 08, 2020 at 09:02:07AM +0200, Sam Ravnborg wrote:
On Fri, Apr 03, 2020 at 03:57:47PM +0200, Daniel Vetter wrote:
We've had lots of conversions to embeddeding, but didn't stop using ->dev_private. Which defeats the point of this.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Reviewed-by: Sam Ravnborg sam@ravnborg.org
Went right ahead and pushed this since a doc patch only, thanks for taking a look! -Daniel
include/drm/drm_device.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index d39132b477dd..a55874db9dd4 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -88,9 +88,12 @@ struct drm_device { /** * @dev_private: *
* DRM driver private data. Instead of using this pointer it is
* recommended that drivers use drm_dev_init() and embed struct
* &drm_device in their larger per-device structure.
* DRM driver private data. This is deprecated and should be left set to
* NULL.
*
* Instead of using this pointer it is recommended that drivers use
* drm_dev_init() and embed struct &drm_device in their larger
*/ void *dev_private;* per-device structure.
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
This means we also need to slightly restructure the exit code, so that final cleanup of the drm_device is triggered by unregistering the platform device. Note that devres is both clean up when the driver is unbound (not the case for vgem, we don't bind), and also when unregistering the device (very much the case for vgem). Therefore we can rely on devres even though vgem isn't a proper platform device driver.
This also somewhat untangles the load code, since the drm and platform device setup are no longer interleaved, but two distinct steps.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Emil Velikov emil.velikov@collabora.com Cc: Sean Paul seanpaul@chromium.org Cc: Chris Wilson chris@chris-wilson.co.uk Cc: Sam Ravnborg sam@ravnborg.org Cc: Rob Clark robdclark@chromium.org --- drivers/gpu/drm/vgem/vgem_drv.c | 51 ++++++++++----------------------- 1 file changed, 15 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index ec1a8ebb6f1b..2ce3b547312a 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -427,16 +427,8 @@ static int vgem_prime_mmap(struct drm_gem_object *obj, return 0; }
-static void vgem_release(struct drm_device *dev) -{ - struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm); - - platform_device_unregister(vgem->platform); -} - static struct drm_driver vgem_driver = { .driver_features = DRIVER_GEM | DRIVER_RENDER, - .release = vgem_release, .open = vgem_open, .postclose = vgem_postclose, .gem_free_object_unlocked = vgem_gem_free_object, @@ -469,48 +461,35 @@ static struct drm_driver vgem_driver = { static int __init vgem_init(void) { int ret; + struct platform_device *pdev;
- vgem_device = kzalloc(sizeof(*vgem_device), GFP_KERNEL); - if (!vgem_device) - return -ENOMEM; - - vgem_device->platform = - platform_device_register_simple("vgem", -1, NULL, 0); - if (IS_ERR(vgem_device->platform)) { - ret = PTR_ERR(vgem_device->platform); - goto out_free; - } + pdev = platform_device_register_simple("vgem", -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(vgem_device->platform);
- dma_coerce_mask_and_coherent(&vgem_device->platform->dev, + dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); - ret = drm_dev_init(&vgem_device->drm, &vgem_driver, - &vgem_device->platform->dev); - if (ret) - goto out_unregister; - drmm_add_final_kfree(&vgem_device->drm, vgem_device); + + vgem_device = devm_drm_dev_alloc(&pdev->dev, &vgem_driver, + struct vgem_device, drm); + if (IS_ERR(vgem_device)) { + platform_device_unregister(pdev); + return PTR_ERR(vgem_device); + } + vgem_device->platform = pdev;
/* Final step: expose the device/driver to userspace */ ret = drm_dev_register(&vgem_device->drm, 0); if (ret) - goto out_put; + return ret;
return 0; - -out_put: - drm_dev_put(&vgem_device->drm); - return ret; - -out_unregister: - platform_device_unregister(vgem_device->platform); -out_free: - kfree(vgem_device); - return ret; }
static void __exit vgem_exit(void) { drm_dev_unregister(&vgem_device->drm); - drm_dev_put(&vgem_device->drm); + platform_device_unregister(vgem_device->platform); }
module_init(vgem_init);
This means we also need to slightly restructure the exit code, so that final cleanup of the drm_device is triggered by unregistering the platform device. Note that devres is both clean up when the driver is unbound (not the case for vkms, we don't bind), and also when unregistering the device (very much the case for vkms). Therefore we can rely on devres even though vkms isn't a proper platform device driver.
This also somewhat untangles the load code, since the drm and platform device setup are no longer interleaved, but two distinct steps.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Haneen Mohammed hamohammed.sa@gmail.com Cc: Daniel Vetter daniel@ffwll.ch --- drivers/gpu/drm/vkms/vkms_drv.c | 48 +++++++++++---------------------- 1 file changed, 16 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index eef85f1a0ce5..fec2a4b91c4d 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -61,9 +61,6 @@ static void vkms_release(struct drm_device *dev) { struct vkms_device *vkms = container_of(dev, struct vkms_device, drm);
- platform_device_unregister(vkms->platform); - drm_atomic_helper_shutdown(&vkms->drm); - drm_mode_config_cleanup(&vkms->drm); destroy_workqueue(vkms->output.composer_workq); }
@@ -142,30 +139,26 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev) static int __init vkms_init(void) { int ret; + struct platform_device *pdev;
- vkms_device = kzalloc(sizeof(*vkms_device), GFP_KERNEL); - if (!vkms_device) - return -ENOMEM; + pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev);
- vkms_device->platform = - platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (IS_ERR(vkms_device->platform)) { - ret = PTR_ERR(vkms_device->platform); - goto out_free; + vkms_device = devm_drm_dev_alloc(&pdev->dev, &vkms_driver, + struct vkms_device, drm); + if (IS_ERR(vkms_device)) { + platform_device_unregister(pdev); + return PTR_ERR(vkms_device); } - - ret = drm_dev_init(&vkms_device->drm, &vkms_driver, - &vkms_device->platform->dev); - if (ret) - goto out_unregister; - drmm_add_final_kfree(&vkms_device->drm, vkms_device); + vkms_device->platform = pdev;
ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev, DMA_BIT_MASK(64));
if (ret) { DRM_ERROR("Could not initialize DMA support\n"); - goto out_put; + return ret; }
vkms_device->drm.irq_enabled = true; @@ -173,28 +166,18 @@ static int __init vkms_init(void) ret = drm_vblank_init(&vkms_device->drm, 1); if (ret) { DRM_ERROR("Failed to vblank\n"); - goto out_put; + return ret; }
ret = vkms_modeset_init(vkms_device); if (ret) - goto out_put; + return ret;
ret = drm_dev_register(&vkms_device->drm, 0); if (ret) - goto out_put; + return ret;
return 0; - -out_put: - drm_dev_put(&vkms_device->drm); - return ret; - -out_unregister: - platform_device_unregister(vkms_device->platform); -out_free: - kfree(vkms_device); - return ret; }
static void __exit vkms_exit(void) @@ -205,7 +188,8 @@ static void __exit vkms_exit(void) }
drm_dev_unregister(&vkms_device->drm); - drm_dev_put(&vkms_device->drm); + drm_atomic_helper_shutdown(&vkms_device->drm); + platform_device_unregister(vkms_device->platform); }
module_init(vkms_init);
Doesn't apply to upstream kernels since a rather long time.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com --- drivers/gpu/drm/vboxvideo/vbox_ttm.c | 12 ------------ 1 file changed, 12 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c index 976423d0c3cc..f5a06675da43 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c @@ -24,25 +24,13 @@ int vbox_mm_init(struct vbox_private *vbox) return ret; }
-#ifdef DRM_MTRR_WC - vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0), - DRM_MTRR_WC); -#else vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); -#endif return 0; }
void vbox_mm_fini(struct vbox_private *vbox) { -#ifdef DRM_MTRR_WC - drm_mtrr_del(vbox->fb_mtrr, - pci_resource_start(vbox->ddev.pdev, 0), - pci_resource_len(vbox->ddev.pdev, 0), DRM_MTRR_WC); -#else arch_phys_wc_del(vbox->fb_mtrr); -#endif drm_vram_helper_release_mm(&vbox->ddev); }
On Fri, Apr 03, 2020 at 03:57:50PM +0200, Daniel Vetter wrote:
Doesn't apply to upstream kernels since a rather long time.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/vboxvideo/vbox_ttm.c | 12 ------------ 1 file changed, 12 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c index 976423d0c3cc..f5a06675da43 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c @@ -24,25 +24,13 @@ int vbox_mm_init(struct vbox_private *vbox) return ret; }
-#ifdef DRM_MTRR_WC
- vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
pci_resource_len(dev->pdev, 0),
DRM_MTRR_WC);
-#else vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); -#endif return 0; }
void vbox_mm_fini(struct vbox_private *vbox) { -#ifdef DRM_MTRR_WC
- drm_mtrr_del(vbox->fb_mtrr,
pci_resource_start(vbox->ddev.pdev, 0),
pci_resource_len(vbox->ddev.pdev, 0), DRM_MTRR_WC);
-#else arch_phys_wc_del(vbox->fb_mtrr); -#endif drm_vram_helper_release_mm(&vbox->ddev); } -- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Straightforward conversion.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index d685ec197fa0..be0600b22cf5 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -46,25 +46,19 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret;
- vbox = kzalloc(sizeof(*vbox), GFP_KERNEL); - if (!vbox) - return -ENOMEM; - - ret = drm_dev_init(&vbox->ddev, &driver, &pdev->dev); - if (ret) { - kfree(vbox); - return ret; - } + vbox = devm_drm_dev_alloc(&pdev->dev, &driver, + struct vbox_private, ddev); + if (IS_ERR(vbox)) + return PTR_ERR(vbox);
vbox->ddev.pdev = pdev; vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); - drmm_add_final_kfree(&vbox->ddev, vbox); mutex_init(&vbox->hw_mutex);
ret = pci_enable_device(pdev); if (ret) - goto err_dev_put; + return ret;
ret = vbox_hw_init(vbox); if (ret) @@ -102,8 +96,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vbox_hw_fini(vbox); err_pci_disable: pci_disable_device(pdev); -err_dev_put: - drm_dev_put(&vbox->ddev); return ret; }
@@ -116,7 +108,6 @@ static void vbox_pci_remove(struct pci_dev *pdev) vbox_mode_fini(vbox); vbox_mm_fini(vbox); vbox_hw_fini(vbox); - drm_dev_put(&vbox->ddev); }
#ifdef CONFIG_PM_SLEEP
We use the baseclass pattern here, so lets to the proper (and more typesafe) upcasting.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_irq.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +++++----- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index be0600b22cf5..d34cddd809fd 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -52,7 +52,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return PTR_ERR(vbox);
vbox->ddev.pdev = pdev; - vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h index 87421903816c..ac7c2effc46f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h @@ -127,6 +127,7 @@ struct vbox_encoder { #define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base) #define to_vbox_connector(x) container_of(x, struct vbox_connector, base) #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) +#define to_vbox_dev(x) container_of(x, struct vbox_private, ddev)
bool vbox_check_supported(u16 id); int vbox_hw_init(struct vbox_private *vbox); diff --git a/drivers/gpu/drm/vboxvideo/vbox_irq.c b/drivers/gpu/drm/vboxvideo/vbox_irq.c index 16a1e29f5292..631657fa554f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_irq.c +++ b/drivers/gpu/drm/vboxvideo/vbox_irq.c @@ -34,7 +34,7 @@ void vbox_report_hotplug(struct vbox_private *vbox) irqreturn_t vbox_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg; - struct vbox_private *vbox = (struct vbox_private *)dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(dev); u32 host_flags = vbox_get_flags(vbox);
if (!(host_flags & HGSMIHOSTFLAGS_IRQ)) diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 0883a435e62b..d9a5af62af89 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -36,7 +36,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) u16 flags; s32 x_offset, y_offset;
- vbox = crtc->dev->dev_private; + vbox = to_vbox_dev(crtc->dev); width = vbox_crtc->width ? vbox_crtc->width : 640; height = vbox_crtc->height ? vbox_crtc->height : 480; bpp = fb ? fb->format->cpp[0] * 8 : 32; @@ -77,7 +77,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) static int vbox_set_view(struct drm_crtc *crtc) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); - struct vbox_private *vbox = crtc->dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbva_infoview *p;
/* @@ -174,7 +174,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, int x, int y) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(fb->obj[0]); - struct vbox_private *vbox = crtc->dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
@@ -272,7 +272,7 @@ static void vbox_primary_atomic_update(struct drm_plane *plane, { struct drm_crtc *crtc = plane->state->crtc; struct drm_framebuffer *fb = plane->state->fb; - struct vbox_private *vbox = fb->dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(fb->dev); struct drm_mode_rect *clips; uint32_t num_clips, i;
@@ -704,7 +704,7 @@ static int vbox_get_modes(struct drm_connector *connector) int preferred_width, preferred_height;
vbox_connector = to_vbox_connector(connector); - vbox = connector->dev->dev_private; + vbox = to_vbox_dev(connector->dev);
hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) + HOST_FLAGS_OFFSET);
Hi
Am 03.04.20 um 15:57 schrieb Daniel Vetter:
We use the baseclass pattern here, so lets to the proper (and more typesafe) upcasting.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
drivers/gpu/drm/vboxvideo/vbox_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_irq.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +++++----- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index be0600b22cf5..d34cddd809fd 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -52,7 +52,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return PTR_ERR(vbox);
vbox->ddev.pdev = pdev;
- vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h index 87421903816c..ac7c2effc46f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h @@ -127,6 +127,7 @@ struct vbox_encoder { #define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base) #define to_vbox_connector(x) container_of(x, struct vbox_connector, base) #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) +#define to_vbox_dev(x) container_of(x, struct vbox_private, ddev)
I suggest ot call this macro to to_vbox_device(). At some point, we should rename struct vbox_private to struct vbox_device for consistency among drivers. The new macro's name would then fit.
For the overall patch:
Acked-by: Thomas Zimmermann tzimmermann@suse.de
Best regards Thomas
bool vbox_check_supported(u16 id); int vbox_hw_init(struct vbox_private *vbox); diff --git a/drivers/gpu/drm/vboxvideo/vbox_irq.c b/drivers/gpu/drm/vboxvideo/vbox_irq.c index 16a1e29f5292..631657fa554f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_irq.c +++ b/drivers/gpu/drm/vboxvideo/vbox_irq.c @@ -34,7 +34,7 @@ void vbox_report_hotplug(struct vbox_private *vbox) irqreturn_t vbox_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg;
- struct vbox_private *vbox = (struct vbox_private *)dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(dev); u32 host_flags = vbox_get_flags(vbox);
if (!(host_flags & HGSMIHOSTFLAGS_IRQ))
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 0883a435e62b..d9a5af62af89 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -36,7 +36,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) u16 flags; s32 x_offset, y_offset;
- vbox = crtc->dev->dev_private;
- vbox = to_vbox_dev(crtc->dev); width = vbox_crtc->width ? vbox_crtc->width : 640; height = vbox_crtc->height ? vbox_crtc->height : 480; bpp = fb ? fb->format->cpp[0] * 8 : 32;
@@ -77,7 +77,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) static int vbox_set_view(struct drm_crtc *crtc) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
- struct vbox_private *vbox = crtc->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbva_infoview *p;
/*
@@ -174,7 +174,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, int x, int y) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(fb->obj[0]);
- struct vbox_private *vbox = crtc->dev->dev_private;
- struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
@@ -272,7 +272,7 @@ static void vbox_primary_atomic_update(struct drm_plane *plane, { struct drm_crtc *crtc = plane->state->crtc; struct drm_framebuffer *fb = plane->state->fb;
- struct vbox_private *vbox = fb->dev->dev_private;
- struct vbox_private *vbox = to_vbox_dev(fb->dev); struct drm_mode_rect *clips; uint32_t num_clips, i;
@@ -704,7 +704,7 @@ static int vbox_get_modes(struct drm_connector *connector) int preferred_width, preferred_height;
vbox_connector = to_vbox_connector(connector);
- vbox = connector->dev->dev_private;
vbox = to_vbox_dev(connector->dev);
hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) + HOST_FLAGS_OFFSET);
On Mon, Apr 6, 2020 at 7:27 PM Thomas Zimmermann tzimmermann@suse.de wrote:
Hi
Am 03.04.20 um 15:57 schrieb Daniel Vetter:
We use the baseclass pattern here, so lets to the proper (and more typesafe) upcasting.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
drivers/gpu/drm/vboxvideo/vbox_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_irq.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +++++----- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index be0600b22cf5..d34cddd809fd 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -52,7 +52,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return PTR_ERR(vbox);
vbox->ddev.pdev = pdev;
vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h index 87421903816c..ac7c2effc46f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h @@ -127,6 +127,7 @@ struct vbox_encoder { #define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base) #define to_vbox_connector(x) container_of(x, struct vbox_connector, base) #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) +#define to_vbox_dev(x) container_of(x, struct vbox_private, ddev)
I suggest ot call this macro to to_vbox_device(). At some point, we should rename struct vbox_private to struct vbox_device for consistency among drivers. The new macro's name would then fit.
So I've seen naming conventions around this with a _dev suffix, a _drm suffix, a _priv suffix and no suffix (since it's the top level object you kinda can justify that too). I admit the choice I went with was occasionally a bit random, but that's mostly because there's not much consistency here at all. This applies both to the upcast macro and the struct itself.
iow I'm not sure this bikeshed is worth repainting, current status is rather multicolor already ... It's also an enormous amounts of churn to repaint this stuff already (just git grep dev_private -- drivers/gpu/drm), so I'm not super enthusiastic about adding more churn on top ...
Still feel strongly about this one and the others you've brought up? -Daniel
For the overall patch:
Acked-by: Thomas Zimmermann tzimmermann@suse.de
Best regards Thomas
bool vbox_check_supported(u16 id); int vbox_hw_init(struct vbox_private *vbox); diff --git a/drivers/gpu/drm/vboxvideo/vbox_irq.c b/drivers/gpu/drm/vboxvideo/vbox_irq.c index 16a1e29f5292..631657fa554f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_irq.c +++ b/drivers/gpu/drm/vboxvideo/vbox_irq.c @@ -34,7 +34,7 @@ void vbox_report_hotplug(struct vbox_private *vbox) irqreturn_t vbox_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg;
struct vbox_private *vbox = (struct vbox_private *)dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(dev); u32 host_flags = vbox_get_flags(vbox); if (!(host_flags & HGSMIHOSTFLAGS_IRQ))
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 0883a435e62b..d9a5af62af89 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -36,7 +36,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) u16 flags; s32 x_offset, y_offset;
vbox = crtc->dev->dev_private;
vbox = to_vbox_dev(crtc->dev); width = vbox_crtc->width ? vbox_crtc->width : 640; height = vbox_crtc->height ? vbox_crtc->height : 480; bpp = fb ? fb->format->cpp[0] * 8 : 32;
@@ -77,7 +77,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) static int vbox_set_view(struct drm_crtc *crtc) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
struct vbox_private *vbox = crtc->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbva_infoview *p; /*
@@ -174,7 +174,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, int x, int y) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(fb->obj[0]);
struct vbox_private *vbox = crtc->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
@@ -272,7 +272,7 @@ static void vbox_primary_atomic_update(struct drm_plane *plane, { struct drm_crtc *crtc = plane->state->crtc; struct drm_framebuffer *fb = plane->state->fb;
struct vbox_private *vbox = fb->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(fb->dev); struct drm_mode_rect *clips; uint32_t num_clips, i;
@@ -704,7 +704,7 @@ static int vbox_get_modes(struct drm_connector *connector) int preferred_width, preferred_height;
vbox_connector = to_vbox_connector(connector);
vbox = connector->dev->dev_private;
vbox = to_vbox_dev(connector->dev); hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) + HOST_FLAGS_OFFSET);
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer
Hi
Am 07.04.20 um 09:24 schrieb Daniel Vetter:
On Mon, Apr 6, 2020 at 7:27 PM Thomas Zimmermann tzimmermann@suse.de wrote:
Hi
Am 03.04.20 um 15:57 schrieb Daniel Vetter:
We use the baseclass pattern here, so lets to the proper (and more typesafe) upcasting.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
drivers/gpu/drm/vboxvideo/vbox_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_irq.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +++++----- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index be0600b22cf5..d34cddd809fd 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -52,7 +52,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return PTR_ERR(vbox);
vbox->ddev.pdev = pdev;
vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h index 87421903816c..ac7c2effc46f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h @@ -127,6 +127,7 @@ struct vbox_encoder { #define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base) #define to_vbox_connector(x) container_of(x, struct vbox_connector, base) #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) +#define to_vbox_dev(x) container_of(x, struct vbox_private, ddev)
I suggest ot call this macro to to_vbox_device(). At some point, we should rename struct vbox_private to struct vbox_device for consistency among drivers. The new macro's name would then fit.
So I've seen naming conventions around this with a _dev suffix, a _drm suffix, a _priv suffix and no suffix (since it's the top level object you kinda can justify that too). I admit the choice I went with was occasionally a bit random, but that's mostly because there's not much consistency here at all. This applies both to the upcast macro and the struct itself.
iow I'm not sure this bikeshed is worth repainting, current status is rather multicolor already ... It's also an enormous amounts of churn to repaint this stuff already (just git grep dev_private -- drivers/gpu/drm), so I'm not super enthusiastic about adding more churn on top ...
Still feel strongly about this one and the others you've brought up?
I have no strong feelings about it. :) But since you're introducing the macro, I thought that naming it to_vbox_device() would be consisted within the driver.
Best regards Thomas
-Daniel
For the overall patch:
Acked-by: Thomas Zimmermann tzimmermann@suse.de
Best regards Thomas
bool vbox_check_supported(u16 id); int vbox_hw_init(struct vbox_private *vbox); diff --git a/drivers/gpu/drm/vboxvideo/vbox_irq.c b/drivers/gpu/drm/vboxvideo/vbox_irq.c index 16a1e29f5292..631657fa554f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_irq.c +++ b/drivers/gpu/drm/vboxvideo/vbox_irq.c @@ -34,7 +34,7 @@ void vbox_report_hotplug(struct vbox_private *vbox) irqreturn_t vbox_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg;
struct vbox_private *vbox = (struct vbox_private *)dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(dev); u32 host_flags = vbox_get_flags(vbox); if (!(host_flags & HGSMIHOSTFLAGS_IRQ))
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 0883a435e62b..d9a5af62af89 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -36,7 +36,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) u16 flags; s32 x_offset, y_offset;
vbox = crtc->dev->dev_private;
vbox = to_vbox_dev(crtc->dev); width = vbox_crtc->width ? vbox_crtc->width : 640; height = vbox_crtc->height ? vbox_crtc->height : 480; bpp = fb ? fb->format->cpp[0] * 8 : 32;
@@ -77,7 +77,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) static int vbox_set_view(struct drm_crtc *crtc) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
struct vbox_private *vbox = crtc->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbva_infoview *p; /*
@@ -174,7 +174,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, int x, int y) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(fb->obj[0]);
struct vbox_private *vbox = crtc->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
@@ -272,7 +272,7 @@ static void vbox_primary_atomic_update(struct drm_plane *plane, { struct drm_crtc *crtc = plane->state->crtc; struct drm_framebuffer *fb = plane->state->fb;
struct vbox_private *vbox = fb->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(fb->dev); struct drm_mode_rect *clips; uint32_t num_clips, i;
@@ -704,7 +704,7 @@ static int vbox_get_modes(struct drm_connector *connector) int preferred_width, preferred_height;
vbox_connector = to_vbox_connector(connector);
vbox = connector->dev->dev_private;
vbox = to_vbox_dev(connector->dev); hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) + HOST_FLAGS_OFFSET);
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer
On Fri, Apr 03, 2020 at 03:57:52PM +0200, Daniel Vetter wrote:
We use the baseclass pattern here, so lets to the proper (and more typesafe) upcasting.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
Acked-by: Sam Ravnborg sam@ravnborg.org
As for naming discussed in other mail I had gone for to_vbox() - as we name the variable assinged vbox whereever we use it. But no strong feeling as long as we get away from dev_private and are consistent.
Sam
drivers/gpu/drm/vboxvideo/vbox_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_irq.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +++++----- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index be0600b22cf5..d34cddd809fd 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -52,7 +52,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return PTR_ERR(vbox);
vbox->ddev.pdev = pdev;
- vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h index 87421903816c..ac7c2effc46f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h @@ -127,6 +127,7 @@ struct vbox_encoder { #define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base) #define to_vbox_connector(x) container_of(x, struct vbox_connector, base) #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) +#define to_vbox_dev(x) container_of(x, struct vbox_private, ddev)
bool vbox_check_supported(u16 id); int vbox_hw_init(struct vbox_private *vbox); diff --git a/drivers/gpu/drm/vboxvideo/vbox_irq.c b/drivers/gpu/drm/vboxvideo/vbox_irq.c index 16a1e29f5292..631657fa554f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_irq.c +++ b/drivers/gpu/drm/vboxvideo/vbox_irq.c @@ -34,7 +34,7 @@ void vbox_report_hotplug(struct vbox_private *vbox) irqreturn_t vbox_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg;
- struct vbox_private *vbox = (struct vbox_private *)dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(dev); u32 host_flags = vbox_get_flags(vbox);
if (!(host_flags & HGSMIHOSTFLAGS_IRQ))
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 0883a435e62b..d9a5af62af89 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -36,7 +36,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) u16 flags; s32 x_offset, y_offset;
- vbox = crtc->dev->dev_private;
- vbox = to_vbox_dev(crtc->dev); width = vbox_crtc->width ? vbox_crtc->width : 640; height = vbox_crtc->height ? vbox_crtc->height : 480; bpp = fb ? fb->format->cpp[0] * 8 : 32;
@@ -77,7 +77,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) static int vbox_set_view(struct drm_crtc *crtc) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
- struct vbox_private *vbox = crtc->dev->dev_private;
struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbva_infoview *p;
/*
@@ -174,7 +174,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, int x, int y) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(fb->obj[0]);
- struct vbox_private *vbox = crtc->dev->dev_private;
- struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
@@ -272,7 +272,7 @@ static void vbox_primary_atomic_update(struct drm_plane *plane, { struct drm_crtc *crtc = plane->state->crtc; struct drm_framebuffer *fb = plane->state->fb;
- struct vbox_private *vbox = fb->dev->dev_private;
- struct vbox_private *vbox = to_vbox_dev(fb->dev); struct drm_mode_rect *clips; uint32_t num_clips, i;
@@ -704,7 +704,7 @@ static int vbox_get_modes(struct drm_connector *connector) int preferred_width, preferred_height;
vbox_connector = to_vbox_connector(connector);
- vbox = connector->dev->dev_private;
vbox = to_vbox_dev(connector->dev);
hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) + HOST_FLAGS_OFFSET);
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Allows us to drop the cleanup code on the floor.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 6 ++---- drivers/gpu/drm/vboxvideo/vbox_main.c | 7 +------ 2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index d34cddd809fd..c80695c2f6c0 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -55,13 +55,13 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
- ret = pci_enable_device(pdev); + ret = pcim_enable_device(pdev); if (ret) return ret;
ret = vbox_hw_init(vbox); if (ret) - goto err_pci_disable; + return ret;
ret = vbox_mm_init(vbox); if (ret) @@ -93,8 +93,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vbox_mm_fini(vbox); err_hw_fini: vbox_hw_fini(vbox); -err_pci_disable: - pci_disable_device(pdev); return ret; }
diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index 9dcab115a261..1336ab9795fc 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -71,8 +71,6 @@ static void vbox_accel_fini(struct vbox_private *vbox)
for (i = 0; i < vbox->num_crtcs; ++i) vbva_disable(&vbox->vbva_info[i], vbox->guest_pool, i); - - pci_iounmap(vbox->ddev.pdev, vbox->vbva_buffers); }
/* Do we support the 4.3 plus mode hint reporting interface? */ @@ -125,7 +123,7 @@ int vbox_hw_init(struct vbox_private *vbox) /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ vbox->guest_pool = gen_pool_create(4, -1); if (!vbox->guest_pool) - goto err_unmap_guest_heap; + return -ENOMEM;
ret = gen_pool_add_virt(vbox->guest_pool, (unsigned long)vbox->guest_heap, @@ -168,8 +166,6 @@ int vbox_hw_init(struct vbox_private *vbox)
err_destroy_guest_pool: gen_pool_destroy(vbox->guest_pool); -err_unmap_guest_heap: - pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); return ret; }
@@ -177,5 +173,4 @@ void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); gen_pool_destroy(vbox->guest_pool); - pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); }
On Fri, Apr 03, 2020 at 03:57:53PM +0200, Daniel Vetter wrote:
Allows us to drop the cleanup code on the floor.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
With this change we avoid calling pci_disable_device() twise in case vbox_mm_init() fails. Once in vbox_hw_fini() and once in the error path.
Which is just a small extra bonus.
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/vboxvideo/vbox_drv.c | 6 ++---- drivers/gpu/drm/vboxvideo/vbox_main.c | 7 +------ 2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index d34cddd809fd..c80695c2f6c0 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -55,13 +55,13 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
- ret = pci_enable_device(pdev);
ret = pcim_enable_device(pdev); if (ret) return ret;
ret = vbox_hw_init(vbox); if (ret)
goto err_pci_disable;
return ret;
ret = vbox_mm_init(vbox); if (ret)
@@ -93,8 +93,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vbox_mm_fini(vbox); err_hw_fini: vbox_hw_fini(vbox); -err_pci_disable:
- pci_disable_device(pdev); return ret;
}
diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index 9dcab115a261..1336ab9795fc 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -71,8 +71,6 @@ static void vbox_accel_fini(struct vbox_private *vbox)
for (i = 0; i < vbox->num_crtcs; ++i) vbva_disable(&vbox->vbva_info[i], vbox->guest_pool, i);
- pci_iounmap(vbox->ddev.pdev, vbox->vbva_buffers);
}
/* Do we support the 4.3 plus mode hint reporting interface? */ @@ -125,7 +123,7 @@ int vbox_hw_init(struct vbox_private *vbox) /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ vbox->guest_pool = gen_pool_create(4, -1); if (!vbox->guest_pool)
goto err_unmap_guest_heap;
return -ENOMEM;
ret = gen_pool_add_virt(vbox->guest_pool, (unsigned long)vbox->guest_heap,
@@ -168,8 +166,6 @@ int vbox_hw_init(struct vbox_private *vbox)
err_destroy_guest_pool: gen_pool_destroy(vbox->guest_pool); -err_unmap_guest_heap:
- pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); return ret;
}
@@ -177,5 +173,4 @@ void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); gen_pool_destroy(vbox->guest_pool);
- pci_iounmap(vbox->ddev.pdev, vbox->guest_heap);
}
2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On Wed, Apr 08, 2020 at 09:21:46AM +0200, Sam Ravnborg wrote:
On Fri, Apr 03, 2020 at 03:57:53PM +0200, Daniel Vetter wrote:
Allows us to drop the cleanup code on the floor.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
With this change we avoid calling pci_disable_device() twise in case vbox_mm_init() fails. Once in vbox_hw_fini() and once in the error path.
Yup, I forgot to mention this in the commit message. I've added your remark here as a quote, thanks for checking stuff in detail. -Daniel
Which is just a small extra bonus.
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/vboxvideo/vbox_drv.c | 6 ++---- drivers/gpu/drm/vboxvideo/vbox_main.c | 7 +------ 2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index d34cddd809fd..c80695c2f6c0 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -55,13 +55,13 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
- ret = pci_enable_device(pdev);
ret = pcim_enable_device(pdev); if (ret) return ret;
ret = vbox_hw_init(vbox); if (ret)
goto err_pci_disable;
return ret;
ret = vbox_mm_init(vbox); if (ret)
@@ -93,8 +93,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vbox_mm_fini(vbox); err_hw_fini: vbox_hw_fini(vbox); -err_pci_disable:
- pci_disable_device(pdev); return ret;
}
diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index 9dcab115a261..1336ab9795fc 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -71,8 +71,6 @@ static void vbox_accel_fini(struct vbox_private *vbox)
for (i = 0; i < vbox->num_crtcs; ++i) vbva_disable(&vbox->vbva_info[i], vbox->guest_pool, i);
- pci_iounmap(vbox->ddev.pdev, vbox->vbva_buffers);
}
/* Do we support the 4.3 plus mode hint reporting interface? */ @@ -125,7 +123,7 @@ int vbox_hw_init(struct vbox_private *vbox) /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ vbox->guest_pool = gen_pool_create(4, -1); if (!vbox->guest_pool)
goto err_unmap_guest_heap;
return -ENOMEM;
ret = gen_pool_add_virt(vbox->guest_pool, (unsigned long)vbox->guest_heap,
@@ -168,8 +166,6 @@ int vbox_hw_init(struct vbox_private *vbox)
err_destroy_guest_pool: gen_pool_destroy(vbox->guest_pool); -err_unmap_guest_heap:
- pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); return ret;
}
@@ -177,5 +173,4 @@ void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); gen_pool_destroy(vbox->guest_pool);
- pci_iounmap(vbox->ddev.pdev, vbox->guest_heap);
}
2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Aside from deleting all the cleanup code we're now also setting a name for the pool
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com --- drivers/gpu/drm/vboxvideo/vbox_main.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index 1336ab9795fc..d68d9bad7674 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -121,7 +121,8 @@ int vbox_hw_init(struct vbox_private *vbox) return -ENOMEM;
/* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ - vbox->guest_pool = gen_pool_create(4, -1); + vbox->guest_pool = devm_gen_pool_create(vbox->ddev.dev, 4, -1, + "vboxvideo-accel"); if (!vbox->guest_pool) return -ENOMEM;
@@ -130,12 +131,12 @@ int vbox_hw_init(struct vbox_private *vbox) GUEST_HEAP_OFFSET(vbox), GUEST_HEAP_USABLE_SIZE, -1); if (ret) - goto err_destroy_guest_pool; + return ret;
ret = hgsmi_test_query_conf(vbox->guest_pool); if (ret) { DRM_ERROR("vboxvideo: hgsmi_test_query_conf failed\n"); - goto err_destroy_guest_pool; + return ret; }
/* Reduce available VRAM size to reflect the guest heap. */ @@ -147,30 +148,23 @@ int vbox_hw_init(struct vbox_private *vbox)
if (!have_hgsmi_mode_hints(vbox)) { ret = -ENOTSUPP; - goto err_destroy_guest_pool; + return ret; }
vbox->last_mode_hints = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs, sizeof(struct vbva_modehint), GFP_KERNEL); - if (!vbox->last_mode_hints) { - ret = -ENOMEM; - goto err_destroy_guest_pool; - } + if (!vbox->last_mode_hints) + return -ENOMEM;
ret = vbox_accel_init(vbox); if (ret) - goto err_destroy_guest_pool; + return ret;
return 0; - -err_destroy_guest_pool: - gen_pool_destroy(vbox->guest_pool); - return ret; }
void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); - gen_pool_destroy(vbox->guest_pool); }
On Fri, Apr 03, 2020 at 03:57:54PM +0200, Daniel Vetter wrote:
Aside from deleting all the cleanup code we're now also setting a name for the pool
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com
Nice cleanup. Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/vboxvideo/vbox_main.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index 1336ab9795fc..d68d9bad7674 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -121,7 +121,8 @@ int vbox_hw_init(struct vbox_private *vbox) return -ENOMEM;
/* Create guest-heap mem-pool use 2^4 = 16 byte chunks */
- vbox->guest_pool = gen_pool_create(4, -1);
- vbox->guest_pool = devm_gen_pool_create(vbox->ddev.dev, 4, -1,
if (!vbox->guest_pool) return -ENOMEM;"vboxvideo-accel");
@@ -130,12 +131,12 @@ int vbox_hw_init(struct vbox_private *vbox) GUEST_HEAP_OFFSET(vbox), GUEST_HEAP_USABLE_SIZE, -1); if (ret)
goto err_destroy_guest_pool;
return ret;
ret = hgsmi_test_query_conf(vbox->guest_pool); if (ret) { DRM_ERROR("vboxvideo: hgsmi_test_query_conf failed\n");
goto err_destroy_guest_pool;
return ret;
}
/* Reduce available VRAM size to reflect the guest heap. */
@@ -147,30 +148,23 @@ int vbox_hw_init(struct vbox_private *vbox)
if (!have_hgsmi_mode_hints(vbox)) { ret = -ENOTSUPP;
goto err_destroy_guest_pool;
return ret;
}
vbox->last_mode_hints = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs, sizeof(struct vbva_modehint), GFP_KERNEL);
- if (!vbox->last_mode_hints) {
ret = -ENOMEM;
goto err_destroy_guest_pool;
- }
if (!vbox->last_mode_hints)
return -ENOMEM;
ret = vbox_accel_init(vbox); if (ret)
goto err_destroy_guest_pool;
return ret;
return 0;
-err_destroy_guest_pool:
- gen_pool_destroy(vbox->guest_pool);
- return ret;
}
void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox);
- gen_pool_destroy(vbox->guest_pool);
}
2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
And switch the helper over to container_of, which is a bunch faster than chasing a pointer. Plus allows gcc to see through this maze.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net --- drivers/gpu/drm/v3d/v3d_drv.c | 1 - drivers/gpu/drm/v3d/v3d_drv.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 8d0c0daaac81..ead62a15d48f 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -265,7 +265,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) }
platform_set_drvdata(pdev, drm); - drm->dev_private = v3d; drmm_add_final_kfree(drm, v3d);
ret = map_regs(v3d, &v3d->hub_regs, "hub"); diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index e0775c884553..112d80aed5f6 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -121,7 +121,7 @@ struct v3d_dev { static inline struct v3d_dev * to_v3d_dev(struct drm_device *dev) { - return (struct v3d_dev *)dev->dev_private; + return container_of(dev, struct v3d_dev, drm); }
static inline bool
On Fri, Apr 3, 2020 at 6:58 AM Daniel Vetter daniel.vetter@ffwll.ch wrote:
And switch the helper over to container_of, which is a bunch faster than chasing a pointer. Plus allows gcc to see through this maze.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Acked-by: Eric Anholt eric@anholt.net
Also allows us to simplify the unroll code since the drm_dev_put disappears.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net --- drivers/gpu/drm/v3d/v3d_drv.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index ead62a15d48f..f57d408ef371 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -251,29 +251,23 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) u32 ident1;
- v3d = kzalloc(sizeof(*v3d), GFP_KERNEL); - if (!v3d) - return -ENOMEM; + v3d = devm_drm_dev_alloc(dev, &v3d_drm_driver, struct v3d_dev, drm); + if (IS_ERR(v3d)) + return PTR_ERR(v3d); + v3d->dev = dev; v3d->pdev = pdev; drm = &v3d->drm;
- ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev); - if (ret) { - kfree(v3d); - return ret; - } - platform_set_drvdata(pdev, drm); - drmm_add_final_kfree(drm, v3d);
ret = map_regs(v3d, &v3d->hub_regs, "hub"); if (ret) - goto dev_destroy; + return ret;
ret = map_regs(v3d, &v3d->core_regs[0], "core0"); if (ret) - goto dev_destroy; + return ret;
mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO); dev->coherent_dma_mask = @@ -291,29 +285,28 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) ret = PTR_ERR(v3d->reset);
if (ret == -EPROBE_DEFER) - goto dev_destroy; + return ret;
v3d->reset = NULL; ret = map_regs(v3d, &v3d->bridge_regs, "bridge"); if (ret) { dev_err(dev, "Failed to get reset control or bridge regs\n"); - goto dev_destroy; + return ret; } }
if (v3d->ver < 41) { ret = map_regs(v3d, &v3d->gca_regs, "gca"); if (ret) - goto dev_destroy; + return ret; }
v3d->mmu_scratch = dma_alloc_wc(dev, 4096, &v3d->mmu_scratch_paddr, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); if (!v3d->mmu_scratch) { dev_err(dev, "Failed to allocate MMU scratch page\n"); - ret = -ENOMEM; - goto dev_destroy; + return -ENOMEM; }
pm_runtime_use_autosuspend(dev); @@ -340,8 +333,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) v3d_gem_destroy(drm); dma_free: dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr); -dev_destroy: - drm_dev_put(drm); return ret; }
@@ -354,8 +345,6 @@ static int v3d_platform_drm_remove(struct platform_device *pdev)
v3d_gem_destroy(drm);
- drm_dev_put(drm); - dma_free_wc(v3d->dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr);
return 0;
On Fri, Apr 3, 2020 at 6:58 AM Daniel Vetter daniel.vetter@ffwll.ch wrote:
Also allows us to simplify the unroll code since the drm_dev_put disappears.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Acked-by: Eric Anholt eric@anholt.net
We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because: - reviewers need to check whether the pointer is for the same or different objects if there's multiple - compilers have an easier time too
But also a bit a bikeshed, so feel free to ignore.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net --- drivers/gpu/drm/v3d/v3d_debugfs.c | 12 ++++++------ drivers/gpu/drm/v3d/v3d_drv.c | 12 ++++++------ drivers/gpu/drm/v3d/v3d_drv.h | 2 -- drivers/gpu/drm/v3d/v3d_gem.c | 17 +++++++++-------- drivers/gpu/drm/v3d/v3d_irq.c | 12 ++++++------ drivers/gpu/drm/v3d/v3d_mmu.c | 10 +++++----- drivers/gpu/drm/v3d/v3d_sched.c | 10 +++++----- 7 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c index 2b0ea5f8febd..e76b24bb8828 100644 --- a/drivers/gpu/drm/v3d/v3d_debugfs.c +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c @@ -132,7 +132,7 @@ static int v3d_v3d_debugfs_ident(struct seq_file *m, void *unused) u32 ident0, ident1, ident2, ident3, cores; int ret, core;
- ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret;
@@ -187,8 +187,8 @@ static int v3d_v3d_debugfs_ident(struct seq_file *m, void *unused) (misccfg & V3D_MISCCFG_OVRTMUOUT) != 0); }
- pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_mark_last_busy(v3d->drm.dev); + pm_runtime_put_autosuspend(v3d->drm.dev);
return 0; } @@ -219,7 +219,7 @@ static int v3d_measure_clock(struct seq_file *m, void *unused) int measure_ms = 1000; int ret;
- ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret;
@@ -245,8 +245,8 @@ static int v3d_measure_clock(struct seq_file *m, void *unused) cycles / (measure_ms * 1000), (cycles / (measure_ms * 100)) % 10);
- pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_mark_last_busy(v3d->drm.dev); + pm_runtime_put_autosuspend(v3d->drm.dev);
return 0; } diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index f57d408ef371..37cb880f2826 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -105,7 +105,7 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, if (args->value != 0) return -EINVAL;
- ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret; if (args->param >= DRM_V3D_PARAM_V3D_CORE0_IDENT0 && @@ -114,8 +114,8 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, } else { args->value = V3D_READ(offset); } - pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_mark_last_busy(v3d->drm.dev); + pm_runtime_put_autosuspend(v3d->drm.dev); return 0; }
@@ -237,7 +237,7 @@ map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name) struct resource *res = platform_get_resource_byname(v3d->pdev, IORESOURCE_MEM, name);
- *regs = devm_ioremap_resource(v3d->dev, res); + *regs = devm_ioremap_resource(v3d->drm.dev, res); return PTR_ERR_OR_ZERO(*regs); }
@@ -255,7 +255,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) if (IS_ERR(v3d)) return PTR_ERR(v3d);
- v3d->dev = dev; v3d->pdev = pdev; drm = &v3d->drm;
@@ -345,7 +344,8 @@ static int v3d_platform_drm_remove(struct platform_device *pdev)
v3d_gem_destroy(drm);
- dma_free_wc(v3d->dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr); + dma_free_wc(v3d->drm.dev, 4096, v3d->mmu_scratch, + v3d->mmu_scratch_paddr);
return 0; } diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 112d80aed5f6..4d2d1f2fe1af 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -14,7 +14,6 @@ #include "uapi/drm/v3d_drm.h"
struct clk; -struct device; struct platform_device; struct reset_control;
@@ -47,7 +46,6 @@ struct v3d_dev { int ver; bool single_irq_line;
- struct device *dev; struct platform_device *pdev; void __iomem *hub_regs; void __iomem *core_regs[3]; diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 549dde83408b..09a7639cf161 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -370,8 +370,8 @@ v3d_job_free(struct kref *ref) dma_fence_put(job->irq_fence); dma_fence_put(job->done_fence);
- pm_runtime_mark_last_busy(job->v3d->dev); - pm_runtime_put_autosuspend(job->v3d->dev); + pm_runtime_mark_last_busy(job->v3d->drm.dev); + pm_runtime_put_autosuspend(job->v3d->drm.dev);
kfree(job); } @@ -439,7 +439,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, job->v3d = v3d; job->free = free;
- ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret;
@@ -458,7 +458,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, return 0; fail: xa_destroy(&job->deps); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_put_autosuspend(v3d->drm.dev); return ret; }
@@ -886,12 +886,12 @@ v3d_gem_init(struct drm_device *dev) */ drm_mm_init(&v3d->mm, 1, pt_size / sizeof(u32) - 1);
- v3d->pt = dma_alloc_wc(v3d->dev, pt_size, + v3d->pt = dma_alloc_wc(v3d->drm.dev, pt_size, &v3d->pt_paddr, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); if (!v3d->pt) { drm_mm_takedown(&v3d->mm); - dev_err(v3d->dev, + dev_err(v3d->drm.dev, "Failed to allocate page tables. " "Please ensure you have CMA enabled.\n"); return -ENOMEM; @@ -903,7 +903,7 @@ v3d_gem_init(struct drm_device *dev) ret = v3d_sched_init(v3d); if (ret) { drm_mm_takedown(&v3d->mm); - dma_free_coherent(v3d->dev, 4096 * 1024, (void *)v3d->pt, + dma_free_coherent(v3d->drm.dev, 4096 * 1024, (void *)v3d->pt, v3d->pt_paddr); }
@@ -925,5 +925,6 @@ v3d_gem_destroy(struct drm_device *dev)
drm_mm_takedown(&v3d->mm);
- dma_free_coherent(v3d->dev, 4096 * 1024, (void *)v3d->pt, v3d->pt_paddr); + dma_free_coherent(v3d->drm.dev, 4096 * 1024, (void *)v3d->pt, + v3d->pt_paddr); } diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index 662e67279a7b..f4ce6d057c90 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -128,7 +128,7 @@ v3d_irq(int irq, void *arg) * always-allowed mode. */ if (intsts & V3D_INT_GMPV) - dev_err(v3d->dev, "GMP violation\n"); + dev_err(v3d->drm.dev, "GMP violation\n");
/* V3D 4.2 wires the hub and core IRQs together, so if we & * didn't see the common one then check hub for MMU IRQs. @@ -189,7 +189,7 @@ v3d_hub_irq(int irq, void *arg) client = v3d41_axi_ids[axi_id]; }
- dev_err(v3d->dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n", + dev_err(v3d->drm.dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n", client, axi_id, (long long)vio_addr, ((intsts & V3D_HUB_INT_MMU_WRV) ? ", write violation" : ""), @@ -221,12 +221,12 @@ v3d_irq_init(struct v3d_dev *v3d) if (irq1 == -EPROBE_DEFER) return irq1; if (irq1 > 0) { - ret = devm_request_irq(v3d->dev, irq1, + ret = devm_request_irq(v3d->drm.dev, irq1, v3d_irq, IRQF_SHARED, "v3d_core0", v3d); if (ret) goto fail; - ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), v3d_hub_irq, IRQF_SHARED, "v3d_hub", v3d); if (ret) @@ -234,7 +234,7 @@ v3d_irq_init(struct v3d_dev *v3d) } else { v3d->single_irq_line = true;
- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), v3d_irq, IRQF_SHARED, "v3d", v3d); if (ret) @@ -246,7 +246,7 @@ v3d_irq_init(struct v3d_dev *v3d)
fail: if (ret != -EPROBE_DEFER) - dev_err(v3d->dev, "IRQ setup failed: %d\n", ret); + dev_err(v3d->drm.dev, "IRQ setup failed: %d\n", ret); return ret; }
diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c index 395e81d97163..3b81ea28c0bb 100644 --- a/drivers/gpu/drm/v3d/v3d_mmu.c +++ b/drivers/gpu/drm/v3d/v3d_mmu.c @@ -40,7 +40,7 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d) ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & V3D_MMU_CTL_TLB_CLEARING), 100); if (ret) - dev_err(v3d->dev, "TLB clear wait idle pre-wait failed\n"); + dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n");
V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) | V3D_MMU_CTL_TLB_CLEAR); @@ -52,14 +52,14 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d) ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & V3D_MMU_CTL_TLB_CLEARING), 100); if (ret) { - dev_err(v3d->dev, "TLB clear wait idle failed\n"); + dev_err(v3d->drm.dev, "TLB clear wait idle failed\n"); return ret; }
ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) & V3D_MMUC_CONTROL_FLUSHING), 100); if (ret) - dev_err(v3d->dev, "MMUC flush wait idle failed\n"); + dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
return ret; } @@ -109,7 +109,7 @@ void v3d_mmu_insert_ptes(struct v3d_bo *bo) shmem_obj->base.size >> V3D_MMU_PAGE_SHIFT);
if (v3d_mmu_flush_all(v3d)) - dev_err(v3d->dev, "MMU flush timeout\n"); + dev_err(v3d->drm.dev, "MMU flush timeout\n"); }
void v3d_mmu_remove_ptes(struct v3d_bo *bo) @@ -122,5 +122,5 @@ void v3d_mmu_remove_ptes(struct v3d_bo *bo) v3d->pt[page] = 0;
if (v3d_mmu_flush_all(v3d)) - dev_err(v3d->dev, "MMU flush timeout\n"); + dev_err(v3d->drm.dev, "MMU flush timeout\n"); } diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index 8c2df6d95283..0747614a78f0 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -403,7 +403,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_bin"); if (ret) { - dev_err(v3d->dev, "Failed to create bin scheduler: %d.", ret); + dev_err(v3d->drm.dev, "Failed to create bin scheduler: %d.", ret); return ret; }
@@ -413,7 +413,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_render"); if (ret) { - dev_err(v3d->dev, "Failed to create render scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create render scheduler: %d.", ret); v3d_sched_fini(v3d); return ret; @@ -425,7 +425,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_tfu"); if (ret) { - dev_err(v3d->dev, "Failed to create TFU scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create TFU scheduler: %d.", ret); v3d_sched_fini(v3d); return ret; @@ -438,7 +438,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_csd"); if (ret) { - dev_err(v3d->dev, "Failed to create CSD scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create CSD scheduler: %d.", ret); v3d_sched_fini(v3d); return ret; @@ -450,7 +450,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_cache_clean"); if (ret) { - dev_err(v3d->dev, "Failed to create CACHE_CLEAN scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create CACHE_CLEAN scheduler: %d.", ret); v3d_sched_fini(v3d); return ret;
On Fri, Apr 3, 2020 at 6:58 AM Daniel Vetter daniel.vetter@ffwll.ch wrote:
We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because:
- reviewers need to check whether the pointer is for the same or different objects if there's multiple
- compilers have an easier time too
But also a bit a bikeshed, so feel free to ignore.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net
a-b.
We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because: - reviewers need to check whether the pointer is for the same or different objects if there's multiple - compilers have an easier time too
To avoid having to pull in some big headers I implemented the casting function as a macro instead of a static inline. Typechecking thanks to container_of still assured.
But also a bit a bikeshed, so feel free to ignore.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net --- drivers/gpu/drm/v3d/v3d_drv.c | 3 +-- drivers/gpu/drm/v3d/v3d_drv.h | 3 ++- drivers/gpu/drm/v3d/v3d_irq.c | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 37cb880f2826..82a7dfdd14c2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -235,7 +235,7 @@ static int map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name) { struct resource *res = - platform_get_resource_byname(v3d->pdev, IORESOURCE_MEM, name); + platform_get_resource_byname(v3d_to_pdev(v3d), IORESOURCE_MEM, name);
*regs = devm_ioremap_resource(v3d->drm.dev, res); return PTR_ERR_OR_ZERO(*regs); @@ -255,7 +255,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) if (IS_ERR(v3d)) return PTR_ERR(v3d);
- v3d->pdev = pdev; drm = &v3d->drm;
platform_set_drvdata(pdev, drm); diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 4d2d1f2fe1af..935f23b524b2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -46,7 +46,6 @@ struct v3d_dev { int ver; bool single_irq_line;
- struct platform_device *pdev; void __iomem *hub_regs; void __iomem *core_regs[3]; void __iomem *bridge_regs; @@ -128,6 +127,8 @@ v3d_has_csd(struct v3d_dev *v3d) return v3d->ver >= 41; }
+#define v3d_to_pdev(v3d) to_platform_device(v3d->drm.dev) + /* The per-fd struct, which tracks the MMU mappings. */ struct v3d_file_priv { struct v3d_dev *v3d; diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index f4ce6d057c90..51b65263c657 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -217,7 +217,7 @@ v3d_irq_init(struct v3d_dev *v3d) V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);
- irq1 = platform_get_irq(v3d->pdev, 1); + irq1 = platform_get_irq(v3d_to_pdev(v3d), 1); if (irq1 == -EPROBE_DEFER) return irq1; if (irq1 > 0) { @@ -226,7 +226,8 @@ v3d_irq_init(struct v3d_dev *v3d) "v3d_core0", v3d); if (ret) goto fail; - ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, + platform_get_irq(v3d_to_pdev(v3d), 0), v3d_hub_irq, IRQF_SHARED, "v3d_hub", v3d); if (ret) @@ -234,7 +235,8 @@ v3d_irq_init(struct v3d_dev *v3d) } else { v3d->single_irq_line = true;
- ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, + platform_get_irq(v3d_to_pdev(v3d), 0), v3d_irq, IRQF_SHARED, "v3d", v3d); if (ret)
On Fri, Apr 3, 2020 at 6:58 AM Daniel Vetter daniel.vetter@ffwll.ch wrote:
We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because:
- reviewers need to check whether the pointer is for the same or
different objects if there's multiple
- compilers have an easier time too
To avoid having to pull in some big headers I implemented the casting function as a macro instead of a static inline. Typechecking thanks to container_of still assured.
But also a bit a bikeshed, so feel free to ignore.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt <eric@anholt.net
Acked-by: Eric Anholt eric@anholt.net
Hi Daniel.
On Fri, Apr 03, 2020 at 03:57:58PM +0200, Daniel Vetter wrote:
We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because:
- reviewers need to check whether the pointer is for the same or
different objects if there's multiple
- compilers have an easier time too
To avoid having to pull in some big headers I implemented the casting function as a macro instead of a static inline.
Hmm...
Typechecking thanks to container_of still assured.
But also a bit a bikeshed, so feel free to ignore.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net
This and patch 13 has same subject - confusing.
Sam
drivers/gpu/drm/v3d/v3d_drv.c | 3 +-- drivers/gpu/drm/v3d/v3d_drv.h | 3 ++- drivers/gpu/drm/v3d/v3d_irq.c | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 37cb880f2826..82a7dfdd14c2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -235,7 +235,7 @@ static int map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name) { struct resource *res =
platform_get_resource_byname(v3d->pdev, IORESOURCE_MEM, name);
platform_get_resource_byname(v3d_to_pdev(v3d), IORESOURCE_MEM, name);
*regs = devm_ioremap_resource(v3d->drm.dev, res); return PTR_ERR_OR_ZERO(*regs);
@@ -255,7 +255,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) if (IS_ERR(v3d)) return PTR_ERR(v3d);
v3d->pdev = pdev; drm = &v3d->drm;
platform_set_drvdata(pdev, drm);
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 4d2d1f2fe1af..935f23b524b2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -46,7 +46,6 @@ struct v3d_dev { int ver; bool single_irq_line;
- struct platform_device *pdev; void __iomem *hub_regs; void __iomem *core_regs[3]; void __iomem *bridge_regs;
@@ -128,6 +127,8 @@ v3d_has_csd(struct v3d_dev *v3d) return v3d->ver >= 41; }
+#define v3d_to_pdev(v3d) to_platform_device(v3d->drm.dev)
/* The per-fd struct, which tracks the MMU mappings. */ struct v3d_file_priv { struct v3d_dev *v3d; diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index f4ce6d057c90..51b65263c657 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -217,7 +217,7 @@ v3d_irq_init(struct v3d_dev *v3d) V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);
- irq1 = platform_get_irq(v3d->pdev, 1);
- irq1 = platform_get_irq(v3d_to_pdev(v3d), 1); if (irq1 == -EPROBE_DEFER) return irq1; if (irq1 > 0) {
@@ -226,7 +226,8 @@ v3d_irq_init(struct v3d_dev *v3d) "v3d_core0", v3d); if (ret) goto fail;
ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0),
ret = devm_request_irq(v3d->drm.dev,
if (ret)platform_get_irq(v3d_to_pdev(v3d), 0), v3d_hub_irq, IRQF_SHARED, "v3d_hub", v3d);
@@ -234,7 +235,8 @@ v3d_irq_init(struct v3d_dev *v3d) } else { v3d->single_irq_line = true;
ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0),
ret = devm_request_irq(v3d->drm.dev,
if (ret)platform_get_irq(v3d_to_pdev(v3d), 0), v3d_irq, IRQF_SHARED, "v3d", v3d);
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On Wed, Apr 08, 2020 at 09:27:01AM +0200, Sam Ravnborg wrote:
Hi Daniel.
On Fri, Apr 03, 2020 at 03:57:58PM +0200, Daniel Vetter wrote:
We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because:
- reviewers need to check whether the pointer is for the same or
different objects if there's multiple
- compilers have an easier time too
To avoid having to pull in some big headers I implemented the casting function as a macro instead of a static inline.
Hmm...
Typechecking thanks to container_of still assured.
But also a bit a bikeshed, so feel free to ignore.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net
This and patch 13 has same subject - confusing.
dev != pdev
But yeah I agree it's a nice trick I'm pulling here :-)
Cheers, Daniel
Sam
drivers/gpu/drm/v3d/v3d_drv.c | 3 +-- drivers/gpu/drm/v3d/v3d_drv.h | 3 ++- drivers/gpu/drm/v3d/v3d_irq.c | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 37cb880f2826..82a7dfdd14c2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -235,7 +235,7 @@ static int map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name) { struct resource *res =
platform_get_resource_byname(v3d->pdev, IORESOURCE_MEM, name);
platform_get_resource_byname(v3d_to_pdev(v3d), IORESOURCE_MEM, name);
*regs = devm_ioremap_resource(v3d->drm.dev, res); return PTR_ERR_OR_ZERO(*regs);
@@ -255,7 +255,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) if (IS_ERR(v3d)) return PTR_ERR(v3d);
v3d->pdev = pdev; drm = &v3d->drm;
platform_set_drvdata(pdev, drm);
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 4d2d1f2fe1af..935f23b524b2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -46,7 +46,6 @@ struct v3d_dev { int ver; bool single_irq_line;
- struct platform_device *pdev; void __iomem *hub_regs; void __iomem *core_regs[3]; void __iomem *bridge_regs;
@@ -128,6 +127,8 @@ v3d_has_csd(struct v3d_dev *v3d) return v3d->ver >= 41; }
+#define v3d_to_pdev(v3d) to_platform_device(v3d->drm.dev)
/* The per-fd struct, which tracks the MMU mappings. */ struct v3d_file_priv { struct v3d_dev *v3d; diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index f4ce6d057c90..51b65263c657 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -217,7 +217,7 @@ v3d_irq_init(struct v3d_dev *v3d) V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);
- irq1 = platform_get_irq(v3d->pdev, 1);
- irq1 = platform_get_irq(v3d_to_pdev(v3d), 1); if (irq1 == -EPROBE_DEFER) return irq1; if (irq1 > 0) {
@@ -226,7 +226,8 @@ v3d_irq_init(struct v3d_dev *v3d) "v3d_core0", v3d); if (ret) goto fail;
ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0),
ret = devm_request_irq(v3d->drm.dev,
if (ret)platform_get_irq(v3d_to_pdev(v3d), 0), v3d_hub_irq, IRQF_SHARED, "v3d_hub", v3d);
@@ -234,7 +235,8 @@ v3d_irq_init(struct v3d_dev *v3d) } else { v3d->single_irq_line = true;
ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0),
ret = devm_request_irq(v3d->drm.dev,
if (ret)platform_get_irq(v3d_to_pdev(v3d), 0), v3d_irq, IRQF_SHARED, "v3d", v3d);
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Also init the fbdev emulation before we register the device, that way we can rely on the auto-cleanup and simplify the probe error code even more.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Gleixner tglx@linutronix.de --- drivers/gpu/drm/udl/udl_drv.c | 36 +++++++++++------------------------ 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 1ce2d865c36d..4ba5149fdd57 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -57,27 +57,20 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) struct udl_device *udl; int r;
- udl = kzalloc(sizeof(*udl), GFP_KERNEL); - if (!udl) - return ERR_PTR(-ENOMEM); - - r = drm_dev_init(&udl->drm, &driver, &interface->dev); - if (r) { - kfree(udl); - return ERR_PTR(r); - } + udl = devm_drm_dev_alloc(&interface->dev, &driver, + struct udl_device, drm); + if (IS_ERR(udl)) + return udl;
udl->udev = udev; udl->drm.dev_private = udl; - drmm_add_final_kfree(&udl->drm, udl);
r = udl_init(udl); - if (r) { - drm_dev_put(&udl->drm); + if (r) return ERR_PTR(r); - }
usb_set_intfdata(interface, udl); + return udl; }
@@ -91,23 +84,17 @@ static int udl_usb_probe(struct usb_interface *interface, if (IS_ERR(udl)) return PTR_ERR(udl);
+ r = drm_fbdev_generic_setup(&udl->drm, 0); + if (r) + return r; + r = drm_dev_register(&udl->drm, 0); if (r) - goto err_free; + return r;
DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index);
- r = drm_fbdev_generic_setup(&udl->drm, 0); - if (r) - goto err_drm_dev_unregister; - return 0; - -err_drm_dev_unregister: - drm_dev_unregister(&udl->drm); -err_free: - drm_dev_put(&udl->drm); - return r; }
static void udl_usb_disconnect(struct usb_interface *interface) @@ -117,7 +104,6 @@ static void udl_usb_disconnect(struct usb_interface *interface) drm_kms_helper_poll_fini(dev); udl_drop_usb(dev); drm_dev_unplug(dev); - drm_dev_put(dev); }
/*
Den 03.04.2020 15.57, skrev Daniel Vetter:
Also init the fbdev emulation before we register the device, that way we can rely on the auto-cleanup and simplify the probe error code even more.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Gleixner tglx@linutronix.de
drivers/gpu/drm/udl/udl_drv.c | 36 +++++++++++------------------------ 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 1ce2d865c36d..4ba5149fdd57 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -57,27 +57,20 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) struct udl_device *udl; int r;
- udl = kzalloc(sizeof(*udl), GFP_KERNEL);
- if (!udl)
return ERR_PTR(-ENOMEM);
- r = drm_dev_init(&udl->drm, &driver, &interface->dev);
- if (r) {
kfree(udl);
return ERR_PTR(r);
- }
udl = devm_drm_dev_alloc(&interface->dev, &driver,
struct udl_device, drm);
if (IS_ERR(udl))
return udl;
udl->udev = udev; udl->drm.dev_private = udl;
drmm_add_final_kfree(&udl->drm, udl);
r = udl_init(udl);
if (r) {
drm_dev_put(&udl->drm);
- if (r) return ERR_PTR(r);
}
usb_set_intfdata(interface, udl);
- return udl;
}
@@ -91,23 +84,17 @@ static int udl_usb_probe(struct usb_interface *interface, if (IS_ERR(udl)) return PTR_ERR(udl);
- r = drm_fbdev_generic_setup(&udl->drm, 0);
It doesn't feel right to have a client open the device before the DRM device itself is registered. I would prefer to keep it where it is but ignore any errors. A failing client shouldn't prevent the driver from probing. drm_fbdev_generic_setup() do print errors if it fails. So yeah, in hindsight I should have made drm_fbdev_generic_setup() return void.
Noralf.
- if (r)
return r;
- r = drm_dev_register(&udl->drm, 0); if (r)
goto err_free;
return r;
DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index);
- r = drm_fbdev_generic_setup(&udl->drm, 0);
- if (r)
goto err_drm_dev_unregister;
- return 0;
-err_drm_dev_unregister:
- drm_dev_unregister(&udl->drm);
-err_free:
- drm_dev_put(&udl->drm);
- return r;
}
static void udl_usb_disconnect(struct usb_interface *interface) @@ -117,7 +104,6 @@ static void udl_usb_disconnect(struct usb_interface *interface) drm_kms_helper_poll_fini(dev); udl_drop_usb(dev); drm_dev_unplug(dev);
- drm_dev_put(dev);
}
/*
On Sun, Apr 5, 2020 at 12:18 PM Noralf Trønnes noralf@tronnes.org wrote:
Den 03.04.2020 15.57, skrev Daniel Vetter:
Also init the fbdev emulation before we register the device, that way we can rely on the auto-cleanup and simplify the probe error code even more.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Gleixner tglx@linutronix.de
drivers/gpu/drm/udl/udl_drv.c | 36 +++++++++++------------------------ 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 1ce2d865c36d..4ba5149fdd57 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -57,27 +57,20 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) struct udl_device *udl; int r;
udl = kzalloc(sizeof(*udl), GFP_KERNEL);
if (!udl)
return ERR_PTR(-ENOMEM);
r = drm_dev_init(&udl->drm, &driver, &interface->dev);
if (r) {
kfree(udl);
return ERR_PTR(r);
}
udl = devm_drm_dev_alloc(&interface->dev, &driver,
struct udl_device, drm);
if (IS_ERR(udl))
return udl; udl->udev = udev; udl->drm.dev_private = udl;
drmm_add_final_kfree(&udl->drm, udl); r = udl_init(udl);
if (r) {
drm_dev_put(&udl->drm);
if (r) return ERR_PTR(r);
} usb_set_intfdata(interface, udl);
return udl;
}
@@ -91,23 +84,17 @@ static int udl_usb_probe(struct usb_interface *interface, if (IS_ERR(udl)) return PTR_ERR(udl);
r = drm_fbdev_generic_setup(&udl->drm, 0);
It doesn't feel right to have a client open the device before the DRM device itself is registered. I would prefer to keep it where it is but ignore any errors. A failing client shouldn't prevent the driver from probing. drm_fbdev_generic_setup() do print errors if it fails. So yeah, in hindsight I should have made drm_fbdev_generic_setup() return void.
Hm, we have all kinds of usage right now, some check for errors, some dont, some do this before drm_dev_register, some after. If your recommendation is to not check for errors then I'm happy to implement that, but we're a bit inconsistent. Maybe we should do a patch that at least always returns 0 no matter what, plus document that the return value shouldn't be checked? -Daniel
Noralf.
if (r)
return r;
r = drm_dev_register(&udl->drm, 0); if (r)
goto err_free;
return r; DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index);
r = drm_fbdev_generic_setup(&udl->drm, 0);
if (r)
goto err_drm_dev_unregister;
return 0;
-err_drm_dev_unregister:
drm_dev_unregister(&udl->drm);
-err_free:
drm_dev_put(&udl->drm);
return r;
}
static void udl_usb_disconnect(struct usb_interface *interface) @@ -117,7 +104,6 @@ static void udl_usb_disconnect(struct usb_interface *interface) drm_kms_helper_poll_fini(dev); udl_drop_usb(dev); drm_dev_unplug(dev);
drm_dev_put(dev);
}
/*
Den 05.04.2020 15.47, skrev Daniel Vetter:
On Sun, Apr 5, 2020 at 12:18 PM Noralf Trønnes noralf@tronnes.org wrote:
Den 03.04.2020 15.57, skrev Daniel Vetter:
Also init the fbdev emulation before we register the device, that way we can rely on the auto-cleanup and simplify the probe error code even more.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Gleixner tglx@linutronix.de
drivers/gpu/drm/udl/udl_drv.c | 36 +++++++++++------------------------ 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 1ce2d865c36d..4ba5149fdd57 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -57,27 +57,20 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) struct udl_device *udl; int r;
udl = kzalloc(sizeof(*udl), GFP_KERNEL);
if (!udl)
return ERR_PTR(-ENOMEM);
r = drm_dev_init(&udl->drm, &driver, &interface->dev);
if (r) {
kfree(udl);
return ERR_PTR(r);
}
udl = devm_drm_dev_alloc(&interface->dev, &driver,
struct udl_device, drm);
if (IS_ERR(udl))
return udl; udl->udev = udev; udl->drm.dev_private = udl;
drmm_add_final_kfree(&udl->drm, udl); r = udl_init(udl);
if (r) {
drm_dev_put(&udl->drm);
if (r) return ERR_PTR(r);
} usb_set_intfdata(interface, udl);
return udl;
}
@@ -91,23 +84,17 @@ static int udl_usb_probe(struct usb_interface *interface, if (IS_ERR(udl)) return PTR_ERR(udl);
r = drm_fbdev_generic_setup(&udl->drm, 0);
It doesn't feel right to have a client open the device before the DRM device itself is registered. I would prefer to keep it where it is but ignore any errors. A failing client shouldn't prevent the driver from probing. drm_fbdev_generic_setup() do print errors if it fails. So yeah, in hindsight I should have made drm_fbdev_generic_setup() return void.
Hm, we have all kinds of usage right now, some check for errors, some dont, some do this before drm_dev_register, some after. If your recommendation is to not check for errors then I'm happy to implement that, but we're a bit inconsistent. Maybe we should do a patch that at least always returns 0 no matter what, plus document that the return value shouldn't be checked?
Yeah, always returning zero and documenting it would be a good start.
I counted 41 drivers using generic fbdev now, didn't know it was that much used. Only 11 drivers are hand rolling their own: armada gma500 amd omapdrm nouveau i915 msm tegra exynos radeon rockchip
Noralf.
Am 05.04.20 um 12:18 schrieb Noralf Trønnes:
Den 03.04.2020 15.57, skrev Daniel Vetter:
Also init the fbdev emulation before we register the device, that way we can rely on the auto-cleanup and simplify the probe error code even more.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Gleixner tglx@linutronix.de
drivers/gpu/drm/udl/udl_drv.c | 36 +++++++++++------------------------ 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 1ce2d865c36d..4ba5149fdd57 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -57,27 +57,20 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) struct udl_device *udl; int r;
- udl = kzalloc(sizeof(*udl), GFP_KERNEL);
- if (!udl)
return ERR_PTR(-ENOMEM);
- r = drm_dev_init(&udl->drm, &driver, &interface->dev);
- if (r) {
kfree(udl);
return ERR_PTR(r);
- }
udl = devm_drm_dev_alloc(&interface->dev, &driver,
struct udl_device, drm);
if (IS_ERR(udl))
return udl;
udl->udev = udev; udl->drm.dev_private = udl;
drmm_add_final_kfree(&udl->drm, udl);
r = udl_init(udl);
if (r) {
drm_dev_put(&udl->drm);
- if (r) return ERR_PTR(r);
}
usb_set_intfdata(interface, udl);
- return udl;
}
@@ -91,23 +84,17 @@ static int udl_usb_probe(struct usb_interface *interface, if (IS_ERR(udl)) return PTR_ERR(udl);
- r = drm_fbdev_generic_setup(&udl->drm, 0);
It doesn't feel right to have a client open the device before the DRM device itself is registered. I would prefer to keep it where it is but
Agreed. IMHO we should also go through drivers and make the fbdev setup the final step everywhere.
Best regards Thomas
ignore any errors. A failing client shouldn't prevent the driver from probing. drm_fbdev_generic_setup() do print errors if it fails. So yeah, in hindsight I should have made drm_fbdev_generic_setup() return void.
Noralf.
- if (r)
return r;
- r = drm_dev_register(&udl->drm, 0); if (r)
goto err_free;
return r;
DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index);
- r = drm_fbdev_generic_setup(&udl->drm, 0);
- if (r)
goto err_drm_dev_unregister;
- return 0;
-err_drm_dev_unregister:
- drm_dev_unregister(&udl->drm);
-err_free:
- drm_dev_put(&udl->drm);
- return r;
}
static void udl_usb_disconnect(struct usb_interface *interface) @@ -117,7 +104,6 @@ static void udl_usb_disconnect(struct usb_interface *interface) drm_kms_helper_poll_fini(dev); udl_drop_usb(dev); drm_dev_unplug(dev);
- drm_dev_put(dev);
}
/*
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
We're mostly there already, just a handful of places that didn't use the to_udl container_of cast. To make sure no new appear, don't set ->dev_private.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Alexios Zavras alexios.zavras@intel.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Cc: Thomas Gleixner tglx@linutronix.de Cc: "José Roberto de Souza" jose.souza@intel.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Gerd Hoffmann kraxel@redhat.com Cc: Allison Randal allison@lohutok.net --- drivers/gpu/drm/udl/udl_connector.c | 4 ++-- drivers/gpu/drm/udl/udl_drv.c | 1 - drivers/gpu/drm/udl/udl_modeset.c | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index 0afdfb0d1fe1..cdc1c42e1669 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -59,7 +59,7 @@ static int udl_get_modes(struct drm_connector *connector) static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct udl_device *udl = connector->dev->dev_private; + struct udl_device *udl = to_udl(connector->dev); if (!udl->sku_pixel_limit) return 0;
@@ -72,7 +72,7 @@ static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, static enum drm_connector_status udl_detect(struct drm_connector *connector, bool force) { - struct udl_device *udl = connector->dev->dev_private; + struct udl_device *udl = to_udl(connector->dev); struct udl_drm_connector *udl_connector = container_of(connector, struct udl_drm_connector, diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 4ba5149fdd57..126545428895 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -63,7 +63,6 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) return udl;
udl->udev = udev; - udl->drm.dev_private = udl;
r = udl_init(udl); if (r) diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 8cad01f3d163..99518a826435 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -215,7 +215,7 @@ static char *udl_dummy_render(char *wrptr) static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct urb *urb; char *buf; int retval; @@ -369,7 +369,7 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc *crtc = &pipe->crtc; struct drm_device *dev = crtc->dev; struct drm_framebuffer *fb = plane_state->fb; - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct drm_display_mode *mode = &crtc_state->mode; char *buf; char *wrptr; @@ -464,7 +464,7 @@ static const struct drm_mode_config_funcs udl_mode_funcs = { int udl_modeset_init(struct drm_device *dev) { size_t format_count = ARRAY_SIZE(udl_simple_display_pipe_formats); - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct drm_connector *connector; int ret;
Am 03.04.20 um 15:58 schrieb Daniel Vetter:
We're mostly there already, just a handful of places that didn't use the to_udl container_of cast. To make sure no new appear, don't set ->dev_private.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Alexios Zavras alexios.zavras@intel.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Cc: Thomas Gleixner tglx@linutronix.de Cc: "José Roberto de Souza" jose.souza@intel.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Gerd Hoffmann kraxel@redhat.com Cc: Allison Randal allison@lohutok.net
Reviewed-by: Thomas Zimmermann tzimmermann@suse.de
drivers/gpu/drm/udl/udl_connector.c | 4 ++-- drivers/gpu/drm/udl/udl_drv.c | 1 - drivers/gpu/drm/udl/udl_modeset.c | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index 0afdfb0d1fe1..cdc1c42e1669 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -59,7 +59,7 @@ static int udl_get_modes(struct drm_connector *connector) static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) {
- struct udl_device *udl = connector->dev->dev_private;
- struct udl_device *udl = to_udl(connector->dev); if (!udl->sku_pixel_limit) return 0;
@@ -72,7 +72,7 @@ static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, static enum drm_connector_status udl_detect(struct drm_connector *connector, bool force) {
- struct udl_device *udl = connector->dev->dev_private;
- struct udl_device *udl = to_udl(connector->dev); struct udl_drm_connector *udl_connector = container_of(connector, struct udl_drm_connector,
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 4ba5149fdd57..126545428895 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -63,7 +63,6 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) return udl;
udl->udev = udev;
udl->drm.dev_private = udl;
r = udl_init(udl); if (r)
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 8cad01f3d163..99518a826435 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -215,7 +215,7 @@ static char *udl_dummy_render(char *wrptr) static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev;
- struct udl_device *udl = dev->dev_private;
- struct udl_device *udl = to_udl(dev); struct urb *urb; char *buf; int retval;
@@ -369,7 +369,7 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc *crtc = &pipe->crtc; struct drm_device *dev = crtc->dev; struct drm_framebuffer *fb = plane_state->fb;
- struct udl_device *udl = dev->dev_private;
- struct udl_device *udl = to_udl(dev); struct drm_display_mode *mode = &crtc_state->mode; char *buf; char *wrptr;
@@ -464,7 +464,7 @@ static const struct drm_mode_config_funcs udl_mode_funcs = { int udl_modeset_init(struct drm_device *dev) { size_t format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
- struct udl_device *udl = dev->dev_private;
- struct udl_device *udl = to_udl(dev); struct drm_connector *connector; int ret;
On Fri, Apr 03, 2020 at 03:58:00PM +0200, Daniel Vetter wrote:
We're mostly there already, just a handful of places that didn't use the to_udl container_of cast. To make sure no new appear, don't set ->dev_private.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Sean Paul sean@poorly.run Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Alexios Zavras alexios.zavras@intel.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Cc: Thomas Gleixner tglx@linutronix.de Cc: "José Roberto de Souza" jose.souza@intel.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Gerd Hoffmann kraxel@redhat.com Cc: Allison Randal allison@lohutok.net
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/udl/udl_connector.c | 4 ++-- drivers/gpu/drm/udl/udl_drv.c | 1 - drivers/gpu/drm/udl/udl_modeset.c | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index 0afdfb0d1fe1..cdc1c42e1669 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -59,7 +59,7 @@ static int udl_get_modes(struct drm_connector *connector) static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) {
- struct udl_device *udl = connector->dev->dev_private;
- struct udl_device *udl = to_udl(connector->dev); if (!udl->sku_pixel_limit) return 0;
@@ -72,7 +72,7 @@ static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, static enum drm_connector_status udl_detect(struct drm_connector *connector, bool force) {
- struct udl_device *udl = connector->dev->dev_private;
- struct udl_device *udl = to_udl(connector->dev); struct udl_drm_connector *udl_connector = container_of(connector, struct udl_drm_connector,
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 4ba5149fdd57..126545428895 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -63,7 +63,6 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) return udl;
udl->udev = udev;
udl->drm.dev_private = udl;
r = udl_init(udl); if (r)
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 8cad01f3d163..99518a826435 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -215,7 +215,7 @@ static char *udl_dummy_render(char *wrptr) static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev;
- struct udl_device *udl = dev->dev_private;
- struct udl_device *udl = to_udl(dev); struct urb *urb; char *buf; int retval;
@@ -369,7 +369,7 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc *crtc = &pipe->crtc; struct drm_device *dev = crtc->dev; struct drm_framebuffer *fb = plane_state->fb;
- struct udl_device *udl = dev->dev_private;
- struct udl_device *udl = to_udl(dev); struct drm_display_mode *mode = &crtc_state->mode; char *buf; char *wrptr;
@@ -464,7 +464,7 @@ static const struct drm_mode_config_funcs udl_mode_funcs = { int udl_modeset_init(struct drm_device *dev) { size_t format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
- struct udl_device *udl = dev->dev_private;
- struct udl_device *udl = to_udl(dev); struct drm_connector *connector; int ret;
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Already using devm_drm_dev_init, so very simple replacment.
Aside: There was an oddity in the old code, we allocated priv but in the error path we've freed priv->dbidev ...
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: David Lechner david@lechnology.com --- drivers/gpu/drm/tiny/st7735r.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c index 631801c36f46..ccbf49a53202 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/tiny/st7735r.c @@ -195,21 +195,16 @@ static int st7735r_probe(struct spi_device *spi) if (!cfg) cfg = (void *)spi_get_device_id(spi)->driver_data;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_drm_dev_alloc(dev, &st7735r_driver, + struct st7735r_priv, dbidev.drm); + if (IS_ERR(priv)) + return PTR_ERR(priv);
dbidev = &priv->dbidev; priv->cfg = cfg;
dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &st7735r_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev);
dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) {
On 4/3/20 8:58 AM, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Aside: There was an oddity in the old code, we allocated priv but in the error path we've freed priv->dbidev ...
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: David Lechner david@lechnology.com
Acked-by: David Lechner david@lechnology.com
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: David Lechner david@lechnology.com --- drivers/gpu/drm/tiny/st7586.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c index c3295c717ba6..2a1fae422f7a 100644 --- a/drivers/gpu/drm/tiny/st7586.c +++ b/drivers/gpu/drm/tiny/st7586.c @@ -317,18 +317,13 @@ static int st7586_probe(struct spi_device *spi) size_t bufsize; int ret;
- dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &st7586_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev);
dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &st7586_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev);
bufsize = (st7586_mode.vdisplay + 2) / 3 * st7586_mode.hdisplay;
On 4/3/20 8:58 AM, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: David Lechner david@lechnology.com
Acked-by: David Lechner david@lechnology.com
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "Noralf Trønnes" noralf@tronnes.org --- drivers/gpu/drm/tiny/repaper.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 862c3ee6055d..1c0e7169545b 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -1002,19 +1002,13 @@ static int repaper_probe(struct spi_device *spi) } }
- epd = kzalloc(sizeof(*epd), GFP_KERNEL); - if (!epd) - return -ENOMEM; + epd = devm_drm_dev_alloc(dev, &repaper_driver, + struct repaper_epd, drm); + if (IS_ERR(epd)) + return PTR_ERR(epd);
drm = &epd->drm;
- ret = devm_drm_dev_init(dev, drm, &repaper_driver); - if (ret) { - kfree(epd); - return ret; - } - drmm_add_final_kfree(drm, epd); - ret = drmm_mode_config_init(drm); if (ret) return ret;
Den 03.04.2020 15.58, skrev Daniel Vetter:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "Noralf Trønnes" noralf@tronnes.org
Acked-by: Noralf Trønnes noralf@tronnes.org
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "Noralf Trønnes" noralf@tronnes.org --- drivers/gpu/drm/tiny/mi0283qt.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c index decaf57053ff..08ac549ab0f7 100644 --- a/drivers/gpu/drm/tiny/mi0283qt.c +++ b/drivers/gpu/drm/tiny/mi0283qt.c @@ -187,18 +187,13 @@ static int mi0283qt_probe(struct spi_device *spi) u32 rotation = 0; int ret;
- dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &mi0283qt_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev);
dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &mi0283qt_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev);
dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) {
Den 03.04.2020 15.58, skrev Daniel Vetter:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "Noralf Trønnes" noralf@tronnes.org
Acked-by: Noralf Trønnes noralf@tronnes.org
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Kamlesh Gurudasani kamlesh.gurudasani@gmail.com --- drivers/gpu/drm/tiny/ili9486.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c index c4079bf9e2c8..2702ea557d29 100644 --- a/drivers/gpu/drm/tiny/ili9486.c +++ b/drivers/gpu/drm/tiny/ili9486.c @@ -197,18 +197,13 @@ static int ili9486_probe(struct spi_device *spi) u32 rotation = 0; int ret;
- dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &ili9486_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev);
dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &ili9486_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev);
dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) {
Den 03.04.2020 15.58, skrev Daniel Vetter:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Kamlesh Gurudasani kamlesh.gurudasani@gmail.com
Acked-by: Noralf Trønnes noralf@tronnes.org
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Eric Anholt eric@anholt.net Cc: David Lechner david@lechnology.com --- drivers/gpu/drm/tiny/ili9341.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c index e152de369019..bb819f45a5d3 100644 --- a/drivers/gpu/drm/tiny/ili9341.c +++ b/drivers/gpu/drm/tiny/ili9341.c @@ -183,18 +183,13 @@ static int ili9341_probe(struct spi_device *spi) u32 rotation = 0; int ret;
- dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &ili9341_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev);
dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &ili9341_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev);
dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) {
On 4/3/20 8:58 AM, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Eric Anholt eric@anholt.net Cc: David Lechner david@lechnology.com
Acked-by: David Lechner david@lechnology.com
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: David Lechner david@lechnology.com --- drivers/gpu/drm/tiny/ili9225.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c index 118477af4491..d1a5ab6747d5 100644 --- a/drivers/gpu/drm/tiny/ili9225.c +++ b/drivers/gpu/drm/tiny/ili9225.c @@ -376,18 +376,13 @@ static int ili9225_probe(struct spi_device *spi) u32 rotation = 0; int ret;
- dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &ili9225_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev);
dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &ili9225_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev);
dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) {
On 4/3/20 8:58 AM, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: David Lechner david@lechnology.com
Acked-by: David Lechner david@lechnology.com
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Eric Anholt eric@anholt.net --- drivers/gpu/drm/tiny/hx8357d.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c index af7f3d10aac3..b4bc358a3269 100644 --- a/drivers/gpu/drm/tiny/hx8357d.c +++ b/drivers/gpu/drm/tiny/hx8357d.c @@ -226,17 +226,12 @@ static int hx8357d_probe(struct spi_device *spi) u32 rotation = 0; int ret;
- dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &hx8357d_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev);
drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &hx8357d_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev);
dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW); if (IS_ERR(dc)) {
On Fri, Apr 3, 2020 at 6:59 AM Daniel Vetter daniel.vetter@ffwll.ch wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Acked-by: Eric Anholt eric@anholt.net
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com --- drivers/gpu/drm/tiny/gm12u320.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 6f0ea2827d62..907739a67bf6 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -631,22 +631,17 @@ static int gm12u320_usb_probe(struct usb_interface *interface, if (interface->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV;
- gm12u320 = kzalloc(sizeof(*gm12u320), GFP_KERNEL); - if (gm12u320 == NULL) - return -ENOMEM; + gm12u320 = devm_drm_dev_alloc(&interface->dev, &gm12u320_drm_driver, + struct gm12u320_device, dev); + if (IS_ERR(gm12u320)) + return PTR_ERR(gm12u320);
gm12u320->udev = interface_to_usbdev(interface); INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); mutex_init(&gm12u320->fb_update.lock);
dev = &gm12u320->dev; - ret = devm_drm_dev_init(&interface->dev, dev, &gm12u320_drm_driver); - if (ret) { - kfree(gm12u320); - return ret; - } dev->dev_private = gm12u320; - drmm_add_final_kfree(dev, gm12u320);
ret = drmm_mode_config_init(dev); if (ret)
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Hans de Goede hdegoede@redhat.com --- drivers/gpu/drm/tiny/gm12u320.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 907739a67bf6..cc397671f689 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -98,6 +98,8 @@ struct gm12u320_device { } fb_update; };
+#define to_gm12u320(__dev) container_of(__dev, struct gm12u320_device, dev) + static const char cmd_data[CMD_SIZE] = { 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x68, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, @@ -408,7 +410,7 @@ static void gm12u320_fb_update_work(struct work_struct *work) static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb, struct drm_rect *dirty) { - struct gm12u320_device *gm12u320 = fb->dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(fb->dev); struct drm_framebuffer *old_fb = NULL; bool wakeup = false;
@@ -558,7 +560,7 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state) { struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT }; - struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT; gm12u320_fb_mark_dirty(plane_state->fb, &rect); @@ -566,7 +568,7 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe) { - struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
gm12u320_stop_fb_update(gm12u320); } @@ -641,7 +643,6 @@ static int gm12u320_usb_probe(struct usb_interface *interface, mutex_init(&gm12u320->fb_update.lock);
dev = &gm12u320->dev; - dev->dev_private = gm12u320;
ret = drmm_mode_config_init(dev); if (ret) @@ -706,7 +707,7 @@ static __maybe_unused int gm12u320_suspend(struct usb_interface *interface, static __maybe_unused int gm12u320_resume(struct usb_interface *interface) { struct drm_device *dev = usb_get_intfdata(interface); - struct gm12u320_device *gm12u320 = dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(dev);
gm12u320_set_ecomode(gm12u320);
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com --- drivers/gpu/drm/tidss/tidss_drv.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index ad449d104306..7d4465d58be8 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -135,20 +135,13 @@ static int tidss_probe(struct platform_device *pdev)
dev_dbg(dev, "%s\n", __func__);
- /* Can't use devm_* since drm_device's lifetime may exceed dev's */ - tidss = kzalloc(sizeof(*tidss), GFP_KERNEL); - if (!tidss) - return -ENOMEM; + tidss = devm_drm_dev_alloc(&pdev->dev, &tidss_driver, + struct tidss_device, ddev); + if (IS_ERR(tidss)) + return PTR_ERR(tidss);
ddev = &tidss->ddev;
- ret = devm_drm_dev_init(&pdev->dev, ddev, &tidss_driver); - if (ret) { - kfree(ddev); - return ret; - } - drmm_add_final_kfree(ddev, tidss); - tidss->dev = dev; tidss->feat = of_device_get_match_data(dev);
On Fri, Apr 03, 2020 at 03:58:11PM +0200, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/tidss/tidss_drv.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index ad449d104306..7d4465d58be8 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -135,20 +135,13 @@ static int tidss_probe(struct platform_device *pdev)
dev_dbg(dev, "%s\n", __func__);
- /* Can't use devm_* since drm_device's lifetime may exceed dev's */
- tidss = kzalloc(sizeof(*tidss), GFP_KERNEL);
- if (!tidss)
return -ENOMEM;
tidss = devm_drm_dev_alloc(&pdev->dev, &tidss_driver,
struct tidss_device, ddev);
if (IS_ERR(tidss))
return PTR_ERR(tidss);
ddev = &tidss->ddev;
- ret = devm_drm_dev_init(&pdev->dev, ddev, &tidss_driver);
- if (ret) {
kfree(ddev);
return ret;
- }
- drmm_add_final_kfree(ddev, tidss);
- tidss->dev = dev; tidss->feat = of_device_get_match_data(dev);
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On 03/04/2020 16:58, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com
Tested-by: Jyri Sarha jsarha@ti.com
drivers/gpu/drm/tidss/tidss_drv.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index ad449d104306..7d4465d58be8 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -135,20 +135,13 @@ static int tidss_probe(struct platform_device *pdev)
dev_dbg(dev, "%s\n", __func__);
- /* Can't use devm_* since drm_device's lifetime may exceed dev's */
- tidss = kzalloc(sizeof(*tidss), GFP_KERNEL);
- if (!tidss)
return -ENOMEM;
tidss = devm_drm_dev_alloc(&pdev->dev, &tidss_driver,
struct tidss_device, ddev);
if (IS_ERR(tidss))
return PTR_ERR(tidss);
ddev = &tidss->ddev;
- ret = devm_drm_dev_init(&pdev->dev, ddev, &tidss_driver);
- if (ret) {
kfree(ddev);
return ret;
- }
- drmm_add_final_kfree(ddev, tidss);
- tidss->dev = dev; tidss->feat = of_device_get_match_data(dev);
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com --- drivers/gpu/drm/tidss/tidss_crtc.c | 16 ++++++++-------- drivers/gpu/drm/tidss/tidss_drv.c | 2 -- drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ drivers/gpu/drm/tidss/tidss_irq.c | 12 ++++++------ drivers/gpu/drm/tidss/tidss_kms.c | 2 +- drivers/gpu/drm/tidss/tidss_plane.c | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index d4ce9bab8c7e..2396262c09e4 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -24,7 +24,7 @@ static void tidss_crtc_finish_page_flip(struct tidss_crtc *tcrtc) { struct drm_device *ddev = tcrtc->crtc.dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct drm_pending_vblank_event *event; unsigned long flags; bool busy; @@ -88,7 +88,7 @@ static int tidss_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct dispc_device *dispc = tidss->dispc; struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; @@ -165,7 +165,7 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned long flags;
dev_dbg(ddev->dev, @@ -216,7 +216,7 @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); const struct drm_display_mode *mode = &crtc->state->adjusted_mode; unsigned long flags; int r; @@ -259,7 +259,7 @@ static void tidss_crtc_atomic_disable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned long flags;
dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event); @@ -295,7 +295,7 @@ enum drm_mode_status tidss_crtc_mode_valid(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev);
return dispc_vp_mode_valid(tidss->dispc, tcrtc->hw_videoport, mode); } @@ -314,7 +314,7 @@ static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs = { static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
@@ -328,7 +328,7 @@ static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) static void tidss_crtc_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 7d4465d58be8..99edc66ebdef 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -147,8 +147,6 @@ static int tidss_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tidss);
- ddev->dev_private = tidss; - ret = dispc_init(tidss); if (ret) { dev_err(dev, "failed to initialize dispc: %d\n", ret); diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index e2aa6436ad18..b23cd95c8d78 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -33,6 +33,8 @@ struct tidss_device { struct drm_atomic_state *saved_state; };
+#define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev) + int tidss_runtime_get(struct tidss_device *tidss); void tidss_runtime_put(struct tidss_device *tidss);
diff --git a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c index 612c046738e5..1b80f2d62e0a 100644 --- a/drivers/gpu/drm/tidss/tidss_irq.c +++ b/drivers/gpu/drm/tidss/tidss_irq.c @@ -23,7 +23,7 @@ static void tidss_irq_update(struct tidss_device *tidss) void tidss_irq_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags; @@ -38,7 +38,7 @@ void tidss_irq_enable_vblank(struct drm_crtc *crtc) void tidss_irq_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags; @@ -53,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc) irqreturn_t tidss_irq_handler(int irq, void *arg) { struct drm_device *ddev = (struct drm_device *)arg; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned int id; dispc_irq_t irqstatus;
@@ -95,7 +95,7 @@ void tidss_irq_resume(struct tidss_device *tidss)
void tidss_irq_preinstall(struct drm_device *ddev) { - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev);
spin_lock_init(&tidss->wait_lock);
@@ -109,7 +109,7 @@ void tidss_irq_preinstall(struct drm_device *ddev)
int tidss_irq_postinstall(struct drm_device *ddev) { - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned long flags; unsigned int i;
@@ -138,7 +138,7 @@ int tidss_irq_postinstall(struct drm_device *ddev)
void tidss_irq_uninstall(struct drm_device *ddev) { - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev);
tidss_runtime_get(tidss); dispc_set_irqenable(tidss->dispc, 0); diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index 4bd339a467a4..4b99e9fa84a5 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -25,7 +25,7 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *ddev = old_state->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c index ff99b2dd4a17..23bb3e59504b 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -22,7 +22,7 @@ static int tidss_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_device *ddev = plane->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); const struct drm_format_info *finfo; struct drm_crtc_state *crtc_state; @@ -101,7 +101,7 @@ static void tidss_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); struct drm_plane_state *state = plane->state; u32 hw_videoport; @@ -133,7 +133,7 @@ static void tidss_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane);
dev_dbg(ddev->dev, "%s\n", __func__);
On Fri, Apr 03, 2020 at 03:58:12PM +0200, Daniel Vetter wrote:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/tidss/tidss_crtc.c | 16 ++++++++-------- drivers/gpu/drm/tidss/tidss_drv.c | 2 -- drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ drivers/gpu/drm/tidss/tidss_irq.c | 12 ++++++------ drivers/gpu/drm/tidss/tidss_kms.c | 2 +- drivers/gpu/drm/tidss/tidss_plane.c | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index d4ce9bab8c7e..2396262c09e4 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -24,7 +24,7 @@ static void tidss_crtc_finish_page_flip(struct tidss_crtc *tcrtc) { struct drm_device *ddev = tcrtc->crtc.dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct drm_pending_vblank_event *event; unsigned long flags; bool busy;
@@ -88,7 +88,7 @@ static int tidss_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct dispc_device *dispc = tidss->dispc; struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport;
@@ -165,7 +165,7 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev); unsigned long flags;
dev_dbg(ddev->dev,
@@ -216,7 +216,7 @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); const struct drm_display_mode *mode = &crtc->state->adjusted_mode; unsigned long flags; int r;
@@ -259,7 +259,7 @@ static void tidss_crtc_atomic_disable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev); unsigned long flags;
dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event);
@@ -295,7 +295,7 @@ enum drm_mode_status tidss_crtc_mode_valid(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
return dispc_vp_mode_valid(tidss->dispc, tcrtc->hw_videoport, mode);
} @@ -314,7 +314,7 @@ static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs = { static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
@@ -328,7 +328,7 @@ static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) static void tidss_crtc_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 7d4465d58be8..99edc66ebdef 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -147,8 +147,6 @@ static int tidss_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tidss);
- ddev->dev_private = tidss;
- ret = dispc_init(tidss); if (ret) { dev_err(dev, "failed to initialize dispc: %d\n", ret);
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index e2aa6436ad18..b23cd95c8d78 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -33,6 +33,8 @@ struct tidss_device { struct drm_atomic_state *saved_state; };
+#define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev)
int tidss_runtime_get(struct tidss_device *tidss); void tidss_runtime_put(struct tidss_device *tidss);
diff --git a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c index 612c046738e5..1b80f2d62e0a 100644 --- a/drivers/gpu/drm/tidss/tidss_irq.c +++ b/drivers/gpu/drm/tidss/tidss_irq.c @@ -23,7 +23,7 @@ static void tidss_irq_update(struct tidss_device *tidss) void tidss_irq_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags;
@@ -38,7 +38,7 @@ void tidss_irq_enable_vblank(struct drm_crtc *crtc) void tidss_irq_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags;
@@ -53,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc) irqreturn_t tidss_irq_handler(int irq, void *arg) { struct drm_device *ddev = (struct drm_device *)arg;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); unsigned int id; dispc_irq_t irqstatus;
@@ -95,7 +95,7 @@ void tidss_irq_resume(struct tidss_device *tidss)
void tidss_irq_preinstall(struct drm_device *ddev) {
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
spin_lock_init(&tidss->wait_lock);
@@ -109,7 +109,7 @@ void tidss_irq_preinstall(struct drm_device *ddev)
int tidss_irq_postinstall(struct drm_device *ddev) {
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); unsigned long flags; unsigned int i;
@@ -138,7 +138,7 @@ int tidss_irq_postinstall(struct drm_device *ddev)
void tidss_irq_uninstall(struct drm_device *ddev) {
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
tidss_runtime_get(tidss); dispc_set_irqenable(tidss->dispc, 0);
diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index 4bd339a467a4..4b99e9fa84a5 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -25,7 +25,7 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *ddev = old_state->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c index ff99b2dd4a17..23bb3e59504b 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -22,7 +22,7 @@ static int tidss_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_device *ddev = plane->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); const struct drm_format_info *finfo; struct drm_crtc_state *crtc_state;
@@ -101,7 +101,7 @@ static void tidss_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); struct drm_plane_state *state = plane->state; u32 hw_videoport;
@@ -133,7 +133,7 @@ static void tidss_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane);
dev_dbg(ddev->dev, "%s\n", __func__);
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On 03/04/2020 16:58, Daniel Vetter wrote:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com
Tested-by: Jyri Sarha jsarha@ti.com
drivers/gpu/drm/tidss/tidss_crtc.c | 16 ++++++++-------- drivers/gpu/drm/tidss/tidss_drv.c | 2 -- drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ drivers/gpu/drm/tidss/tidss_irq.c | 12 ++++++------ drivers/gpu/drm/tidss/tidss_kms.c | 2 +- drivers/gpu/drm/tidss/tidss_plane.c | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index d4ce9bab8c7e..2396262c09e4 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -24,7 +24,7 @@ static void tidss_crtc_finish_page_flip(struct tidss_crtc *tcrtc) { struct drm_device *ddev = tcrtc->crtc.dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct drm_pending_vblank_event *event; unsigned long flags; bool busy;
@@ -88,7 +88,7 @@ static int tidss_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct dispc_device *dispc = tidss->dispc; struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport;
@@ -165,7 +165,7 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev); unsigned long flags;
dev_dbg(ddev->dev,
@@ -216,7 +216,7 @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); const struct drm_display_mode *mode = &crtc->state->adjusted_mode; unsigned long flags; int r;
@@ -259,7 +259,7 @@ static void tidss_crtc_atomic_disable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev); unsigned long flags;
dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event);
@@ -295,7 +295,7 @@ enum drm_mode_status tidss_crtc_mode_valid(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
return dispc_vp_mode_valid(tidss->dispc, tcrtc->hw_videoport, mode);
} @@ -314,7 +314,7 @@ static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs = { static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
@@ -328,7 +328,7 @@ static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) static void tidss_crtc_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 7d4465d58be8..99edc66ebdef 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -147,8 +147,6 @@ static int tidss_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tidss);
- ddev->dev_private = tidss;
- ret = dispc_init(tidss); if (ret) { dev_err(dev, "failed to initialize dispc: %d\n", ret);
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index e2aa6436ad18..b23cd95c8d78 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -33,6 +33,8 @@ struct tidss_device { struct drm_atomic_state *saved_state; };
+#define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev)
int tidss_runtime_get(struct tidss_device *tidss); void tidss_runtime_put(struct tidss_device *tidss);
diff --git a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c index 612c046738e5..1b80f2d62e0a 100644 --- a/drivers/gpu/drm/tidss/tidss_irq.c +++ b/drivers/gpu/drm/tidss/tidss_irq.c @@ -23,7 +23,7 @@ static void tidss_irq_update(struct tidss_device *tidss) void tidss_irq_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags;
@@ -38,7 +38,7 @@ void tidss_irq_enable_vblank(struct drm_crtc *crtc) void tidss_irq_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags;
@@ -53,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc) irqreturn_t tidss_irq_handler(int irq, void *arg) { struct drm_device *ddev = (struct drm_device *)arg;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); unsigned int id; dispc_irq_t irqstatus;
@@ -95,7 +95,7 @@ void tidss_irq_resume(struct tidss_device *tidss)
void tidss_irq_preinstall(struct drm_device *ddev) {
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
spin_lock_init(&tidss->wait_lock);
@@ -109,7 +109,7 @@ void tidss_irq_preinstall(struct drm_device *ddev)
int tidss_irq_postinstall(struct drm_device *ddev) {
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); unsigned long flags; unsigned int i;
@@ -138,7 +138,7 @@ int tidss_irq_postinstall(struct drm_device *ddev)
void tidss_irq_uninstall(struct drm_device *ddev) {
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
tidss_runtime_get(tidss); dispc_set_irqenable(tidss->dispc, 0);
diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index 4bd339a467a4..4b99e9fa84a5 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -25,7 +25,7 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *ddev = old_state->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev);
dev_dbg(ddev->dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c index ff99b2dd4a17..23bb3e59504b 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -22,7 +22,7 @@ static int tidss_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_device *ddev = plane->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); const struct drm_format_info *finfo; struct drm_crtc_state *crtc_state;
@@ -101,7 +101,7 @@ static void tidss_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev;
- struct tidss_device *tidss = ddev->dev_private;
- struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); struct drm_plane_state *state = plane->state; u32 hw_videoport;
@@ -133,7 +133,7 @@ static void tidss_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev;
- struct tidss_device *tidss = ddev->dev_private;
struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane);
dev_dbg(ddev->dev, "%s\n", __func__);
Not used anymore since the switch to suspend/resume helpers.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com --- drivers/gpu/drm/tidss/tidss_drv.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index b23cd95c8d78..3b0a3d87b7c4 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -29,8 +29,6 @@ struct tidss_device {
spinlock_t wait_lock; /* protects the irq masks */ dispc_irq_t irq_mask; /* enabled irqs in addition to wait_list */ - - struct drm_atomic_state *saved_state; };
#define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev)
On Fri, Apr 03, 2020 at 03:58:13PM +0200, Daniel Vetter wrote:
Not used anymore since the switch to suspend/resume helpers.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com
Good spot. Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/tidss/tidss_drv.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index b23cd95c8d78..3b0a3d87b7c4 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -29,8 +29,6 @@ struct tidss_device {
spinlock_t wait_lock; /* protects the irq masks */ dispc_irq_t irq_mask; /* enabled irqs in addition to wait_list */
- struct drm_atomic_state *saved_state;
};
#define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev)
2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On 03/04/2020 16:58, Daniel Vetter wrote:
Not used anymore since the switch to suspend/resume helpers.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com
Tested-by: Jyri Sarha jsarha@ti.com
drivers/gpu/drm/tidss/tidss_drv.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index b23cd95c8d78..3b0a3d87b7c4 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -29,8 +29,6 @@ struct tidss_device {
spinlock_t wait_lock; /* protects the irq masks */ dispc_irq_t irq_mask; /* enabled irqs in addition to wait_list */
- struct drm_atomic_state *saved_state;
};
#define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev)
Also need to remove the drm_dev_put from the remove hook.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org --- drivers/gpu/drm/qxl/qxl_drv.c | 15 ++++++++------- drivers/gpu/drm/qxl/qxl_drv.h | 3 +-- drivers/gpu/drm/qxl/qxl_kms.c | 12 +----------- 3 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 09102e2efabc..6b4ae4c5fb76 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -81,13 +81,16 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -EINVAL; /* TODO: ENODEV ? */ }
- qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL); - if (!qdev) + qdev = devm_drm_dev_alloc(&pdev->dev, &qxl_driver, + struct qxl_device, ddev); + if (IS_ERR(qdev)) { + pr_err("Unable to init drm dev"); return -ENOMEM; + }
ret = pci_enable_device(pdev); if (ret) - goto free_dev; + return ret;
ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "qxl"); if (ret) @@ -101,7 +104,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } }
- ret = qxl_device_init(qdev, &qxl_driver, pdev); + ret = qxl_device_init(qdev, pdev); if (ret) goto put_vga;
@@ -128,8 +131,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vga_put(pdev, VGA_RSRC_LEGACY_IO); disable_pci: pci_disable_device(pdev); -free_dev: - kfree(qdev); + return ret; }
@@ -155,7 +157,6 @@ qxl_pci_remove(struct pci_dev *pdev) drm_atomic_helper_shutdown(dev); if (is_vga(pdev)) vga_put(pdev, VGA_RSRC_LEGACY_IO); - drm_dev_put(dev); }
DEFINE_DRM_GEM_FOPS(qxl_fops); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 435126facc9b..86ac191d9205 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -276,8 +276,7 @@ struct qxl_device { extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl;
-int qxl_device_init(struct qxl_device *qdev, struct drm_driver *drv, - struct pci_dev *pdev); +int qxl_device_init(struct qxl_device *qdev, struct pci_dev *pdev); void qxl_device_fini(struct qxl_device *qdev);
int qxl_modeset_init(struct qxl_device *qdev); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 9eed1a375f24..91a34dd835d7 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -108,21 +108,13 @@ static void qxl_gc_work(struct work_struct *work) }
int qxl_device_init(struct qxl_device *qdev, - struct drm_driver *drv, struct pci_dev *pdev) { int r, sb;
- r = drm_dev_init(&qdev->ddev, drv, &pdev->dev); - if (r) { - pr_err("Unable to init drm dev"); - goto error; - } - qdev->ddev.pdev = pdev; pci_set_drvdata(pdev, &qdev->ddev); qdev->ddev.dev_private = qdev; - drmm_add_final_kfree(&qdev->ddev, qdev);
mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex); @@ -138,8 +130,7 @@ int qxl_device_init(struct qxl_device *qdev, qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0)); if (!qdev->vram_mapping) { pr_err("Unable to create vram_mapping"); - r = -ENOMEM; - goto error; + return -ENOMEM; }
if (pci_resource_len(pdev, 4) > 0) { @@ -293,7 +284,6 @@ int qxl_device_init(struct qxl_device *qdev, io_mapping_free(qdev->surface_mapping); vram_mapping_free: io_mapping_free(qdev->vram_mapping); -error: return r; }
On Fri, Apr 03, 2020 at 03:58:14PM +0200, Daniel Vetter wrote:
Also need to remove the drm_dev_put from the remove hook.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org
Acked-by: Gerd Hoffmann kraxel@redhat.com
Am 03.04.20 um 15:58 schrieb Daniel Vetter:
Also need to remove the drm_dev_put from the remove hook.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org
drivers/gpu/drm/qxl/qxl_drv.c | 15 ++++++++------- drivers/gpu/drm/qxl/qxl_drv.h | 3 +-- drivers/gpu/drm/qxl/qxl_kms.c | 12 +----------- 3 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 09102e2efabc..6b4ae4c5fb76 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -81,13 +81,16 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -EINVAL; /* TODO: ENODEV ? */ }
- qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL);
- if (!qdev)
- qdev = devm_drm_dev_alloc(&pdev->dev, &qxl_driver,
struct qxl_device, ddev);
- if (IS_ERR(qdev)) {
return -ENOMEM;pr_err("Unable to init drm dev");
- }
My feeling is that it is too early to allocate. Wouldn't it be better to first do the pdev and conflicting-fb stuff and allocate right before qxl_device_init() ?
Best regards Thomas
ret = pci_enable_device(pdev); if (ret)
goto free_dev;
return ret;
ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "qxl"); if (ret)
@@ -101,7 +104,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } }
- ret = qxl_device_init(qdev, &qxl_driver, pdev);
- ret = qxl_device_init(qdev, pdev); if (ret) goto put_vga;
@@ -128,8 +131,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vga_put(pdev, VGA_RSRC_LEGACY_IO); disable_pci: pci_disable_device(pdev); -free_dev:
- kfree(qdev);
- return ret;
}
@@ -155,7 +157,6 @@ qxl_pci_remove(struct pci_dev *pdev) drm_atomic_helper_shutdown(dev); if (is_vga(pdev)) vga_put(pdev, VGA_RSRC_LEGACY_IO);
- drm_dev_put(dev);
}
DEFINE_DRM_GEM_FOPS(qxl_fops); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 435126facc9b..86ac191d9205 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -276,8 +276,7 @@ struct qxl_device { extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl;
-int qxl_device_init(struct qxl_device *qdev, struct drm_driver *drv,
struct pci_dev *pdev);
+int qxl_device_init(struct qxl_device *qdev, struct pci_dev *pdev); void qxl_device_fini(struct qxl_device *qdev);
int qxl_modeset_init(struct qxl_device *qdev); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 9eed1a375f24..91a34dd835d7 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -108,21 +108,13 @@ static void qxl_gc_work(struct work_struct *work) }
int qxl_device_init(struct qxl_device *qdev,
struct pci_dev *pdev)struct drm_driver *drv,
{ int r, sb;
r = drm_dev_init(&qdev->ddev, drv, &pdev->dev);
if (r) {
pr_err("Unable to init drm dev");
goto error;
}
qdev->ddev.pdev = pdev; pci_set_drvdata(pdev, &qdev->ddev); qdev->ddev.dev_private = qdev;
drmm_add_final_kfree(&qdev->ddev, qdev);
mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex);
@@ -138,8 +130,7 @@ int qxl_device_init(struct qxl_device *qdev, qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0)); if (!qdev->vram_mapping) { pr_err("Unable to create vram_mapping");
r = -ENOMEM;
goto error;
return -ENOMEM;
}
if (pci_resource_len(pdev, 4) > 0) {
@@ -293,7 +284,6 @@ int qxl_device_init(struct qxl_device *qdev, io_mapping_free(qdev->surface_mapping); vram_mapping_free: io_mapping_free(qdev->vram_mapping); -error: return r; }
On Mon, Apr 6, 2020 at 7:29 PM Thomas Zimmermann tzimmermann@suse.de wrote:
Am 03.04.20 um 15:58 schrieb Daniel Vetter:
Also need to remove the drm_dev_put from the remove hook.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org
drivers/gpu/drm/qxl/qxl_drv.c | 15 ++++++++------- drivers/gpu/drm/qxl/qxl_drv.h | 3 +-- drivers/gpu/drm/qxl/qxl_kms.c | 12 +----------- 3 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 09102e2efabc..6b4ae4c5fb76 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -81,13 +81,16 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -EINVAL; /* TODO: ENODEV ? */ }
qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL);
if (!qdev)
qdev = devm_drm_dev_alloc(&pdev->dev, &qxl_driver,
struct qxl_device, ddev);
if (IS_ERR(qdev)) {
pr_err("Unable to init drm dev"); return -ENOMEM;
}
My feeling is that it is too early to allocate. Wouldn't it be better to first do the pdev and conflicting-fb stuff and allocate right before qxl_device_init() ?
It doesn't matter. I can reorder, or I can also not reorder, it'll have 0 effects on cleanup (all done automatically) or correctness (it's just a memory allocation, it doesn't do anything). -Daniel
Best regards Thomas
ret = pci_enable_device(pdev); if (ret)
goto free_dev;
return ret; ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "qxl"); if (ret)
@@ -101,7 +104,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } }
ret = qxl_device_init(qdev, &qxl_driver, pdev);
ret = qxl_device_init(qdev, pdev); if (ret) goto put_vga;
@@ -128,8 +131,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vga_put(pdev, VGA_RSRC_LEGACY_IO); disable_pci: pci_disable_device(pdev); -free_dev:
kfree(qdev);
return ret;
}
@@ -155,7 +157,6 @@ qxl_pci_remove(struct pci_dev *pdev) drm_atomic_helper_shutdown(dev); if (is_vga(pdev)) vga_put(pdev, VGA_RSRC_LEGACY_IO);
drm_dev_put(dev);
}
DEFINE_DRM_GEM_FOPS(qxl_fops); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 435126facc9b..86ac191d9205 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -276,8 +276,7 @@ struct qxl_device { extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl;
-int qxl_device_init(struct qxl_device *qdev, struct drm_driver *drv,
struct pci_dev *pdev);
+int qxl_device_init(struct qxl_device *qdev, struct pci_dev *pdev); void qxl_device_fini(struct qxl_device *qdev);
int qxl_modeset_init(struct qxl_device *qdev); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 9eed1a375f24..91a34dd835d7 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -108,21 +108,13 @@ static void qxl_gc_work(struct work_struct *work) }
int qxl_device_init(struct qxl_device *qdev,
struct drm_driver *drv, struct pci_dev *pdev)
{ int r, sb;
r = drm_dev_init(&qdev->ddev, drv, &pdev->dev);
if (r) {
pr_err("Unable to init drm dev");
goto error;
}
qdev->ddev.pdev = pdev; pci_set_drvdata(pdev, &qdev->ddev); qdev->ddev.dev_private = qdev;
drmm_add_final_kfree(&qdev->ddev, qdev); mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex);
@@ -138,8 +130,7 @@ int qxl_device_init(struct qxl_device *qdev, qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0)); if (!qdev->vram_mapping) { pr_err("Unable to create vram_mapping");
r = -ENOMEM;
goto error;
return -ENOMEM; } if (pci_resource_len(pdev, 4) > 0) {
@@ -293,7 +284,6 @@ int qxl_device_init(struct qxl_device *qdev, io_mapping_free(qdev->surface_mapping); vram_mapping_free: io_mapping_free(qdev->vram_mapping); -error: return r; }
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org --- drivers/gpu/drm/qxl/qxl_debugfs.c | 7 +++---- drivers/gpu/drm/qxl/qxl_display.c | 32 +++++++++++++++---------------- drivers/gpu/drm/qxl/qxl_drv.c | 8 ++++---- drivers/gpu/drm/qxl/qxl_drv.h | 4 ++-- drivers/gpu/drm/qxl/qxl_dumb.c | 2 +- drivers/gpu/drm/qxl/qxl_gem.c | 2 +- drivers/gpu/drm/qxl/qxl_ioctl.c | 14 +++++++------- drivers/gpu/drm/qxl/qxl_irq.c | 2 +- drivers/gpu/drm/qxl/qxl_kms.c | 1 - drivers/gpu/drm/qxl/qxl_object.c | 2 +- drivers/gpu/drm/qxl/qxl_release.c | 2 +- drivers/gpu/drm/qxl/qxl_ttm.c | 2 +- 12 files changed, 38 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c index 88123047fdd4..524d35b648d8 100644 --- a/drivers/gpu/drm/qxl/qxl_debugfs.c +++ b/drivers/gpu/drm/qxl/qxl_debugfs.c @@ -39,7 +39,7 @@ static int qxl_debugfs_irq_received(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; - struct qxl_device *qdev = node->minor->dev->dev_private; + struct qxl_device *qdev = to_qxl(node->minor->dev);
seq_printf(m, "%d\n", atomic_read(&qdev->irq_received)); seq_printf(m, "%d\n", atomic_read(&qdev->irq_received_display)); @@ -53,7 +53,7 @@ static int qxl_debugfs_buffers_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; - struct qxl_device *qdev = node->minor->dev->dev_private; + struct qxl_device *qdev = to_qxl(node->minor->dev); struct qxl_bo *bo;
list_for_each_entry(bo, &qdev->gem.objects, list) { @@ -83,8 +83,7 @@ void qxl_debugfs_init(struct drm_minor *minor) { #if defined(CONFIG_DEBUG_FS) - struct qxl_device *dev = - (struct qxl_device *) minor->dev->dev_private; + struct qxl_device *dev = to_qxl(minor->dev);
drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, minor->debugfs_root, minor); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 09583a08e141..1082cd5d2fd4 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -221,7 +221,7 @@ static int qxl_add_mode(struct drm_connector *connector, bool preferred) { struct drm_device *dev = connector->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_display_mode *mode = NULL; int rc;
@@ -242,7 +242,7 @@ static int qxl_add_mode(struct drm_connector *connector, static int qxl_add_monitors_config_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_output *output = drm_connector_to_qxl_output(connector); int h = output->index; struct qxl_head *head; @@ -310,7 +310,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc *crtc, const char *reason) { struct drm_device *dev = crtc->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); struct qxl_head head; int oldcount, i = qcrtc->index; @@ -400,7 +400,7 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, unsigned int num_clips) { /* TODO: vmwgfx where this was cribbed from had locking. Why? */ - struct qxl_device *qdev = fb->dev->dev_private; + struct qxl_device *qdev = to_qxl(fb->dev); struct drm_clip_rect norect; struct qxl_bo *qobj; bool is_primary; @@ -462,7 +462,7 @@ static const struct drm_crtc_helper_funcs qxl_crtc_helper_funcs = { static int qxl_primary_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct qxl_bo *bo;
if (!state->crtc || !state->fb) @@ -476,7 +476,7 @@ static int qxl_primary_atomic_check(struct drm_plane *plane, static int qxl_primary_apply_cursor(struct drm_plane *plane) { struct drm_device *dev = plane->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_framebuffer *fb = plane->state->fb; struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); struct qxl_cursor_cmd *cmd; @@ -523,7 +523,7 @@ static int qxl_primary_apply_cursor(struct drm_plane *plane) static void qxl_primary_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct qxl_bo *bo = gem_to_qxl_bo(plane->state->fb->obj[0]); struct qxl_bo *primary; struct drm_clip_rect norect = { @@ -554,7 +554,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, static void qxl_primary_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev);
if (old_state->fb) { struct qxl_bo *bo = gem_to_qxl_bo(old_state->fb->obj[0]); @@ -570,7 +570,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *dev = plane->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_framebuffer *fb = plane->state->fb; struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); struct qxl_release *release; @@ -679,7 +679,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, static void qxl_cursor_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct qxl_release *release; struct qxl_cursor_cmd *cmd; int ret; @@ -762,7 +762,7 @@ static void qxl_calc_dumb_shadow(struct qxl_device *qdev, static int qxl_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct drm_gem_object *obj; struct qxl_bo *user_bo; struct qxl_surface surf; @@ -923,7 +923,7 @@ static int qdev_crtc_init(struct drm_device *dev, int crtc_id) { struct qxl_crtc *qxl_crtc; struct drm_plane *primary, *cursor; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); int r;
qxl_crtc = kzalloc(sizeof(struct qxl_crtc), GFP_KERNEL); @@ -965,7 +965,7 @@ static int qdev_crtc_init(struct drm_device *dev, int crtc_id) static int qxl_conn_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_output *output = drm_connector_to_qxl_output(connector); unsigned int pwidth = 1024; unsigned int pheight = 768; @@ -991,7 +991,7 @@ static enum drm_mode_status qxl_conn_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_device *ddev = connector->dev; - struct qxl_device *qdev = ddev->dev_private; + struct qxl_device *qdev = to_qxl(ddev);
if (qxl_check_mode(qdev, mode->hdisplay, mode->vdisplay) != 0) return MODE_BAD; @@ -1021,7 +1021,7 @@ static enum drm_connector_status qxl_conn_detect( struct qxl_output *output = drm_connector_to_qxl_output(connector); struct drm_device *ddev = connector->dev; - struct qxl_device *qdev = ddev->dev_private; + struct qxl_device *qdev = to_qxl(ddev); bool connected = false;
/* The first monitor is always connected */ @@ -1071,7 +1071,7 @@ static int qxl_mode_create_hotplug_mode_update_property(struct qxl_device *qdev)
static int qdev_output_init(struct drm_device *dev, int num_output) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_output *qxl_output; struct drm_connector *connector; struct drm_encoder *encoder; diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 6b4ae4c5fb76..13872b882775 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -137,7 +137,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static void qxl_drm_release(struct drm_device *dev) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev);
/* * TODO: qxl_device_fini() call should be in qxl_pci_remove(), @@ -164,7 +164,7 @@ DEFINE_DRM_GEM_FOPS(qxl_fops); static int qxl_drm_freeze(struct drm_device *dev) { struct pci_dev *pdev = dev->pdev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); int ret;
ret = drm_mode_config_helper_suspend(dev); @@ -186,7 +186,7 @@ static int qxl_drm_freeze(struct drm_device *dev)
static int qxl_drm_resume(struct drm_device *dev, bool thaw) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev);
qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; if (!thaw) { @@ -245,7 +245,7 @@ static int qxl_pm_restore(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - struct qxl_device *qdev = drm_dev->dev_private; + struct qxl_device *qdev = to_qxl(drm_dev);
qxl_io_reset(qdev); return qxl_drm_resume(drm_dev, false); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 86ac191d9205..31e35f787df2 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -192,8 +192,6 @@ struct qxl_debugfs {
int qxl_debugfs_fence_init(struct qxl_device *rdev);
-struct qxl_device; - struct qxl_device { struct drm_device ddev;
@@ -273,6 +271,8 @@ struct qxl_device { int monitors_config_height; };
+#define to_qxl(dev) container_of(dev, struct qxl_device, ddev) + extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl;
diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index 272d19b677d8..24e903383aa1 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c @@ -32,7 +32,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_bo *qobj; uint32_t handle; int r; diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c index 69f37db1027a..5ff6fa9b799c 100644 --- a/drivers/gpu/drm/qxl/qxl_gem.c +++ b/drivers/gpu/drm/qxl/qxl_gem.c @@ -34,7 +34,7 @@ void qxl_gem_object_free(struct drm_gem_object *gobj) struct qxl_device *qdev; struct ttm_buffer_object *tbo;
- qdev = (struct qxl_device *)gobj->dev->dev_private; + qdev = to_qxl(gobj->dev);
qxl_surface_evict(qdev, qobj, false);
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 8117a45b3610..d9a583966949 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -36,7 +36,7 @@ static int qxl_alloc_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_alloc *qxl_alloc = data; int ret; struct qxl_bo *qobj; @@ -64,7 +64,7 @@ static int qxl_alloc_ioctl(struct drm_device *dev, void *data, static int qxl_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_map *qxl_map = data;
return qxl_mode_dumb_mmap(file_priv, &qdev->ddev, qxl_map->handle, @@ -279,7 +279,7 @@ static int qxl_process_single_command(struct qxl_device *qdev, static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_execbuffer *execbuffer = data; struct drm_qxl_command user_cmd; int cmd_num; @@ -304,7 +304,7 @@ static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data, static int qxl_update_area_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_update_area *update_area = data; struct qxl_rect area = {.left = update_area->left, .top = update_area->top, @@ -354,7 +354,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, static int qxl_getparam_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_getparam *param = data;
switch (param->param) { @@ -373,7 +373,7 @@ static int qxl_getparam_ioctl(struct drm_device *dev, void *data, static int qxl_clientcap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_clientcap *param = data; int byte, idx;
@@ -394,7 +394,7 @@ static int qxl_clientcap_ioctl(struct drm_device *dev, void *data, static int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_alloc_surf *param = data; struct qxl_bo *qobj; int handle; diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c index 8435af108632..1ba5a702d763 100644 --- a/drivers/gpu/drm/qxl/qxl_irq.c +++ b/drivers/gpu/drm/qxl/qxl_irq.c @@ -32,7 +32,7 @@ irqreturn_t qxl_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *) arg; - struct qxl_device *qdev = (struct qxl_device *)dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); uint32_t pending;
pending = xchg(&qdev->ram_header->int_pending, 0); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 91a34dd835d7..a6d873052cd4 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -114,7 +114,6 @@ int qxl_device_init(struct qxl_device *qdev,
qdev->ddev.pdev = pdev; pci_set_drvdata(pdev, &qdev->ddev); - qdev->ddev.dev_private = qdev;
mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex); diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index ab72dc3476e9..edc8a9916872 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -33,7 +33,7 @@ static void qxl_ttm_bo_destroy(struct ttm_buffer_object *tbo) struct qxl_device *qdev;
bo = to_qxl_bo(tbo); - qdev = (struct qxl_device *)bo->tbo.base.dev->dev_private; + qdev = to_qxl(bo->tbo.base.dev);
qxl_surface_evict(qdev, bo, false); WARN_ON_ONCE(bo->map_count > 0); diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 2feca734c7b1..4fae3e393da1 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -243,7 +243,7 @@ static int qxl_release_validate_bo(struct qxl_bo *bo) return ret;
/* allocate a surface for reserved + validated buffers */ - ret = qxl_bo_check_id(bo->tbo.base.dev->dev_private, bo); + ret = qxl_bo_check_id(to_qxl(bo->tbo.base.dev), bo); if (ret) return ret; return 0; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 93a2eb14844b..f09a712b1ed2 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -243,7 +243,7 @@ static void qxl_bo_move_notify(struct ttm_buffer_object *bo, if (!qxl_ttm_bo_is_qxl_bo(bo)) return; qbo = to_qxl_bo(bo); - qdev = qbo->tbo.base.dev->dev_private; + qdev = to_qxl(qbo->tbo.base.dev);
if (bo->mem.mem_type == TTM_PL_PRIV && qbo->surface_id) qxl_surface_evict(qdev, qbo, new_mem ? true : false);
On Fri, Apr 03, 2020 at 03:58:15PM +0200, Daniel Vetter wrote:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org
Acked-by: Gerd Hoffmann kraxel@redhat.com
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Linus Walleij linus.walleij@linaro.org --- drivers/gpu/drm/mcde/mcde_drv.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 88cc6b4a7a64..bdb525e3c5d7 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -307,24 +307,16 @@ static int mcde_probe(struct platform_device *pdev) int ret; int i;
- mcde = kzalloc(sizeof(*mcde), GFP_KERNEL); - if (!mcde) - return -ENOMEM; - mcde->dev = dev; - - ret = devm_drm_dev_init(dev, &mcde->drm, &mcde_drm_driver); - if (ret) { - kfree(mcde); - return ret; - } + mcde = devm_drm_dev_alloc(dev, &mcde_drm_driver, struct mcde, drm); + if (IS_ERR(mcde)) + return PTR_ERR(mcde); drm = &mcde->drm; drm->dev_private = mcde; - drmm_add_final_kfree(drm, mcde); + mcde->dev = dev; platform_set_drvdata(pdev, drm);
/* Enable continuous updates: this is what Linux' framebuffer expects */ mcde->oneshot_mode = false; - drm->dev_private = mcde;
/* First obtain and turn on the main power */ mcde->epod = devm_regulator_get(dev, "epod");
On Fri, Apr 03, 2020 at 03:58:16PM +0200, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Linus Walleij linus.walleij@linaro.org
Acked-by: Sam Ravnborg sam@ravnborg.org
But one comment below.
drivers/gpu/drm/mcde/mcde_drv.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 88cc6b4a7a64..bdb525e3c5d7 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -307,24 +307,16 @@ static int mcde_probe(struct platform_device *pdev) int ret; int i;
- mcde = kzalloc(sizeof(*mcde), GFP_KERNEL);
- if (!mcde)
return -ENOMEM;
- mcde->dev = dev;
- ret = devm_drm_dev_init(dev, &mcde->drm, &mcde_drm_driver);
- if (ret) {
kfree(mcde);
return ret;
- }
- mcde = devm_drm_dev_alloc(dev, &mcde_drm_driver, struct mcde, drm);
- if (IS_ERR(mcde))
drm = &mcde->drm; drm->dev_private = mcde;return PTR_ERR(mcde);
- drmm_add_final_kfree(drm, mcde);
mcde->dev = dev; platform_set_drvdata(pdev, drm);
/* Enable continuous updates: this is what Linux' framebuffer expects */ mcde->oneshot_mode = false;
- drm->dev_private = mcde;
It is assinged twice - but this change really belongs in next patch.
/* First obtain and turn on the main power */ mcde->epod = devm_regulator_get(dev, "epod"); -- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Linus Walleij linus.walleij@linaro.org --- drivers/gpu/drm/mcde/mcde_display.c | 10 +++++----- drivers/gpu/drm/mcde/mcde_drm.h | 2 ++ drivers/gpu/drm/mcde/mcde_drv.c | 5 ++--- drivers/gpu/drm/mcde/mcde_dsi.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/mcde/mcde_display.c b/drivers/gpu/drm/mcde/mcde_display.c index e59907e68854..04e1d38d41f7 100644 --- a/drivers/gpu/drm/mcde/mcde_display.c +++ b/drivers/gpu/drm/mcde/mcde_display.c @@ -948,7 +948,7 @@ static void mcde_display_disable(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); struct drm_pending_vblank_event *event;
drm_crtc_vblank_off(crtc); @@ -1020,7 +1020,7 @@ static void mcde_display_update(struct drm_simple_display_pipe *pipe, { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); struct drm_pending_vblank_event *event = crtc->state->event; struct drm_plane *plane = &pipe->plane; struct drm_plane_state *pstate = plane->state; @@ -1078,7 +1078,7 @@ static int mcde_display_enable_vblank(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); u32 val;
/* Enable all VBLANK IRQs */ @@ -1097,7 +1097,7 @@ static void mcde_display_disable_vblank(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm);
/* Disable all VBLANK IRQs */ writel(0, mcde->regs + MCDE_IMSCPP); @@ -1117,7 +1117,7 @@ static struct drm_simple_display_pipe_funcs mcde_display_funcs = {
int mcde_display_init(struct drm_device *drm) { - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); int ret; static const u32 formats[] = { DRM_FORMAT_ARGB8888, diff --git a/drivers/gpu/drm/mcde/mcde_drm.h b/drivers/gpu/drm/mcde/mcde_drm.h index 80edd6628979..679c2c4e6d9d 100644 --- a/drivers/gpu/drm/mcde/mcde_drm.h +++ b/drivers/gpu/drm/mcde/mcde_drm.h @@ -34,6 +34,8 @@ struct mcde { struct regulator *vana; };
+#define to_mcde(dev) container_of(dev, struct mcde, drm) + bool mcde_dsi_irq(struct mipi_dsi_device *mdsi); void mcde_dsi_te_request(struct mipi_dsi_device *mdsi); extern struct platform_driver mcde_dsi_driver; diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index bdb525e3c5d7..84f3e2dbd77b 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -164,7 +164,7 @@ static irqreturn_t mcde_irq(int irq, void *data) static int mcde_modeset_init(struct drm_device *drm) { struct drm_mode_config *mode_config; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); int ret;
if (!mcde->bridge) { @@ -311,7 +311,6 @@ static int mcde_probe(struct platform_device *pdev) if (IS_ERR(mcde)) return PTR_ERR(mcde); drm = &mcde->drm; - drm->dev_private = mcde; mcde->dev = dev; platform_set_drvdata(pdev, drm);
@@ -486,7 +485,7 @@ static int mcde_probe(struct platform_device *pdev) static int mcde_remove(struct platform_device *pdev) { struct drm_device *drm = platform_get_drvdata(pdev); - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm);
component_master_del(&pdev->dev, &mcde_drm_comp_ops); clk_disable_unprepare(mcde->mcde_clk); diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index 7af5ebb0c436..1baa2324cdb9 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -1020,7 +1020,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); struct mcde_dsi *d = dev_get_drvdata(dev); struct device_node *child; struct drm_panel *panel = NULL;
On Fri, Apr 03, 2020 at 03:58:17PM +0200, Daniel Vetter wrote:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Linus Walleij linus.walleij@linaro.org
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/mcde/mcde_display.c | 10 +++++----- drivers/gpu/drm/mcde/mcde_drm.h | 2 ++ drivers/gpu/drm/mcde/mcde_drv.c | 5 ++--- drivers/gpu/drm/mcde/mcde_dsi.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/mcde/mcde_display.c b/drivers/gpu/drm/mcde/mcde_display.c index e59907e68854..04e1d38d41f7 100644 --- a/drivers/gpu/drm/mcde/mcde_display.c +++ b/drivers/gpu/drm/mcde/mcde_display.c @@ -948,7 +948,7 @@ static void mcde_display_disable(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev;
- struct mcde *mcde = drm->dev_private;
struct mcde *mcde = to_mcde(drm); struct drm_pending_vblank_event *event;
drm_crtc_vblank_off(crtc);
@@ -1020,7 +1020,7 @@ static void mcde_display_update(struct drm_simple_display_pipe *pipe, { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev;
- struct mcde *mcde = drm->dev_private;
- struct mcde *mcde = to_mcde(drm); struct drm_pending_vblank_event *event = crtc->state->event; struct drm_plane *plane = &pipe->plane; struct drm_plane_state *pstate = plane->state;
@@ -1078,7 +1078,7 @@ static int mcde_display_enable_vblank(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev;
- struct mcde *mcde = drm->dev_private;
struct mcde *mcde = to_mcde(drm); u32 val;
/* Enable all VBLANK IRQs */
@@ -1097,7 +1097,7 @@ static void mcde_display_disable_vblank(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev;
- struct mcde *mcde = drm->dev_private;
struct mcde *mcde = to_mcde(drm);
/* Disable all VBLANK IRQs */ writel(0, mcde->regs + MCDE_IMSCPP);
@@ -1117,7 +1117,7 @@ static struct drm_simple_display_pipe_funcs mcde_display_funcs = {
int mcde_display_init(struct drm_device *drm) {
- struct mcde *mcde = drm->dev_private;
- struct mcde *mcde = to_mcde(drm); int ret; static const u32 formats[] = { DRM_FORMAT_ARGB8888,
diff --git a/drivers/gpu/drm/mcde/mcde_drm.h b/drivers/gpu/drm/mcde/mcde_drm.h index 80edd6628979..679c2c4e6d9d 100644 --- a/drivers/gpu/drm/mcde/mcde_drm.h +++ b/drivers/gpu/drm/mcde/mcde_drm.h @@ -34,6 +34,8 @@ struct mcde { struct regulator *vana; };
+#define to_mcde(dev) container_of(dev, struct mcde, drm)
bool mcde_dsi_irq(struct mipi_dsi_device *mdsi); void mcde_dsi_te_request(struct mipi_dsi_device *mdsi); extern struct platform_driver mcde_dsi_driver; diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index bdb525e3c5d7..84f3e2dbd77b 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -164,7 +164,7 @@ static irqreturn_t mcde_irq(int irq, void *data) static int mcde_modeset_init(struct drm_device *drm) { struct drm_mode_config *mode_config;
- struct mcde *mcde = drm->dev_private;
struct mcde *mcde = to_mcde(drm); int ret;
if (!mcde->bridge) {
@@ -311,7 +311,6 @@ static int mcde_probe(struct platform_device *pdev) if (IS_ERR(mcde)) return PTR_ERR(mcde); drm = &mcde->drm;
- drm->dev_private = mcde; mcde->dev = dev; platform_set_drvdata(pdev, drm);
@@ -486,7 +485,7 @@ static int mcde_probe(struct platform_device *pdev) static int mcde_remove(struct platform_device *pdev) { struct drm_device *drm = platform_get_drvdata(pdev);
- struct mcde *mcde = drm->dev_private;
struct mcde *mcde = to_mcde(drm);
component_master_del(&pdev->dev, &mcde_drm_comp_ops); clk_disable_unprepare(mcde->mcde_clk);
diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index 7af5ebb0c436..1baa2324cdb9 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -1020,7 +1020,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data;
- struct mcde *mcde = drm->dev_private;
- struct mcde *mcde = to_mcde(drm); struct mcde_dsi *d = dev_get_drvdata(dev); struct device_node *child; struct drm_panel *panel = NULL;
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On Fri, Apr 3, 2020 at 3:59 PM Daniel Vetter daniel.vetter@ffwll.ch wrote:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Linus Walleij linus.walleij@linaro.org
Nice, thanks! Reviewed-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Paul Cercueil paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index a9bc6623b488..bb62d8e93985 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -614,9 +614,10 @@ static int ingenic_drm_probe(struct platform_device *pdev) return -EINVAL; }
- priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_drm_dev_alloc(dev, &ingenic_drm_driver_data, + struct ingenic_drm, drm); + if (IS_ERR(priv)) + return PTR_ERR(priv);
priv->soc_info = soc_info; priv->dev = dev; @@ -625,13 +626,6 @@ static int ingenic_drm_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- ret = devm_drm_dev_init(dev, drm, &ingenic_drm_driver_data); - if (ret) { - kfree(priv); - return ret; - } - drmm_add_final_kfree(drm, priv); - ret = drmm_mode_config_init(drm); if (ret) return ret;
On Fri, Apr 03, 2020 at 03:58:18PM +0200, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Paul Cercueil paul@crapouillou.net
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/ingenic/ingenic-drm.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index a9bc6623b488..bb62d8e93985 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -614,9 +614,10 @@ static int ingenic_drm_probe(struct platform_device *pdev) return -EINVAL; }
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
return -ENOMEM;
priv = devm_drm_dev_alloc(dev, &ingenic_drm_driver_data,
struct ingenic_drm, drm);
if (IS_ERR(priv))
return PTR_ERR(priv);
priv->soc_info = soc_info; priv->dev = dev;
@@ -625,13 +626,6 @@ static int ingenic_drm_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- ret = devm_drm_dev_init(dev, drm, &ingenic_drm_driver_data);
- if (ret) {
kfree(priv);
return ret;
- }
- drmm_add_final_kfree(drm, priv);
- ret = drmm_mode_config_init(drm); if (ret) return ret;
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Entirely not used, just copypasta.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Paul Cercueil paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index bb62d8e93985..3386270cb8a3 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -622,7 +622,6 @@ static int ingenic_drm_probe(struct platform_device *pdev) priv->soc_info = soc_info; priv->dev = dev; drm = &priv->drm; - drm->dev_private = priv;
platform_set_drvdata(pdev, priv);
On Fri, Apr 03, 2020 at 03:58:19PM +0200, Daniel Vetter wrote:
Entirely not used, just copypasta.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Paul Cercueil paul@crapouillou.net
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/ingenic/ingenic-drm.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index bb62d8e93985..3386270cb8a3 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -622,7 +622,6 @@ static int ingenic_drm_probe(struct platform_device *pdev) priv->soc_info = soc_info; priv->dev = dev; drm = &priv->drm;
drm->dev_private = priv;
platform_set_drvdata(pdev, priv);
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Komeda uses the component framework, which does open/close a new devres group around all the bind callbacks. Which means we can use devm_ functions for managing the drm_device cleanup, with leaking stuff in case of deferred probes or other reasons to unbind components, or the component_master.
Also note that this fixes a double-free in the probe unroll code, bot drm_dev_put and kfree(kms) result in the kms allocation getting freed.
Aside: komeda_bind could be cleaned up a lot, devm_kfree is a bit redundant. Plus I'm not clear on why there's suballocations for mdrv->mdev and mdrv->kms. Plus I'm not sure the lifetimes are correct with all that devm_kzalloc usage ... That structure layout is also the reason why komeda still uses drm_device->dev_private and can't easily be replaced with a proper container_of upcasting. I'm pretty sure that there's endless amounts of hotunplug/hotremove bugs in there with all the unprotected dereferencing of drm_device->dev_private.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "James (Qian) Wang" james.qian.wang@arm.com Cc: Liviu Dudau liviu.dudau@arm.com Cc: Mihail Atanassov mihail.atanassov@arm.com --- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 16dfd5cdb66c..6b85d5f4caa8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -261,18 +261,16 @@ static void komeda_kms_mode_config_init(struct komeda_kms_dev *kms,
struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) { - struct komeda_kms_dev *kms = kzalloc(sizeof(*kms), GFP_KERNEL); + struct komeda_kms_dev *kms; struct drm_device *drm; int err;
- if (!kms) - return ERR_PTR(-ENOMEM); + kms = devm_drm_dev_alloc(mdev->dev, &komeda_kms_driver, + struct komeda_kms_dev, base); + if (IS_ERR(kms)) + return kms;
drm = &kms->base; - err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev); - if (err) - goto free_kms; - drmm_add_final_kfree(drm, kms);
drm->dev_private = mdev;
@@ -329,9 +327,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL; - drm_dev_put(drm); -free_kms: - kfree(kms); return ERR_PTR(err); }
@@ -348,5 +343,4 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL; - drm_dev_put(drm); }
On Fri, Apr 03, 2020 at 09:58:20PM +0800, Daniel Vetter wrote:
Komeda uses the component framework, which does open/close a new devres group around all the bind callbacks. Which means we can use devm_ functions for managing the drm_device cleanup, with leaking stuff in case of deferred probes or other reasons to unbind components, or the component_master.
Also note that this fixes a double-free in the probe unroll code, bot drm_dev_put and kfree(kms) result in the kms allocation getting freed.
Aside: komeda_bind could be cleaned up a lot, devm_kfree is a bit redundant. Plus I'm not clear on why there's suballocations for mdrv->mdev and mdrv->kms. Plus I'm not sure the lifetimes are correct with all that devm_kzalloc usage ... That structure layout is also the reason why komeda still uses drm_device->dev_private and can't easily be replaced with a proper container_of upcasting. I'm pretty sure that there's endless amounts of hotunplug/hotremove bugs in there with all the unprotected dereferencing of drm_device->dev_private.
Hi Daniel:
Thank you for the patch.
Reviewed-by: James Qian Wang james.qian.wang@arm.com
For why komeda has two devices komeda_dev and komeda_kms_dev. That because komeda treats drm_crtc/plane as virtual, which pick the real komeda resources to satify the user's requirement. In the initial driver design we want to clear the difference of these two class structures so we defined two devices:
- komeda_dev: managing the real komeda device and resources.
- komeda_kms_dev the virtual device managing the drm related stuff like komeda_crtc/plane.
And yes, even for that we don't need two sub-allocations, we are planing to move the komeda_dev into the komeda_kms_dev or just merge two devices together.
Thanks James
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "James (Qian) Wang" james.qian.wang@arm.com Cc: Liviu Dudau liviu.dudau@arm.com Cc: Mihail Atanassov mihail.atanassov@arm.com
drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 16dfd5cdb66c..6b85d5f4caa8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -261,18 +261,16 @@ static void komeda_kms_mode_config_init(struct komeda_kms_dev *kms,
struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) {
- struct komeda_kms_dev *kms = kzalloc(sizeof(*kms), GFP_KERNEL);
- struct komeda_kms_dev *kms; struct drm_device *drm; int err;
- if (!kms)
return ERR_PTR(-ENOMEM);
kms = devm_drm_dev_alloc(mdev->dev, &komeda_kms_driver,
struct komeda_kms_dev, base);
if (IS_ERR(kms))
return kms;
drm = &kms->base;
err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev);
if (err)
goto free_kms;
drmm_add_final_kfree(drm, kms);
drm->dev_private = mdev;
@@ -329,9 +327,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL;
- drm_dev_put(drm);
-free_kms:
- kfree(kms); return ERR_PTR(err);
}
@@ -348,5 +343,4 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL;
- drm_dev_put(drm);
}
2.25.1
On Wed, Apr 8, 2020 at 10:41 AM james qian wang (Arm Technology China) james.qian.wang@arm.com wrote:
On Fri, Apr 03, 2020 at 09:58:20PM +0800, Daniel Vetter wrote:
Komeda uses the component framework, which does open/close a new devres group around all the bind callbacks. Which means we can use devm_ functions for managing the drm_device cleanup, with leaking stuff in case of deferred probes or other reasons to unbind components, or the component_master.
Also note that this fixes a double-free in the probe unroll code, bot drm_dev_put and kfree(kms) result in the kms allocation getting freed.
Aside: komeda_bind could be cleaned up a lot, devm_kfree is a bit redundant. Plus I'm not clear on why there's suballocations for mdrv->mdev and mdrv->kms. Plus I'm not sure the lifetimes are correct with all that devm_kzalloc usage ... That structure layout is also the reason why komeda still uses drm_device->dev_private and can't easily be replaced with a proper container_of upcasting. I'm pretty sure that there's endless amounts of hotunplug/hotremove bugs in there with all the unprotected dereferencing of drm_device->dev_private.
Hi Daniel:
Thank you for the patch.
Reviewed-by: James Qian Wang james.qian.wang@arm.com
For why komeda has two devices komeda_dev and komeda_kms_dev. That because komeda treats drm_crtc/plane as virtual, which pick the real komeda resources to satify the user's requirement. In the initial driver design we want to clear the difference of these two class structures so we defined two devices:
komeda_dev: managing the real komeda device and resources.
komeda_kms_dev the virtual device managing the drm related stuff like komeda_crtc/plane.
And yes, even for that we don't need two sub-allocations, we are planing to move the komeda_dev into the komeda_kms_dev or just merge two devices together.
Yeah I think the logical split makes a lot of sense, e.g. amdgpu has a similar split between the drm front-end structures, and the DC back-end stuff that deals with the hardware. Same as other drivers. The issue I think I'm seeing with komeda is all the pointer chasing (not a problem, just a bit of indirection that's not strictly needed), and that when you unload the back-end disappears right away, while the front-end might still be used by userspace. And then all the pointers you have lead to oopses.
I admit that for built-in hw hotunplug isn't really a major use-case. But we do have some usb drivers nowadays in drm, so I'm trying to clean this all up a bit and make sure that as many drivers as possible have clean&correct code in this area.
Anyway if you're already planning to look into this then awesome!
Cheers, Daniel
Thanks James
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: "James (Qian) Wang" james.qian.wang@arm.com Cc: Liviu Dudau liviu.dudau@arm.com Cc: Mihail Atanassov mihail.atanassov@arm.com
drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 16dfd5cdb66c..6b85d5f4caa8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -261,18 +261,16 @@ static void komeda_kms_mode_config_init(struct komeda_kms_dev *kms,
struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) {
struct komeda_kms_dev *kms = kzalloc(sizeof(*kms), GFP_KERNEL);
struct komeda_kms_dev *kms; struct drm_device *drm; int err;
if (!kms)
return ERR_PTR(-ENOMEM);
kms = devm_drm_dev_alloc(mdev->dev, &komeda_kms_driver,
struct komeda_kms_dev, base);
if (IS_ERR(kms))
return kms; drm = &kms->base;
err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev);
if (err)
goto free_kms;
drmm_add_final_kfree(drm, kms); drm->dev_private = mdev;
@@ -329,9 +327,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL;
drm_dev_put(drm);
-free_kms:
kfree(kms); return ERR_PTR(err);
}
@@ -348,5 +343,4 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL;
drm_dev_put(drm);
}
2.25.1
Also remove the now no longer needed build bug on since that's already not needed anymore with drmm_add_final_kfree. Conversion to managed drm_device cleanup is easy, the final drm_dev_put() is already the last thing in both the bind unbind as in the unbind flow.
Also, this relies on component.c correctly wrapping bind&unbind in separate devres groups, which it does.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Russell King linux@armlinux.org.uk --- drivers/gpu/drm/armada/armada_drv.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index dd9ed71ed942..2546ff9d1c92 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -87,24 +87,13 @@ static int armada_drm_bind(struct device *dev) "armada-drm")) return -EBUSY;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - /* - * The drm_device structure must be at the start of - * armada_private for drm_dev_put() to work correctly. - */ - BUILD_BUG_ON(offsetof(struct armada_private, drm) != 0); - - ret = drm_dev_init(&priv->drm, &armada_drm_driver, dev); - if (ret) { - dev_err(dev, "[" DRM_NAME ":%s] drm_dev_init failed: %d\n", - __func__, ret); - kfree(priv); - return ret; + priv = devm_drm_dev_alloc(dev, &armada_drm_driver, + struct armada_private, drm); + if (IS_ERR(priv)) { + dev_err(dev, "[" DRM_NAME ":%s] devm_drm_dev_alloc failed: %li\n", + __func__, PTR_ERR(priv)); + return PTR_ERR(priv); } - drmm_add_final_kfree(&priv->drm, priv);
/* Remove early framebuffers */ ret = drm_fb_helper_remove_conflicting_framebuffers(NULL, @@ -174,7 +163,6 @@ static int armada_drm_bind(struct device *dev) err_kms: drm_mode_config_cleanup(&priv->drm); drm_mm_takedown(&priv->linear); - drm_dev_put(&priv->drm); return ret; }
@@ -194,8 +182,6 @@ static void armada_drm_unbind(struct device *dev)
drm_mode_config_cleanup(&priv->drm); drm_mm_takedown(&priv->linear); - - drm_dev_put(&priv->drm); }
static int compare_of(struct device *dev, void *data)
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Russell King linux@armlinux.org.uk --- drivers/gpu/drm/armada/armada_crtc.c | 4 ++-- drivers/gpu/drm/armada/armada_debugfs.c | 2 +- drivers/gpu/drm/armada/armada_drm.h | 2 ++ drivers/gpu/drm/armada/armada_drv.c | 4 +--- drivers/gpu/drm/armada/armada_fbdev.c | 4 ++-- drivers/gpu/drm/armada/armada_gem.c | 4 ++-- drivers/gpu/drm/armada/armada_overlay.c | 8 ++++---- 7 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index c2b92acd1e9a..8686e50226a5 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -757,7 +757,7 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) static void armada_drm_crtc_destroy(struct drm_crtc *crtc) { struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); - struct armada_private *priv = crtc->dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(crtc->dev);
if (dcrtc->cursor_obj) drm_gem_object_put_unlocked(&dcrtc->cursor_obj->obj); @@ -901,7 +901,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, struct resource *res, int irq, const struct armada_variant *variant, struct device_node *port) { - struct armada_private *priv = drm->dev_private; + struct armada_private *priv = drm_to_armada_dev(drm); struct armada_crtc *dcrtc; struct drm_plane *primary; void __iomem *base; diff --git a/drivers/gpu/drm/armada/armada_debugfs.c b/drivers/gpu/drm/armada/armada_debugfs.c index c6fc2f1d58e9..29f4b52e3c8d 100644 --- a/drivers/gpu/drm/armada/armada_debugfs.c +++ b/drivers/gpu/drm/armada/armada_debugfs.c @@ -19,7 +19,7 @@ static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct armada_private *priv = dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(dev); struct drm_printer p = drm_seq_file_printer(m);
mutex_lock(&priv->linear_lock); diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h index a11bdaccbb33..6a5a87932576 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h @@ -73,6 +73,8 @@ struct armada_private { #endif };
+#define drm_to_armada_dev(dev) container_of(dev, struct armada_private, drm) + int armada_fbdev_init(struct drm_device *); void armada_fbdev_fini(struct drm_device *);
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 2546ff9d1c92..2a9ee76ee585 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -106,8 +106,6 @@ static int armada_drm_bind(struct device *dev) return ret; }
- priv->drm.dev_private = priv; - dev_set_drvdata(dev, &priv->drm);
/* Mode setting support */ @@ -169,7 +167,7 @@ static int armada_drm_bind(struct device *dev) static void armada_drm_unbind(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); - struct armada_private *priv = drm->dev_private; + struct armada_private *priv = drm_to_armada_dev(drm);
drm_kms_helper_poll_fini(&priv->drm); armada_fbdev_fini(&priv->drm); diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index f2dc371bd8e5..c9a414b3a8c4 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -117,7 +117,7 @@ static const struct drm_fb_helper_funcs armada_fb_helper_funcs = {
int armada_fbdev_init(struct drm_device *dev) { - struct armada_private *priv = dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(dev); struct drm_fb_helper *fbh; int ret;
@@ -151,7 +151,7 @@ int armada_fbdev_init(struct drm_device *dev)
void armada_fbdev_fini(struct drm_device *dev) { - struct armada_private *priv = dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(dev); struct drm_fb_helper *fbh = priv->fbdev;
if (fbh) { diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 976685f2939e..2c7d5f71e715 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -39,7 +39,7 @@ static size_t roundup_gem_size(size_t size) void armada_gem_free_object(struct drm_gem_object *obj) { struct armada_gem_object *dobj = drm_to_armada_gem(obj); - struct armada_private *priv = obj->dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(obj->dev);
DRM_DEBUG_DRIVER("release obj %p\n", dobj);
@@ -77,7 +77,7 @@ void armada_gem_free_object(struct drm_gem_object *obj) int armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj) { - struct armada_private *priv = dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(dev); size_t size = obj->obj.size;
if (obj->page || obj->linear) diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 07f0da4d9ba1..30e01101f59e 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -344,7 +344,7 @@ static int armada_overlay_set_property(struct drm_plane *plane, struct drm_plane_state *state, struct drm_property *property, uint64_t val) { - struct armada_private *priv = plane->dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(plane->dev);
#define K2R(val) (((val) >> 0) & 0xff) #define K2G(val) (((val) >> 8) & 0xff) @@ -412,7 +412,7 @@ static int armada_overlay_get_property(struct drm_plane *plane, const struct drm_plane_state *state, struct drm_property *property, uint64_t *val) { - struct armada_private *priv = plane->dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(plane->dev);
#define C2K(c,s) (((c) >> (s)) & 0xff) #define R2BGR(r,g,b,s) (C2K(r,s) << 0 | C2K(g,s) << 8 | C2K(b,s) << 16) @@ -505,7 +505,7 @@ static const struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
static int armada_overlay_create_properties(struct drm_device *dev) { - struct armada_private *priv = dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(dev);
if (priv->colorkey_prop) return 0; @@ -539,7 +539,7 @@ static int armada_overlay_create_properties(struct drm_device *dev)
int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) { - struct armada_private *priv = dev->dev_private; + struct armada_private *priv = drm_to_armada_dev(dev); struct drm_mode_object *mobj; struct drm_plane *overlay; int ret;
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Sam Ravnborg sam@ravnborg.org Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Rob Herring robh@kernel.org Cc: Thomas Zimmermann tzimmermann@suse.de Cc: virtualization@lists.linux-foundation.org Cc: Emil Velikov emil.velikov@collabora.com --- drivers/gpu/drm/cirrus/cirrus.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index a36269717c3b..4b65637147ba 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -567,18 +567,13 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return ret;
ret = -ENOMEM; - cirrus = kzalloc(sizeof(*cirrus), GFP_KERNEL); - if (cirrus == NULL) - return ret; + cirrus = devm_drm_dev_alloc(&pdev->dev, &cirrus_driver, + struct cirrus_device, dev); + if (IS_ERR(cirrus)) + return PTR_ERR(cirrus);
dev = &cirrus->dev; - ret = devm_drm_dev_init(&pdev->dev, dev, &cirrus_driver); - if (ret) { - kfree(cirrus); - return ret; - } dev->dev_private = cirrus; - drmm_add_final_kfree(dev, cirrus);
cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
Den 03.04.2020 15.58, skrev Daniel Vetter:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Sam Ravnborg sam@ravnborg.org Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Rob Herring robh@kernel.org Cc: Thomas Zimmermann tzimmermann@suse.de Cc: virtualization@lists.linux-foundation.org Cc: Emil Velikov emil.velikov@collabora.com
Acked-by: Noralf Trønnes noralf@tronnes.org
On Fri, Apr 03, 2020 at 03:58:23PM +0200, Daniel Vetter wrote:
Already using devm_drm_dev_init, so very simple replacment.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Sam Ravnborg sam@ravnborg.org Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Rob Herring robh@kernel.org Cc: Thomas Zimmermann tzimmermann@suse.de Cc: virtualization@lists.linux-foundation.org Cc: Emil Velikov emil.velikov@collabora.com
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/cirrus/cirrus.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index a36269717c3b..4b65637147ba 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -567,18 +567,13 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return ret;
ret = -ENOMEM;
- cirrus = kzalloc(sizeof(*cirrus), GFP_KERNEL);
- if (cirrus == NULL)
return ret;
cirrus = devm_drm_dev_alloc(&pdev->dev, &cirrus_driver,
struct cirrus_device, dev);
if (IS_ERR(cirrus))
return PTR_ERR(cirrus);
dev = &cirrus->dev;
ret = devm_drm_dev_init(&pdev->dev, dev, &cirrus_driver);
if (ret) {
kfree(cirrus);
return ret;
} dev->dev_private = cirrus;
drmm_add_final_kfree(dev, cirrus);
cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Eric Anholt eric@anholt.net Cc: Thomas Zimmermann tzimmermann@suse.de Cc: virtualization@lists.linux-foundation.org --- drivers/gpu/drm/cirrus/cirrus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index 4b65637147ba..744a8e337e41 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -59,6 +59,8 @@ struct cirrus_device { void __iomem *mmio; };
+#define to_cirrus(_dev) container_of(_dev, struct cirrus_device, dev) + /* ------------------------------------------------------------------ */ /* * The meat of this driver. The core passes us a mode and we have to program @@ -311,7 +313,7 @@ static int cirrus_mode_set(struct cirrus_device *cirrus, static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, struct drm_rect *rect) { - struct cirrus_device *cirrus = fb->dev->dev_private; + struct cirrus_device *cirrus = to_cirrus(fb->dev); void *vmap; int idx, ret;
@@ -436,7 +438,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) { - struct cirrus_device *cirrus = pipe->crtc.dev->dev_private; + struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev);
cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); cirrus_fb_blit_fullscreen(plane_state->fb); @@ -445,7 +447,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) { - struct cirrus_device *cirrus = pipe->crtc.dev->dev_private; + struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); struct drm_plane_state *state = pipe->plane.state; struct drm_crtc *crtc = &pipe->crtc; struct drm_rect rect; @@ -573,7 +575,6 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return PTR_ERR(cirrus);
dev = &cirrus->dev; - dev->dev_private = cirrus;
cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
On Fri, Apr 3, 2020 at 6:59 AM Daniel Vetter daniel.vetter@ffwll.ch wrote:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Sam Ravnborg sam@ravnborg.org
Acked-by: Eric Anholt eric@anholt.net
Am 03.04.20 um 15:58 schrieb Daniel Vetter:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Eric Anholt eric@anholt.net Cc: Thomas Zimmermann tzimmermann@suse.de Cc: virtualization@lists.linux-foundation.org
drivers/gpu/drm/cirrus/cirrus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index 4b65637147ba..744a8e337e41 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -59,6 +59,8 @@ struct cirrus_device { void __iomem *mmio; };
+#define to_cirrus(_dev) container_of(_dev, struct cirrus_device, dev)
Maybe to_cirrus_device() ? I had the same comment for vbox and I think it applies to all patches.
Best regards Thomas
/* ------------------------------------------------------------------ */ /*
- The meat of this driver. The core passes us a mode and we have to program
@@ -311,7 +313,7 @@ static int cirrus_mode_set(struct cirrus_device *cirrus, static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, struct drm_rect *rect) {
- struct cirrus_device *cirrus = fb->dev->dev_private;
- struct cirrus_device *cirrus = to_cirrus(fb->dev); void *vmap; int idx, ret;
@@ -436,7 +438,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) {
- struct cirrus_device *cirrus = pipe->crtc.dev->dev_private;
struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev);
cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); cirrus_fb_blit_fullscreen(plane_state->fb);
@@ -445,7 +447,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) {
- struct cirrus_device *cirrus = pipe->crtc.dev->dev_private;
- struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); struct drm_plane_state *state = pipe->plane.state; struct drm_crtc *crtc = &pipe->crtc; struct drm_rect rect;
@@ -573,7 +575,6 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return PTR_ERR(cirrus);
dev = &cirrus->dev;
dev->dev_private = cirrus;
cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
Hi Thomas.
On Mon, Apr 06, 2020 at 01:58:54PM +0200, Thomas Zimmermann wrote:
Am 03.04.20 um 15:58 schrieb Daniel Vetter:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Eric Anholt eric@anholt.net Cc: Thomas Zimmermann tzimmermann@suse.de Cc: virtualization@lists.linux-foundation.org
drivers/gpu/drm/cirrus/cirrus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index 4b65637147ba..744a8e337e41 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -59,6 +59,8 @@ struct cirrus_device { void __iomem *mmio; };
+#define to_cirrus(_dev) container_of(_dev, struct cirrus_device, dev)
Maybe to_cirrus_device() ? I had the same comment for vbox and I think it applies to all patches.
The variable name is consistently using the name "cirrus" - so my personal preference is to_cirrus().
Also IMO struct cirrus_device is misnamed. It is more than a device.
Sam
Best regards Thomas
/* ------------------------------------------------------------------ */ /*
- The meat of this driver. The core passes us a mode and we have to program
@@ -311,7 +313,7 @@ static int cirrus_mode_set(struct cirrus_device *cirrus, static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, struct drm_rect *rect) {
- struct cirrus_device *cirrus = fb->dev->dev_private;
- struct cirrus_device *cirrus = to_cirrus(fb->dev); void *vmap; int idx, ret;
@@ -436,7 +438,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) {
- struct cirrus_device *cirrus = pipe->crtc.dev->dev_private;
struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev);
cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); cirrus_fb_blit_fullscreen(plane_state->fb);
@@ -445,7 +447,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) {
- struct cirrus_device *cirrus = pipe->crtc.dev->dev_private;
- struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); struct drm_plane_state *state = pipe->plane.state; struct drm_crtc *crtc = &pipe->crtc; struct drm_rect rect;
@@ -573,7 +575,6 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return PTR_ERR(cirrus);
dev = &cirrus->dev;
dev->dev_private = cirrus;
cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On Fri, Apr 03, 2020 at 03:58:24PM +0200, Daniel Vetter wrote:
Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Dave Airlie airlied@redhat.com Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: "Noralf Trønnes" noralf@tronnes.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Eric Anholt eric@anholt.net Cc: Thomas Zimmermann tzimmermann@suse.de Cc: virtualization@lists.linux-foundation.org
Acked-by: Sam Ravnborg sam@ravnborg.org
drivers/gpu/drm/cirrus/cirrus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index 4b65637147ba..744a8e337e41 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -59,6 +59,8 @@ struct cirrus_device { void __iomem *mmio; };
+#define to_cirrus(_dev) container_of(_dev, struct cirrus_device, dev)
/* ------------------------------------------------------------------ */ /*
- The meat of this driver. The core passes us a mode and we have to program
@@ -311,7 +313,7 @@ static int cirrus_mode_set(struct cirrus_device *cirrus, static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, struct drm_rect *rect) {
- struct cirrus_device *cirrus = fb->dev->dev_private;
- struct cirrus_device *cirrus = to_cirrus(fb->dev); void *vmap; int idx, ret;
@@ -436,7 +438,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) {
- struct cirrus_device *cirrus = pipe->crtc.dev->dev_private;
struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev);
cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); cirrus_fb_blit_fullscreen(plane_state->fb);
@@ -445,7 +447,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) {
- struct cirrus_device *cirrus = pipe->crtc.dev->dev_private;
- struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); struct drm_plane_state *state = pipe->plane.state; struct drm_crtc *crtc = &pipe->crtc; struct drm_rect rect;
@@ -573,7 +575,6 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return PTR_ERR(cirrus);
dev = &cirrus->dev;
dev->dev_private = cirrus;
cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-- 2.25.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Luckily we're already well set up in the main driver, with drm_dev_put() being the last thing in both the unload error case and the pci remove function.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 17 ++++------------- drivers/gpu/drm/i915/i915_pci.c | 2 -- 2 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a7a3b4b98572..9c0ff25c5d41 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -879,19 +879,11 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) (struct intel_device_info *)ent->driver_data; struct intel_device_info *device_info; struct drm_i915_private *i915; - int err;
- i915 = kzalloc(sizeof(*i915), GFP_KERNEL); - if (!i915) - return ERR_PTR(-ENOMEM); - - err = drm_dev_init(&i915->drm, &driver, &pdev->dev); - if (err) { - kfree(i915); - return ERR_PTR(err); - } - - drmm_add_final_kfree(&i915->drm, i915); + i915 = devm_drm_dev_alloc(&pdev->dev, &driver, + struct drm_i915_private, drm); + if (IS_ERR(i915)) + return i915;
i915->drm.pdev = pdev; pci_set_drvdata(pdev, i915); @@ -1008,7 +1000,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_disable_device(pdev); out_fini: i915_probe_error(i915, "Device initialization failed (%d)\n", ret); - drm_dev_put(&i915->drm); return ret; }
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 2c80a0194c80..0f8b439d6fd5 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -920,8 +920,6 @@ static void i915_pci_remove(struct pci_dev *pdev)
i915_driver_remove(i915); pci_set_drvdata(pdev, NULL); - - drm_dev_put(&i915->drm); }
/* is device_id present in comma separated list of ids */
Just some prep work before we rework the lifetime handling, which requires replacing all the drm_dev_put in selftests by something else.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c | 2 +- drivers/gpu/drm/i915/gt/selftest_timeline.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 2 +- drivers/gpu/drm/i915/selftests/i915_request.c | 2 +- drivers/gpu/drm/i915/selftests/i915_vma.c | 2 +- drivers/gpu/drm/i915/selftests/intel_memory_region.c | 2 +- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 2 +- drivers/gpu/drm/i915/selftests/mock_gem_device.h | 5 +++++ 13 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 2d0fd50c5312..d19bb011fc6b 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1789,7 +1789,7 @@ int i915_gem_huge_page_mock_selftests(void) i915_vm_put(&ppgtt->vm);
out_unlock: - drm_dev_put(&dev_priv->drm); + mock_destroy_device(dev_priv); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index f4f933240b39..d9d96d23e37e 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -1986,7 +1986,7 @@ int i915_gem_context_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c index 2a52b92586b9..0845ce1ae37c 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c @@ -272,7 +272,7 @@ int i915_gem_dmabuf_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c index 2b6db6f799de..085644edebfc 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c @@ -85,7 +85,7 @@ int i915_gem_object_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c index 34932871b3a5..2a9709eb5a42 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c @@ -73,6 +73,6 @@ int i915_gem_phys_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; } diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c index c2578a0f2f14..1c0865227714 100644 --- a/drivers/gpu/drm/i915/gt/selftest_timeline.c +++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c @@ -157,7 +157,7 @@ static int mock_hwsp_freelist(void *arg) __mock_hwsp_record(&state, na, NULL); kfree(state.history); err_put: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index 028baae9631f..f88473d396f4 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -536,7 +536,7 @@ int i915_gem_evict_mock_selftests(void) with_intel_runtime_pm(&i915->runtime_pm, wakeref) err = i915_subtests(tests, &i915->gt);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 5d2a02fcf595..035e4f77f06f 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -1714,7 +1714,7 @@ int i915_gem_gtt_mock_selftests(void) mock_fini_ggtt(ggtt); kfree(ggtt); out_put: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index 1dab0360f76a..6bc6a2fc83ab 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -521,7 +521,7 @@ int i915_request_mock_selftests(void) with_intel_runtime_pm(&i915->runtime_pm, wakeref) err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915);
return err; } diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index 58b5f40a07dd..7d51cc2da36f 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c @@ -841,7 +841,7 @@ int i915_vma_mock_selftests(void) mock_fini_ggtt(ggtt); kfree(ggtt); out_put: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 6e80d99048e4..5226767d5384 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -791,7 +791,7 @@ int intel_memory_region_mock_selftests(void)
intel_memory_region_put(mem); out_unref: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 9b105b811f1f..03607647cdeb 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -214,7 +214,7 @@ struct drm_i915_private *mock_gem_device(void) intel_gt_driver_late_release(&i915->gt); intel_memory_regions_driver_release(i915); drm_mode_config_cleanup(&i915->drm); - drm_dev_put(&i915->drm); + mock_destroy_device(i915);
return NULL; } diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.h b/drivers/gpu/drm/i915/selftests/mock_gem_device.h index b5dc4e394555..2e3c7585a7bb 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.h +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.h @@ -7,4 +7,9 @@ struct drm_i915_private; struct drm_i915_private *mock_gem_device(void); void mock_device_flush(struct drm_i915_private *i915);
+static inline void mock_destroy_device(struct drm_i915_private *i915) +{ + drm_dev_put(&i915->drm); +} + #endif /* !__MOCK_GEM_DEVICE_H__ */
Just some prep work before we rework the lifetime handling, which requires replacing all the drm_dev_put in selftests by something else.
v2: Don't go with a static inline, upsets the header tests and separation.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c | 2 +- drivers/gpu/drm/i915/gt/selftest_timeline.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 2 +- drivers/gpu/drm/i915/selftests/i915_request.c | 2 +- drivers/gpu/drm/i915/selftests/i915_vma.c | 2 +- drivers/gpu/drm/i915/selftests/intel_memory_region.c | 2 +- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 7 ++++++- drivers/gpu/drm/i915/selftests/mock_gem_device.h | 2 ++ 13 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 2d0fd50c5312..d19bb011fc6b 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1789,7 +1789,7 @@ int i915_gem_huge_page_mock_selftests(void) i915_vm_put(&ppgtt->vm);
out_unlock: - drm_dev_put(&dev_priv->drm); + mock_destroy_device(dev_priv); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index f4f933240b39..d9d96d23e37e 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -1986,7 +1986,7 @@ int i915_gem_context_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c index 2a52b92586b9..0845ce1ae37c 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c @@ -272,7 +272,7 @@ int i915_gem_dmabuf_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c index 2b6db6f799de..085644edebfc 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c @@ -85,7 +85,7 @@ int i915_gem_object_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c index 34932871b3a5..2a9709eb5a42 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c @@ -73,6 +73,6 @@ int i915_gem_phys_mock_selftests(void)
err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; } diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c index c2578a0f2f14..1c0865227714 100644 --- a/drivers/gpu/drm/i915/gt/selftest_timeline.c +++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c @@ -157,7 +157,7 @@ static int mock_hwsp_freelist(void *arg) __mock_hwsp_record(&state, na, NULL); kfree(state.history); err_put: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index 028baae9631f..f88473d396f4 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -536,7 +536,7 @@ int i915_gem_evict_mock_selftests(void) with_intel_runtime_pm(&i915->runtime_pm, wakeref) err = i915_subtests(tests, &i915->gt);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 5d2a02fcf595..035e4f77f06f 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -1714,7 +1714,7 @@ int i915_gem_gtt_mock_selftests(void) mock_fini_ggtt(ggtt); kfree(ggtt); out_put: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index 1dab0360f76a..6bc6a2fc83ab 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -521,7 +521,7 @@ int i915_request_mock_selftests(void) with_intel_runtime_pm(&i915->runtime_pm, wakeref) err = i915_subtests(tests, i915);
- drm_dev_put(&i915->drm); + mock_destroy_device(i915);
return err; } diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index 58b5f40a07dd..7d51cc2da36f 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c @@ -841,7 +841,7 @@ int i915_vma_mock_selftests(void) mock_fini_ggtt(ggtt); kfree(ggtt); out_put: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 6e80d99048e4..5226767d5384 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -791,7 +791,7 @@ int intel_memory_region_mock_selftests(void)
intel_memory_region_put(mem); out_unref: - drm_dev_put(&i915->drm); + mock_destroy_device(i915); return err; }
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 9b105b811f1f..41afc357f4d0 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -214,7 +214,12 @@ struct drm_i915_private *mock_gem_device(void) intel_gt_driver_late_release(&i915->gt); intel_memory_regions_driver_release(i915); drm_mode_config_cleanup(&i915->drm); - drm_dev_put(&i915->drm); + mock_destroy_device(i915);
return NULL; } + +void mock_destroy_device(struct drm_i915_private *i915) +{ + drm_dev_put(&i915->drm); +} diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.h b/drivers/gpu/drm/i915/selftests/mock_gem_device.h index b5dc4e394555..953cfe4fab34 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.h +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.h @@ -7,4 +7,6 @@ struct drm_i915_private; struct drm_i915_private *mock_gem_device(void); void mock_device_flush(struct drm_i915_private *i915);
+void mock_destroy_device(struct drm_i915_private *i915); + #endif /* !__MOCK_GEM_DEVICE_H__ */
The big change is device_add so that device_del can auto-cleanup devres resources. This allows us to use devm_drm_dev_alloc, which removes the last user of drm_dev_init.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- .../gpu/drm/i915/selftests/mock_gem_device.c | 31 +++++++++---------- .../gpu/drm/i915/selftests/mock_gem_device.h | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 03607647cdeb..ea73d1f7cf12 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -123,12 +123,6 @@ struct drm_i915_private *mock_gem_device(void) pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); if (!pdev) return NULL; - i915 = kzalloc(sizeof(*i915), GFP_KERNEL); - if (!i915) { - kfree(pdev); - return NULL; - } - device_initialize(&pdev->dev); pdev->class = PCI_BASE_CLASS_DISPLAY << 16; pdev->dev.release = release_dev; @@ -139,8 +133,23 @@ struct drm_i915_private *mock_gem_device(void) /* hack to disable iommu for the fake device; force identity mapping */ pdev->dev.archdata.iommu = (void *)-1; #endif + err = device_add(&pdev->dev); + if (err) { + kfree(pdev); + return NULL; + } + + i915 = devm_drm_dev_alloc(&pdev->dev, &mock_driver, + struct drm_i915_private, drm); + if (err) { + pr_err("Failed to allocate mock GEM device: err=%d\n", err); + put_device(&pdev->dev); + + return NULL; + }
pci_set_drvdata(pdev, i915); + i915->drm.pdev = pdev;
dev_pm_domain_set(&pdev->dev, &pm_domain); pm_runtime_enable(&pdev->dev); @@ -148,16 +157,6 @@ struct drm_i915_private *mock_gem_device(void) if (pm_runtime_enabled(&pdev->dev)) WARN_ON(pm_runtime_get_sync(&pdev->dev));
- err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev); - if (err) { - pr_err("Failed to initialise mock GEM device: err=%d\n", err); - put_device(&pdev->dev); - kfree(i915); - - return NULL; - } - i915->drm.pdev = pdev; - drmm_add_final_kfree(&i915->drm, i915);
intel_runtime_pm_init_early(&i915->runtime_pm);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.h b/drivers/gpu/drm/i915/selftests/mock_gem_device.h index 2e3c7585a7bb..4f309a05c85a 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.h +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.h @@ -9,7 +9,7 @@ void mock_device_flush(struct drm_i915_private *i915);
static inline void mock_destroy_device(struct drm_i915_private *i915) { - drm_dev_put(&i915->drm); + device_del(i915->drm.dev); }
#endif /* !__MOCK_GEM_DEVICE_H__ */
The big change is device_add so that device_del can auto-cleanup devres resources. This allows us to use devm_drm_dev_alloc, which removes the last user of drm_dev_init.
v2: Rebased
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- .../gpu/drm/i915/selftests/mock_gem_device.c | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 41afc357f4d0..1ab97fa55929 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -123,12 +123,6 @@ struct drm_i915_private *mock_gem_device(void) pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); if (!pdev) return NULL; - i915 = kzalloc(sizeof(*i915), GFP_KERNEL); - if (!i915) { - kfree(pdev); - return NULL; - } - device_initialize(&pdev->dev); pdev->class = PCI_BASE_CLASS_DISPLAY << 16; pdev->dev.release = release_dev; @@ -139,8 +133,23 @@ struct drm_i915_private *mock_gem_device(void) /* hack to disable iommu for the fake device; force identity mapping */ pdev->dev.archdata.iommu = (void *)-1; #endif + err = device_add(&pdev->dev); + if (err) { + kfree(pdev); + return NULL; + } + + i915 = devm_drm_dev_alloc(&pdev->dev, &mock_driver, + struct drm_i915_private, drm); + if (err) { + pr_err("Failed to allocate mock GEM device: err=%d\n", err); + put_device(&pdev->dev); + + return NULL; + }
pci_set_drvdata(pdev, i915); + i915->drm.pdev = pdev;
dev_pm_domain_set(&pdev->dev, &pm_domain); pm_runtime_enable(&pdev->dev); @@ -148,16 +157,6 @@ struct drm_i915_private *mock_gem_device(void) if (pm_runtime_enabled(&pdev->dev)) WARN_ON(pm_runtime_get_sync(&pdev->dev));
- err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev); - if (err) { - pr_err("Failed to initialise mock GEM device: err=%d\n", err); - put_device(&pdev->dev); - kfree(i915); - - return NULL; - } - i915->drm.pdev = pdev; - drmm_add_final_kfree(&i915->drm, i915);
intel_runtime_pm_init_early(&i915->runtime_pm);
@@ -221,5 +220,5 @@ struct drm_i915_private *mock_gem_device(void)
void mock_destroy_device(struct drm_i915_private *i915) { - drm_dev_put(&i915->drm); + device_del(i915->drm.dev); }
Following functions are only used internally, not by drivers: - drm_dev_init - devm_drm_dev_init - drmm_add_final_kfree
Also, now that we have a very slick and polished way to allocate a drm_device with devm_drm_dev_alloc, update all the docs to reflect the new reality. Mostly this consists of deleting old and misleading hints. Two main ones:
- it is no longer required that the drm_device base class is first in the structure. devm_drm_dev_alloc can cope with it being anywhere
- obviously embedded no needs devm_drm_dev_alloc
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- .../driver-api/driver-model/devres.rst | 2 +- drivers/gpu/drm/drm_drv.c | 119 ++++-------------- drivers/gpu/drm/drm_internal.h | 1 + drivers/gpu/drm/drm_managed.c | 15 +-- include/drm/drm_device.h | 2 +- include/drm/drm_drv.h | 20 +-- 6 files changed, 34 insertions(+), 125 deletions(-)
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 46c13780994c..74a4a3fa8c52 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -263,7 +263,7 @@ DMA dmam_pool_destroy()
DRM - devm_drm_dev_init() + devm_drm_dev_alloc()
GPIO devm_gpiod_get() diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 9e60b784b3ac..64e20c630aa7 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -240,13 +240,13 @@ void drm_minor_release(struct drm_minor *minor) * DOC: driver instance overview * * A device instance for a drm driver is represented by &struct drm_device. This - * is initialized with drm_dev_init(), usually from bus-specific ->probe() - * callbacks implemented by the driver. The driver then needs to initialize all - * the various subsystems for the drm device like memory management, vblank - * handling, modesetting support and intial output configuration plus obviously - * initialize all the corresponding hardware bits. Finally when everything is up - * and running and ready for userspace the device instance can be published - * using drm_dev_register(). + * is allocated and initialized with devm_drm_dev_alloc(), usually from + * bus-specific ->probe() callbacks implemented by the driver. The driver then + * needs to initialize all the various subsystems for the drm device like memory + * management, vblank handling, modesetting support and intial output + * configuration plus obviously initialize all the corresponding hardware bits. + * Finally when everything is up and running and ready for userspace the device + * instance can be published using drm_dev_register(). * * There is also deprecated support for initalizing device instances using * bus-specific helpers and the &drm_driver.load callback. But due to @@ -274,7 +274,7 @@ void drm_minor_release(struct drm_minor *minor) * * The following example shows a typical structure of a DRM display driver. * The example focus on the probe() function and the other functions that is - * almost always present and serves as a demonstration of devm_drm_dev_init(). + * almost always present and serves as a demonstration of devm_drm_dev_alloc(). * * .. code-block:: c * @@ -294,22 +294,12 @@ void drm_minor_release(struct drm_minor *minor) * struct drm_device *drm; * int ret; * - * // devm_kzalloc() can't be used here because the drm_device ' - * // lifetime can exceed the device lifetime if driver unbind - * // happens when userspace still has open file descriptors. - * priv = kzalloc(sizeof(*priv), GFP_KERNEL); - * if (!priv) - * return -ENOMEM; - * + * priv = devm_drm_dev_alloc(&pdev->dev, &driver_drm_driver, + * struct driver_device, drm); + * if (IS_ERR(priv)) + * return PTR_ERR(priv); * drm = &priv->drm; * - * ret = devm_drm_dev_init(&pdev->dev, drm, &driver_drm_driver); - * if (ret) { - * kfree(priv); - * return ret; - * } - * drmm_add_final_kfree(drm, priv); - * * ret = drmm_mode_config_init(drm); * if (ret) * return ret; @@ -550,9 +540,9 @@ static void drm_fs_inode_free(struct inode *inode) * following guidelines apply: * * - The entire device initialization procedure should be run from the - * &component_master_ops.master_bind callback, starting with drm_dev_init(), - * then binding all components with component_bind_all() and finishing with - * drm_dev_register(). + * &component_master_ops.master_bind callback, starting with + * devm_drm_dev_alloc(), then binding all components with + * component_bind_all() and finishing with drm_dev_register(). * * - The opaque pointer passed to all components through component_bind_all() * should point at &struct drm_device of the device instance, not some driver @@ -583,43 +573,9 @@ static void drm_dev_init_release(struct drm_device *dev, void *res) drm_legacy_destroy_members(dev); }
-/** - * drm_dev_init - Initialise new DRM device - * @dev: DRM device - * @driver: DRM driver - * @parent: Parent device object - * - * Initialize a new DRM device. No device registration is done. - * Call drm_dev_register() to advertice the device to user space and register it - * with other core subsystems. This should be done last in the device - * initialization sequence to make sure userspace can't access an inconsistent - * state. - * - * The initial ref-count of the object is 1. Use drm_dev_get() and - * drm_dev_put() to take and drop further ref-counts. - * - * It is recommended that drivers embed &struct drm_device into their own device - * structure. - * - * Drivers that do not want to allocate their own device struct - * embedding &struct drm_device can call drm_dev_alloc() instead. For drivers - * that do embed &struct drm_device it must be placed first in the overall - * structure, and the overall structure must be allocated using kmalloc(): The - * drm core's release function unconditionally calls kfree() on the @dev pointer - * when the final reference is released. To override this behaviour, and so - * allow embedding of the drm_device inside the driver's device struct at an - * arbitrary offset, you must supply a &drm_driver.release callback and control - * the finalization explicitly. - * - * Note that drivers must call drmm_add_final_kfree() after this function has - * completed successfully. - * - * RETURNS: - * 0 on success, or error code on failure. - */ -int drm_dev_init(struct drm_device *dev, - struct drm_driver *driver, - struct device *parent) +static int drm_dev_init(struct drm_device *dev, + struct drm_driver *driver, + struct device *parent) { int ret;
@@ -699,31 +655,15 @@ int drm_dev_init(struct drm_device *dev,
return ret; } -EXPORT_SYMBOL(drm_dev_init);
static void devm_drm_dev_init_release(void *data) { drm_dev_put(data); }
-/** - * devm_drm_dev_init - Resource managed drm_dev_init() - * @parent: Parent device object - * @dev: DRM device - * @driver: DRM driver - * - * Managed drm_dev_init(). The DRM device initialized with this function is - * automatically put on driver detach using drm_dev_put(). - * - * Note that drivers must call drmm_add_final_kfree() after this function has - * completed successfully. - * - * RETURNS: - * 0 on success, or error code on failure. - */ -int devm_drm_dev_init(struct device *parent, - struct drm_device *dev, - struct drm_driver *driver) +static int devm_drm_dev_init(struct device *parent, + struct drm_device *dev, + struct drm_driver *driver) { int ret;
@@ -737,7 +677,6 @@ int devm_drm_dev_init(struct device *parent,
return ret; } -EXPORT_SYMBOL(devm_drm_dev_init);
void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, size_t size, size_t offset) @@ -767,19 +706,9 @@ EXPORT_SYMBOL(__devm_drm_dev_alloc); * @driver: DRM driver to allocate device for * @parent: Parent device object * - * Allocate and initialize a new DRM device. No device registration is done. - * Call drm_dev_register() to advertice the device to user space and register it - * with other core subsystems. This should be done last in the device - * initialization sequence to make sure userspace can't access an inconsistent - * state. - * - * The initial ref-count of the object is 1. Use drm_dev_get() and - * drm_dev_put() to take and drop further ref-counts. - * - * Note that for purely virtual devices @parent can be NULL. - * - * Drivers that wish to subclass or embed &struct drm_device into their - * own struct should look at using drm_dev_init() instead. + * This is the deprecated version of devm_drm_dev_alloc(), which doesn not support + * subclassing through embedding the struct &drm_device in a driver private + * structure, and which does not support automatic cleanup through devres. * * RETURNS: * Pointer to new DRM device, or ERR_PTR on failure. diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 2470a352730b..79f11d3c525e 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -91,6 +91,7 @@ void drm_minor_release(struct drm_minor *minor);
/* drm_managed.c */ void drm_managed_release(struct drm_device *dev); +void drmm_add_final_kfree(struct drm_device *dev, void *container);
/* drm_vblank.c */ void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe); diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c index 9cebfe370a65..a2a0c5b7ab78 100644 --- a/drivers/gpu/drm/drm_managed.c +++ b/drivers/gpu/drm/drm_managed.c @@ -25,7 +25,7 @@ * be done directly with drmm_kmalloc() and the related functions. Everything * will be released on the final drm_dev_put() in reverse order of how the * release actions have been added and memory has been allocated since driver - * loading started with drm_dev_init(). + * loading started with devm_drm_dev_alloc(). * * Note that release actions and managed memory can also be added and removed * during the lifetime of the driver, all the functions are fully concurrent @@ -123,18 +123,6 @@ static void add_dr(struct drm_device *dev, struct drmres *dr) dr, dr->node.name, (unsigned long) dr->node.size); }
-/** - * drmm_add_final_kfree - add release action for the final kfree() - * @dev: DRM device - * @container: pointer to the kmalloc allocation containing @dev - * - * Since the allocation containing the struct &drm_device must be allocated - * before it can be initialized with drm_dev_init() there's no way to allocate - * that memory with drmm_kmalloc(). To side-step this chicken-egg problem the - * pointer for this final kfree() must be specified by calling this function. It - * will be released in the final drm_dev_put() for @dev, after all other release - * actions installed through drmm_add_action() have been processed. - */ void drmm_add_final_kfree(struct drm_device *dev, void *container) { WARN_ON(dev->managed.final_kfree); @@ -142,7 +130,6 @@ void drmm_add_final_kfree(struct drm_device *dev, void *container) WARN_ON(dev + 1 > (struct drm_device *) (container + ksize(container))); dev->managed.final_kfree = container; } -EXPORT_SYMBOL(drmm_add_final_kfree);
int __drmm_add_action(struct drm_device *dev, drmres_release_t action, diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index a55874db9dd4..ee9e20ce9b85 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -92,7 +92,7 @@ struct drm_device { * NULL. * * Instead of using this pointer it is recommended that drivers use - * drm_dev_init() and embed struct &drm_device in their larger + * devm_drm_dev_alloc() and embed struct &drm_device in their larger * per-device structure. */ void *dev_private; diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 26776be5a21e..2806cc5eae3a 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -163,13 +163,12 @@ struct drm_driver { /** * @load: * - * Backward-compatible driver callback to complete - * initialization steps after the driver is registered. For - * this reason, may suffer from race conditions and its use is - * deprecated for new drivers. It is therefore only supported - * for existing drivers not yet converted to the new scheme. - * See drm_dev_init() and drm_dev_register() for proper and - * race-free way to set up a &struct drm_device. + * Backward-compatible driver callback to complete initialization steps + * after the driver is registered. For this reason, may suffer from + * race conditions and its use is deprecated for new drivers. It is + * therefore only supported for existing drivers not yet converted to + * the new scheme. See devm_drm_dev_alloc() and drm_dev_register() for + * proper and race-free way to set up a &struct drm_device. * * This is deprecated, do not use! * @@ -619,13 +618,6 @@ struct drm_driver { int dev_priv_size; };
-int drm_dev_init(struct drm_device *dev, - struct drm_driver *driver, - struct device *parent); -int devm_drm_dev_init(struct device *parent, - struct drm_device *dev, - struct drm_driver *driver); - void* __devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, size_t size, size_t offset);
Den 03.04.2020 15.58, skrev Daniel Vetter:
Following functions are only used internally, not by drivers:
- drm_dev_init
- devm_drm_dev_init
- drmm_add_final_kfree
Also, now that we have a very slick and polished way to allocate a drm_device with devm_drm_dev_alloc, update all the docs to reflect the new reality. Mostly this consists of deleting old and misleading hints. Two main ones:
it is no longer required that the drm_device base class is first in the structure. devm_drm_dev_alloc can cope with it being anywhere
obviously embedded no needs devm_drm_dev_alloc
s/no/now/ ?
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
<snip>
@@ -240,13 +240,13 @@ void drm_minor_release(struct drm_minor *minor)
- DOC: driver instance overview
- A device instance for a drm driver is represented by &struct drm_device. This
- is initialized with drm_dev_init(), usually from bus-specific ->probe()
- callbacks implemented by the driver. The driver then needs to initialize all
- the various subsystems for the drm device like memory management, vblank
- handling, modesetting support and intial output configuration plus obviously
- initialize all the corresponding hardware bits. Finally when everything is up
- and running and ready for userspace the device instance can be published
- using drm_dev_register().
- is allocated and initialized with devm_drm_dev_alloc(), usually from
- bus-specific ->probe() callbacks implemented by the driver. The driver then
- needs to initialize all the various subsystems for the drm device like memory
- management, vblank handling, modesetting support and intial output
s/intial/initial/
- configuration plus obviously initialize all the corresponding hardware bits.
- Finally when everything is up and running and ready for userspace the device
- instance can be published using drm_dev_register().
- There is also deprecated support for initalizing device instances using
- bus-specific helpers and the &drm_driver.load callback. But due to
<snip>
@@ -767,19 +706,9 @@ EXPORT_SYMBOL(__devm_drm_dev_alloc);
- @driver: DRM driver to allocate device for
- @parent: Parent device object
- Allocate and initialize a new DRM device. No device registration is done.
- Call drm_dev_register() to advertice the device to user space and register it
- with other core subsystems. This should be done last in the device
- initialization sequence to make sure userspace can't access an inconsistent
- state.
- The initial ref-count of the object is 1. Use drm_dev_get() and
- drm_dev_put() to take and drop further ref-counts.
- Note that for purely virtual devices @parent can be NULL.
- Drivers that wish to subclass or embed &struct drm_device into their
- own struct should look at using drm_dev_init() instead.
- This is the deprecated version of devm_drm_dev_alloc(), which doesn not support
s/doesn/does/
- subclassing through embedding the struct &drm_device in a driver private
- structure, and which does not support automatic cleanup through devres.
- RETURNS:
- Pointer to new DRM device, or ERR_PTR on failure.
Acked-by: Noralf Trønnes noralf@tronnes.org
Hi Daniel.
Made specific reply to several patches.
This bunch:
drm/st7735r: Use devm_drm_dev_alloc drm/st7586: Use devm_drm_dev_alloc drm/repaper: Use devm_drm_dev_alloc drm/mi0283qt: Use devm_drm_dev_alloc drm/ili9486: Use devm_drm_dev_alloc drm/ili9341: Use devm_drm_dev_alloc drm/ili9225: Use devm_drm_dev_alloc drm/hx8357d: Use devm_drm_dev_alloc drm/gm12u320: Use devm_drm_dev_alloc drm/gm12u320: Don't use drm_device->dev_private
are all: Acked-by: Sam Ravnborg sam@ravnborg.org
I will take a look at patch 44 later today. I steered away from the vgem, i915 stuff on purpose. I leave that to more competent persons.
Sam
On Wed, Apr 08, 2020 at 10:08:17AM +0200, Sam Ravnborg wrote:
Hi Daniel.
Made specific reply to several patches.
This bunch:
drm/st7735r: Use devm_drm_dev_alloc drm/st7586: Use devm_drm_dev_alloc drm/repaper: Use devm_drm_dev_alloc drm/mi0283qt: Use devm_drm_dev_alloc drm/ili9486: Use devm_drm_dev_alloc drm/ili9341: Use devm_drm_dev_alloc drm/ili9225: Use devm_drm_dev_alloc drm/hx8357d: Use devm_drm_dev_alloc drm/gm12u320: Use devm_drm_dev_alloc drm/gm12u320: Don't use drm_device->dev_private
are all: Acked-by: Sam Ravnborg sam@ravnborg.org
I will take a look at patch 44 later today. I steered away from the vgem, i915 stuff on purpose. I leave that to more competent persons.
Yeah I think next round I'll leave out the vkms, vgem and i915-selftest, since that's a bigger discussion. But hopefully I can land the devm_drm_dev_alloc and many of the more basic conversions in here soonish.
Thanks a lot for looking through this all. -Daniel
dri-devel@lists.freedesktop.org