diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gv11b/gr_gv11b.c')
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/gr_gv11b.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c index 694ff8ad..aed45ceb 100644 --- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c | |||
@@ -2093,23 +2093,30 @@ static int gr_gv11b_handle_warp_esr_error_mmu_nack(struct gk20a *g, | |||
2093 | u32 warp_esr_error, | 2093 | u32 warp_esr_error, |
2094 | struct channel_gk20a *fault_ch) | 2094 | struct channel_gk20a *fault_ch) |
2095 | { | 2095 | { |
2096 | struct tsg_gk20a *tsg; | ||
2097 | u32 offset; | 2096 | u32 offset; |
2097 | int err = 0; | ||
2098 | 2098 | ||
2099 | fault_ch = gk20a_channel_get(fault_ch); | ||
2099 | if (fault_ch) { | 2100 | if (fault_ch) { |
2100 | tsg = &g->fifo.tsg[fault_ch->tsgid]; | 2101 | if (!fault_ch->mmu_nack_handled) { |
2101 | 2102 | /* recovery is not done for the channel implying mmu | |
2102 | /* | 2103 | * nack interrupt is serviced before mmu fault. Force |
2103 | * Upon receiving MMU_FAULT error, MMU will forward MMU_NACK | 2104 | * recovery by returning an error. Also indicate we |
2104 | * to SM. So MMU_FAULT handling path will take care of | 2105 | * should skip a second recovery. |
2105 | * triggering RC recovery | 2106 | */ |
2106 | * | 2107 | fault_ch->mmu_nack_handled = true; |
2107 | * In MMU_NACK handling path, we just set the error notifier | 2108 | err = -EFAULT; |
2108 | * and clear the interrupt so that the User Space sees the error | 2109 | } |
2109 | * as soon as semaphores are released by SM | ||
2110 | */ | ||
2111 | gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg); | ||
2112 | } | 2110 | } |
2111 | /* else mmu fault is serviced first and channel is closed */ | ||
2112 | |||
2113 | /* do not release reference to ch as we do not want userspace to close | ||
2114 | * this channel on recovery. Otherwise mmu fault handler will enter | ||
2115 | * recovery path even if channel is invalid. We want to explicitly check | ||
2116 | * for teardown value in mmu fault handler. | ||
2117 | */ | ||
2118 | if (!err) | ||
2119 | gk20a_channel_put(fault_ch); | ||
2113 | 2120 | ||
2114 | /* clear interrupt */ | 2121 | /* clear interrupt */ |
2115 | offset = gk20a_gr_gpc_offset(g, gpc) + | 2122 | offset = gk20a_gr_gpc_offset(g, gpc) + |
@@ -2122,7 +2129,7 @@ static int gr_gv11b_handle_warp_esr_error_mmu_nack(struct gk20a *g, | |||
2122 | "ESR %s(0x%x)", | 2129 | "ESR %s(0x%x)", |
2123 | "MMU NACK ERROR", | 2130 | "MMU NACK ERROR", |
2124 | warp_esr_error); | 2131 | warp_esr_error); |
2125 | return 0; | 2132 | return err; |
2126 | } | 2133 | } |
2127 | 2134 | ||
2128 | static bool gr_gv11b_check_warp_esr_error(struct gk20a *g, u32 warp_esr_error) | 2135 | static bool gr_gv11b_check_warp_esr_error(struct gk20a *g, u32 warp_esr_error) |