summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2018-09-03 01:21:02 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-09-04 10:25:45 -0400
commitbac38f52cc6f2ddc435a748dd9c85f3c5d88153f (patch)
treeb53198fc14aa9d470d41b5d36caee934ef8c5bbc
parent16ad9f537979c5f3717fc5781b1c2fad22a76f96 (diff)
gpu: nvgpu: protect clk_arb init with mutex.
g->clk_arb is currently initialized as a part of gk20a_finalize_poweron(). Any subsequent call to gk20a_finalize_poweron reinitializes the clk_arb and leading to memory leaks. This is resolved by protecting the g->clk_arb initialization with a mutex clk_arb_enable_lock in struct gk20a. We skip initializing the g->clk_arb if its not NULL. Bug 2061372 Change-Id: I59158e0a5e4c827fdbd6d9ea2d04c78d0986347a Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1811650 Reviewed-by: Deepak Nibade <dnibade@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c14
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gp106/clk_arb_gp106.c4
-rw-r--r--drivers/gpu/nvgpu/os/linux/driver_common.c1
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.c2
5 files changed, 22 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 983a82f9..8543196b 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -750,12 +750,20 @@ error_check:
750 750
751int nvgpu_clk_arb_init_arbiter(struct gk20a *g) 751int nvgpu_clk_arb_init_arbiter(struct gk20a *g)
752{ 752{
753 int err = 0;
754
753 if (!g->ops.clk.support_clk_freq_controller || 755 if (!g->ops.clk.support_clk_freq_controller ||
754 !g->ops.clk_arb.get_arbiter_clk_domains) { 756 !g->ops.clk_arb.get_arbiter_clk_domains) {
755 return 0; 757 return 0;
756 } 758 }
757 759
758 return g->ops.clk_arb.arbiter_clk_init(g); 760 nvgpu_mutex_acquire(&g->clk_arb_enable_lock);
761
762 err = g->ops.clk_arb.arbiter_clk_init(g);
763
764 nvgpu_mutex_release(&g->clk_arb_enable_lock);
765
766 return err;
759} 767}
760 768
761void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g) 769void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g)
@@ -783,10 +791,14 @@ void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g)
783{ 791{
784 struct nvgpu_clk_arb *arb = g->clk_arb; 792 struct nvgpu_clk_arb *arb = g->clk_arb;
785 793
794 nvgpu_mutex_acquire(&g->clk_arb_enable_lock);
795
786 if (arb) { 796 if (arb) {
787 nvgpu_clk_arb_worker_deinit(g); 797 nvgpu_clk_arb_worker_deinit(g);
788 g->ops.clk_arb.clk_arb_cleanup(g->clk_arb); 798 g->ops.clk_arb.clk_arb_cleanup(g->clk_arb);
789 } 799 }
800
801 nvgpu_mutex_release(&g->clk_arb_enable_lock);
790} 802}
791 803
792int nvgpu_clk_arb_init_session(struct gk20a *g, 804int nvgpu_clk_arb_init_session(struct gk20a *g,
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index bdf3a168..f62dfb94 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -1588,6 +1588,8 @@ struct gk20a {
1588 1588
1589 struct nvgpu_clk_arb *clk_arb; 1589 struct nvgpu_clk_arb *clk_arb;
1590 1590
1591 struct nvgpu_mutex clk_arb_enable_lock;
1592
1591 struct gk20a_ce_app ce_app; 1593 struct gk20a_ce_app ce_app;
1592 1594
1593 bool ltc_intr_en_illegal_compstat; 1595 bool ltc_intr_en_illegal_compstat;
diff --git a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c
index 860344d0..001f2bfc 100644
--- a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c
@@ -121,6 +121,10 @@ int gp106_init_clk_arbiter(struct gk20a *g)
121 121
122 clk_arb_dbg(g, " "); 122 clk_arb_dbg(g, " ");
123 123
124 if (g->clk_arb != NULL) {
125 return 0;
126 }
127
124 arb = nvgpu_kzalloc(g, sizeof(struct nvgpu_clk_arb)); 128 arb = nvgpu_kzalloc(g, sizeof(struct nvgpu_clk_arb));
125 if (!arb) 129 if (!arb)
126 return -ENOMEM; 130 return -ENOMEM;
diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c
index 16af2cb0..b81cc90c 100644
--- a/drivers/gpu/nvgpu/os/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/os/linux/driver_common.c
@@ -65,6 +65,7 @@ static void nvgpu_init_vars(struct gk20a *g)
65 nvgpu_mutex_init(&g->poweroff_lock); 65 nvgpu_mutex_init(&g->poweroff_lock);
66 nvgpu_mutex_init(&g->ctxsw_disable_lock); 66 nvgpu_mutex_init(&g->ctxsw_disable_lock);
67 nvgpu_mutex_init(&g->tpc_pg_lock); 67 nvgpu_mutex_init(&g->tpc_pg_lock);
68 nvgpu_mutex_init(&g->clk_arb_enable_lock);
68 69
69 l->regs_saved = l->regs; 70 l->regs_saved = l->regs;
70 l->bar1_saved = l->bar1; 71 l->bar1_saved = l->bar1;
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c
index cb501683..d226ceeb 100644
--- a/drivers/gpu/nvgpu/os/linux/module.c
+++ b/drivers/gpu/nvgpu/os/linux/module.c
@@ -1310,6 +1310,8 @@ int nvgpu_remove(struct device *dev, struct class *class)
1310 if (platform->remove) 1310 if (platform->remove)
1311 platform->remove(dev); 1311 platform->remove(dev);
1312 1312
1313 nvgpu_mutex_destroy(&g->clk_arb_enable_lock);
1314
1313 nvgpu_log_fn(g, "removed"); 1315 nvgpu_log_fn(g, "removed");
1314 1316
1315 return err; 1317 return err;