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>
This commit is contained in:
parent
04947ea3d8
commit
eed663a48b
1 changed files with 13 additions and 8 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue