[PATCH] RFC: WIP: drm/i915/fbc: Resize CFB full in non-full modeset paths
Paulo Zanoni
paulo.r.zanoni at intel.com
Thu Apr 5 16:42:18 UTC 2018
Em Qua, 2018-04-04 às 18:21 -0700, José Roberto de Souza escreveu:
> A simple page flip can cause the CFB required sized to increase and
> if it is bigger than the currently allocated CFB it needs to be
> resize to activate FBC again.
>
> Until now this case was not being handled but CI is starting to
> get some of this errors.
>
> So here it will free the old CFB and a try to allocate the required
> CFB in the schedule activation work, it will happen after one vblank
> so is guarantee that FBC was completed disabled and is not using CFB.
For CI specifically, have they tried to increase the stolen memory size
in the BIOS?
>
> Signed-off-by: José Roberto de Souza <jose.souza at intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 1 +
> drivers/gpu/drm/i915/intel_fbc.c | 49 ++++++++++++++++++++++++++--
> ------------
> 2 files changed, 33 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 5373b171bb96..5405b0b0f1c0 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -566,6 +566,7 @@ struct intel_fbc {
> } work;
>
> const char *no_fbc_reason;
> + bool try_resize_cfb;
> };
>
> /*
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> b/drivers/gpu/drm/i915/intel_fbc.c
> index 707d49c12638..ced11dd5747a 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -41,6 +41,11 @@
> #include "intel_drv.h"
> #include "i915_drv.h"
>
> +#define NO_FBC_REASON_NOT_ENOUGH_STOLEN_MEM "not enough stolen
> memory"
[przanoni at przanoni-mobl ~]$ echo "NO_FBC_REASON_NOT_ENOUGH_STOLEN_MEM"
| wc -c
36
[przanoni at przanoni-mobl ~]$ echo "not enough stolen memory" | wc -c
25
> +
> +static void __intel_fbc_cleanup_cfb(struct drm_i915_private
> *dev_priv);
> +static int intel_fbc_alloc_cfb(struct intel_crtc *crtc);
Please just move the functions up/down so we can avoid these.
> +
> static inline bool fbc_supported(struct drm_i915_private *dev_priv)
> {
> return HAS_FBC(dev_priv);
> @@ -446,6 +451,14 @@ static void intel_fbc_work_fn(struct work_struct
> *__work)
> goto retry;
> }
>
> + if (fbc->try_resize_cfb) {
> + __intel_fbc_cleanup_cfb(dev_priv);
> + if (intel_fbc_alloc_cfb(crtc)) {
> + fbc->no_fbc_reason =
> NO_FBC_REASON_NOT_ENOUGH_STOLEN_MEM;
> + goto out;
> + }
> + }
> +
> intel_fbc_hw_activate(dev_priv);
>
> work->scheduled = false;
> @@ -843,22 +856,6 @@ static bool intel_fbc_can_activate(struct
> intel_crtc *crtc)
> return false;
> }
>
> - /* It is possible for the required CFB size change without a
> - * crtc->disable + crtc->enable since it is possible to
> change the
> - * stride without triggering a full modeset. Since we try to
> - * over-allocate the CFB, there's a chance we may keep FBC
> enabled even
> - * if this happens, but if we exceed the current CFB size
> we'll have to
> - * disable FBC. Notice that it would be possible to disable
> FBC, wait
> - * for a frame, free the stolen node, then try to reenable
> FBC in case
> - * we didn't get any invalidate/deactivate calls, but this
> would require
> - * a lot of tracking just for a specific case. If we
> conclude it's an
> - * important case, we can implement it later. */
> - if (intel_fbc_calculate_cfb_size(dev_priv, &fbc-
> >state_cache) >
> - fbc->compressed_fb.size * fbc->threshold) {
> - fbc->no_fbc_reason = "CFB requirements changed";
> - return false;
> - }
> -
> /*
> * Work around a problem on GEN9+ HW, where enabling FBC on
> a plane
> * having a Y offset that isn't divisible by 4 causes FIFO
> underrun
> @@ -870,6 +867,24 @@ static bool intel_fbc_can_activate(struct
> intel_crtc *crtc)
> return false;
> }
>
> + /* It is possible for the required CFB size change without a
> + * crtc->disable + crtc->enable since it is possible to
> change the
> + * stride without triggering a full modeset. Since we try to
> + * over-allocate the CFB, there's a chance we may keep FBC
> enabled even
> + * if this happens, but if we exceed the current CFB size
> we'll have to
> + * resize CFB.
> + */
> + if (!drm_mm_node_allocated(&fbc->compressed_fb)) {
> + fbc->try_resize_cfb = true;
> + DRM_DEBUG_KMS("Previous try to resize failed, trying
> again in the next schedule activation");
> + } else if (intel_fbc_calculate_cfb_size(dev_priv, &fbc-
> >state_cache) >
> + fbc->compressed_fb.size * fbc->threshold) {
> + fbc->try_resize_cfb = true;
> + DRM_DEBUG_KMS("CFB requirements changed, next
> schedule activation will try to resize it");
> + } else {
> + fbc->try_resize_cfb = false;
> + }
It's been a while since I worked with FBC so please help me with this
one: what is preventing our code from forever trying to enable FBC in
every single frame in case there's just not enough stolen memory?
> +
> return true;
> }
>
> @@ -1192,7 +1207,7 @@ void intel_fbc_enable(struct intel_crtc *crtc,
>
> intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
> if (intel_fbc_alloc_cfb(crtc)) {
> - fbc->no_fbc_reason = "not enough stolen memory";
> + fbc->no_fbc_reason =
> NO_FBC_REASON_NOT_ENOUGH_STOLEN_MEM;
> goto out;
> }
>
More information about the Intel-gfx-trybot
mailing list