On Sun, Feb 03, 2019 at 04:41:55PM +0100, Noralf Trønnes wrote:
If userspace has open fd(s) when drm_dev_unplug() is run, it will result in drm_dev_unregister() being called twice. First in drm_dev_unplug() and then later in drm_release() through the call to drm_put_dev().
Since userspace already holds a ref on drm_device through the drm_minor, it's not necessary to add extra ref counting based on no open file handles. Instead just drm_dev_put() unconditionally in drm_dev_unplug().
We now has this:
- Userpace holds a ref on drm_device as long as there's open fd(s)
- The driver holds a ref on drm_device as long as it's bound to the struct device
When both sides are done with drm_device, it is released.
Signed-off-by: Noralf Trønnes noralf@tronnes.org
Reviewed-by: Sean Paul sean@poorly.run
drivers/gpu/drm/drm_drv.c | 6 +----- drivers/gpu/drm/drm_file.c | 6 ++---- 2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 381581b01d48..05bbc2b622fc 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -376,11 +376,7 @@ void drm_dev_unplug(struct drm_device *dev) synchronize_srcu(&drm_unplug_srcu);
drm_dev_unregister(dev);
- mutex_lock(&drm_global_mutex);
- if (dev->open_count == 0)
drm_dev_put(dev);
- mutex_unlock(&drm_global_mutex);
- drm_dev_put(dev);
} EXPORT_SYMBOL(drm_dev_unplug);
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 46f48f245eb5..3f20f598cd7c 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -479,11 +479,9 @@ int drm_release(struct inode *inode, struct file *filp)
drm_file_free(file_priv);
- if (!--dev->open_count) {
- if (!--dev->open_count) drm_lastclose(dev);
if (drm_dev_is_unplugged(dev))
drm_put_dev(dev);
- }
mutex_unlock(&drm_global_mutex);
drm_minor_release(minor);
-- 2.20.1