From e768e74df8be8abe8442d958bde7a4a2886694ba Mon Sep 17 00:00:00 2001 From: skadamati Date: Fri, 30 Jun 2017 14:17:25 +0530 Subject: gpu: nvgpu: Fix race condition during poweron When two or more apps ran simultaneously First app context sets power_on flag & starts init Other app context check the power_on flag and try to use GPU without init completed Which makes aother apps to assert Added mutex to synchronize poweron access Bug 200297265 Change-Id: Ie138f7f43bb0dd3304ed91ae3649a6a4947bee91 Signed-off-by: skadamati Reviewed-on: https://git-master/r/1511436 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/driver_common.c | 1 + drivers/gpu/nvgpu/common/linux/module.c | 3 +++ drivers/gpu/nvgpu/gk20a/gk20a.h | 1 + drivers/gpu/nvgpu/vgpu/vgpu.c | 1 + 4 files changed, 6 insertions(+) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c index c2bd9d78..b12917d6 100644 --- a/drivers/gpu/nvgpu/common/linux/driver_common.c +++ b/drivers/gpu/nvgpu/common/linux/driver_common.c @@ -50,6 +50,7 @@ static void nvgpu_init_vars(struct gk20a *g) nvgpu_mutex_init(&platform->railgate_lock); nvgpu_mutex_init(&g->dbg_sessions_lock); nvgpu_mutex_init(&g->client_lock); + nvgpu_mutex_init(&g->poweron_lock); nvgpu_mutex_init(&g->poweroff_lock); g->regs_saved = g->regs; diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index b107a721..0b5dfec8 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c @@ -88,15 +88,18 @@ int gk20a_busy(struct gk20a *g) goto fail; } } else { + nvgpu_mutex_acquire(&g->poweron_lock); if (!g->power_on) { ret = gk20a_gpu_is_virtual(dev) ? vgpu_pm_finalize_poweron(dev) : gk20a_pm_finalize_poweron(dev); if (ret) { atomic_dec(&g->usage_count); + nvgpu_mutex_release(&g->poweron_lock); goto fail; } } + nvgpu_mutex_release(&g->poweron_lock); } fail: diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 9203882c..d45477fc 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -1075,6 +1075,7 @@ struct gk20a { #endif unsigned int ch_wdt_timeout_ms; + struct nvgpu_mutex poweron_lock; struct nvgpu_mutex poweroff_lock; /* Channel priorities */ diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index f02acad0..bd52dc0a 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c @@ -243,6 +243,7 @@ static void vgpu_remove_support(struct gk20a *g) static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform) { + nvgpu_mutex_init(&g->poweron_lock); nvgpu_mutex_init(&g->poweroff_lock); g->regs_saved = g->regs; g->bar1_saved = g->bar1; -- cgit v1.2.2