mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
Merge "msm: kgsl: Use worker to put refcount on mem entry"
This commit is contained in:
commit
c984db7626
3 changed files with 28 additions and 10 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue