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: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200204150146.2006481-5-daniel.vetter@ffwll.ch
This commit is contained in:
parent
c368ec194d
commit
591a2abf14
|
@ -1079,17 +1079,14 @@ static int drm_stub_open(struct inode *inode, struct file *filp)
|
|||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
mutex_lock(&drm_global_mutex);
|
||||
minor = drm_minor_acquire(iminor(inode));
|
||||
if (IS_ERR(minor)) {
|
||||
err = PTR_ERR(minor);
|
||||
goto out_unlock;
|
||||
}
|
||||
if (IS_ERR(minor))
|
||||
return PTR_ERR(minor);
|
||||
|
||||
new_fops = fops_get(minor->dev->driver->fops);
|
||||
if (!new_fops) {
|
||||
err = -ENODEV;
|
||||
goto out_release;
|
||||
goto out;
|
||||
}
|
||||
|
||||
replace_fops(filp, new_fops);
|
||||
|
@ -1098,10 +1095,9 @@ static int drm_stub_open(struct inode *inode, struct file *filp)
|
|||
else
|
||||
err = 0;
|
||||
|
||||
out_release:
|
||||
out:
|
||||
drm_minor_release(minor);
|
||||
out_unlock:
|
||||
mutex_unlock(&drm_global_mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -378,6 +378,8 @@ int drm_open(struct inode *inode, struct file *filp)
|
|||
if (IS_ERR(minor))
|
||||
return PTR_ERR(minor);
|
||||
|
||||
mutex_lock(&drm_global_mutex);
|
||||
|
||||
dev = minor->dev;
|
||||
if (!atomic_fetch_inc(&dev->open_count))
|
||||
need_setup = 1;
|
||||
|
@ -395,10 +397,14 @@ int drm_open(struct inode *inode, struct file *filp)
|
|||
goto err_undo;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&drm_global_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
err_undo:
|
||||
atomic_dec(&dev->open_count);
|
||||
mutex_unlock(&drm_global_mutex);
|
||||
drm_minor_release(minor);
|
||||
return retcode;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue