Commit f935675f authored by Maarten Lankhorst's avatar Maarten Lankhorst

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: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com> #v1
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 5008e874
...@@ -13165,8 +13165,13 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, ...@@ -13165,8 +13165,13 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
return ret; return ret;
} }
ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;
ret = drm_atomic_helper_prepare_planes(dev, state); ret = drm_atomic_helper_prepare_planes(dev, state);
mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }
...@@ -13268,7 +13273,10 @@ static int intel_atomic_commit(struct drm_device *dev, ...@@ -13268,7 +13273,10 @@ static int intel_atomic_commit(struct drm_device *dev,
/* FIXME: add subpixel order */ /* FIXME: add subpixel order */
drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_wait_for_vblanks(dev, state);
mutex_lock(&dev->struct_mutex);
drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_helper_cleanup_planes(dev, state);
mutex_unlock(&dev->struct_mutex);
if (any_ms) if (any_ms)
intel_modeset_check_state(dev, state); intel_modeset_check_state(dev, state);
...@@ -13437,6 +13445,8 @@ static void intel_shared_dpll_init(struct drm_device *dev) ...@@ -13437,6 +13445,8 @@ static void intel_shared_dpll_init(struct drm_device *dev)
* bits. Some older platforms need special physical address handling for * bits. Some older platforms need special physical address handling for
* cursor planes. * cursor planes.
* *
* Must be called with struct_mutex held.
*
* Returns 0 on success, negative error code on failure. * Returns 0 on success, negative error code on failure.
*/ */
int int
...@@ -13453,10 +13463,6 @@ intel_prepare_plane_fb(struct drm_plane *plane, ...@@ -13453,10 +13463,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
if (!obj && !old_obj) if (!obj && !old_obj)
return 0; return 0;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
return ret;
if (old_obj) { if (old_obj) {
struct drm_crtc_state *crtc_state = struct drm_crtc_state *crtc_state =
drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc); drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc);
...@@ -13477,7 +13483,7 @@ intel_prepare_plane_fb(struct drm_plane *plane, ...@@ -13477,7 +13483,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
/* Swallow -EIO errors to allow updates during hw lockup. */ /* Swallow -EIO errors to allow updates during hw lockup. */
if (ret && ret != -EIO) if (ret && ret != -EIO)
goto out; return ret;
} }
if (!obj) { if (!obj) {
...@@ -13495,9 +13501,6 @@ intel_prepare_plane_fb(struct drm_plane *plane, ...@@ -13495,9 +13501,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
if (ret == 0) if (ret == 0)
i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
out:
mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }
...@@ -13507,6 +13510,8 @@ intel_prepare_plane_fb(struct drm_plane *plane, ...@@ -13507,6 +13510,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
* @fb: old framebuffer that was on plane * @fb: old framebuffer that was on plane
* *
* Cleans up a framebuffer that has just been removed from a plane. * Cleans up a framebuffer that has just been removed from a plane.
*
* Must be called with struct_mutex held.
*/ */
void void
intel_cleanup_plane_fb(struct drm_plane *plane, intel_cleanup_plane_fb(struct drm_plane *plane,
...@@ -13520,7 +13525,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, ...@@ -13520,7 +13525,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
if (!obj && !old_obj) if (!obj && !old_obj)
return; return;
mutex_lock(&dev->struct_mutex);
if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR || if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
!INTEL_INFO(dev)->cursor_needs_physical)) !INTEL_INFO(dev)->cursor_needs_physical))
intel_unpin_fb_obj(old_state->fb, old_state); intel_unpin_fb_obj(old_state->fb, old_state);
...@@ -13529,7 +13533,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, ...@@ -13529,7 +13533,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) || if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
(obj && !(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); i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
mutex_unlock(&dev->struct_mutex);
} }
int int
......
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