Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 562f1c30 authored by Steve Cohen's avatar Steve Cohen
Browse files

drm/msm: use new mutex for protecting address space lists



Added a new list_lock mutex to protect access to the active_list and
clients lists as opposed to relying on the global dev->struct_mutex.
This is needed since in porting aspace from 4.9 to 4.14, the device
struct_mutex is not always used by the upper layers which access
these lists.

Change-Id: I9d3714de2a8be6021a0554e4fe6a4f4dcd3f71d7
Signed-off-by: default avatarSteve Cohen <cohens@codeaurora.org>
parent 8a0b4875
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -433,8 +433,11 @@ int msm_gem_get_iova(struct drm_gem_object *obj,

	*iova = vma->iova;

	if (aspace && aspace->domain_attached)
	if (aspace && aspace->domain_attached) {
		mutex_lock(&aspace->list_lock);
		msm_gem_add_obj_to_aspace_active_list(aspace, obj);
		mutex_unlock(&aspace->list_lock);
	}

	mutex_unlock(&msm_obj->lock);
	return 0;
@@ -487,7 +490,7 @@ void msm_gem_aspace_domain_attach_detach_update(
	if (!aspace)
		return;

	mutex_lock(&aspace->dev->struct_mutex);
	mutex_lock(&aspace->list_lock);
	if (is_detach) {
		/* Indicate to clients domain is getting detached */
		list_for_each_entry(aclient, &aspace->clients, list) {
@@ -513,7 +516,7 @@ void msm_gem_aspace_domain_attach_detach_update(
			obj = &msm_obj->base;
			ret = msm_gem_get_iova(obj, aspace, &iova);
			if (ret) {
				mutex_unlock(&aspace->dev->struct_mutex);
				mutex_unlock(&aspace->list_lock);
				return;
			}
		}
@@ -525,7 +528,7 @@ void msm_gem_aspace_domain_attach_detach_update(
						is_detach);
		}
	}
	mutex_unlock(&aspace->dev->struct_mutex);
	mutex_unlock(&aspace->list_lock);
}

int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
@@ -644,7 +647,12 @@ void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass)
	mutex_lock_nested(&msm_obj->lock, subclass);

	put_iova(obj);
	msm_gem_remove_obj_from_aspace_active_list(msm_obj->aspace, obj);
	if (msm_obj->aspace) {
		mutex_lock(&msm_obj->aspace->list_lock);
		msm_gem_remove_obj_from_aspace_active_list(msm_obj->aspace,
				obj);
		mutex_unlock(&msm_obj->aspace->list_lock);
	}

	msm_gem_vunmap_locked(obj);

@@ -878,7 +886,12 @@ void msm_gem_free_object(struct drm_gem_object *obj)
	mutex_lock(&msm_obj->lock);

	put_iova(obj);
	msm_gem_remove_obj_from_aspace_active_list(msm_obj->aspace, obj);
	if (msm_obj->aspace) {
		mutex_lock(&msm_obj->aspace->list_lock);
		msm_gem_remove_obj_from_aspace_active_list(msm_obj->aspace,
				obj);
		mutex_unlock(&msm_obj->aspace->list_lock);
	}

	if (obj->import_attach) {
		if (msm_obj->vaddr)
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct msm_gem_address_space {
	struct list_head active_list;
	/* list of clients */
	struct list_head clients;
	struct mutex list_lock; /* Protects active_list & clients */
};

struct msm_gem_vma {
+8 −7
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ static void smmu_aspace_add_to_active(
		struct msm_gem_address_space *aspace,
		struct msm_gem_object *msm_obj)
{
	WARN_ON(!mutex_is_locked(&aspace->dev->struct_mutex));
	WARN_ON(!mutex_is_locked(&aspace->list_lock));
	list_move_tail(&msm_obj->iova_list, &aspace->active_list);
}

@@ -75,7 +75,7 @@ static void smmu_aspace_remove_from_active(
{
	struct msm_gem_object *msm_obj, *next;

	WARN_ON(!mutex_is_locked(&aspace->dev->struct_mutex));
	WARN_ON(!mutex_is_locked(&aspace->list_lock));

	list_for_each_entry_safe(msm_obj, next, &aspace->active_list,
			iova_list) {
@@ -109,18 +109,18 @@ static int smmu_aspace_register_cb(
	INIT_LIST_HEAD(&aclient->list);

	/* check if callback is already registered */
	mutex_lock(&aspace->dev->struct_mutex);
	mutex_lock(&aspace->list_lock);
	list_for_each_entry(temp, &aspace->clients, list) {
		if ((temp->cb == aclient->cb) &&
			(temp->cb_data == aclient->cb_data)) {
			kfree(aclient);
			mutex_unlock(&aspace->dev->struct_mutex);
			mutex_unlock(&aspace->list_lock);
			return -EEXIST;
		}
	}

	list_move_tail(&aclient->list, &aspace->clients);
	mutex_unlock(&aspace->dev->struct_mutex);
	mutex_unlock(&aspace->list_lock);

	return 0;
}
@@ -136,7 +136,7 @@ static int smmu_aspace_unregister_cb(
	if (!aspace || !cb)
		return -EINVAL;

	mutex_lock(&aspace->dev->struct_mutex);
	mutex_lock(&aspace->list_lock);
	list_for_each_entry(aclient, &aspace->clients, list) {
		if ((aclient->cb == cb) &&
			(aclient->cb_data == cb_data)) {
@@ -146,7 +146,7 @@ static int smmu_aspace_unregister_cb(
			break;
		}
	}
	mutex_unlock(&aspace->dev->struct_mutex);
	mutex_unlock(&aspace->list_lock);

	return rc;
}
@@ -182,6 +182,7 @@ msm_gem_smmu_address_space_create(struct drm_device *dev, struct msm_mmu *mmu,
	INIT_LIST_HEAD(&aspace->active_list);
	INIT_LIST_HEAD(&aspace->clients);
	kref_init(&aspace->kref);
	mutex_init(&aspace->list_lock);

	return aspace;
}