diff options
| author | Deepak Kumar <dkumar@codeaurora.org> | 2016-03-02 16:30:14 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-25 16:03:32 -0700 |
| commit | da15ce4aa9cb993f8c3da4623faaf8dab4885e33 (patch) | |
| tree | da4036e737eca8c261dd9f5d11a1e062a207af6f | |
| parent | eaad873607a2a994a1dd9ce6c310b8b0b765e25f (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.c | 19 |
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; |
