Loading drivers/gpu/msm/kgsl.c +8 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading drivers/gpu/msm/kgsl.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading drivers/gpu/msm/kgsl_sharedmem.c +13 −8 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading @@ -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 Loading
drivers/gpu/msm/kgsl.c +8 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading
drivers/gpu/msm/kgsl.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/gpu/msm/kgsl_sharedmem.c +13 −8 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading @@ -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