msm: kgsl: Use event workqueue for event work instead of RT Kthread worker

Currently, both dispatcher work and event work is handled by real time
kthread worker. This results in two problems:

1) Event work can result in freeing memory either as part of
free on timestamp or while putting a context. As freeing memory
can take time it shouldn't be done as part of RT thread as it can
result in hogging CPU for longer duration and not giving chance to
other tasks to run.

2) Event work remains unprocessed till kthread worker finishes
dispatcher work. As dispatcher work first schedules the event
work for previously retired commands and then tries to submit
new commands. The scheduled event work doesn't get processed till
dispatcher work finishes. This can result in even longer delays
in case dispatcher work gets blocked after scheduling event work
because of mutexes locks etc.

To avoid this, use event workqueue for event work. This will decouple
both dispatcher and event work and will also make sure that high
latency work like freeing-up memory is not done as part of RT thread.

Change-Id: I74734a1bc177feecaac6626109349752da44da80
Signed-off-by: Deepak Kumar <dkumar@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index b9f5017..8456be7 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -315,7 +315,7 @@
 	void *priv;
 	struct list_head node;
 	unsigned int created;
-	struct kthread_work work;
+	struct work_struct work;
 	int result;
 	struct kgsl_event_group *group;
 };
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
index 759a966..47582da 100644
--- a/drivers/gpu/msm/kgsl_events.c
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2017, 2019, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -32,7 +32,7 @@
 {
 	list_del(&event->node);
 	event->result = result;
-	kthread_queue_work(&kgsl_driver.worker, &event->work);
+	queue_work(device->events_wq, &event->work);
 }
 
 /**
@@ -42,7 +42,7 @@
  * Each event callback has its own work struct and is run on a event specific
  * workqeuue.  This is the worker that queues up the event callback function.
  */
-static void _kgsl_event_worker(struct kthread_work *work)
+static void _kgsl_event_worker(struct work_struct *work)
 {
 	struct kgsl_event *event = container_of(work, struct kgsl_event, work);
 	int id = KGSL_CONTEXT_ID(event->context);
@@ -286,7 +286,7 @@
 	event->created = jiffies;
 	event->group = group;
 
-	kthread_init_work(&event->work, _kgsl_event_worker);
+	INIT_WORK(&event->work, _kgsl_event_worker);
 
 	trace_kgsl_register_event(KGSL_CONTEXT_ID(context), timestamp, func);
 
@@ -301,7 +301,7 @@
 
 	if (timestamp_cmp(retired, timestamp) >= 0) {
 		event->result = KGSL_EVENT_RETIRED;
-		kthread_queue_work(&kgsl_driver.worker, &event->work);
+		queue_work(device->events_wq, &event->work);
 		spin_unlock(&group->lock);
 		return 0;
 	}