public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: Daniel Colascione <dancol@dancol.org>
Cc: dri-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
	"Christian Koenig" <christian.koenig@amd.com>,
	"Huang Rui" <ray.huang@amd.com>,
	"Matthew Auld" <matthew.auld@intel.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH] Limit reclaim to avoid TTM desktop stutter under mem pressure
Date: Mon, 6 Apr 2026 14:02:44 -0700	[thread overview]
Message-ID: <adQfdL0zV7SOo+al@gsse-cloud1.jf.intel.com> (raw)
In-Reply-To: <87341fsa85.fsf@dancol.org>

On Tue, Mar 31, 2026 at 10:08:58PM -0400, Daniel Colascione wrote:
> TTM seems to be too eager to kick off reclaim while kwin is drawing
> 
> I've noticed that in 7.0-rc6, and since at least 6.17, kwin_wayland
> stalls in DRM ioctls to xe when the system is under memory pressure,
> causing missed frames, cursor-movement stutter, and general
> sluggishness. The root cause seems to be synchronous and asynchronous
> reclaim in ttm_pool_alloc_page as TTM tries, and fails, to allocate
> progressively lower-order pages in response to pool-cache misses when
> allocating graphics buffers.
> 
> Memory is fragmented enough that the compaction fails (as I can see in
> compact_fail and compact_stall in /proc/vmstat; extfrag says the normal
> pool is unusable for large allocations too). Additionally, compaction
> seems to be emptying the ttm pool, since page_pool in TTM debugfs
> reports all the buckets are empty while I'm seeing the
> kwin_wayland sluggishness.
> 
> In profiles, I see time dominated by copy_pages and clear_pages in the
> TTM paging code. kswapd runs constantly despite the system as a whole
> having plenty of free memory.
> 
> I can reproduce the problem on my 32GB-RAM X1C Gen 13 by booting with
> kernelcore=8G (not needed, but makes the repro happen sooner), running a
> find / >/dev/null (to fragment memory), and doing general web
> browsing. The stalls seem self-perpetuating once it gets started; it
> persists even after killing the find. I've noticed this stall in
> ordinary use too, even without the kernelcore= zone tweak, but without
> kernelcore, it usually takes a while (hours?) after boot for memory to
> become fragmented enough that higher-order allocations fail.
> 
> The patch below fixes the issue for me. TBC, I'm not sure it's the
> _right_ fix, but it works for me. I'm guessing that even if the approach
> is right, a new module parameter isn't warranted.
> 
> With the patch below, when I set my new max_reclaim_order ttm module
> parameter to zero, the kwin_wayland stalls under memory pressure
> stop. (TBC, this setting inhibits sync or async reclaim except for
> order-zero pages.)  TTM allocation occurs in latency-critical paths
> (e.g. Wayland frame commit): do you think we _should_ reclaim here?
> 
> BTW, I also tried having xe pass a beneficial order of 9, but it didn't
> help: we end up doing a lot of compaction work below this order anyway.

I was going to suggest changing Xe to align with what AMDGPU is doing [1].

Unfortunate this didn’t help.

[1] https://elixir.bootlin.com/linux/v6.19.11/source/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c#L1795

> 
> Signed-off-by: Daniel Colascione <dancol@dancol.org>
> 
> diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
> index c0d95559197c..fd255914c0d3 100644
> --- a/drivers/gpu/drm/ttm/ttm_pool.c
> +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> @@ -115,9 +115,13 @@ struct ttm_pool_tt_restore {
>  };
>  
>  static unsigned long page_pool_size;
> +static unsigned int max_reclaim_order;
>  
>  MODULE_PARM_DESC(page_pool_size, "Number of pages in the WC/UC/DMA pool");
>  module_param(page_pool_size, ulong, 0644);
> +MODULE_PARM_DESC(max_reclaim_order,
> +                "Maximum order that keeps upstream reclaim behavior");
> +module_param(max_reclaim_order, uint, 0644);
>  
>  static atomic_long_t allocated_pages;
>  
> @@ -146,16 +150,14 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
>          * Mapping pages directly into an userspace process and calling
>          * put_page() on a TTM allocated page is illegal.
>          */
> -       if (order)
> +       if (order) {
>                 gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN |
>                         __GFP_THISNODE;
> -
> -       /*
> -        * Do not add latency to the allocation path for allocations orders
> -        * device tolds us do not bring them additional performance gains.
> -        */
> -       if (beneficial_order && order > beneficial_order)
> -               gfp_flags &= ~__GFP_DIRECT_RECLAIM;
> +               if (beneficial_order && order > beneficial_order)
> +                       gfp_flags &= ~__GFP_DIRECT_RECLAIM;
> +               if (order > max_reclaim_order)
> +                       gfp_flags &= ~__GFP_RECLAIM;

I’m not very familiar with this code, but at first glance it doesn’t
seem quite right.

Would setting Xe’s beneficial to 9, similar to AMD’s, along with this
diff, help?

If I’m understanding this correctly, we would try a single allocation
attempt with __GFP_DIRECT_RECLAIM cleared for the size we care about,
still attempt allocations from the pools, and then finally fall back to
allocating single pages one at a time.

Matt

diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index aa41099c5ecf..f1f430aba0c1 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -714,6 +714,7 @@ static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
                            struct ttm_pool_alloc_state *alloc,
                            struct ttm_pool_tt_restore *restore)
 {
+       const unsigned int beneficial_order = ttm_pool_beneficial_order(pool);
        enum ttm_caching page_caching;
        gfp_t gfp_flags = GFP_USER;
        pgoff_t caching_divide;
@@ -757,7 +758,8 @@ static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
                if (!p) {
                        page_caching = ttm_cached;
                        allow_pools = false;
-                       p = ttm_pool_alloc_page(pool, gfp_flags, order);
+                       if (!order || order >= beneficial_order)
+                               p = ttm_pool_alloc_page(pool, gfp_flags, order);
                }
                /* If that fails, lower the order if possible and retry. */
                if (!p) {


> +       }
>  
>         if (!ttm_pool_uses_dma_alloc(pool)) {
>                 p = alloc_pages_node(pool->nid, gfp_flags, order);

  parent reply	other threads:[~2026-04-06 21:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-01  2:08 [RFC PATCH] Limit reclaim to avoid TTM desktop stutter under mem pressure Daniel Colascione
2026-04-01  7:35 ` Thomas Hellström
2026-04-01 10:16 ` Christian König
2026-04-06 21:02 ` Matthew Brost [this message]
2026-04-06 21:53   ` Matthew Brost

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=adQfdL0zV7SOo+al@gsse-cloud1.jf.intel.com \
    --to=matthew.brost@intel.com \
    --cc=airlied@gmail.com \
    --cc=christian.koenig@amd.com \
    --cc=dancol@dancol.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthew.auld@intel.com \
    --cc=mripard@kernel.org \
    --cc=ray.huang@amd.com \
    --cc=simona@ffwll.ch \
    --cc=thomas.hellstrom@linux.intel.com \
    --cc=tzimmermann@suse.de \
    /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