On Mon, 30 Mar 2026 11:39:00 +0100
Steven Price <[email protected]> wrote:

> Hi Boris,
> 
> On 30/03/2026 10:48, Boris Brezillon wrote:
> > Hello,
> > 
> > This is an attempt at adding a GEM shrinker to panthor so the system
> > can finally reclaim GPU memory.
> > 
> > This implementation is losely based on the MSM shrinker (which is why
> > I added the MSM maintainers in Cc), and it's relying on the drm_gpuvm
> > eviction/validation infrastructure.
> > 
> > I've only done very basic IGT-based [1] and chromium-based (opening
> > a lot of tabs on Aquarium until the system starts reclaiming+swapping
> > out GPU buffers) testing, but I'm posting this early so I can get
> > preliminary feedback on the implementation. If someone knows about
> > better tools/ways to test the shrinker, please let me know.  
> 
> I did my own pretty basic testing (glmark with memhog) and managed to hit 
> this:
> 
> [  265.053172] ============================================
> [  265.053667] WARNING: possible recursive locking detected
> [  265.054159] 7.0.0-rc3-00694-gadfa5ca08767 #1 Not tainted
> [  265.054655] --------------------------------------------
> [  265.055143] glmark2-es2-drm/443 is trying to acquire lock:
> [  265.055651] ffff0001194011a8 (reservation_ww_class_mutex){+.+.}-{4:4}, at: 
> drm_gpuvm_bo_deferred_cleanup+0x100/0x2c0 [drm_gpuvm]
> [  265.056738] 
> [  265.056738] but task is already holding lock:
> [  265.057278] ffff80008b7c79e8 (reservation_ww_class_mutex){+.+.}-{4:4}, at: 
> panthor_ioctl_group_submit+0x424/0x560 [panthor]
> [  265.058324] 
> [  265.058324] other info that might help us debug this:
> [  265.058927]  Possible unsafe locking scenario:
> [  265.058927] 
> [  265.059475]        CPU0
> [  265.059706]        ----
> [  265.059939]   lock(reservation_ww_class_mutex);
> [  265.060365]   lock(reservation_ww_class_mutex);
> [  265.060788] 
> [  265.060788]  *** DEADLOCK ***
> [  265.060788] 
> [  265.061338]  May be due to missing lock nesting notation
> [  265.061338] 
> [  265.061964] 3 locks held by glmark2-es2-drm/443:
> [  265.062395]  #0: ffff80008493c458 (drm_unplug_srcu){.+.+}-{0:0}, at: 
> drm_dev_enter+0x0/0x140
> [  265.063188]  #1: ffff80008b7c79c0 
> (reservation_ww_class_acquire){+.+.}-{0:0}, at: 
> panthor_ioctl_group_submit+0x424/0x560 [panthor]
> [  265.064288]  #2: ffff80008b7c79e8 
> (reservation_ww_class_mutex){+.+.}-{4:4}, at: 
> panthor_ioctl_group_submit+0x424/0x560 [panthor]
> [  265.065370] 
> [  265.065370] stack backtrace:
> [  265.065780] CPU: 4 UID: 1000 PID: 443 Comm: glmark2-es2-drm Not tainted 
> 7.0.0-rc3-00694-gadfa5ca08767 #1 PREEMPT 
> [  265.065787] Hardware name: Radxa ROCK 5B (DT)
> [  265.065791] Call trace:
> [  265.065793]  show_stack+0x18/0x24 (C)
> [  265.065802]  dump_stack_lvl+0x6c/0x94
> [  265.065810]  dump_stack+0x1c/0x28
> [  265.065815]  print_deadlock_bug+0x224/0x238
> [  265.065822]  __lock_acquire+0xe54/0x1600
> [  265.065829]  lock_acquire+0x3cc/0x420
> [  265.065834]  __ww_mutex_lock.constprop.0+0x1fc/0x2c40
> [  265.065844]  ww_mutex_lock+0x50/0x168
> [  265.065850]  drm_gpuvm_bo_deferred_cleanup+0x100/0x2c0 [drm_gpuvm]
> [  265.065862]  panthor_vm_cleanup_op_ctx+0x188/0x270 [panthor]
> [  265.065881]  panthor_vm_bo_validate+0x404/0x758 [panthor]
> [  265.065898]  drm_gpuvm_validate+0x28c/0xf50 [drm_gpuvm]
> [  265.065907]  panthor_vm_prepare_mapped_bos_resvs+0x64/0x80 [panthor]
> [  265.065925]  panthor_ioctl_group_submit+0x418/0x560 [panthor]
> [  265.065942]  drm_ioctl_kernel+0x15c/0x2c0
> [  265.065947]  drm_ioctl+0x56c/0xb1c
> [  265.065952]  __arm64_sys_ioctl+0x124/0x1a4
> [  265.065961]  invoke_syscall+0x70/0x260
> [  265.065967]  el0_svc_common.constprop.0+0xac/0x230
> [  265.065972]  do_el0_svc+0x40/0x58
> [  265.065976]  el0_svc+0x4c/0x210
> [  265.065981]  el0t_64_sync_handler+0xa0/0xe4
> [  265.065986]  el0t_64_sync+0x198/0x19c
> 

Nice catch! I've fixed it by skipping the
drm_gpuvm_bo_deferred_cleanup() call in panthor_vm_cleanup_op_ctx()
when the operation is a VMA repopulation. In that case, the VM resv
lock will be held (because the SUBMIT logic acquires it), and the very
same lock is taken in drm_gpuvm_bo_deferred_cleanup(). We could have
added a drm_gpuvm_bo_deferred_cleanup_locked() variant, but in
practice, the VMA repopulation never calls drm_gpuvm_bo_put_deferred(),
so there's nothing for us to cleanup, and the only reason we were going
past the if (!bo_defer) test in drm_gpuvm_bo_deferred_cleanup() is
because other threads can race with the VMA repopulation and queue
vm_bos to the deferred cleanup list.

TLDR; this should be sorted out in v7, which I plan to post soon (I'd
like to maximize the time this patch series spends in linux-next so we
can detect issues early and fix them before it hits Linus' tree).

Reply via email to