Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Christian König" <christian.koenig@amd.com>
To: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>,
	intel-xe@lists.freedesktop.org
Cc: "Matthew Brost" <matthew.brost@intel.com>,
	"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
	"Maarten Lankhorst" <dev@lankhorst.se>,
	"Michal Wajdeczko" <michal.wajdeczko@intel.com>,
	dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 1/3] drm/sa: Scan all holes when fences are disabled
Date: Thu, 12 Mar 2026 08:56:33 +0100	[thread overview]
Message-ID: <c97a444f-1b47-4281-8cdb-b544c8fb59af@amd.com> (raw)
In-Reply-To: <20260311155233.1903253-6-satyanarayana.k.v.p@intel.com>

On 3/11/26 16:52, Satyanarayana K V P wrote:
> The suballocator algorithm tracks a hole cursor at the last allocation
> and tries to allocate after it. This is optimized for fence-ordered
> progress, where older allocations are expected to become reusable first.
> 
> In fence-enabled mode, that ordering assumption holds. In fence-disabled
> mode, allocations may be freed in arbitrary order, so limiting allocation
> to the current hole window can miss valid free space and fail allocations
> despite sufficient total space.
> 
> Update the fence-disabled path to walk through all holes and select any
> fitting range, while keeping the existing fence-based behavior unchanged.

Mhm, that sounds like we are abusing the SA for an unfit use case to me.

The whole idea of the SA is to work with fence protected allocation, if you don't need that then you can also use the drm_mm for the job.

So why are you not using drm_mm for that?

Regards,
Christian.

