diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 3632963ac..03bebfa07 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -600,6 +600,7 @@ static void gk20a_remove_fifo_support(struct fifo_gk20a *f) } gk20a_fifo_delete_runlist(f); + nvgpu_mutex_destroy(&f->runlist_submit_mutex); nvgpu_kfree(g, f->pbdma_map); f->pbdma_map = NULL; @@ -919,6 +920,12 @@ int gk20a_init_fifo_setup_sw_common(struct gk20a *g) return err; } + err = nvgpu_mutex_init(&f->runlist_submit_mutex); + if (err) { + nvgpu_err(g, "failed to init runlist_submit_mutex"); + return err; + } + g->ops.fifo.init_pbdma_intr_descs(f); /* just filling in data/tables */ f->num_channels = g->ops.fifo.get_num_fifos(g); @@ -3583,6 +3590,7 @@ int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, runlist->count = 0; } + nvgpu_mutex_acquire(&f->runlist_submit_mutex); g->ops.fifo.runlist_hw_submit(g, runlist_id, runlist->count, new_buf); if (wait_for_finish) { @@ -3590,6 +3598,7 @@ int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, if (ret == -ETIMEDOUT) { nvgpu_err(g, "runlist %d update timeout", runlist_id); + nvgpu_mutex_release(&f->runlist_submit_mutex); /* trigger runlist update timeout recovery */ return ret; @@ -3597,6 +3606,7 @@ int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, nvgpu_err(g, "runlist update interrupted"); } } + nvgpu_mutex_release(&f->runlist_submit_mutex); runlist->cur_buffer = new_buf; diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 21922426c..60e8998a7 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h @@ -185,6 +185,7 @@ struct fifo_gk20a { struct nvgpu_list_node free_chs; struct nvgpu_mutex free_chs_mutex; struct nvgpu_mutex gr_reset_mutex; + struct nvgpu_mutex runlist_submit_mutex; struct tsg_gk20a *tsg; struct nvgpu_mutex tsg_inuse_mutex;