Op 23-03-16 om 16:07 schreef Ville Syrjälä: > On Wed, Mar 23, 2016 at 02:24:30PM +0100, Maarten Lankhorst wrote: >> Rename intel_unpin_work to intel_flip_work and use it for mmio flips >> and unpinning. Use flip_queued_req to hold the wait request in the >> mmio case and allow the vblank interrupt to complete mmio work to >> have mmio flips run correctly on g4 and earlier. > Before you actually go and trust drm_vblank_count() you should make it > race free. How about adding the below to the patch? diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index befac649aa96..05ec832e02de 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11224,12 +11224,11 @@ static void intel_mmio_flip_work_func(struct work_struct *w) false, false, MAX_SCHEDULE_TIMEOUT) < 0); - intel_pipe_update_start(crtc); + intel_pipe_update_start(crtc, work); primary->update_plane(&primary->base, crtc->config, to_intel_plane_state(primary->base.state)); - atomic_set(&work->pending, INTEL_FLIP_PENDING); - intel_pipe_update_end(crtc); + intel_pipe_update_end(crtc, work); } static int intel_default_queue_flip(struct drm_device *dev, @@ -13800,7 +13799,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, bool modeset = needs_modeset(crtc->state); /* Perform vblank evasion around commit operation */ - intel_pipe_update_start(intel_crtc); + intel_pipe_update_start(intel_crtc, NULL); if (modeset) return; @@ -13816,7 +13815,7 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc, { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - intel_pipe_update_end(intel_crtc); + intel_pipe_update_end(intel_crtc, NULL); } /** diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cac368138764..86d486cfd778 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1604,8 +1604,8 @@ bool intel_sdvo_init(struct drm_device *dev, int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); -void intel_pipe_update_start(struct intel_crtc *crtc); -void intel_pipe_update_end(struct intel_crtc *crtc); +void intel_pipe_update_start(struct intel_crtc *crtc, struct intel_flip_work *work); +void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work); /* intel_tv.c */ void intel_tv_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 8821533561b1..8da59a1eca56 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -78,7 +78,8 @@ static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, * avoid random delays. The value written to @start_vbl_count should be * supplied to intel_pipe_update_end() for error checking. */ -void intel_pipe_update_start(struct intel_crtc *crtc) +void intel_pipe_update_start(struct intel_crtc *crtc, + struct intel_flip_work *work) { struct drm_device *dev = crtc->base.dev; const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; @@ -142,6 +143,9 @@ void intel_pipe_update_start(struct intel_crtc *crtc) crtc->debug.start_vbl_count = dev->driver->get_vblank_counter(dev, pipe); + if (work) + work->flip_queued_vblank = crtc->debug.start_vbl_count; + trace_i915_pipe_update_vblank_evaded(crtc); } @@ -154,7 +158,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc) * re-enables interrupts and verifies the update was actually completed * before a vblank using the value of @start_vbl_count. */ -void intel_pipe_update_end(struct intel_crtc *crtc) +void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work) { struct drm_device *dev = crtc->base.dev; enum pipe pipe = crtc->pipe; @@ -162,6 +166,12 @@ void intel_pipe_update_end(struct intel_crtc *crtc) u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe); ktime_t end_vbl_time = ktime_get(); + if (work) { + work->flip_queued_vblank = end_vbl_count; + smp_mb__before_atomic(); + atomic_set(&work->pending, INTEL_FLIP_PENDING); + } + trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); local_irq_enable(); _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx