aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/host1x/syncpt.c
diff options
context:
space:
mode:
authorArto Merilainen <amerilainen@nvidia.com>2016-11-08 19:51:33 +0200
committerThierry Reding <treding@nvidia.com>2016-11-11 15:33:13 +0100
commitd4b5781890b9329b9e7720f14d3eeb5661348535 (patch)
treea1ce286f7e473f0bd9103f0d59321d1af6d46faf /drivers/gpu/host1x/syncpt.c
parentgpu: host1x: Store device address to all bufs (diff)
downloadlinux-dev-d4b5781890b9329b9e7720f14d3eeb5661348535.tar.xz
linux-dev-d4b5781890b9329b9e7720f14d3eeb5661348535.zip
gpu: host1x: Add locking to syncpt
Currently syncpoints are not locked by mutex and this causes races if we are aggressively freeing and allocating syncpoints. This patch adds missing mutex protection to syncpoint structures. Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Reviewed-by: Shridhar Rasal <srasal@nvidia.com> Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> [treding@nvidia.com: use better label names, don't reset local variable] Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/host1x/syncpt.c')
-rw-r--r--drivers/gpu/host1x/syncpt.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index 95589328ad52..25c11a85050b 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -1,7 +1,7 @@
/*
* Tegra host1x Syncpoints
*
- * Copyright (c) 2010-2013, NVIDIA Corporation.
+ * Copyright (c) 2010-2015, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -61,22 +61,24 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
struct host1x_syncpt *sp = host->syncpt;
char *name;
+ mutex_lock(&host->syncpt_mutex);
+
for (i = 0; i < host->info->nb_pts && sp->name; i++, sp++)
;
if (i >= host->info->nb_pts)
- return NULL;
+ goto unlock;
if (flags & HOST1X_SYNCPT_HAS_BASE) {
sp->base = host1x_syncpt_base_request(host);
if (!sp->base)
- return NULL;
+ goto unlock;
}
name = kasprintf(GFP_KERNEL, "%02u-%s", sp->id,
dev ? dev_name(dev) : NULL);
if (!name)
- return NULL;
+ goto free_base;
sp->dev = dev;
sp->name = name;
@@ -86,7 +88,15 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
else
sp->client_managed = false;
+ mutex_unlock(&host->syncpt_mutex);
return sp;
+
+free_base:
+ host1x_syncpt_base_free(sp->base);
+ sp->base = NULL;
+unlock:
+ mutex_unlock(&host->syncpt_mutex);
+ return NULL;
}
u32 host1x_syncpt_id(struct host1x_syncpt *sp)
@@ -378,6 +388,7 @@ int host1x_syncpt_init(struct host1x *host)
for (i = 0; i < host->info->nb_bases; i++)
bases[i].id = i;
+ mutex_init(&host->syncpt_mutex);
host->syncpt = syncpt;
host->bases = bases;
@@ -405,12 +416,16 @@ void host1x_syncpt_free(struct host1x_syncpt *sp)
if (!sp)
return;
+ mutex_lock(&sp->host->syncpt_mutex);
+
host1x_syncpt_base_free(sp->base);
kfree(sp->name);
sp->base = NULL;
sp->dev = NULL;
sp->name = NULL;
sp->client_managed = false;
+
+ mutex_unlock(&sp->host->syncpt_mutex);
}
EXPORT_SYMBOL(host1x_syncpt_free);