diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 570a3708c..4c55f8cec 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -947,6 +947,8 @@ static int gk20a_init_vidmem(struct mm_gk20a *mm) mm->vidmem.bootstrap_base = bootstrap_base; mm->vidmem.bootstrap_size = bootstrap_size; + mutex_init(&mm->vidmem.first_clear_mutex); + INIT_WORK(&mm->vidmem.clear_mem_worker, gk20a_vidmem_clear_mem_worker); atomic_set(&mm->vidmem.clears_pending, 0); INIT_LIST_HEAD(&mm->vidmem.clear_list_head); @@ -2190,11 +2192,16 @@ int gk20a_vidmem_buf_alloc(struct gk20a *g, size_t bytes) buf->g = g; if (!g->mm.vidmem.cleared) { - err = gk20a_vidmem_clear_all(g); - if (err) { - gk20a_err(g->dev, "failed to clear whole vidmem"); - goto err_kfree; + mutex_lock(&g->mm.vidmem.first_clear_mutex); + if (!g->mm.vidmem.cleared) { + err = gk20a_vidmem_clear_all(g); + if (err) { + gk20a_err(g->dev, + "failed to clear whole vidmem"); + goto err_kfree; + } } + mutex_unlock(&g->mm.vidmem.first_clear_mutex); } buf->mem = kzalloc(sizeof(struct mem_desc), GFP_KERNEL); diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 8ce110a15..ee2bb61ea 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h @@ -417,6 +417,7 @@ struct mm_gk20a { u32 ce_ctx_id; bool cleared; + struct mutex first_clear_mutex; struct list_head clear_list_head; struct mutex clear_list_mutex;