diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c index 8e46d70de..aea277aeb 100644 --- a/drivers/gpu/nvgpu/common/fifo/channel.c +++ b/drivers/gpu/nvgpu/common/fifo/channel.c @@ -248,6 +248,7 @@ static void channel_kernelmode_deinit(struct nvgpu_channel *ch) int nvgpu_channel_set_syncpt(struct nvgpu_channel *ch) { struct gk20a *g = ch->g; + struct nvgpu_tsg *tsg = nvgpu_tsg_from_ch(ch); struct nvgpu_channel_sync_syncpt *sync_syncpt; u32 new_syncpt = 0U; u32 old_syncpt = g->ops.ramfc.get_syncpt(ch); @@ -268,9 +269,12 @@ int nvgpu_channel_set_syncpt(struct nvgpu_channel *ch) } if ((new_syncpt != 0U) && (new_syncpt != old_syncpt)) { + nvgpu_mutex_acquire(&tsg->ctx_init_lock); + /* disable channel */ err = nvgpu_channel_disable_tsg(g, ch); if (err != 0) { + nvgpu_mutex_release(&tsg->ctx_init_lock); nvgpu_err(g, "failed to disable channel/TSG"); return err; } @@ -288,6 +292,8 @@ int nvgpu_channel_set_syncpt(struct nvgpu_channel *ch) if (err != 0) { nvgpu_err(g, "failed to enable channel/TSG"); } + + nvgpu_mutex_release(&tsg->ctx_init_lock); } nvgpu_log_fn(g, "done"); @@ -296,6 +302,9 @@ out: if (nvgpu_channel_enable_tsg(g, ch) != 0) { nvgpu_err(g, "failed to enable channel/TSG"); } + + nvgpu_mutex_release(&tsg->ctx_init_lock); + return err; } #endif diff --git a/drivers/gpu/nvgpu/common/gr/gr_setup.c b/drivers/gpu/nvgpu/common/gr/gr_setup.c index ecb2e648f..470b6933f 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_setup.c +++ b/drivers/gpu/nvgpu/common/gr/gr_setup.c @@ -41,12 +41,16 @@ static int nvgpu_gr_setup_zcull(struct gk20a *g, struct nvgpu_channel *c, struct nvgpu_gr_ctx *gr_ctx) { + struct nvgpu_tsg *tsg = nvgpu_tsg_from_ch(c); int ret = 0; nvgpu_log_fn(g, " "); + nvgpu_mutex_acquire(&tsg->ctx_init_lock); + ret = nvgpu_channel_disable_tsg(g, c); if (ret != 0) { + nvgpu_mutex_release(&tsg->ctx_init_lock); nvgpu_err(g, "failed to disable channel/TSG"); return ret; } @@ -68,6 +72,8 @@ static int nvgpu_gr_setup_zcull(struct gk20a *g, struct nvgpu_channel *c, nvgpu_err(g, "failed to re-enable channel/TSG"); } + nvgpu_mutex_release(&tsg->ctx_init_lock); + return ret; out: @@ -81,6 +87,8 @@ out: nvgpu_err(g, "failed to enable channel/TSG"); } + nvgpu_mutex_release(&tsg->ctx_init_lock); + return ret; } @@ -185,25 +193,30 @@ int nvgpu_gr_setup_alloc_obj_ctx(struct nvgpu_channel *c, u32 class_num, nvgpu_mutex_acquire(&tsg->ctx_init_lock); + g->ops.tsg.disable(tsg); + + err = g->ops.fifo.preempt_tsg(g, tsg); + if (err != 0) { + nvgpu_err(g, "preempt failed %d", err); + goto enable_tsg; + } + err = nvgpu_tsg_validate_class_veid_pbdma(c); if (err != 0) { nvgpu_err(g, "Invalid class/veid/pbdma config"); - nvgpu_mutex_release(&tsg->ctx_init_lock); - goto out; + goto enable_tsg; } err = nvgpu_tsg_subctx_alloc_gr_subctx(g, c); if (err != 0) { nvgpu_err(g, "failed to alloc gr subctx"); - nvgpu_mutex_release(&tsg->ctx_init_lock); - goto out; + goto enable_tsg; } err = nvgpu_tsg_subctx_setup_subctx_header(g, c); if (err != 0) { nvgpu_err(g, "failed to setup subctx header"); - nvgpu_mutex_release(&tsg->ctx_init_lock); - goto out; + goto enable_tsg; } gr_ctx = tsg->gr_ctx; @@ -211,8 +224,7 @@ int nvgpu_gr_setup_alloc_obj_ctx(struct nvgpu_channel *c, u32 class_num, mappings = nvgpu_gr_ctx_alloc_or_get_mappings(g, tsg, c); if (mappings == NULL) { nvgpu_err(g, "fail to allocate/get ctx mappings struct"); - nvgpu_mutex_release(&tsg->ctx_init_lock); - goto out; + goto enable_tsg; } err = nvgpu_gr_obj_ctx_alloc(g, gr->golden_image, @@ -223,8 +235,7 @@ int nvgpu_gr_setup_alloc_obj_ctx(struct nvgpu_channel *c, u32 class_num, if (err != 0) { nvgpu_err(g, "failed to allocate gr ctx buffer"); - nvgpu_mutex_release(&tsg->ctx_init_lock); - goto out; + goto enable_tsg; } nvgpu_gr_ctx_set_tsgid(gr_ctx, tsg->tsgid); @@ -263,10 +274,17 @@ int nvgpu_gr_setup_alloc_obj_ctx(struct nvgpu_channel *c, u32 class_num, nvgpu_gr_ctx_mark_ctx_initialized(gr_ctx); + g->ops.tsg.enable(tsg); + nvgpu_mutex_release(&tsg->ctx_init_lock); nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gr, "done"); return 0; + +enable_tsg: + g->ops.tsg.enable(tsg); + + nvgpu_mutex_release(&tsg->ctx_init_lock); out: /* 1. gr_ctx, patch_ctx and global ctx buffer mapping can be reused so no need to release them. diff --git a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c index fbbc6d968..87a3a17e5 100644 --- a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c +++ b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c @@ -63,6 +63,8 @@ int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, nvgpu_log_fn(g, " "); + nvgpu_mutex_acquire(&tsg->ctx_init_lock); + g->ops.tsg.disable(tsg); ret = g->ops.fifo.preempt_tsg(g, tsg); @@ -75,6 +77,9 @@ int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, out: g->ops.tsg.enable(tsg); + + nvgpu_mutex_release(&tsg->ctx_init_lock); + return ret; } diff --git a/drivers/gpu/nvgpu/hal/gr/gr/gr_gp10b.c b/drivers/gpu/nvgpu/hal/gr/gr/gr_gp10b.c index 2c1f40a5f..091e2aeee 100644 --- a/drivers/gpu/nvgpu/hal/gr/gr/gr_gp10b.c +++ b/drivers/gpu/nvgpu/hal/gr/gr/gr_gp10b.c @@ -766,11 +766,15 @@ int gr_gp10b_set_boosted_ctx(struct nvgpu_channel *ch, } gr_ctx = tsg->gr_ctx; + + nvgpu_mutex_acquire(&tsg->ctx_init_lock); + nvgpu_gr_ctx_set_boosted_ctx(gr_ctx, boost); mem = nvgpu_gr_ctx_get_ctx_mem(gr_ctx, NVGPU_GR_CTX_CTX); err = nvgpu_channel_disable_tsg(g, ch); if (err != 0) { + nvgpu_mutex_release(&tsg->ctx_init_lock); return err; } @@ -792,6 +796,9 @@ int gr_gp10b_set_boosted_ctx(struct nvgpu_channel *ch, if (err != 0) { nvgpu_err(g, "failed to enable channel/TSG"); } + + nvgpu_mutex_release(&tsg->ctx_init_lock); + return err; out: @@ -805,6 +812,9 @@ out: /* ch might not be bound to tsg anymore */ nvgpu_err(g, "failed to enable channel/TSG"); } + + nvgpu_mutex_release(&tsg->ctx_init_lock); + return err; } #endif diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index 5f1e400ad..28b5408b7 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -1963,27 +1963,33 @@ static int nvgpu_dbg_gpu_ioctl_get_gr_context(struct dbg_session_gk20a *dbg_s, return -EINVAL; } + nvgpu_mutex_acquire(&tsg->ctx_init_lock); + ctx_mem = nvgpu_gr_ctx_get_ctx_mem(tsg->gr_ctx, NVGPU_GR_CTX_CTX); if (ctx_mem == NULL || !nvgpu_mem_is_valid(ctx_mem)) { nvgpu_err(g, "invalid context mem"); - return -EINVAL; + err = -EINVAL; + goto out; } if (ctx_mem->size > (u64)UINT_MAX) { nvgpu_err(ch->g, "ctx size is larger than expected"); - return -EINVAL; + err = -EINVAL; + goto out; } /* Check if the input buffer size equals the gr context size */ size = (u32)ctx_mem->size; if (args->size != size) { nvgpu_err(g, "size mismatch: %d != %d", args->size, size); - return -EINVAL; + err = -EINVAL; + goto out; } if (nvgpu_channel_disable_tsg(g, ch) != 0) { nvgpu_err(g, "failed to disable channel/TSG"); - return -EINVAL; + err = -EINVAL; + goto out; } err = nvgpu_preempt_channel(g, ch); @@ -1998,9 +2004,13 @@ done: enable_err = nvgpu_channel_enable_tsg(g, ch); if (enable_err != 0) { nvgpu_err(g, "failed to re-enable channel/TSG"); + nvgpu_mutex_release(&tsg->ctx_init_lock); return (err != 0) ? err : enable_err; } +out: + nvgpu_mutex_release(&tsg->ctx_init_lock); + return err; }