msm: kgsl: Fix context reference counting
Get rid of kgsl_find_context. Use instead kgsl_context_get that does
correct RCU read locking around the itr_find and increases the
reference count on the context before returning it. This eliminates
the chance that a context will be destroyed while somebody is still
using it. Of course increased use of kgsl_context_get is accompanied
by kgsl_context_put in all the right places.
Change-Id: Ic0dedbad73d497fd9b451aefad8e5b28d33b829d
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
index b1b11cc..c5b7e91 100644
--- a/drivers/gpu/msm/kgsl_events.c
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -59,7 +59,7 @@
return -EINVAL;
if (id != KGSL_MEMSTORE_GLOBAL) {
- context = idr_find(&device->context_idr, id);
+ context = kgsl_context_get(device, id);
if (context == NULL)
return -EINVAL;
}
@@ -75,12 +75,15 @@
if (timestamp_cmp(cur_ts, ts) >= 0) {
trace_kgsl_fire_event(id, ts, 0);
cb(device, priv, id, ts);
+ kgsl_context_put(context);
return 0;
}
event = kzalloc(sizeof(*event), GFP_KERNEL);
- if (event == NULL)
+ if (event == NULL) {
+ kgsl_context_put(context);
return -ENOMEM;
+ }
event->context = context;
event->timestamp = ts;
@@ -91,10 +94,6 @@
trace_kgsl_register_event(id, ts);
- /* inc refcount to avoid race conditions in cleanup */
- if (context)
- kgsl_context_get(context);
-
/* Add the event to either the owning context or the global list */
if (context) {
@@ -143,7 +142,7 @@
* Increment the refcount to avoid freeing the context while
* cancelling its events
*/
- kgsl_context_get(context);
+ _kgsl_context_get(context);
/* Remove ourselves from the master pending list */
list_del_init(&context->events_list);
@@ -320,7 +319,7 @@
* Increment the refcount to make sure that the list_del_init
* is called with a valid context's list
*/
- kgsl_context_get(context);
+ _kgsl_context_get(context);
/*
* If kgsl_timestamp_expired_context returns 0 then it no longer
* has any pending events and can be removed from the list