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>
This commit is contained in:
Debarshi Dutta
2018-09-03 10:51:02 +05:30
committed by mobile promotions
parent 16ad9f5379
commit bac38f52cc
5 changed files with 22 additions and 1 deletions

View File

@@ -750,12 +750,20 @@ error_check:
int nvgpu_clk_arb_init_arbiter(struct gk20a *g)
{
int err = 0;
if (!g->ops.clk.support_clk_freq_controller ||
!g->ops.clk_arb.get_arbiter_clk_domains) {
return 0;
}
return g->ops.clk_arb.arbiter_clk_init(g);
nvgpu_mutex_acquire(&g->clk_arb_enable_lock);
err = g->ops.clk_arb.arbiter_clk_init(g);
nvgpu_mutex_release(&g->clk_arb_enable_lock);
return err;
}
void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g)
@@ -783,10 +791,14 @@ void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g)
{
struct nvgpu_clk_arb *arb = g->clk_arb;
nvgpu_mutex_acquire(&g->clk_arb_enable_lock);
if (arb) {
nvgpu_clk_arb_worker_deinit(g);
g->ops.clk_arb.clk_arb_cleanup(g->clk_arb);
}
nvgpu_mutex_release(&g->clk_arb_enable_lock);
}
int nvgpu_clk_arb_init_session(struct gk20a *g,

View File

@@ -1588,6 +1588,8 @@ struct gk20a {
struct nvgpu_clk_arb *clk_arb;
struct nvgpu_mutex clk_arb_enable_lock;
struct gk20a_ce_app ce_app;
bool ltc_intr_en_illegal_compstat;

View File

@@ -121,6 +121,10 @@ int gp106_init_clk_arbiter(struct gk20a *g)
clk_arb_dbg(g, " ");
if (g->clk_arb != NULL) {
return 0;
}
arb = nvgpu_kzalloc(g, sizeof(struct nvgpu_clk_arb));
if (!arb)
return -ENOMEM;

View File

@@ -65,6 +65,7 @@ static void nvgpu_init_vars(struct gk20a *g)
nvgpu_mutex_init(&g->poweroff_lock);
nvgpu_mutex_init(&g->ctxsw_disable_lock);
nvgpu_mutex_init(&g->tpc_pg_lock);
nvgpu_mutex_init(&g->clk_arb_enable_lock);
l->regs_saved = l->regs;
l->bar1_saved = l->bar1;

View File

@@ -1310,6 +1310,8 @@ int nvgpu_remove(struct device *dev, struct class *class)
if (platform->remove)
platform->remove(dev);
nvgpu_mutex_destroy(&g->clk_arb_enable_lock);
nvgpu_log_fn(g, "removed");
return err;