msm: kgsl: Do INIT_WORK() just before queueing a deferred mem entry
gpuobj_free_on_fence() is used infrequently enough that it doesn't make sense to do INIT_WORK() when the memory object is created, especially if debug objects are enabled because INIT_WORK() will go off and do a bunch of accounting that we don't need. Do the INIT_WORK() just before queueing in those rare cases that this actually happens. CRs-Fixed: 1009183 Change-Id: Ic0dedbad1015883788e12815806e3249a1e09b21 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
committed by
Carter Cooper
parent
340d8516dc
commit
dd9a770d23
@@ -233,6 +233,8 @@ int kgsl_readtimestamp(struct kgsl_device *device, void *priv,
|
||||
}
|
||||
EXPORT_SYMBOL(kgsl_readtimestamp);
|
||||
|
||||
static long gpumem_free_entry(struct kgsl_mem_entry *entry);
|
||||
|
||||
/* Scheduled by kgsl_mem_entry_put_deferred() */
|
||||
static void _deferred_put(struct work_struct *work)
|
||||
{
|
||||
@@ -247,10 +249,8 @@ kgsl_mem_entry_create(void)
|
||||
{
|
||||
struct kgsl_mem_entry *entry = kzalloc(sizeof(*entry), GFP_KERNEL);
|
||||
|
||||
if (entry != NULL) {
|
||||
if (entry != NULL)
|
||||
kref_init(&entry->refcount);
|
||||
INIT_WORK(&entry->work, _deferred_put);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
@@ -1857,7 +1857,10 @@ static long gpuobj_free_on_timestamp(struct kgsl_device_private *dev_priv,
|
||||
|
||||
static void gpuobj_free_fence_func(void *priv)
|
||||
{
|
||||
kgsl_mem_entry_put_deferred((struct kgsl_mem_entry *) priv);
|
||||
struct kgsl_mem_entry *entry = priv;
|
||||
|
||||
INIT_WORK(&entry->work, _deferred_put);
|
||||
queue_work(kgsl_driver.mem_workqueue, &entry->work);
|
||||
}
|
||||
|
||||
static long gpuobj_free_on_fence(struct kgsl_device_private *dev_priv,
|
||||
@@ -4099,8 +4102,9 @@ static int __init kgsl_core_init(void)
|
||||
INIT_LIST_HEAD(&kgsl_driver.pagetable_list);
|
||||
|
||||
kgsl_driver.workqueue = create_singlethread_workqueue("kgsl-workqueue");
|
||||
kgsl_driver.mem_workqueue =
|
||||
create_singlethread_workqueue("kgsl-mementry");
|
||||
|
||||
kgsl_driver.mem_workqueue = alloc_workqueue("kgsl-mementry",
|
||||
WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
|
||||
|
||||
kgsl_events_init();
|
||||
|
||||
|
||||
@@ -473,21 +473,6 @@ kgsl_mem_entry_put(struct kgsl_mem_entry *entry)
|
||||
kref_put(&entry->refcount, kgsl_mem_entry_destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* kgsl_mem_entry_put_deferred() - Schedule a task to put the memory entry
|
||||
* @entry: Mem entry to put
|
||||
*
|
||||
* This function is for atomic contexts where a normal kgsl_mem_entry_put()
|
||||
* would result in the memory entry getting destroyed and possibly taking
|
||||
* mutexes along the way. Schedule the work to happen outside of the atomic
|
||||
* context.
|
||||
*/
|
||||
static inline void kgsl_mem_entry_put_deferred(struct kgsl_mem_entry *entry)
|
||||
{
|
||||
if (entry != NULL)
|
||||
queue_work(kgsl_driver.mem_workqueue, &entry->work);
|
||||
}
|
||||
|
||||
/*
|
||||
* kgsl_addr_range_overlap() - Checks if 2 ranges overlap
|
||||
* @gpuaddr1: Start of first address range
|
||||
|
||||
Reference in New Issue
Block a user