All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Cc: <intel-xe@lists.freedesktop.org>,
	Matthew Auld <matthew.auld@intel.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Subject: Re: [PATCH v4 4/4] drm/xe: Update non-purgeable shrinker batch size based on average BO size
Date: Fri, 16 Oct 2026 11:44:00 -0700	[thread overview]
Message-ID: <atJwcKZTBf1lKhID@gsse-cloud1.jf.intel.com> (raw)
In-Reply-To: <20261016133523.3622-5-thomas.hellstrom@linux.intel.com>

On Fri, Oct 16, 2026 at 03:35:23PM +0200, Thomas Hellström wrote:
> Update our preferred vmscan batch size for the non-purgeable shrinker
> on count passes that allow backup (__GFP_FS), to avoid invoking
> scan_objects() for requests too small to free even a single
> average-sized GEM object. Our rough estimate for an effective batch
> is twice the average number of pages per populated ttm_tt across
> the full shrinkable and purgeable population. The factor of two
> provides headroom so that most scan invocations can free at least one
> GEM object despite variability in object sizes.
> 
> The batch value is updated as an exponential moving average,
> (old_batch + avg) / 2, to smooth out sudden changes in the object
> population. It is floored at 128 pages, the kernel default
> SHRINK_BATCH, to ensure the shrinker remains responsive when there
> are very few objects.
> 
> The populated_tts counter introduced in an earlier commit provides the
> object count needed for the average. We inherit the same justification
> as the analogous mechanism in i915: shrinking a GEM object has
> non-trivial per-object overhead, so firing the shrinker for requests
> smaller than a single object is wasteful.
> 
> This is only applied to the non-purgeable shrinker: purgeable objects
> are reclaimed without writeback or GPU idling, so they're cheap enough
> that the core default batch size is fine for them.
> 
> v3:
> - Original patch reworked on top of shrinker split (Matt Brost)
> 
> Assisted-by: LLM
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  drivers/gpu/drm/xe/xe_shrinker.c | 48 ++++++++++++++++++++++++++++----
>  1 file changed, 42 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/xe_shrinker.c b/drivers/gpu/drm/xe/xe_shrinker.c
> index 8e3fe675e0f3..955908b3bdf3 100644
> --- a/drivers/gpu/drm/xe/xe_shrinker.c
> +++ b/drivers/gpu/drm/xe/xe_shrinker.c
> @@ -30,6 +30,8 @@
>   * @shrinkable_pages: Number of pages that are currently shrinkable.
>   * @purgeable_pages: Number of pages that are currently purgeable.
>   * @populated_tts: Number of populated ttm_tts currently shrinkable or purgeable.
> + * @batch_avg: Exponential moving average of the preferred non-purgeable
> + * batch size, based on the average populated ttm_tt size.
>   * @shrink: Pointer to the mm shrinker handling non-purgeable (shrinkable) objects.
>   * @purge_shrink: Pointer to the mm shrinker handling purgeable objects.
>   * @pm_worker: Worker to wake up the device if required.
> @@ -40,6 +42,7 @@ struct xe_shrinker {
>  	long shrinkable_pages;
>  	long purgeable_pages;
>  	long populated_tts;
> +	long batch_avg;
>  	struct shrinker *shrink;
>  	struct shrinker *purge_shrink;
>  	struct work_struct pm_worker;
> @@ -203,6 +206,28 @@ xe_shrinker_count_purgeable(struct shrinker *shrink, struct shrink_control *sc)
>  	return num_pages ? num_pages : SHRINK_EMPTY;
>  }
>  
> +/**
> + * DOC: Batch size calculation
> + *
> + * Update our preferred vmscan batch size for the non-purgeable shrinker
> + * on count passes that allow backup (__GFP_FS), to avoid invoking
> + * scan_objects() for requests too small to free even a single
> + * average-sized GEM object. Our rough estimate for an effective batch
> + * is twice the average number of pages per populated ttm_tt across
> + * the full shrinkable and purgeable population. The factor of two
> + * provides headroom so that most scan invocations can free at least one
> + * GEM object despite variability in object sizes.
> + *
> + * The batch value is updated as an exponential moving average,
> + * (old_batch + avg) / 2, to smooth out sudden changes in the object
> + * population. It is floored at 128 pages, the kernel default
> + * SHRINK_BATCH, to ensure the shrinker remains responsive when there
> + * are very few objects.
> + *
> + * We only do this for the non-purgeable shrinker: purgeable objects are
> + * reclaimed without writeback or GPU idling, so shrinking them is cheap
> + * enough that the core default batch size is fine.
> + */
>  static unsigned long
>  xe_shrinker_count(struct shrinker *shrink, struct shrink_control *sc)
>  {
> @@ -210,15 +235,26 @@ xe_shrinker_count(struct shrinker *shrink, struct shrink_control *sc)
>  	unsigned long num_pages;
>  	bool can_backup = !!(sc->gfp_mask & __GFP_FS);
>  
> +	if (!can_backup)
> +		return SHRINK_EMPTY;
> +
>  	num_pages = ttm_backup_bytes_avail() >> PAGE_SHIFT;
> -	read_lock(&shrinker->lock);
> +	/* Consistently use write_lock() for simplicity. */
> +	write_lock(&shrinker->lock);
>  
> -	if (can_backup)
> -		num_pages = min_t(unsigned long, num_pages, shrinker->shrinkable_pages);
> -	else
> -		num_pages = 0;
> +	num_pages = min_t(unsigned long, num_pages, shrinker->shrinkable_pages);
>  
> -	read_unlock(&shrinker->lock);
> +	if (shrinker->populated_tts) {
> +		unsigned long avg = 2 * (shrinker->shrinkable_pages +
> +					 shrinker->purgeable_pages) /
> +				     shrinker->populated_tts;
> +
> +		shrinker->batch_avg = max((shrinker->batch_avg + (long)avg) >> 1,
> +					  128L /* default SHRINK_BATCH */);
> +		WRITE_ONCE(shrink->batch, shrinker->batch_avg);
> +	}
> +
> +	write_unlock(&shrinker->lock);
>  
>  	return num_pages ? num_pages : SHRINK_EMPTY;
>  }
> -- 
> 2.56.0
> 

  parent reply	other threads:[~2026-10-16 18:44 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 13:35 [PATCH v4 0/4] drm/xe: Adjust the bo shrinker batch size Thomas Hellström
2026-10-16 13:35 ` [PATCH v4 1/4] drm/xe: Don't abort the shrinker walk on -EBUSY Thomas Hellström
2026-10-16 13:44   ` sashiko-bot
2026-10-16 13:55   ` Matthew Brost
2026-10-16 13:35 ` [PATCH v4 2/4] drm/xe: Track number of populated ttm_tts in the shrinker Thomas Hellström
2026-10-16 14:26   ` Matthew Brost
2026-10-16 13:35 ` [PATCH v4 3/4] drm/xe: Split the bo shrinker into purgeable and non-purgeable shrinkers Thomas Hellström
2026-10-16 13:53   ` sashiko-bot
2026-10-16 14:09     ` Thomas Hellström
2026-10-16 18:41       ` Matthew Brost
2026-10-16 18:16   ` Matthew Brost
2026-10-16 13:35 ` [PATCH v4 4/4] drm/xe: Update non-purgeable shrinker batch size based on average BO size Thomas Hellström
2026-10-16 13:45   ` sashiko-bot
2026-10-16 14:06     ` Thomas Hellström
2026-10-16 18:42       ` Matthew Brost
2026-10-16 18:44   ` Matthew Brost [this message]
2026-10-16 13:45 ` ✓ CI.KUnit: success for drm/xe: Adjust the bo shrinker batch size (rev4) Patchwork
2026-10-16 14:37 ` ✓ Xe.CI.BAT: " Patchwork
2026-10-16 22:14 ` ✓ 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=atJwcKZTBf1lKhID@gsse-cloud1.jf.intel.com \
    --to=matthew.brost@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthew.auld@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.