From ff706e54564dc2142525edeaf8a9411bedc82fe6 Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Wed, 14 Apr 2021 23:40:27 +0530 Subject: [PATCH] gpu: nvgpu: handle ctx_reload when force unbinding the channel When force closing the channel, NEXT and CTX_RELOAD bits might be set. Currently CTX_RELOAD bit is ignored. However, due to this, the channel created after the erroneous unbind encounters FECS fault. If the channel is unbound while it is running, fifo unbind error happens and can lead to unspecified behavior. By moving CTX_RELOAD to other channel in the TSG, the channel can be unbound safely. In other cases, if the channel is truly running something when it is being unbound it should either get preempted or be handled through engine reset. Bug 200701444 Change-Id: Iba956544dcaa1144c6064247257c64cbe9a29ae6 Signed-off-by: Sagar Kamble Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2515083 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-misra Reviewed-by: svc-mobile-cert Reviewed-by: Deepak Nibade Reviewed-by: Alex Waterman Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/tsg.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index 63f25973d..3ab9a379a 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -338,7 +338,7 @@ int nvgpu_tsg_unbind_channel_check_hw_state(struct nvgpu_tsg *tsg, { struct gk20a *g = ch->g; struct nvgpu_channel_hw_state hw_state; - int err; + int err = 0; nvgpu_rwsem_down_read(&tsg->ch_list_lock); g->ops.channel.read_state(g, ch, &hw_state); @@ -346,9 +346,6 @@ int nvgpu_tsg_unbind_channel_check_hw_state(struct nvgpu_tsg *tsg, if (g->ops.tsg.unbind_channel_check_hw_next != NULL) { err = g->ops.tsg.unbind_channel_check_hw_next(ch, &hw_state); - if (err != 0) { - return err; - } } if (g->ops.tsg.unbind_channel_check_ctx_reload != NULL) { @@ -360,7 +357,7 @@ int nvgpu_tsg_unbind_channel_check_hw_state(struct nvgpu_tsg *tsg, &hw_state); } - return 0; + return err; } void nvgpu_tsg_unbind_channel_check_ctx_reload(struct nvgpu_tsg *tsg,