mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
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
This commit is contained in:
parent
7a2c65dd32
commit
7e13ad8964
@ -1137,7 +1137,7 @@ static bool amdgpu_switcheroo_can_switch(struct pci_dev *pdev)
|
||||
* locking inversion with the driver load path. And the access here is
|
||||
* completely racy anyway. So don't bother with locking for now.
|
||||
*/
|
||||
return dev->open_count == 0;
|
||||
return atomic_read(&dev->open_count) == 0;
|
||||
}
|
||||
|
||||
static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -43,7 +43,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
|
||||
* locking inversion with the driver load path. And the access here is
|
||||
* completely racy anyway. So don't bother with locking for now.
|
||||
*/
|
||||
return i915 && i915->drm.open_count == 0;
|
||||
return i915 && atomic_read(&i915->drm.open_count) == 0;
|
||||
}
|
||||
|
||||
static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
|
||||
|
@ -72,7 +72,7 @@ nouveau_switcheroo_can_switch(struct pci_dev *pdev)
|
||||
* locking inversion with the driver load path. And the access here is
|
||||
* completely racy anyway. So don't bother with locking for now.
|
||||
*/
|
||||
return dev->open_count == 0;
|
||||
return atomic_read(&dev->open_count) == 0;
|
||||
}
|
||||
|
||||
static const struct vga_switcheroo_client_ops
|
||||
|
@ -1263,7 +1263,7 @@ static bool radeon_switcheroo_can_switch(struct pci_dev *pdev)
|
||||
* locking inversion with the driver load path. And the access here is
|
||||
* completely racy anyway. So don't bother with locking for now.
|
||||
*/
|
||||
return dev->open_count == 0;
|
||||
return atomic_read(&dev->open_count) == 0;
|
||||
}
|
||||
|
||||
static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = {
|
||||
|
@ -144,7 +144,7 @@ struct drm_device {
|
||||
* Usage counter for outstanding files open,
|
||||
* protected by drm_global_mutex
|
||||
*/
|
||||
int open_count;
|
||||
atomic_t open_count;
|
||||
|
||||
/** @filelist_mutex: Protects @filelist. */
|
||||
struct mutex filelist_mutex;
|
||||
|
Loading…
Reference in New Issue
Block a user