RE: [PATCH] drm/xe/display: Re-use display vmas when possible

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Intel-xe <intel-xe-bounces@xxxxxxxxxxxxxxxxxxxxx> On Behalf Of
> Maarten Lankhorst
> Sent: Friday, December 6, 2024 1:10 AM
> To: intel-xe@xxxxxxxxxxxxxxxxxxxxx
> Cc: intel-gfx@xxxxxxxxxxxxxxxxxxxxx; Maarten Lankhorst <dev@xxxxxxxxxxxx>
> Subject: [PATCH] drm/xe/display: Re-use display vmas when possible
> 
> i915 has this really nice, infrastructure where everything becomes
> complicated, GGTT needs eviction, etc..
> 
> Lets not do that, and make the dumbest possible interface instead.
> Try to retrieve the VMA from old_plane_state, or intel_fbdev if kernel
> fb.
> 
> Signed-off-by: Maarten Lankhorst <dev@xxxxxxxxxxxx>

LGTM and it is fixing NOSPC issue for 64 bpp linear framebuffer.
Reviewed-by: Animesh Manna <animesh.manna@xxxxxxxxx>

> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c |  2 +-
>  drivers/gpu/drm/i915/display/intel_cursor.c   |  2 +-
>  drivers/gpu/drm/i915/display/intel_fb_pin.c   |  3 +-
>  drivers/gpu/drm/i915/display/intel_fb_pin.h   |  3 +-
>  drivers/gpu/drm/i915/display/intel_fbdev.c    |  5 ++
>  drivers/gpu/drm/i915/display/intel_fbdev.h    |  8 ++++
>  .../gpu/drm/xe/compat-i915-headers/i915_vma.h |  3 ++
>  drivers/gpu/drm/xe/display/xe_fb_pin.c        | 48 +++++++++++++++++--
>  8 files changed, 65 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index d89630b2d5c19..632b2b0723dd7 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -1144,7 +1144,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
>  	if (!obj)
>  		return 0;
> 
> -	ret = intel_plane_pin_fb(new_plane_state);
> +	ret = intel_plane_pin_fb(new_plane_state, old_plane_state);
>  	if (ret)
>  		return ret;
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c
> b/drivers/gpu/drm/i915/display/intel_cursor.c
> index ed88a28a3afae..5984310982e73 100644
> --- a/drivers/gpu/drm/i915/display/intel_cursor.c
> +++ b/drivers/gpu/drm/i915/display/intel_cursor.c
> @@ -864,7 +864,7 @@ intel_legacy_cursor_update(struct drm_plane
> *_plane,
>  	if (ret)
>  		goto out_free;
> 
> -	ret = intel_plane_pin_fb(new_plane_state);
> +	ret = intel_plane_pin_fb(new_plane_state, old_plane_state);
>  	if (ret)
>  		goto out_free;
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c
> b/drivers/gpu/drm/i915/display/intel_fb_pin.c
> index d3a86f9c6bc86..dd3ac7f98dfcc 100644
> --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
> +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
> @@ -252,7 +252,8 @@ intel_plane_fb_min_phys_alignment(const struct
> intel_plane_state *plane_state)
>  	return plane->min_alignment(plane, fb, 0);
>  }
> 
> -int intel_plane_pin_fb(struct intel_plane_state *plane_state)
> +int intel_plane_pin_fb(struct intel_plane_state *plane_state,
> +		       const struct intel_plane_state *old_plane_state)
>  {
>  	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
>  	const struct intel_framebuffer *fb =
> diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h
> b/drivers/gpu/drm/i915/display/intel_fb_pin.h
> index ac0319b53af08..0fc6d90446381 100644
> --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h
> +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h
> @@ -23,7 +23,8 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
> 
>  void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags);
> 
> -int intel_plane_pin_fb(struct intel_plane_state *plane_state);
> +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state,
> +		       const struct intel_plane_state *old_plane_state);
>  void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
> 
>  #endif
> diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c
> b/drivers/gpu/drm/i915/display/intel_fbdev.c
> index 00852ff5b2470..6c08081333976 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
> @@ -695,3 +695,8 @@ struct intel_framebuffer
> *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)
> 
>  	return to_intel_framebuffer(fbdev->helper.fb);
>  }
> +
> +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev)
> +{
> +	return fbdev ? fbdev->vma : NULL;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h
> b/drivers/gpu/drm/i915/display/intel_fbdev.h
> index 08de2d5b34338..24a3434558cb6 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbdev.h
> +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h
> @@ -17,6 +17,8 @@ struct intel_framebuffer;
>  void intel_fbdev_setup(struct drm_i915_private *dev_priv);
>  void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool
> synchronous);
>  struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev
> *fbdev);
> +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev);
> +
>  #else
>  static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv)
>  {
> @@ -30,6 +32,12 @@ static inline struct intel_framebuffer
> *intel_fbdev_framebuffer(struct intel_fbd
>  {
>  	return NULL;
>  }
> +
> +static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev
> *fbdev)
> +{
> +	return NULL;
> +}
> +
>  #endif
> 
>  #endif /* __INTEL_FBDEV_H__ */
> diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
> b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
> index bdae8392e1253..4465c40f81341 100644
> --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
> +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
> @@ -10,6 +10,8 @@
> 
>  #include "xe_ggtt_types.h"
> 
> +#include <linux/refcount.h>
> +
>  /* We don't want these from i915_drm.h in case of Xe */
>  #undef I915_TILING_X
>  #undef I915_TILING_Y
> @@ -19,6 +21,7 @@
>  struct xe_bo;
> 
>  struct i915_vma {
> +	refcount_t ref;
>  	struct xe_bo *bo, *dpt;
>  	struct xe_ggtt_node *node;
>  };
> diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c
> b/drivers/gpu/drm/xe/display/xe_fb_pin.c
> index 761510ae06904..8c3a5debe0953 100644
> --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
> +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
> @@ -9,6 +9,7 @@
>  #include "intel_dpt.h"
>  #include "intel_fb.h"
>  #include "intel_fb_pin.h"
> +#include "intel_fbdev.h"
>  #include "xe_bo.h"
>  #include "xe_device.h"
>  #include "xe_ggtt.h"
> @@ -287,6 +288,7 @@ static struct i915_vma *__xe_pin_fb_vma(const
> struct intel_framebuffer *fb,
>  	if (!vma)
>  		return ERR_PTR(-ENODEV);
> 
> +	refcount_set(&vma->ref, 1);
>  	if (IS_DGFX(to_xe_device(bo->ttm.base.dev)) &&
>  	    intel_fb_rc_ccs_cc_plane(&fb->base) >= 0 &&
>  	    !(bo->flags & XE_BO_FLAG_NEEDS_CPU_ACCESS)) {
> @@ -345,6 +347,9 @@ static struct i915_vma *__xe_pin_fb_vma(const
> struct intel_framebuffer *fb,
> 
>  static void __xe_unpin_fb_vma(struct i915_vma *vma)
>  {
> +	if (!refcount_dec_and_test(&vma->ref))
> +		return;
> +
>  	if (vma->dpt)
>  		xe_bo_unpin_map_no_vm(vma->dpt);
>  	else if (!xe_ggtt_node_allocated(vma->bo->ggtt_node) ||
> @@ -375,25 +380,58 @@ void intel_fb_unpin_vma(struct i915_vma *vma,
> unsigned long flags)
>  	__xe_unpin_fb_vma(vma);
>  }
> 
> -int intel_plane_pin_fb(struct intel_plane_state *plane_state)
> +static bool reuse_vma(struct intel_plane_state *new_plane_state,
> +		      const struct intel_plane_state *old_plane_state)
>  {
> -	struct drm_framebuffer *fb = plane_state->hw.fb;
> +	struct intel_framebuffer *fb =
> to_intel_framebuffer(new_plane_state->hw.fb);
> +	struct xe_device *xe = to_xe_device(fb->base.dev);
> +	struct i915_vma *vma;
> +
> +	if (old_plane_state->hw.fb == new_plane_state->hw.fb &&
> +	    !memcmp(&old_plane_state->view.gtt,
> +		    &new_plane_state->view.gtt,
> +	            sizeof(new_plane_state->view.gtt))) {
> +		vma = old_plane_state->ggtt_vma;
> +		goto found;
> +	}
> +
> +	if (fb == intel_fbdev_framebuffer(xe->display.fbdev.fbdev)) {
> +		vma = intel_fbdev_vma_pointer(xe->display.fbdev.fbdev);
> +		if (vma)
> +			goto found;
> +	}
> +
> +	return false;
> +
> +found:
> +	refcount_inc(&vma->ref);
> +	new_plane_state->ggtt_vma = vma;
> +	return true;
> +}
> +
> +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state,
> +		       const struct intel_plane_state *old_plane_state)
> +{
> +	struct drm_framebuffer *fb = new_plane_state->hw.fb;
>  	struct drm_gem_object *obj = intel_fb_bo(fb);
>  	struct xe_bo *bo = gem_to_xe_bo(obj);
>  	struct i915_vma *vma;
>  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> -	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	struct intel_plane *plane = to_intel_plane(new_plane_state-
> >uapi.plane);
>  	u64 phys_alignment = plane->min_alignment(plane, fb, 0);
> 
> +	if (reuse_vma(new_plane_state, old_plane_state))
> +		return 0;
> +
>  	/* We reject creating !SCANOUT fb's, so this is weird.. */
>  	drm_WARN_ON(bo->ttm.base.dev, !(bo->flags &
> XE_BO_FLAG_SCANOUT));
> 
> -	vma = __xe_pin_fb_vma(intel_fb, &plane_state->view.gtt,
> phys_alignment);
> +	vma = __xe_pin_fb_vma(intel_fb, &new_plane_state->view.gtt,
> phys_alignment);
> 
>  	if (IS_ERR(vma))
>  		return PTR_ERR(vma);
> 
> -	plane_state->ggtt_vma = vma;
> +	new_plane_state->ggtt_vma = vma;
>  	return 0;
>  }
> 
> --
> 2.45.2





[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux