diff options
| author | Jordan Crouse <jcrouse@codeaurora.org> | 2016-05-31 11:24:22 -0600 |
|---|---|---|
| committer | Dumpeti Sathish Kumar <sathyanov14@codeaurora.org> | 2016-11-29 12:32:52 +0530 |
| commit | eed663a48bec729bb66aaad18ab3fac3b7269581 (patch) | |
| tree | b62d33819462fe22ab8bb5fbfe414ddfc100709d /drivers/gpu | |
| parent | 04947ea3d87d476354f8dad45a668e4137196efa (diff) | |
msm: kgsl: Reserve a context ID slot but don't populate immediately
When creating a context allocate an ID but don't populate the slot
with the context pointer until we are done setup up the rest of the
process. This avoids a race if somebody tries to free the same
identifier before the create operation is complete.
Change-Id: Ic0dedbadca5b4cc4ce567afad48a33078b549439
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Dumpeti Sathish Kumar <sathyanov14@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/msm/kgsl.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 699d99651f2c..e2044784e5f9 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -491,21 +491,18 @@ void kgsl_context_dump(struct kgsl_context *context) EXPORT_SYMBOL(kgsl_context_dump); /* Allocate a new context ID */ -static int _kgsl_get_context_id(struct kgsl_device *device, - struct kgsl_context *context) +static int _kgsl_get_context_id(struct kgsl_device *device) { int id; idr_preload(GFP_KERNEL); write_lock(&device->context_lock); - id = idr_alloc(&device->context_idr, context, 1, + /* Allocate the slot but don't put a pointer in it yet */ + id = idr_alloc(&device->context_idr, NULL, 1, KGSL_MEMSTORE_MAX, GFP_NOWAIT); write_unlock(&device->context_lock); idr_preload_end(); - if (id > 0) - context->id = id; - return id; } @@ -529,7 +526,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, char name[64]; int ret = 0, id; - id = _kgsl_get_context_id(device, context); + id = _kgsl_get_context_id(device); if (id == -ENOSPC) { /* * Before declaring that there are no contexts left try @@ -538,7 +535,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, */ flush_workqueue(device->events_wq); - id = _kgsl_get_context_id(device, context); + id = _kgsl_get_context_id(device); } if (id < 0) { @@ -550,6 +547,8 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, return id; } + context->id = id; + kref_init(&context->refcount); /* * Get a refernce to the process private so its not destroyed, until @@ -1733,6 +1732,12 @@ long kgsl_ioctl_drawctxt_create(struct kgsl_device_private *dev_priv, goto done; } trace_kgsl_context_create(dev_priv->device, context, param->flags); + + /* Commit the pointer to the context in context_idr */ + write_lock(&device->context_lock); + idr_replace(&device->context_idr, context, context->id); + write_unlock(&device->context_lock); + param->drawctxt_id = context->id; done: return result; |
