drm/i915: Change locking for struct_mutex, v3.
struct_mutex is being locked for every plane in intel_prepare_plane_fb and intel_cleanup_plane_fb. Require the caller to hold the mutex, and only acquire the mutex for each helper call. This way the lock only needs to be acquired twice in ->atomic_commit(). Once for pinning new framebuffers at the start, the second time for unpinning old framebuffer. Changes since v1: - Use mutex_lock_interruptible instead of i915 variant, to prevent a deadlock when called from the reset code. Changes since v2: - Clarify struct_mutex is locked by the caller. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> #v1 Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Родитель
5008e874ed
Коммит
f935675f0c
|
@ -13165,8 +13165,13 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = mutex_lock_interruptible(&dev->struct_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_atomic_helper_prepare_planes(dev, state);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -13268,7 +13273,10 @@ static int intel_atomic_commit(struct drm_device *dev,
|
|||
/* FIXME: add subpixel order */
|
||||
|
||||
drm_atomic_helper_wait_for_vblanks(dev, state);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_atomic_helper_cleanup_planes(dev, state);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
if (any_ms)
|
||||
intel_modeset_check_state(dev, state);
|
||||
|
@ -13437,6 +13445,8 @@ static void intel_shared_dpll_init(struct drm_device *dev)
|
|||
* bits. Some older platforms need special physical address handling for
|
||||
* cursor planes.
|
||||
*
|
||||
* Must be called with struct_mutex held.
|
||||
*
|
||||
* Returns 0 on success, negative error code on failure.
|
||||
*/
|
||||
int
|
||||
|
@ -13453,10 +13463,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
|
|||
if (!obj && !old_obj)
|
||||
return 0;
|
||||
|
||||
ret = i915_mutex_lock_interruptible(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (old_obj) {
|
||||
struct drm_crtc_state *crtc_state =
|
||||
drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc);
|
||||
|
@ -13477,7 +13483,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
|
|||
|
||||
/* Swallow -EIO errors to allow updates during hw lockup. */
|
||||
if (ret && ret != -EIO)
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
|
@ -13495,9 +13501,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
|
|||
if (ret == 0)
|
||||
i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -13507,6 +13510,8 @@ out:
|
|||
* @fb: old framebuffer that was on plane
|
||||
*
|
||||
* Cleans up a framebuffer that has just been removed from a plane.
|
||||
*
|
||||
* Must be called with struct_mutex held.
|
||||
*/
|
||||
void
|
||||
intel_cleanup_plane_fb(struct drm_plane *plane,
|
||||
|
@ -13520,7 +13525,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
|
|||
if (!obj && !old_obj)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
|
||||
!INTEL_INFO(dev)->cursor_needs_physical))
|
||||
intel_unpin_fb_obj(old_state->fb, old_state);
|
||||
|
@ -13529,7 +13533,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
|
|||
if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
|
||||
(obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit)))
|
||||
i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Загрузка…
Ссылка в новой задаче