mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
Add lockdep annotations to teach lockdep the correct lock hierarchy
and catch ordering violations during development. This follows the
pattern established by dma-resv in drivers/dma-buf/dma-resv.c.
Lock ordering hierarchy (outermost to innermost):
1. userq_sch_mutex - Global userq scheduler (enforce_isolation)
2. userq_mutex - Per-context userq (held across queue create/destroy)
3. notifier_lock - MMU notifier synchronization
4. vram_lock - VRAM memory allocator
5. reset_domain->sem - GPU reset synchronization
6. reset_lock - Reset control mutex
7. srbm_mutex - SRBM register access
8. grbm_idx_mutex - GRBM index register access
9. mmio_idx_lock - MMIO index access (spinlock)
The implementation provides:
- Lock ordering training at module init (amdgpu_lockdep_init)
- Lock class association for real driver locks (amdgpu_lockdep_set_class)
Dummy locks are associated with the same class keys as real driver locks
via lockdep_set_class(), ensuring lockdep connects the training ordering
with actual runtime locks.
Testing:
Build the kernel with CONFIG_PROVE_LOCKING=y (enables CONFIG_LOCKDEP):
scripts/config --enable PROVE_LOCKING
scripts/config --enable DEBUG_LOCKDEP
make -j$(nproc)
On boot, dmesg should show:
AMDGPU: Lockdep annotations initialized (9 lock levels)
The companion IGT test (tests/amdgpu/amd_lockdep) exercises lock-heavy
GPU code paths concurrently to trigger lockdep warnings on violations:
sudo ./build/tests/amdgpu/amd_lockdep
sudo dmesg | grep -A 50 "circular locking dependency"
IGT subtests:
concurrent-reset-and-submit - reset_sem vs submission locks
concurrent-mmap-and-evict - mmap_lock vs vram_lock
concurrent-userptr-and-reset - notifier_lock vs reset_sem
stress-all-paths - all of the above simultaneously
A clean dmesg (no "circular locking dependency" or "possible recursive
locking detected" messages) confirms no lock ordering violations.
For CI integration, the test should be run on kernels compiled with
CONFIG_LOCKDEP=y; dmesg is scanned post-run for lockdep splats.
v2: (Christian)
- Move notifier_lock and vram_lock before reset locks in hierarchy.
HMM invalidation holds notifier_lock and can wait for GPU reset
completion, so notifier_lock must be outer to reset_domain->sem.
- Associate dummy locks with lock class keys via lockdep_set_class()
so lockdep connects training with real driver locks.
- Update commit message to list all 9 lock levels.
Requires CONFIG_PROVE_LOCKING=y to activate.
Cc: Christian Konig <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Reviewed-by: Christian Konig <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
40 lines
913 B
C
40 lines
913 B
C
/* SPDX-License-Identifier: MIT */
|
|
/*
|
|
* Copyright 2024 Advanced Micro Devices, Inc.
|
|
*
|
|
* Lockdep annotation interface for AMDGPU
|
|
*/
|
|
|
|
#ifndef __AMDGPU_LOCKDEP_H__
|
|
#define __AMDGPU_LOCKDEP_H__
|
|
|
|
#include <linux/lockdep.h>
|
|
|
|
struct amdgpu_device;
|
|
|
|
#ifdef CONFIG_LOCKDEP
|
|
|
|
/**
|
|
* amdgpu_lockdep_init - Train lockdep on correct lock ordering
|
|
*
|
|
* Call once during module init to establish the lock dependency chain.
|
|
*/
|
|
int amdgpu_lockdep_init(void);
|
|
|
|
/**
|
|
* amdgpu_lockdep_set_class - Associate lock class keys with real locks
|
|
* @adev: AMDGPU device
|
|
*
|
|
* Call during device init to associate lock classes with actual locks.
|
|
*/
|
|
void amdgpu_lockdep_set_class(struct amdgpu_device *adev);
|
|
|
|
#else /* !CONFIG_LOCKDEP */
|
|
|
|
static inline int amdgpu_lockdep_init(void) { return 0; }
|
|
static inline void amdgpu_lockdep_set_class(struct amdgpu_device *adev) {}
|
|
|
|
#endif /* CONFIG_LOCKDEP */
|
|
|
|
#endif /* __AMDGPU_LOCKDEP_H__ */
|