mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] drm/xe: Use kvmalloc for the VMA ops page-table update array
@ 2026-10-21  0:08 karim.sabar
  2026-10-21 18:57 ` Matthew Brost
  0 siblings, 1 reply; 4+ messages in thread
From: karim.sabar @ 2026-10-21  0:08 UTC (permalink / raw)
  To: Matthew Brost, Thomas Hellström, Rodrigo Vivi, David Airlie,
	Simona Vetter
  Cc: intel-xe, dri-devel, linux-kernel, stable, Karim Sabar

From: Karim Sabar <karim.sabar@utexas.edu>

Big games die after every s2idle resume on flat-CCS iGPUs. The exec
ioctl keeps returning -ENOMEM even with 11-16 GB of RAM free.

On suspend xe_bo_evict_all_user() evicts every user BO in XE_PL_TT on
these parts. On resume the first exec rebinds every VMA in one go and
xe_vma_ops_alloc() kmallocs one 384-byte op per VMA as a single array.
Final Fantasy VII Rebirth has about 33,500 VMAs which means a 12.9 MB
array. It's over the 4 MB KMALLOC_MAX_SIZE and can never succeed.
__GFP_NOWARN keeps it out of dmesg.

Data from a Panther Lake handheld (SteamOS kernel 7.2.7), kretprobes
after resume:
  xe_vma_ops_alloc  -ENOMEM on 63 of 63 attempts
  xe_vm_rebind      -ENOMEM on 63 of 63 attempts
  BO validate, TTM populate, PT prepare  never failed

The array is only used by the CPU and doesn't need to be contiguous.
This switches it to kvmalloc and kvfree.

With the same change applied as a module on that kernel, the game
survives every sleep I tried with zero ENOMEM. The biggest array was
30,753 ops (11.8 MB).

drm-xe-next already does this through commit 0e33330f1238 ("drm/xe: Add
struct xe_pt_job_ops"), but that's part of a big series that won't go
to stable.

I tracked this down and tested it on my own device. I used an AI
assistant to help with the debugging, i.e the kprobe tracing and
reading through the xe code. I ran every test, picked the fix and
reviewed the change myself.

What I couldn't do: this is build-tested on drm-xe-fixes but only
run-tested on the SteamOS 7.2.7 kernel through an equivalent module,
not on a mainline kernel.

Fixes: 2e524668c440 ("drm/xe: Add xe_vm_pgtable_update_op to xe_vma_ops")
Cc: stable@vger.kernel.org # v6.11+
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Karim Sabar <karim.sabar@utexas.edu>
---
Downstream SteamOS report with the same data: https://github.com/ValveSoftware/SteamOS/issues/2962
---
 drivers/gpu/drm/xe/xe_vm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 99e42bd29..5caef443b 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -703,9 +703,9 @@ static int xe_vma_ops_alloc(struct xe_vma_ops *vops, bool array_of_binds)
 			continue;
 
 		vops->pt_update_ops[i].ops =
-			kmalloc_objs(*vops->pt_update_ops[i].ops,
-				     vops->pt_update_ops[i].num_ops,
-				     GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
+			kvmalloc_objs(*vops->pt_update_ops[i].ops,
+				      vops->pt_update_ops[i].num_ops,
+				      GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
 		if (!vops->pt_update_ops[i].ops)
 			return array_of_binds ? -ENOBUFS : -ENOMEM;
 	}
@@ -742,7 +742,7 @@ static void xe_vma_ops_fini(struct xe_vma_ops *vops)
 	xe_vma_svm_prefetch_ops_fini(vops);
 
 	for (i = 0; i < XE_MAX_TILES_PER_DEVICE; ++i)
-		kfree(vops->pt_update_ops[i].ops);
+		kvfree(vops->pt_update_ops[i].ops);
 }
 
 static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask, int inc_val)

---
base-commit: d2ce8fcd778ee6d92748c92d23a56d4416c29d86
change-id: 20261020-xe-kvmalloc-vma-ops-2637ebf81cfd

Best regards,
--  
Karim Sabar <karim.sabar@utexas.edu>


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-22  2:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21  0:08 [PATCH] drm/xe: Use kvmalloc for the VMA ops page-table update array karim.sabar
2026-10-21 18:57 ` Matthew Brost
2026-10-22  2:28   ` karim.sabar
2026-10-22  2:35     ` Matthew Brost

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®