summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeepak Kumar <dkumar@codeaurora.org>2017-05-05 15:42:26 +0530
committerDeepak Kumar <dkumar@codeaurora.org>2017-05-11 17:48:44 +0530
commit281fcb5e184b9d1074dd404016cebacce12a8664 (patch)
treedb11b9e4ff287ec16ad934f0d58637b127ae7c26
parent9416e47b01b79bdde69200f10ffa0992dc407ec2 (diff)
msm: kgsl: Offload mementry destroy work to separate thread
Any memory free ioctl doesn't need to be blocked till the corresponding mementry is destroyed. This change defers the mementry put to unblock all memory free ioctls immediately. This is done to reduce the time spent by user applications in waiting for memory to be freed. Change-Id: Iaa37ac5dbdedc3d02c41886c2bdf7f3d016176ac Signed-off-by: Deepak Kumar <dkumar@codeaurora.org>
-rw-r--r--drivers/gpu/msm/kgsl.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 986026aa1b66..50f55abd6db8 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -255,6 +255,13 @@ static void _deferred_put(struct work_struct *work)
kgsl_mem_entry_put(entry);
}
+static inline void
+kgsl_mem_entry_put_deferred(struct kgsl_mem_entry *entry)
+{
+ if (entry)
+ queue_work(kgsl_driver.mem_workqueue, &entry->work);
+}
+
static inline struct kgsl_mem_entry *
kgsl_mem_entry_create(void)
{
@@ -265,6 +272,7 @@ kgsl_mem_entry_create(void)
/* put this ref in the caller functions after init */
kref_get(&entry->refcount);
+ INIT_WORK(&entry->work, _deferred_put);
}
return entry;
}
@@ -1860,7 +1868,7 @@ long kgsl_ioctl_sharedmem_free(struct kgsl_device_private *dev_priv,
return -EINVAL;
ret = gpumem_free_entry(entry);
- kgsl_mem_entry_put(entry);
+ kgsl_mem_entry_put_deferred(entry);
return ret;
}
@@ -1878,7 +1886,7 @@ long kgsl_ioctl_gpumem_free_id(struct kgsl_device_private *dev_priv,
return -EINVAL;
ret = gpumem_free_entry(entry);
- kgsl_mem_entry_put(entry);
+ kgsl_mem_entry_put_deferred(entry);
return ret;
}
@@ -1915,8 +1923,7 @@ static void gpuobj_free_fence_func(void *priv)
{
struct kgsl_mem_entry *entry = priv;
- INIT_WORK(&entry->work, _deferred_put);
- queue_work(kgsl_driver.mem_workqueue, &entry->work);
+ kgsl_mem_entry_put_deferred(entry);
}
static long gpuobj_free_on_fence(struct kgsl_device_private *dev_priv,
@@ -1980,7 +1987,7 @@ long kgsl_ioctl_gpuobj_free(struct kgsl_device_private *dev_priv,
else
ret = -EINVAL;
- kgsl_mem_entry_put(entry);
+ kgsl_mem_entry_put_deferred(entry);
return ret;
}
@@ -3355,7 +3362,13 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv,
if (entry == NULL)
return -EINVAL;
+ if (!kgsl_mem_entry_set_pend(entry)) {
+ kgsl_mem_entry_put(entry);
+ return -EBUSY;
+ }
+
if (entry->memdesc.cur_bindings != 0) {
+ kgsl_mem_entry_unset_pend(entry);
kgsl_mem_entry_put(entry);
return -EINVAL;
}
@@ -3364,7 +3377,7 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv,
/* One put for find_id(), one put for the kgsl_mem_entry_create() */
kgsl_mem_entry_put(entry);
- kgsl_mem_entry_put(entry);
+ kgsl_mem_entry_put_deferred(entry);
return 0;
}
@@ -3424,7 +3437,13 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv,
if (entry == NULL)
return -EINVAL;
+ if (!kgsl_mem_entry_set_pend(entry)) {
+ kgsl_mem_entry_put(entry);
+ return -EBUSY;
+ }
+
if (entry->bind_tree.rb_node != NULL) {
+ kgsl_mem_entry_unset_pend(entry);
kgsl_mem_entry_put(entry);
return -EINVAL;
}
@@ -3433,7 +3452,7 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv,
/* One put for find_id(), one put for the kgsl_mem_entry_create() */
kgsl_mem_entry_put(entry);
- kgsl_mem_entry_put(entry);
+ kgsl_mem_entry_put_deferred(entry);
return 0;
}
@@ -4906,7 +4925,7 @@ static int __init kgsl_core_init(void)
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
kgsl_driver.mem_workqueue = alloc_workqueue("kgsl-mementry",
- WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
+ WQ_MEM_RECLAIM, 0);
kgsl_events_init();