[Intel-gfx] [PATCH] drm/i915: Unpin framebuffers when crtc is deconfigured.

Daniel Vetter daniel at ffwll.ch
Tue Nov 17 10:54:14 PST 2015


On Wed, Nov 04, 2015 at 02:43:31PM +0100, Maarten Lankhorst wrote:
> When setcrtc is called and steals the last connector away from a crtc
> it's turned off because it can't stay configured without connectors.
> 
> The framebuffer is still preserved however, and that causes troubles
> in the IGT stress test kms_flip.flips-vs-fences which tries to use
> as many pins as possible and hangs on the third crtc because of
> framebuffer pins on the first 2 crtc's.
> 
> Cc: stable at vger.kernel.org #v4.3
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>

drm_atomic_helper_set_config clears the fb for the primary plane if we
clear the mode. Where is the leak?

Also where exactly does it hang - we should have plenty of fences left for
3x2 pinned framebuffers. If you allow more than 2 pinned fb per plane then
that's a bug somewhere with pageflips getting ahead of the unpin worker.
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_display.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5e520ae5f42e..d95d8acae51f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13571,15 +13571,17 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
>  	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
> +	struct drm_crtc_state *crtc_state;
>  	int ret = 0;
>  
>  	if (!obj && !old_obj)
>  		return 0;
>  
> -	if (old_obj) {
> -		struct drm_crtc_state *crtc_state =
> -			drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc);
> +	crtc_state = drm_atomic_get_existing_crtc_state(new_state->state,
> +							new_state->crtc ?:
> +							plane->state->crtc);
>  
> +	if (old_obj) {
>  		/* Big Hammer, we also need to ensure that any pending
>  		 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
>  		 * current scanout is retired before unpinning the old
> @@ -13599,7 +13601,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>  			return ret;
>  	}
>  
> -	if (!obj) {
> +	if (!obj || !crtc_state->enable) {
>  		ret = 0;
>  	} else if (plane->type == DRM_PLANE_TYPE_CURSOR &&
>  	    INTEL_INFO(dev)->cursor_needs_physical) {
> @@ -13644,15 +13646,22 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  	struct intel_plane_state *old_intel_state;
>  	struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
>  	struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
> +	struct drm_crtc_state *old_crtc_state;
>  
>  	old_intel_state = to_intel_plane_state(old_state);
>  
>  	if (!obj && !old_obj)
>  		return;
>  
> -	if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
> -	    !INTEL_INFO(dev)->cursor_needs_physical))
> +	old_crtc_state = drm_atomic_get_existing_crtc_state(old_state->state,
> +							    old_state->crtc ?:
> +							    plane->state->crtc);
> +
> +	if (old_obj && old_crtc_state->enable &&
> +	    (plane->type != DRM_PLANE_TYPE_CURSOR ||
> +	     !INTEL_INFO(dev)->cursor_needs_physical)) {
>  		intel_unpin_fb_obj(old_state->fb, old_state);
> +	}
>  
>  	/* prepare_fb aborted? */
>  	if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the Intel-gfx mailing list