Skip to content

Commit

Permalink
drm/i915/fbc: fix CFB size calculation for gen8+
Browse files Browse the repository at this point in the history
Broadwell and newer actually compress up to 2560 lines instead of 2048
(as documented in the FBC_CTL page). If we don't take this into
consideration we end up reserving too little stolen memory for the
CFB, so we may allocate something else (such as a ring) right after
what we reserved, and the hardware will overwrite it with the contents
of the CFB when FBC is active, causing GPU hangs. Another possibility
is that the CFB may be allocated at the very end of the available
space, so the CFB will overlap the reserved stolen area, leading to
FIFO underruns.

This bug has always been a problem on BDW (the only affected platform
where FBC is enabled by default), but it's much easier to reproduce
since the following commit:
    commit c58b735
    Author: Chris Wilson <chris@chris-wilson.co.uk>
    Date:   Thu Aug 18 17:16:57 2016 +0100
        drm/i915: Allocate rings from stolen

Of course, you can only reproduce the bug if your screen is taller
than 2048 lines.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98213
Fixes: a98ee79 ("drm/i915/fbc: enable FBC by default on HSW and BDW")
Cc: <stable@vger.kernel.org> # v4.6+
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1477065346-13736-1-git-send-email-paulo.r.zanoni@intel.com
  • Loading branch information
Paulo Zanoni committed Oct 24, 2016
1 parent 7c108fd commit 79f2624
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion drivers/gpu/drm/i915/intel_fbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,10 @@ static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv,
int lines;

intel_fbc_get_plane_source_size(cache, NULL, &lines);
if (INTEL_INFO(dev_priv)->gen >= 7)
if (INTEL_GEN(dev_priv) == 7)
lines = min(lines, 2048);
else if (INTEL_GEN(dev_priv) >= 8)
lines = min(lines, 2560);

/* Hardware needs the full buffer stride, not just the active area. */
return lines * cache->fb.stride;
Expand Down

0 comments on commit 79f2624

Please sign in to comment.