mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-27 04:20:51 +07:00
drm: nest modeset locks within fpriv->fbs_lock
Atm we still need to unconditionally take the modeset locks in the rmfb paths. But eventually we only want to take them if there are other users around as a slow-path. This way sane userspace avoids blocking on edid reads and other stuff in rmfb if it ensures that the fb isn't used anywhere by a crtc/plane. We can do a quick check for such other users once framebuffers are properly refcounting by locking at the refcount - if it's more than 1, there are other users left. Again, rmfb racing against other ioctls isn't a real problem, userspace is allowed to shoot its foot. This patch just prepares this by moving the modeset locks to nest within fpriv->fbs_lock. Now the distinction between the fbs_lock and the device-global fb_lock is clear, since we need to hold the fbs_lock outside of any modeset_locks in fb_release. Reviewed-by: Rob Clark <rob@ti.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
2b677e8c08
commit
7d331595b0
@ -2282,13 +2282,13 @@ int drm_mode_addfb(struct drm_device *dev,
|
||||
drm_modeset_unlock_all(dev);
|
||||
return PTR_ERR(fb);
|
||||
}
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
mutex_lock(&file_priv->fbs_lock);
|
||||
or->fb_id = fb->base.id;
|
||||
list_add(&fb->filp_head, &file_priv->fbs);
|
||||
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
|
||||
mutex_unlock(&file_priv->fbs_lock);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2465,6 +2465,7 @@ int drm_mode_addfb2(struct drm_device *dev,
|
||||
drm_modeset_unlock_all(dev);
|
||||
return PTR_ERR(fb);
|
||||
}
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
mutex_lock(&file_priv->fbs_lock);
|
||||
r->fb_id = fb->base.id;
|
||||
@ -2472,7 +2473,6 @@ int drm_mode_addfb2(struct drm_device *dev,
|
||||
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
|
||||
mutex_unlock(&file_priv->fbs_lock);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2670,7 +2670,6 @@ void drm_fb_release(struct drm_file *priv)
|
||||
struct drm_device *dev = priv->minor->dev;
|
||||
struct drm_framebuffer *fb, *tfb;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
mutex_lock(&priv->fbs_lock);
|
||||
list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
|
||||
|
||||
@ -2682,10 +2681,11 @@ void drm_fb_release(struct drm_file *priv)
|
||||
list_del_init(&fb->filp_head);
|
||||
|
||||
/* This will also drop the fpriv->fbs reference. */
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_framebuffer_remove(fb);
|
||||
drm_modeset_unlock_all(dev);
|
||||
}
|
||||
mutex_unlock(&priv->fbs_lock);
|
||||
drm_modeset_unlock_all(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user