[Intel-gfx] [PATCH 1/6] drm/i915: make CRTC enable/disable asynchronous

Jesse Barnes jbarnes at virtuousgeek.org
Thu Mar 6 17:14:51 CET 2014


On Thu, 6 Mar 2014 09:35:23 +0000
Chris Wilson <chris at chris-wilson.co.uk> wrote:

> On Wed, Mar 05, 2014 at 02:48:26PM -0800, Jesse Barnes wrote:
> > @@ -7554,6 +7610,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
> >  		goto fail;
> >  	}
> >  
> > +	intel_sync_crtc(crtc);
> > +
> >  	/* we only need to pin inside GTT if cursor is non-phy */
> >  	mutex_lock(&dev->struct_mutex);
> >  	if (!INTEL_INFO(dev)->cursor_needs_physical) {
> > @@ -7639,6 +7697,8 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
> >  	intel_crtc->cursor_x = clamp_t(int, x, SHRT_MIN, SHRT_MAX);
> >  	intel_crtc->cursor_y = clamp_t(int, y, SHRT_MIN, SHRT_MAX);
> >  
> > +	intel_sync_crtc(crtc);
> > +
> >  	if (intel_crtc->active)
> >  		intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
> >  
> 
> Hmm. Would be much nicer if touching the cursor didn't incur a delay.
> And it would seem to quite easy to capture the state change and queue it
> for when the CRTC is re-enabled.

Do you think that's worthwhile?  I guess we'll block userspace a bit
here, but presumably the cursor won't be visible until the mode set
completes anyway...

But queuing this stuff is another option.

> 
> > @@ -8682,6 +8742,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> >  	if (work == NULL)
> >  		return -ENOMEM;
> >  
> > +	intel_sync_crtc(crtc);
> > +
> >  	work->event = event;
> >  	work->crtc = crtc;
> >  	work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
> > @@ -9677,8 +9739,10 @@ static int __intel_set_mode(struct drm_crtc *crtc,
> >  		intel_crtc_disable(&intel_crtc->base);
> >  
> >  	for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) {
> > -		if (intel_crtc->base.enabled)
> > -			dev_priv->display.crtc_disable(&intel_crtc->base);
> > +		if (intel_crtc->base.enabled) {
> > +			intel_queue_crtc_disable(&intel_crtc->base);
> > +			intel_sync_crtc(&intel_crtc->base);
> > +		}
> >  	}
> >  
> >  	/* crtc->mode is already used by the ->mode_set callbacks, hence we need
> > @@ -9719,7 +9783,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
> >  
> >  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
> >  	for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc)
> > -		dev_priv->display.crtc_enable(&intel_crtc->base);
> > +		intel_queue_crtc_enable(&intel_crtc->base);
> >  
> >  	/* FIXME: add subpixel order */
> >  done:
> > @@ -9740,8 +9804,9 @@ static int intel_set_mode(struct drm_crtc *crtc,
> >  
> >  	ret = __intel_set_mode(crtc, mode, x, y, fb);
> >  
> > -	if (ret == 0)
> > -		intel_modeset_check_state(crtc->dev);
> > +	/* FIXME: check after async crtc enable/disable */
> > +//	if (ret == 0)
> > +//		intel_modeset_check_state(crtc->dev);
> >  
> >  	return ret;
> >  }
> > @@ -10306,6 +10371,9 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
> >  	dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
> >  
> >  	drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
> > +
> > +	INIT_WORK(&intel_crtc->enable_work, intel_crtc_enable_work);
> > +	INIT_WORK(&intel_crtc->disable_work, intel_crtc_disable_work);
> 
> I feel using independent work items (remember the global wq is really a
> pool of many wq) is horribly prone to deadlocks.
> 
> We have the usual caveat that this has an implicit API change in that
> setcrtc can now return before the change is complete - and so userspace
> may write to a still currently visible scanout. Its not a huge issue
> (and is a change I am in favour of), it is just a change in behaviour we
> have to be wary of (which also means stating it in the changelog for future
> reference).

Yeah that's a good point, and if we're not careful it could result in
some visible ugliness.

-- 
Jesse Barnes, Intel Open Source Technology Center



More information about the Intel-gfx mailing list