Currently a tiled frame buffer to be scanned out is always installed with a fence, leading to fence starvation on gen9lp virtualization use case where graphics stacks of service and guest OSes compete for fences. By design, this fence is always needed by i965-(GEN4-) platforms. For GEN4 and above, the fence is only required when the frame buffer compression is enabled. Changes are made to follow graphics hardware design principles. Signed-off-by: Guang Bai <guang.bai@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_display.c | 44 +++++++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_drv.h | 4 +++- drivers/gpu/drm/i915/intel_fbc.c | 2 +- drivers/gpu/drm/i915/intel_fbdev.c | 3 ++- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3dbf5ed..59004f5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2068,7 +2068,8 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, } struct i915_vma * -intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) +intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation, + struct drm_plane *plane, enum pipe pipe) { struct drm_device *dev = fb->dev; struct drm_i915_private *dev_priv = to_i915(dev); @@ -2076,6 +2077,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) struct i915_ggtt_view view; struct i915_vma *vma; u32 alignment; + bool needs_fence = false; + struct intel_plane *intel_plane; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -2105,13 +2108,19 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) vma = i915_gem_object_pin_to_display_plane(obj, alignment, &view); if (IS_ERR(vma)) goto err; + /* + * Install the fence for pre-i965(GEN4-) tiled frame buffers all the + * time but only do it for i965(GEN4) and beyond when the frame buffer + * compression is enabled during boot up or runtime. + */ + intel_plane = to_intel_plane(plane); + if (INTEL_GEN(dev_priv) < 4 || (intel_fbc_can_enable(dev_priv) && + (pipe == PIPE_A) && intel_plane && + (intel_plane->id == PLANE_PRIMARY))) + needs_fence = true; if (i915_vma_is_map_and_fenceable(vma)) { - /* Install a fence for tiled scan-out. Pre-i965 always needs a - * fence, whereas 965+ only requires a fence if using - * framebuffer compression. For simplicity, we always, when - * possible, install a fence as the cost is not that onerous. - * + /* * If we fail to fence the tiled scanout, then either the * modeset will reject the change (which is highly unlikely as * the affected systems, all but one, do not have unmappable @@ -2123,7 +2132,16 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) * something and try to run the system in a "less than optimal" * mode that matches the user configuration. */ - i915_vma_pin_fence(vma); + if (needs_fence) + i915_vma_pin_fence(vma); + else if (vma->fence) + /* + * For a reused fence, increase its ref count even if + * it's not pinned to maintain the count consistancy. + * This is because the count is unconditionally + * decreased when the fence is unpinned. + */ + vma->fence->pin_count++; } i915_vma_get(vma); @@ -2808,7 +2826,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, valid_fb: mutex_lock(&dev->struct_mutex); intel_state->vma = - intel_pin_and_fence_fb_obj(fb, primary->state->rotation); + intel_pin_and_fence_fb_obj(fb, primary->state->rotation, + primary, intel_crtc->pipe); mutex_unlock(&dev->struct_mutex); if (IS_ERR(intel_state->vma)) { DRM_ERROR("failed to pin boot fb on pipe %d: %li\n", @@ -12711,8 +12730,9 @@ intel_prepare_plane_fb(struct drm_plane *plane, ret = i915_gem_object_attach_phys(obj, align); } else { struct i915_vma *vma; - - vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation); + struct intel_crtc *temp_crtc = to_intel_crtc(new_state->crtc); + vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation, + plane, temp_crtc->pipe); if (!IS_ERR(vma)) to_intel_plane_state(new_state)->vma = vma; else @@ -13128,7 +13148,9 @@ intel_legacy_cursor_update(struct drm_plane *plane, goto out_unlock; } } else { - vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation); + struct intel_crtc *temp_crtc = to_intel_crtc(crtc); + vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation, + plane, temp_crtc->pipe); if (IS_ERR(vma)) { DRM_DEBUG_KMS("failed to pin object\n"); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 898064e..7d98e069 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1503,7 +1503,8 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, struct intel_load_detect_pipe *old, struct drm_modeset_acquire_ctx *ctx); struct i915_vma * -intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation); +intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation, + struct drm_plane *plane, enum pipe pipe); void intel_unpin_fb_vma(struct i915_vma *vma); struct drm_framebuffer * intel_framebuffer_create(struct drm_i915_gem_object *obj, @@ -1759,6 +1760,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits, enum fb_op_origin origin); void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv); void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv); +bool intel_fbc_can_enable(struct drm_i915_private *dev_priv); /* intel_hdmi.c */ void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index d7d1ac7..6c9d704 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -862,7 +862,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return true; } -static bool intel_fbc_can_enable(struct drm_i915_private *dev_priv) +bool intel_fbc_can_enable(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index da48af1..ef04c7e 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -211,7 +211,8 @@ static int intelfb_create(struct drm_fb_helper *helper, * This also validates that any existing fb inherited from the * BIOS is suitable for own access. */ - vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_MODE_ROTATE_0); + vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_MODE_ROTATE_0, + NULL, INVALID_PIPE); if (IS_ERR(vma)) { ret = PTR_ERR(vma); goto out_unlock; -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx