summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeepak Kumar <dkumar@codeaurora.org>2016-03-02 16:30:14 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-25 16:03:32 -0700
commitda15ce4aa9cb993f8c3da4623faaf8dab4885e33 (patch)
treeda4036e737eca8c261dd9f5d11a1e062a207af6f
parenteaad873607a2a994a1dd9ce6c310b8b0b765e25f (diff)
msm: kgsl: Avoid racing against context delete while releasing contexts
While releasing contexts take a reference to context inside read rcu lock to avoid racing against context deletion. This will avoid using dangling context pointer in device_release_contexts. Change-Id: I76e787f6dde5a324fec23e81829174bd28134c6c Signed-off-by: Deepak Kumar <dkumar@codeaurora.org>
-rw-r--r--drivers/gpu/msm/kgsl.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 8a8e19cf9f6d..841e7e450baa 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1071,25 +1071,28 @@ static void device_release_contexts(struct kgsl_device_private *dev_priv)
struct kgsl_device *device = dev_priv->device;
struct kgsl_context *context;
int next = 0;
+ int result = 0;
while (1) {
read_lock(&device->context_lock);
context = idr_get_next(&device->context_idr, &next);
- read_unlock(&device->context_lock);
- if (context == NULL)
+ if (context == NULL) {
+ read_unlock(&device->context_lock);
break;
-
- if (context->dev_priv == dev_priv) {
+ } else if (context->dev_priv == dev_priv) {
/*
* Hold a reference to the context in case somebody
* tries to put it while we are detaching
*/
+ result = _kgsl_context_get(context);
+ }
+ read_unlock(&device->context_lock);
- if (_kgsl_context_get(context)) {
- kgsl_context_detach(context);
- kgsl_context_put(context);
- }
+ if (result) {
+ kgsl_context_detach(context);
+ kgsl_context_put(context);
+ result = 0;
}
next = next + 1;