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

Commit c984db76 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Use worker to put refcount on mem entry"

parents dfa16272 0b1bc8a2
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -248,6 +248,13 @@ static void _deferred_put(struct work_struct *work)
	kgsl_mem_entry_put(entry);
}

/* Use a worker to put the refcount on mem entry */
void kgsl_mem_entry_put_deferred(struct kgsl_mem_entry *entry)
{
	INIT_WORK(&entry->work, _deferred_put);
	queue_work(kgsl_driver.mem_workqueue, &entry->work);
}

static struct kgsl_mem_entry *kgsl_mem_entry_create(void)
{
	struct kgsl_mem_entry *entry = kzalloc(sizeof(*entry), GFP_KERNEL);
@@ -2336,8 +2343,7 @@ static bool gpuobj_free_fence_func(void *priv)
			entry->memdesc.gpuaddr, entry->memdesc.size,
			entry->memdesc.flags);

	INIT_WORK(&entry->work, _deferred_put);
	queue_work(kgsl_driver.mem_workqueue, &entry->work);
	kgsl_mem_entry_put_deferred(entry);
	return true;
}

+7 −0
Original line number Diff line number Diff line
@@ -561,6 +561,13 @@ kgsl_mem_entry_put(struct kgsl_mem_entry *entry)
		kref_put(&entry->refcount, kgsl_mem_entry_destroy);
}

/**
 * kgsl_mem_entry_put_deferred() - use a worker to put the refcount
 * on mem entry from a sysfs handler or debugfs handler.
 * @entry - The memory entry
 */
void kgsl_mem_entry_put_deferred(struct kgsl_mem_entry *entry);

/*
 * kgsl_addr_range_overlap() - Checks if 2 ranges overlap
 * @gpuaddr1: Start of first address range
+13 −8
Original line number Diff line number Diff line
@@ -136,7 +136,18 @@ imported_mem_show(struct kgsl_process_private *priv,
			}
		}

		kgsl_mem_entry_put(entry);
		/*
		 * If refcount on mem entry is the last refcount, we will
		 * call kgsl_mem_entry_destroy and detach it from process
		 * list. When there is no refcount on the process private,
		 * we will call kgsl_destroy_process_private to do cleanup.
		 * During cleanup, we will try to remove the same sysfs
		 * node which is in use by the current thread and this
		 * situation will end up in a deadloack.
		 * To avoid this situation, use a worker to put the refcount
		 * on mem entry.
		 */
		kgsl_mem_entry_put_deferred(entry);
		spin_lock(&priv->mem_lock);
	}
	spin_unlock(&priv->mem_lock);
@@ -227,12 +238,6 @@ static ssize_t memtype_sysfs_show(struct kobject *kobj,
	u64 size = 0;
	int id = 0;

	/*
	 * sysfs_remove_file waits for reads to complete before the node is
	 * deleted and process private is freed only once kobj is released.
	 * This implies that priv will not be freed until this function
	 * completes, and no further locking is needed.
	 */
	priv = container_of(kobj, struct kgsl_process_private, kobj_memtype);
	memtype = container_of(attr, struct kgsl_memtype, attr);

@@ -253,7 +258,7 @@ static ssize_t memtype_sysfs_show(struct kobject *kobj,
		if (type == memtype->type)
			size += memdesc->size;

		kgsl_mem_entry_put(entry);
		kgsl_mem_entry_put_deferred(entry);
		spin_lock(&priv->mem_lock);
	}
	spin_unlock(&priv->mem_lock);