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

Commit 281fcb5e authored by Deepak Kumar's avatar Deepak Kumar
Browse files

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: default avatarDeepak Kumar <dkumar@codeaurora.org>
parent 9416e47b
Loading
Loading
Loading
Loading
+27 −8
Original line number Diff line number Diff line
@@ -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();