Merge "msm: kgsl: Remove the "global" locking from the ioctl path"
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 12fa799..d163317 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -461,6 +461,7 @@
struct kgsl_perfcounter_read_group __user *reads, unsigned int count)
{
struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
+ struct kgsl_device *device = &adreno_dev->dev;
struct adreno_perfcount_group *group;
struct kgsl_perfcounter_read_group *list = NULL;
unsigned int i, j;
@@ -488,6 +489,13 @@
goto done;
}
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ ret = kgsl_active_count_get(device);
+ if (ret) {
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ goto done;
+ }
+
/* list iterator */
for (j = 0; j < count; j++) {
@@ -496,7 +504,7 @@
/* Verify that the group ID is within range */
if (list[j].groupid >= counters->group_count) {
ret = -EINVAL;
- goto done;
+ break;
}
group = &(counters->groups[list[j].groupid]);
@@ -512,11 +520,13 @@
}
}
+ kgsl_active_count_put(device);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
/* write the data */
- if (copy_to_user(reads, list,
- sizeof(struct kgsl_perfcounter_read_group) *
- count) != 0)
- ret = -EFAULT;
+ if (ret == 0)
+ ret = copy_to_user(reads, list,
+ sizeof(struct kgsl_perfcounter_read_group) * count);
done:
kfree(list);
@@ -592,8 +602,11 @@
unsigned int *max_counters)
{
struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
+ struct kgsl_device *device = &adreno_dev->dev;
struct adreno_perfcount_group *group;
- unsigned int i;
+ unsigned int i, t;
+ int ret;
+ unsigned int *buf;
*max_counters = 0;
@@ -603,6 +616,8 @@
if (groupid >= counters->group_count)
return -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
group = &(counters->groups[groupid]);
*max_counters = group->reg_count;
@@ -610,20 +625,28 @@
* if NULL countable or *count of zero, return max reg_count in
* *max_counters and return success
*/
- if (countables == NULL || count == 0)
+ if (countables == NULL || count == 0) {
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return 0;
-
- /*
- * Go through all available counters. Write upto *count * countable
- * values.
- */
- for (i = 0; i < group->reg_count && i < count; i++) {
- if (copy_to_user(&countables[i], &(group->regs[i].countable),
- sizeof(unsigned int)) != 0)
- return -EFAULT;
}
- return 0;
+ t = min_t(int, group->reg_count, count);
+
+ buf = kmalloc(t * sizeof(unsigned int), GFP_KERNEL);
+ if (buf == NULL) {
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < t; i++)
+ buf[i] = group->regs[i].countable;
+
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
+ ret = copy_to_user(countables, buf, sizeof(unsigned int) * t);
+ kfree(buf);
+
+ return ret;
}
static inline void refcount_group(struct adreno_perfcount_group *group,
@@ -2832,6 +2855,8 @@
break;
}
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
if (enable) {
device->pwrctrl.ctrl_flags = 0;
adreno_dev->fast_hang_detect = 1;
@@ -2851,6 +2876,7 @@
kgsl_pwrscale_disable(device);
}
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
status = 0;
}
break;
@@ -2869,10 +2895,13 @@
context = kgsl_context_get_owner(dev_priv,
constraint.context_id);
+
if (context == NULL)
break;
+
status = adreno_set_constraint(device, context,
&constraint);
+
kgsl_context_put(context);
}
break;
@@ -3354,24 +3383,28 @@
}
case IOCTL_KGSL_PERFCOUNTER_GET: {
struct kgsl_perfcounter_get *get = data;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
/*
* adreno_perfcounter_get() is called by kernel clients
* during start(), so it is not safe to take an
* active count inside this function.
*/
result = kgsl_active_count_get(device);
- if (result)
- break;
- result = adreno_perfcounter_get(adreno_dev, get->groupid,
- get->countable, &get->offset, &get->offset_hi,
- PERFCOUNTER_FLAG_NONE);
- kgsl_active_count_put(device);
+ if (result == 0) {
+ result = adreno_perfcounter_get(adreno_dev,
+ get->groupid, get->countable, &get->offset,
+ &get->offset_hi, PERFCOUNTER_FLAG_NONE);
+ kgsl_active_count_put(device);
+ }
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
break;
}
case IOCTL_KGSL_PERFCOUNTER_PUT: {
struct kgsl_perfcounter_put *put = data;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
result = adreno_perfcounter_put(adreno_dev, put->groupid,
put->countable, PERFCOUNTER_FLAG_NONE);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
break;
}
case IOCTL_KGSL_PERFCOUNTER_QUERY: {
@@ -3383,12 +3416,8 @@
}
case IOCTL_KGSL_PERFCOUNTER_READ: {
struct kgsl_perfcounter_read *read = data;
- result = kgsl_active_count_get(device);
- if (result)
- break;
result = adreno_perfcounter_read_group(adreno_dev,
read->reads, read->count);
- kgsl_active_count_put(device);
break;
}
default:
diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c
index 45075a5..7785f3b 100644
--- a/drivers/gpu/msm/adreno_profile.c
+++ b/drivers/gpu/msm/adreno_profile.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -680,6 +680,15 @@
if (adreno_is_a2xx(adreno_dev))
return -ENOSPC;
+ buf = kmalloc(len + 1, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, user_buf, len)) {
+ size = -EFAULT;
+ goto error_free;
+ }
+
kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
if (adreno_profile_enabled(profile)) {
@@ -688,8 +697,10 @@
}
ret = kgsl_active_count_get(device);
- if (ret)
- return -EINVAL;
+ if (ret) {
+ size = ret;
+ goto error_unlock;
+ }
/*
* When adding/removing assignments, ensure that the GPU is done with
@@ -697,19 +708,13 @@
* GPU and avoid racey conditions.
*/
if (adreno_idle(device)) {
- size = -EINVAL;
+ size = -ETIMEDOUT;
goto error_put;
}
/* clear all shared buffer results */
adreno_profile_process_results(device);
- buf = kmalloc(len + 1, GFP_KERNEL);
- if (!buf) {
- size = -EINVAL;
- goto error_put;
- }
-
pbuf = buf;
/* clear the log buffer */
@@ -718,10 +723,6 @@
profile->log_tail = profile->log_buffer;
}
- if (copy_from_user(buf, user_buf, len)) {
- size = -EFAULT;
- goto error_free;
- }
/* for sanity and parsing, ensure it is null terminated */
buf[len] = '\0';
@@ -741,12 +742,12 @@
size = len;
-error_free:
- kfree(buf);
error_put:
kgsl_active_count_put(device);
error_unlock:
kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+error_free:
+ kfree(buf);
return size;
}
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 462e7a5..5a33d9d 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1478,7 +1478,6 @@
kgsl_readtimestamp(device, context,
KGSL_TIMESTAMP_RETIRED),
result);
-
return result;
}
@@ -1487,9 +1486,14 @@
void *data)
{
struct kgsl_device_waittimestamp *param = data;
+ struct kgsl_device *device = dev_priv->device;
+ long result = -EINVAL;
- return _device_waittimestamp(dev_priv, NULL,
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ result = _device_waittimestamp(dev_priv, NULL,
param->timestamp, param->timeout);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return result;
}
static long kgsl_ioctl_device_waittimestamp_ctxtid(struct kgsl_device_private
@@ -1498,8 +1502,10 @@
{
struct kgsl_device_waittimestamp_ctxtid *param = data;
struct kgsl_context *context;
+ struct kgsl_device *device = dev_priv->device;
long result = -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->context_id);
if (context)
@@ -1507,6 +1513,7 @@
param->timestamp, param->timeout);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2296,9 +2303,14 @@
void *data)
{
struct kgsl_cmdstream_readtimestamp *param = data;
+ struct kgsl_device *device = dev_priv->device;
+ long result = -EINVAL;
- return _cmdstream_readtimestamp(dev_priv, NULL,
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ result = _cmdstream_readtimestamp(dev_priv, NULL,
param->type, ¶m->timestamp);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return result;
}
static long kgsl_ioctl_cmdstream_readtimestamp_ctxtid(struct kgsl_device_private
@@ -2306,9 +2318,11 @@
void *data)
{
struct kgsl_cmdstream_readtimestamp_ctxtid *param = data;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_context *context;
long result = -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->context_id);
if (context)
@@ -2316,6 +2330,7 @@
param->type, ¶m->timestamp);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2367,9 +2382,14 @@
void *data)
{
struct kgsl_cmdstream_freememontimestamp *param = data;
+ struct kgsl_device *device = dev_priv->device;
+ long result = -EINVAL;
- return _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ result = _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
NULL, param->timestamp, param->type);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return result;
}
static long kgsl_ioctl_cmdstream_freememontimestamp_ctxtid(
@@ -2379,13 +2399,16 @@
{
struct kgsl_cmdstream_freememontimestamp_ctxtid *param = data;
struct kgsl_context *context;
+ struct kgsl_device *device = dev_priv->device;
long result = -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->context_id);
if (context)
result = _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
context, param->timestamp, param->type);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2397,6 +2420,7 @@
struct kgsl_context *context = NULL;
struct kgsl_device *device = dev_priv->device;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = device->ftbl->drawctxt_create(dev_priv, ¶m->flags);
if (IS_ERR(context)) {
result = PTR_ERR(context);
@@ -2405,6 +2429,7 @@
trace_kgsl_context_create(dev_priv->device, context, param->flags);
param->drawctxt_id = context->id;
done:
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2412,14 +2437,17 @@
unsigned int cmd, void *data)
{
struct kgsl_drawctxt_destroy *param = data;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_context *context;
long result;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->drawctxt_id);
result = kgsl_context_detach(context);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -3488,78 +3516,65 @@
typedef long (*kgsl_ioctl_func_t)(struct kgsl_device_private *,
unsigned int, void *);
-#define KGSL_IOCTL_FUNC(_cmd, _func, _flags) \
+#define KGSL_IOCTL_FUNC(_cmd, _func) \
[_IOC_NR((_cmd))] = \
- { .cmd = (_cmd), .func = (_func), .flags = (_flags) }
+ { .cmd = (_cmd), .func = (_func) }
-#define KGSL_IOCTL_LOCK BIT(0)
static const struct {
unsigned int cmd;
kgsl_ioctl_func_t func;
- unsigned int flags;
} kgsl_ioctl_funcs[] = {
KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_GETPROPERTY,
- kgsl_ioctl_device_getproperty,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_getproperty),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP,
- kgsl_ioctl_device_waittimestamp,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_waittimestamp),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID,
- kgsl_ioctl_device_waittimestamp_ctxtid,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_waittimestamp_ctxtid),
KGSL_IOCTL_FUNC(IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS,
- kgsl_ioctl_rb_issueibcmds, 0),
+ kgsl_ioctl_rb_issueibcmds),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SUBMIT_COMMANDS,
- kgsl_ioctl_submit_commands, 0),
+ kgsl_ioctl_submit_commands),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP,
- kgsl_ioctl_cmdstream_readtimestamp,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_readtimestamp),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID,
- kgsl_ioctl_cmdstream_readtimestamp_ctxtid,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_readtimestamp_ctxtid),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP,
- kgsl_ioctl_cmdstream_freememontimestamp,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_freememontimestamp),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_CTXTID,
- kgsl_ioctl_cmdstream_freememontimestamp_ctxtid,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_freememontimestamp_ctxtid),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_CREATE,
- kgsl_ioctl_drawctxt_create,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_drawctxt_create),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_DESTROY,
- kgsl_ioctl_drawctxt_destroy,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_drawctxt_destroy),
KGSL_IOCTL_FUNC(IOCTL_KGSL_MAP_USER_MEM,
- kgsl_ioctl_map_user_mem, 0),
+ kgsl_ioctl_map_user_mem),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FROM_PMEM,
- kgsl_ioctl_map_user_mem, 0),
+ kgsl_ioctl_map_user_mem),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FREE,
- kgsl_ioctl_sharedmem_free, 0),
+ kgsl_ioctl_sharedmem_free),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE,
- kgsl_ioctl_sharedmem_flush_cache, 0),
+ kgsl_ioctl_sharedmem_flush_cache),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC,
- kgsl_ioctl_gpumem_alloc, 0),
+ kgsl_ioctl_gpumem_alloc),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CFF_SYNCMEM,
- kgsl_ioctl_cff_syncmem, 0),
+ kgsl_ioctl_cff_syncmem),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CFF_USER_EVENT,
- kgsl_ioctl_cff_user_event, 0),
+ kgsl_ioctl_cff_user_event),
KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT,
- kgsl_ioctl_timestamp_event,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_timestamp_event),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SETPROPERTY,
- kgsl_ioctl_device_setproperty,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_setproperty),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC_ID,
- kgsl_ioctl_gpumem_alloc_id, 0),
+ kgsl_ioctl_gpumem_alloc_id),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_FREE_ID,
- kgsl_ioctl_gpumem_free_id, 0),
+ kgsl_ioctl_gpumem_free_id),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_GET_INFO,
- kgsl_ioctl_gpumem_get_info, 0),
+ kgsl_ioctl_gpumem_get_info),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_SYNC_CACHE,
- kgsl_ioctl_gpumem_sync_cache, 0),
+ kgsl_ioctl_gpumem_sync_cache),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_SYNC_CACHE_BULK,
- kgsl_ioctl_gpumem_sync_cache_bulk, 0),
+ kgsl_ioctl_gpumem_sync_cache_bulk),
};
static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
@@ -3567,7 +3582,7 @@
struct kgsl_device_private *dev_priv = filep->private_data;
unsigned int nr;
kgsl_ioctl_func_t func;
- int lock, ret;
+ int ret;
char ustack[64];
void *uptr = NULL;
@@ -3624,7 +3639,6 @@
}
func = kgsl_ioctl_funcs[nr].func;
- lock = kgsl_ioctl_funcs[nr].flags & KGSL_IOCTL_LOCK;
} else {
func = dev_priv->device->ftbl->ioctl;
if (!func) {
@@ -3633,19 +3647,10 @@
ret = -ENOIOCTLCMD;
goto done;
}
- lock = 1;
}
- if (lock)
- kgsl_mutex_lock(&dev_priv->device->mutex,
- &dev_priv->device->mutex_owner);
-
ret = func(dev_priv, cmd, uptr);
- if (lock)
- kgsl_mutex_unlock(&dev_priv->device->mutex,
- &dev_priv->device->mutex_owner);
-
/*
* Still copy back on failure, but assume function took
* all necessary precautions sanitizing the return values.
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index 0e694a7..cef052d 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -120,6 +120,8 @@
int ret = -EINVAL;
char fence_name[sizeof(fence->name)] = {};
+ priv.fence_fd = -1;
+
if (len != sizeof(priv))
return -EINVAL;
@@ -127,10 +129,12 @@
if (event == NULL)
return -ENOMEM;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
context = kgsl_context_get_owner(owner, context_id);
if (context == NULL)
- goto fail_pt;
+ goto unlock;
event->context = context;
event->timestamp = timestamp;
@@ -139,7 +143,7 @@
if (pt == NULL) {
KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n");
ret = -ENOMEM;
- goto fail_pt;
+ goto unlock;
}
snprintf(fence_name, sizeof(fence_name),
"%s-pid-%d-ctx-%d-ts-%d",
@@ -153,42 +157,53 @@
kgsl_sync_pt_destroy(pt);
KGSL_DRV_ERR(device, "sync_fence_create failed\n");
ret = -ENOMEM;
- goto fail_fence;
+ goto unlock;
}
priv.fence_fd = get_unused_fd_flags(0);
if (priv.fence_fd < 0) {
- KGSL_DRV_ERR(device, "invalid fence fd\n");
- ret = -EINVAL;
- goto fail_fd;
+ KGSL_DRV_ERR(device, "Unable to get a file descriptor: %d\n",
+ priv.fence_fd);
+ ret = priv.fence_fd;
+ goto unlock;
}
sync_fence_install(fence, priv.fence_fd);
+ /* Unlock the mutex before copying to user */
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
if (copy_to_user(data, &priv, sizeof(priv))) {
ret = -EFAULT;
- goto fail_copy_fd;
+ goto out;
}
/*
* Hold the context ref-count for the event - it will get released in
* the callback
*/
+
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
ret = kgsl_add_event(device, context_id, timestamp,
kgsl_fence_event_cb, event, owner);
+
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
if (ret)
- goto fail_event;
+ goto out;
return 0;
-fail_event:
-fail_copy_fd:
- /* clean up sync_fence_install */
- put_unused_fd(priv.fence_fd);
-fail_fd:
- /* clean up sync_fence_create */
- sync_fence_put(fence);
-fail_fence:
-fail_pt:
+unlock:
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
+out:
+ if (priv.fence_fd >= 0)
+ put_unused_fd(priv.fence_fd);
+
+ if (fence)
+ sync_fence_put(fence);
+
kgsl_context_put(context);
kfree(event);
return ret;