> 
> Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Maarten Lankhorst <dev@lankhorst.se>
> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: dri-devel@lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_suballoc.c | 90 ++++++++++++++++++++++++++++++++++
>  include/drm/drm_suballoc.h     |  5 ++
>  2 files changed, 95 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_suballoc.c b/drivers/gpu/drm/drm_suballoc.c
> index b74277bbc14b..307da191a855 100644
> --- a/drivers/gpu/drm/drm_suballoc.c
> +++ b/drivers/gpu/drm/drm_suballoc.c
> @@ -78,12 +78,33 @@ void drm_suballoc_manager_init(struct drm_suballoc_manager *sa_manager,
>  	sa_manager->size = size;
>  	sa_manager->align = align;
>  	sa_manager->hole = &sa_manager->olist;
> +	sa_manager->fence_disable = false;
>  	INIT_LIST_HEAD(&sa_manager->olist);
>  	for (i = 0; i < DRM_SUBALLOC_MAX_QUEUES; ++i)
>  		INIT_LIST_HEAD(&sa_manager->flist[i]);
>  }
>  EXPORT_SYMBOL(drm_suballoc_manager_init);
>  
> +/**
> + * drm_suballoc_manager_fence_disable() - Enable or disable fence tracking.
> + * @sa_manager: Pointer to the suballocation manager.
> + * @fence_disable: Whether to disable fence tracking for free suballocations.
> + *
> + * When @fence_disable is true allocation scans all holes without waiting on
> + * fences. When false, the manager tracks free suballocations behind fences and
> + * reuses them only after the fence signals.
> + *
> + * This should be called immediately after creating the suballocator and before
> + * any allocations are made. The behaviour is undefined if this is called after
> + * allocations have been made.
> + */
> +void drm_suballoc_manager_fence_disable(struct drm_suballoc_manager *sa_manager,
> +					bool fence_disable)
> +{
> +	sa_manager->fence_disable = fence_disable;
> +}
> +EXPORT_SYMBOL(drm_suballoc_manager_fence_disable);
> +
>  /**
>   * drm_suballoc_manager_fini() - Destroy the drm_suballoc_manager
>   * @sa_manager: pointer to the sa_manager
> @@ -110,6 +131,7 @@ void drm_suballoc_manager_fini(struct drm_suballoc_manager *sa_manager)
>  	}
>  
>  	sa_manager->size = 0;
> +	sa_manager->fence_disable = false;
>  }
>  EXPORT_SYMBOL(drm_suballoc_manager_fini);
>  
> @@ -161,6 +183,69 @@ static size_t drm_suballoc_hole_eoffset(struct drm_suballoc_manager *sa_manager)
>  	return sa_manager->size;
>  }
>  
> +/**
> + * drm_suballoc_hole_soffset_eoffset() - Find a hole fitting size and alignment.
> + * @sa_manager: Suballocator manager.
> + * @soffset: Start offset of the selected hole.
> + * @eoffset: End offset of the selected hole.
> + * @size: Size to be allocated.
> + * @align: Allocation alignment.
> + *
> + * This function is used when fences are disabled. It scans the holes starting
> + * at the current hole pointer and selects the first one that can satisfy @size
> + * once @align padding is applied. We may need to scan the entire list of holes
> + * and update soffset and eoffset for each hole to find a suitable one, as the
> + * current hole pointer may not be the same as sa_manager->hole.
> + *
> + * Return: true if a suitable hole is found, false otherwise.
> + */
> +static bool drm_suballoc_hole_soffset_eoffset(struct drm_suballoc_manager *sa_manager,
> +					      size_t *soffset, size_t *eoffset,
> +					      size_t size, size_t align)
> +{
> +	struct list_head *start, *hole;
> +
> +	if (!sa_manager->fence_disable)
> +		return true;
> +
> +	start = sa_manager->hole;
> +	hole = start;
> +
> +	do {
> +		size_t s, e, wasted;
> +
> +		/*
> +		 * We can't use drm_suballoc_hole_soffset() and
> +		 * drm_suballoc_hole_eoffset() here as the hole may not be same
> +		 * as sa_manager->hole.
> +		 */
> +		if (hole != &sa_manager->olist)
> +			s = list_entry(hole, struct drm_suballoc, olist)->eoffset;
> +		else
> +			s = 0;
> +
> +		if (hole->next != &sa_manager->olist)
> +			e = list_entry(hole->next, struct drm_suballoc, olist)->soffset;
> +		else
> +			e = sa_manager->size;
> +
> +		if (e < s || e == s || (e - s) < size) {
> +			hole = hole->next;
> +			continue;
> +		}
> +
> +		wasted = round_up(s, align) - s;
> +		if ((e - s) >= (size + wasted)) {
> +			*soffset = s;
> +			*eoffset = e;
> +			sa_manager->hole = hole;
> +			return true;
> +		}
> +	} while (hole != start);
> +
> +	return false;
> +}
> +
>  static bool drm_suballoc_try_alloc(struct drm_suballoc_manager *sa_manager,
>  				   struct drm_suballoc *sa,
>  				   size_t size, size_t align)
> @@ -169,6 +254,11 @@ static bool drm_suballoc_try_alloc(struct drm_suballoc_manager *sa_manager,
>  
>  	soffset = drm_suballoc_hole_soffset(sa_manager);
>  	eoffset = drm_suballoc_hole_eoffset(sa_manager);
> +
> +	if (!drm_suballoc_hole_soffset_eoffset(sa_manager, &soffset,
> +					       &eoffset, size, align))
> +		return false;
> +
>  	wasted = round_up(soffset, align) - soffset;
>  
>  	if ((eoffset - soffset) >= (size + wasted)) {
> diff --git a/include/drm/drm_suballoc.h b/include/drm/drm_suballoc.h
> index 29befdda35d2..066412196f8a 100644
> --- a/include/drm/drm_suballoc.h
> +++ b/include/drm/drm_suballoc.h
> @@ -20,6 +20,7 @@
>   * @flist: Array[fence context hash] of queues of fenced allocated ranges.
>   * @size: Size of the managed range.
>   * @align: Default alignment for the managed range.
> + * @fence_disable: Fences are disabled for this SA manager.
>   */
>  struct drm_suballoc_manager {
>  	wait_queue_head_t wq;
> @@ -28,6 +29,7 @@ struct drm_suballoc_manager {
>  	struct list_head flist[DRM_SUBALLOC_MAX_QUEUES];
>  	size_t size;
>  	size_t align;
> +	bool fence_disable;
>  };
>  
>  /**
> @@ -51,6 +53,9 @@ struct drm_suballoc {
>  void drm_suballoc_manager_init(struct drm_suballoc_manager *sa_manager,
>  			       size_t size, size_t align);
>  
> +void drm_suballoc_manager_fence_disable(struct drm_suballoc_manager
> +					*sa_manager, bool fence_disable);
> +
>  void drm_suballoc_manager_fini(struct drm_suballoc_manager *sa_manager);
>  
>  struct drm_suballoc *drm_suballoc_alloc(gfp_t gfp);


  parent reply	other threads:[~2026-03-12  7:56 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-11 15:52 [PATCH 0/3] Scan all holes when fences are disabled in SA Satyanarayana K V P
2026-03-11 15:52 ` [PATCH 1/3] drm/sa: Scan all holes when fences are disabled Satyanarayana K V P
2026-03-11 19:02   ` Thomas Hellström
2026-03-12  7:58     ` Christian König
2026-03-12  7:56   ` Christian König [this message]
2026-03-11 15:52 ` [PATCH 2/3] drm/xe/vf: Disable fences while initializing CCS read/write sub-allocs Satyanarayana K V P
2026-03-11 15:52 ` [PATCH 3/3] drm/tests: Add KUnit test for suballocator allocation Satyanarayana K V P
2026-03-11 17:08 ` ✗ CI.checkpatch: warning for Scan all holes when fences are disabled in SA Patchwork
2026-03-11 17:09 ` ✓ CI.KUnit: success " Patchwork
2026-03-11 18:14 ` ✓ Xe.CI.BAT: " Patchwork
2026-03-12  9:21 ` ✓ Xe.CI.FULL: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c97a444f-1b47-4281-8cdb-b544c8fb59af@amd.com \
    --to=christian.koenig@amd.com \
    --cc=dev@lankhorst.se \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=matthew.brost@intel.com \
    --cc=michal.wajdeczko@intel.com \
    --cc=satyanarayana.k.v.p@intel.com \
    --cc=thomas.hellstrom@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox