Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f935675f authored by Maarten Lankhorst's avatar Maarten Lankhorst
Browse files

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
Loading
Loading
Loading
Loading
+13 −10
Original line number Original line Diff line number Diff line
@@ -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,
	/* 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)
 * 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,
	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,


		/* 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,
	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,
 * @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,
	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,
	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