summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
authorSeshendra Gadagottu <sgadagottu@nvidia.com>2016-01-28 13:54:32 -0500
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-01-29 15:58:22 -0500
commit9e02111a768ab631a6719c1eae8d7c03e6e89c23 (patch)
tree7cb3fb7cd59ca679579e4e7b920f2764a7cb7a81 /drivers/gpu/nvgpu
parent5cb995c7510e0290956a3aa221c6a77d4020b3ff (diff)
gpu: nvgpu: fix race condition with poweroff
When gpu rail-gating is enabled, it is possible that both rail gating code and system shudown can start executing gk20a_pm_prepare_poweroff() in parallel. To synchronize this execution, protect gk20a_pm_prepare_poweroff() with a mutex lock. Bug 200168805 Change-Id: I19536a43ed20c3e82b32c316922dc3e19e3f59bb Signed-off-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-on: http://git-master/r/999548 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c12
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h2
2 files changed, 11 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 0982ecdf..1000eba2 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -669,6 +669,7 @@ static int gk20a_init_support(struct platform_device *dev)
669 mutex_init(&g->dbg_sessions_lock); 669 mutex_init(&g->dbg_sessions_lock);
670 mutex_init(&g->client_lock); 670 mutex_init(&g->client_lock);
671 mutex_init(&g->ch_wdt_lock); 671 mutex_init(&g->ch_wdt_lock);
672 mutex_init(&g->poweroff_lock);
672 673
673 mutex_init(&g->interleave_lock); 674 mutex_init(&g->interleave_lock);
674 g->num_interleaved_channels = 0; 675 g->num_interleaved_channels = 0;
@@ -689,17 +690,19 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
689 690
690 gk20a_dbg_fn(""); 691 gk20a_dbg_fn("");
691 692
692 gk20a_scale_suspend(pdev); 693 mutex_lock(&g->poweroff_lock);
693 694
694 if (!g->power_on) 695 if (!g->power_on)
695 return 0; 696 goto done;
697
698 gk20a_scale_suspend(pdev);
696 699
697 /* cancel any pending cde work */ 700 /* cancel any pending cde work */
698 gk20a_cde_suspend(g); 701 gk20a_cde_suspend(g);
699 702
700 ret = gk20a_channel_suspend(g); 703 ret = gk20a_channel_suspend(g);
701 if (ret) 704 if (ret)
702 return ret; 705 goto done;
703 706
704 /* disable elpg before gr or fifo suspend */ 707 /* disable elpg before gr or fifo suspend */
705 ret |= gk20a_pmu_destroy(g); 708 ret |= gk20a_pmu_destroy(g);
@@ -723,6 +726,9 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
723 /* Stop CPU from accessing the GPU registers. */ 726 /* Stop CPU from accessing the GPU registers. */
724 gk20a_lockout_registers(g); 727 gk20a_lockout_registers(g);
725 728
729done:
730 mutex_unlock(&g->poweroff_lock);
731
726 return ret; 732 return ret;
727} 733}
728 734
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index b02d6111..0207588f 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -521,6 +521,8 @@ struct gk20a {
521 521
522 struct mutex ch_wdt_lock; 522 struct mutex ch_wdt_lock;
523 523
524 struct mutex poweroff_lock;
525
524 /* Channel priorities */ 526 /* Channel priorities */
525 u32 timeslice_low_priority_us; 527 u32 timeslice_low_priority_us;
526 u32 timeslice_medium_priority_us; 528 u32 timeslice_medium_priority_us;