diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-01-24 13:01:07 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-01-24 17:41:34 +0000 |
commit | 7e13ad896484a0165a68197a2e64091ea28c9602 (patch) | |
tree | a20b339f718dd71ca66899a60a970230acc5963a /drivers/gpu/drm/drm_file.c | |
parent | 7a2c65dd32b1cfa8bae55250dfdfe3d049e2f336 (diff) | |
download | linux-7e13ad896484a0165a68197a2e64091ea28c9602.tar.gz |
drm: Avoid drm_global_mutex for simple inc/dec of dev->open_count
Since drm_global_mutex is a true global mutex across devices, we don't
want to acquire it unless absolutely necessary. For maintaining the
device local open_count, we can use atomic operations on the counter
itself, except when making the transition to/from 0. Here, we tackle the
easy portion of delaying acquiring the drm_global_mutex for the final
release by using atomic_dec_and_mutex_lock(), leaving the global
serialisation across the device opens.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Thomas Hellström (VMware) <thomas_os@shipmail.org>
Reviewed-by: Thomas Hellström <thellstrom@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200124130107.125404-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/drm_file.c')
-rw-r--r-- | drivers/gpu/drm/drm_file.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index e25306c49cc6..1075b3a8b5b1 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -220,7 +220,7 @@ void drm_file_free(struct drm_file *file) DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", task_pid_nr(current), (long)old_encode_dev(file->minor->kdev->devt), - READ_ONCE(dev->open_count)); + atomic_read(&dev->open_count)); if (drm_core_check_feature(dev, DRIVER_LEGACY) && dev->driver->preclose) @@ -379,7 +379,7 @@ int drm_open(struct inode *inode, struct file *filp) return PTR_ERR(minor); dev = minor->dev; - if (!dev->open_count++) + if (!atomic_fetch_inc(&dev->open_count)) need_setup = 1; /* share address_space across all char-devs of a single device */ @@ -398,7 +398,7 @@ int drm_open(struct inode *inode, struct file *filp) return 0; err_undo: - dev->open_count--; + atomic_dec(&dev->open_count); drm_minor_release(minor); return retcode; } @@ -440,11 +440,11 @@ int drm_release(struct inode *inode, struct file *filp) mutex_lock(&drm_global_mutex); - DRM_DEBUG("open_count = %d\n", dev->open_count); + DRM_DEBUG("open_count = %d\n", atomic_read(&dev->open_count)); drm_close_helper(filp); - if (!--dev->open_count) + if (atomic_dec_and_test(&dev->open_count)) drm_lastclose(dev); mutex_unlock(&drm_global_mutex); @@ -478,10 +478,10 @@ int drm_release_noglobal(struct inode *inode, struct file *filp) drm_close_helper(filp); - mutex_lock(&drm_global_mutex); - if (!--dev->open_count) + if (atomic_dec_and_mutex_lock(&dev->open_count, &drm_global_mutex)) { drm_lastclose(dev); - mutex_unlock(&drm_global_mutex); + mutex_unlock(&drm_global_mutex); + } drm_minor_release(minor); |