drm/msm: Separate locking of buffer resources from struct_mutex
Buffer object specific resources like pages, domains, sg list need not be protected with struct_mutex. They can be protected with a buffer object level lock. This simplifies locking and makes it easier to avoid potential recursive locking scenarios for SVM involving mmap_sem and struct_mutex. This also removes unnecessary serialization when creating buffer objects, and also between buffer object creation and GPU command submission. Signed-off-by: Sushmita Susheelendra <ssusheel@codeaurora.org> [robclark: squash in handling new locking for shrinker] Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
committed by
Rob Clark
parent
816fa34c05
commit
0e08270a1f
@@ -31,6 +31,7 @@ struct msm_gem_address_space {
|
||||
* and position mm_node->start is in # of pages:
|
||||
*/
|
||||
struct drm_mm mm;
|
||||
spinlock_t lock; /* Protects drm_mm node allocation/removal */
|
||||
struct msm_mmu *mmu;
|
||||
struct kref kref;
|
||||
};
|
||||
@@ -89,6 +90,7 @@ struct msm_gem_object {
|
||||
* an IOMMU. Also used for stolen/splashscreen buffer.
|
||||
*/
|
||||
struct drm_mm_node *vram_node;
|
||||
struct mutex lock; /* Protects resources associated with bo */
|
||||
};
|
||||
#define to_msm_bo(x) container_of(x, struct msm_gem_object, base)
|
||||
|
||||
@@ -99,6 +101,7 @@ static inline bool is_active(struct msm_gem_object *msm_obj)
|
||||
|
||||
static inline bool is_purgeable(struct msm_gem_object *msm_obj)
|
||||
{
|
||||
WARN_ON(!mutex_is_locked(&msm_obj->base.dev->struct_mutex));
|
||||
return (msm_obj->madv == MSM_MADV_DONTNEED) && msm_obj->sgt &&
|
||||
!msm_obj->base.dma_buf && !msm_obj->base.import_attach;
|
||||
}
|
||||
@@ -108,6 +111,25 @@ static inline bool is_vunmapable(struct msm_gem_object *msm_obj)
|
||||
return (msm_obj->vmap_count == 0) && msm_obj->vaddr;
|
||||
}
|
||||
|
||||
/* The shrinker can be triggered while we hold objA->lock, and need
|
||||
* to grab objB->lock to purge it. Lockdep just sees these as a single
|
||||
* class of lock, so we use subclasses to teach it the difference.
|
||||
*
|
||||
* OBJ_LOCK_NORMAL is implicit (ie. normal mutex_lock() call), and
|
||||
* OBJ_LOCK_SHRINKER is used by shrinker.
|
||||
*
|
||||
* It is *essential* that we never go down paths that could trigger the
|
||||
* shrinker for a purgable object. This is ensured by checking that
|
||||
* msm_obj->madv == MSM_MADV_WILLNEED.
|
||||
*/
|
||||
enum msm_gem_lock {
|
||||
OBJ_LOCK_NORMAL,
|
||||
OBJ_LOCK_SHRINKER,
|
||||
};
|
||||
|
||||
void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass);
|
||||
void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass);
|
||||
|
||||
/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc,
|
||||
* associated with the cmdstream submission for synchronization (and
|
||||
* make it easier to unwind when things go wrong, etc). This only
|
||||
|
||||
Reference in New Issue
Block a user