drm/msm: Add priv->mm_lock to protect active/inactive lists

Rather than relying on the big dev->struct_mutex hammer, introduce a
more specific lock for protecting the bo lists.

Change-Id: I4c876a1c3ae51ff62372703a99a8daff0c4a7950
Signed-off-by: Rob Clark <robdclark@chromium.org>
Git-commit: d984457b31c4c53d2af374d5e78b3eb64debd483
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
[samtran@codeaurora.org: avoid changes related to debugfs and shrinker]
Signed-off-by: Samantha Tran <samtran@codeaurora.org>
This commit is contained in:
Rob Clark
2021-03-23 13:49:55 -07:00
committed by Samantha Tran
parent a145e793b2
commit fd50a1ec69
3 changed files with 20 additions and 9 deletions

View File

@@ -798,6 +798,7 @@ static int msm_drm_component_init(struct device *dev)
INIT_LIST_HEAD(&priv->client_event_list);
INIT_LIST_HEAD(&priv->inactive_list);
INIT_LIST_HEAD(&priv->vm_client_list);
mutex_init(&priv->mm_lock);
mutex_init(&priv->vm_client_lock);

View File

@@ -888,8 +888,19 @@ struct msm_drm_private {
struct msm_rd_state *hangrd; /* debugfs to dump hanging submits */
struct msm_perf_state *perf;
/* list of GEM objects: */
/*
* List of inactive GEM objects. Every bo is either in the inactive_list
* or gpu->active_list (for the gpu it is active on[1])
*
* These lists are protected by mm_lock. If struct_mutex is involved, it
* should be aquired prior to mm_lock. One should *not* hold mm_lock in
* get_pages()/vmap()/etc paths, as they can trigger the shrinker.
*
* [1] if someone ever added support for the old 2d cores, there could be
* more than one gpu object
*/
struct list_head inactive_list;
struct mutex mm_lock;
/* worker for delayed free of objects: */
struct work_struct free_work;

View File

@@ -1017,11 +1017,15 @@ void msm_gem_free_object(struct drm_gem_object *obj)
static void free_object(struct msm_gem_object *msm_obj)
{
struct drm_gem_object *obj = &msm_obj->base;
struct drm_device *dev = obj->dev;
struct msm_drm_private *priv = dev->dev_private;
/* object should not be on active list: */
WARN_ON(is_active(msm_obj));
mutex_lock(&priv->mm_lock);
list_del(&msm_obj->mm_list);
mutex_unlock(&priv->mm_lock);
mutex_lock(&msm_obj->lock);
@@ -1149,14 +1153,9 @@ static int msm_gem_new_impl(struct drm_device *dev,
msm_obj->in_active_list = false;
msm_obj->obj_dirty = false;
if (struct_mutex_locked) {
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
} else {
mutex_lock(&dev->struct_mutex);
list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
mutex_unlock(&dev->struct_mutex);
}
mutex_lock(&priv->mm_lock);
list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
mutex_unlock(&priv->mm_lock);
*obj = &msm_obj->base;