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:
Maarten Lankhorst 2015-08-18 13:40:05 +02:00
parent 5008e874ed
commit f935675f0c
1 changed files with 13 additions and 10 deletions

View File

@ -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