diff options
| author | Alice Ryhl <aliceryhl@google.com> | 2025-08-27 13:38:39 +0000 |
|---|---|---|
| committer | Danilo Krummrich <dakr@kernel.org> | 2025-08-28 12:40:43 +0200 |
| commit | 3c8d31b8937a7ee6e5de74f0274810b8705d77ea (patch) | |
| tree | d5eb54a59449cc8f7463e8fafbb6ac1c03bf7c85 /include | |
| parent | 69013f52b4b6782db6941f83b6ff1be123bfa9e5 (diff) | |
gpuvm: remove gem.gpuva.lock_dep_map
Since all users of gem.gpuva.lock_dep_map now rely on the mutex directly
in gpuva, we may remove it. Whether the mutex is used is now tracked by
a flag in gpuvm rather than by whether lock_dep_map is null.
Note that a GEM object may not be pushed to multiple gpuvms that
disagree on the value of this new flag. But that's okay because a single
driver should use the same locking scheme everywhere, and a GEM object
is driver specific (when a GEM is exported with prime, a new GEM object
instance is created from the backing dma-buf).
The flag is present even with CONFIG_LOCKDEP=n because the intent is
that the flag will also cause vm_bo cleanup to become deferred. However,
that will happen in a follow-up patch.
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250827-gpuva-mutex-in-gem-v3-3-bd89f5a82c0d@google.com
[ Use lockdep_is_held() instead of lock_is_held(). - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/drm/drm_gem.h | 41 | ||||
| -rw-r--r-- | include/drm/drm_gpuvm.h | 30 |
2 files changed, 42 insertions, 29 deletions
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index a995c0c1b63c..8d48d2af2649 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -399,6 +399,12 @@ struct drm_gem_object { /** * @gpuva: Fields used by GPUVM to manage mappings pointing to this GEM object. + * + * When DRM_GPUVM_IMMEDIATE_MODE is set, this list is protected by the + * mutex. Otherwise, the list is protected by the GEMs &dma_resv lock. + * + * Note that all entries in this list must agree on whether + * DRM_GPUVM_IMMEDIATE_MODE is set. */ struct { /** @@ -412,17 +418,14 @@ struct drm_gem_object { /** * @gpuva.lock: lock protecting access to &drm_gem_object.gpuva.list - * when the resv lock can't be used. + * when DRM_GPUVM_IMMEDIATE_MODE is used. * - * Should only be used when the VM is being modified in a fence - * signalling path, otherwise you should use &drm_gem_object.resv to - * protect accesses to &drm_gem_object.gpuva.list. + * Only used when DRM_GPUVM_IMMEDIATE_MODE is set. It should be + * safe to take this mutex during the fence signalling path, so + * do not allocate memory while holding this lock. Otherwise, + * the &dma_resv lock should be used. */ struct mutex lock; - -#ifdef CONFIG_LOCKDEP - struct lockdep_map *lock_dep_map; -#endif } gpuva; /** @@ -607,26 +610,12 @@ static inline bool drm_gem_is_imported(const struct drm_gem_object *obj) } #ifdef CONFIG_LOCKDEP -/** - * drm_gem_gpuva_set_lock() - Set the lock protecting accesses to the gpuva list. - * @obj: the &drm_gem_object - * @lock: the lock used to protect the gpuva list. The locking primitive - * must contain a dep_map field. - * - * Call this if you're not proctecting access to the gpuva list with the - * dma-resv lock, but with a custom lock. - */ -#define drm_gem_gpuva_set_lock(obj, lock) \ - if (!WARN((obj)->gpuva.lock_dep_map, \ - "GEM GPUVA lock should be set only once.")) \ - (obj)->gpuva.lock_dep_map = &(lock)->dep_map -#define drm_gem_gpuva_assert_lock_held(obj) \ - lockdep_assert((obj)->gpuva.lock_dep_map ? \ - lock_is_held((obj)->gpuva.lock_dep_map) : \ +#define drm_gem_gpuva_assert_lock_held(gpuvm, obj) \ + lockdep_assert(drm_gpuvm_immediate_mode(gpuvm) ? \ + lockdep_is_held(&(obj)->gpuva.lock) : \ dma_resv_held((obj)->resv)) #else -#define drm_gem_gpuva_set_lock(obj, lock) do {} while (0) -#define drm_gem_gpuva_assert_lock_held(obj) do {} while (0) +#define drm_gem_gpuva_assert_lock_held(gpuvm, obj) do {} while (0) #endif /** diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index 4a22b9d848f7..727b8f336fad 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -197,9 +197,19 @@ enum drm_gpuvm_flags { DRM_GPUVM_RESV_PROTECTED = BIT(0), /** + * @DRM_GPUVM_IMMEDIATE_MODE: use the locking scheme for GEMs designed + * for modifying the GPUVM during the fence signalling path + * + * When set, gpuva.lock is used to protect gpuva.list in all GEM + * objects associated with this GPUVM. Otherwise, the GEMs dma-resv is + * used. + */ + DRM_GPUVM_IMMEDIATE_MODE = BIT(1), + + /** * @DRM_GPUVM_USERBITS: user defined bits */ - DRM_GPUVM_USERBITS = BIT(1), + DRM_GPUVM_USERBITS = BIT(2), }; /** @@ -370,6 +380,19 @@ drm_gpuvm_resv_protected(struct drm_gpuvm *gpuvm) } /** + * drm_gpuvm_immediate_mode() - indicates whether &DRM_GPUVM_IMMEDIATE_MODE is + * set + * @gpuvm: the &drm_gpuvm + * + * Returns: true if &DRM_GPUVM_IMMEDIATE_MODE is set, false otherwise. + */ +static inline bool +drm_gpuvm_immediate_mode(struct drm_gpuvm *gpuvm) +{ + return gpuvm->flags & DRM_GPUVM_IMMEDIATE_MODE; +} + +/** * drm_gpuvm_resv() - returns the &drm_gpuvm's &dma_resv * @gpuvm__: the &drm_gpuvm * @@ -742,9 +765,10 @@ drm_gpuvm_bo_gem_evict(struct drm_gem_object *obj, bool evict) { struct drm_gpuvm_bo *vm_bo; - drm_gem_gpuva_assert_lock_held(obj); - drm_gem_for_each_gpuvm_bo(vm_bo, obj) + drm_gem_for_each_gpuvm_bo(vm_bo, obj) { + drm_gem_gpuva_assert_lock_held(vm_bo->vm, obj); drm_gpuvm_bo_evict(vm_bo, evict); + } } void drm_gpuvm_bo_extobj_add(struct drm_gpuvm_bo *vm_bo); |
