Commit 591a2abf authored by Daniel Vetter's avatar Daniel Vetter

drm: Push drm_global_mutex locking in drm_open

We want to only take the BKL on crap drivers, but to know whether
we have a crap driver we first need to look it up. Split this shuffle
out from the main BKL-disabling patch, for more clarity. Historical
aside: When the kernel-wide BKL was removed, it was replaced by
drm_global_mutex within the scope of the drm subsystem hence why these
two things are (almost) interchangeable as concepts here.

Since the minors are refcounted drm_minor_acquire is purely internal
and this does not have a driver visible effect.

v2: Push the locking even further into drm_open(), suggested by Chris.
This gives us more symmetry with drm_release(), and maybe a futuer
avenue where we make drm_global_mutex locking (partially) opt-in like
with drm_release_noglobal().

v3:
- Actually push this stuff correctly, don't unlock twice (Chris)
- Fix typo on commit message, plus explain why BKL = drm_global_mutex
  (Sam)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Tested-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200204150146.2006481-5-daniel.vetter@ffwll.ch
parent c368ec19
...@@ -1079,17 +1079,14 @@ static int drm_stub_open(struct inode *inode, struct file *filp) ...@@ -1079,17 +1079,14 @@ static int drm_stub_open(struct inode *inode, struct file *filp)
DRM_DEBUG("\n"); DRM_DEBUG("\n");
mutex_lock(&drm_global_mutex);
minor = drm_minor_acquire(iminor(inode)); minor = drm_minor_acquire(iminor(inode));
if (IS_ERR(minor)) { if (IS_ERR(minor))
err = PTR_ERR(minor); return PTR_ERR(minor);
goto out_unlock;
}
new_fops = fops_get(minor->dev->driver->fops); new_fops = fops_get(minor->dev->driver->fops);
if (!new_fops) { if (!new_fops) {
err = -ENODEV; err = -ENODEV;
goto out_release; goto out;
} }
replace_fops(filp, new_fops); replace_fops(filp, new_fops);
...@@ -1098,10 +1095,9 @@ static int drm_stub_open(struct inode *inode, struct file *filp) ...@@ -1098,10 +1095,9 @@ static int drm_stub_open(struct inode *inode, struct file *filp)
else else
err = 0; err = 0;
out_release: out:
drm_minor_release(minor); drm_minor_release(minor);
out_unlock:
mutex_unlock(&drm_global_mutex);
return err; return err;
} }
......
...@@ -378,6 +378,8 @@ int drm_open(struct inode *inode, struct file *filp) ...@@ -378,6 +378,8 @@ int drm_open(struct inode *inode, struct file *filp)
if (IS_ERR(minor)) if (IS_ERR(minor))
return PTR_ERR(minor); return PTR_ERR(minor);
mutex_lock(&drm_global_mutex);
dev = minor->dev; dev = minor->dev;
if (!atomic_fetch_inc(&dev->open_count)) if (!atomic_fetch_inc(&dev->open_count))
need_setup = 1; need_setup = 1;
...@@ -395,10 +397,14 @@ int drm_open(struct inode *inode, struct file *filp) ...@@ -395,10 +397,14 @@ int drm_open(struct inode *inode, struct file *filp)
goto err_undo; goto err_undo;
} }
} }
mutex_unlock(&drm_global_mutex);
return 0; return 0;
err_undo: err_undo:
atomic_dec(&dev->open_count); atomic_dec(&dev->open_count);
mutex_unlock(&drm_global_mutex);
drm_minor_release(minor); drm_minor_release(minor);
return retcode; return retcode;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment