summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gv11b/fb_gv11b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gv11b/fb_gv11b.c')
-rw-r--r--drivers/gpu/nvgpu/gv11b/fb_gv11b.c79
1 files changed, 52 insertions, 27 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/fb_gv11b.c b/drivers/gpu/nvgpu/gv11b/fb_gv11b.c
index 54f0d2d8..2ceb816b 100644
--- a/drivers/gpu/nvgpu/gv11b/fb_gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/fb_gv11b.c
@@ -870,10 +870,11 @@ static void gv11b_fb_copy_from_hw_fault_buf(struct gk20a *g,
870static void gv11b_fb_handle_mmu_fault_common(struct gk20a *g, 870static void gv11b_fb_handle_mmu_fault_common(struct gk20a *g,
871 struct mmu_fault_info *mmfault, u32 *invalidate_replay_val) 871 struct mmu_fault_info *mmfault, u32 *invalidate_replay_val)
872{ 872{
873 unsigned int id_type; 873 unsigned int id_type = ID_TYPE_UNKNOWN;
874 u32 num_lce, act_eng_bitmask = 0; 874 u32 num_lce, act_eng_bitmask = 0;
875 int err = 0; 875 int err = 0;
876 u32 id = ((u32)~0); 876 u32 id = FIFO_INVAL_TSG_ID;
877 unsigned int rc_type = RC_TYPE_NO_RC;
877 878
878 if (!mmfault->valid) 879 if (!mmfault->valid)
879 return; 880 return;
@@ -888,18 +889,23 @@ static void gv11b_fb_handle_mmu_fault_common(struct gk20a *g,
888 /* CE page faults are not reported as replayable */ 889 /* CE page faults are not reported as replayable */
889 nvgpu_log(g, gpu_dbg_intr, "CE Faulted"); 890 nvgpu_log(g, gpu_dbg_intr, "CE Faulted");
890 err = gv11b_fb_fix_page_fault(g, mmfault); 891 err = gv11b_fb_fix_page_fault(g, mmfault);
891 gv11b_fifo_reset_pbdma_and_eng_faulted(g, mmfault->refch, 892 if (mmfault->refch &&
892 mmfault->faulted_pbdma, mmfault->faulted_engine); 893 (u32)mmfault->refch->tsgid != FIFO_INVAL_TSG_ID) {
894 gv11b_fifo_reset_pbdma_and_eng_faulted(g,
895 &g->fifo.tsg[mmfault->refch->tsgid],
896 mmfault->faulted_pbdma,
897 mmfault->faulted_engine);
898 }
893 if (!err) { 899 if (!err) {
894 nvgpu_log(g, gpu_dbg_intr, "CE Page Fault Fixed"); 900 nvgpu_log(g, gpu_dbg_intr, "CE Page Fault Fixed");
895 *invalidate_replay_val = 0; 901 *invalidate_replay_val = 0;
896 /* refch in mmfault is assigned at the time of copying 902 if (mmfault->refch) {
897 * fault info from snap reg or bar2 fault buf 903 gk20a_channel_put(mmfault->refch);
898 */ 904 mmfault->refch = NULL;
899 gk20a_channel_put(mmfault->refch); 905 }
900 return; 906 return;
901 } 907 }
902 /* Do recovery. Channel recovery needs refch */ 908 /* Do recovery */
903 nvgpu_log(g, gpu_dbg_intr, "CE Page Fault Not Fixed"); 909 nvgpu_log(g, gpu_dbg_intr, "CE Page Fault Not Fixed");
904 } 910 }
905 911
@@ -911,16 +917,9 @@ static void gv11b_fb_handle_mmu_fault_common(struct gk20a *g,
911 * instance block, the fault cannot be isolated to a 917 * instance block, the fault cannot be isolated to a
912 * single context so we need to reset the entire runlist 918 * single context so we need to reset the entire runlist
913 */ 919 */
914 id_type = ID_TYPE_UNKNOWN; 920 rc_type = RC_TYPE_MMU_FAULT;
915 921
916 } else if (mmfault->refch) { 922 } else if (mmfault->refch) {
917 if (gk20a_is_channel_marked_as_tsg(mmfault->refch)) {
918 id = mmfault->refch->tsgid;
919 id_type = ID_TYPE_TSG;
920 } else {
921 id = mmfault->chid;
922 id_type = ID_TYPE_CHANNEL;
923 }
924 if (mmfault->refch->mmu_nack_handled) { 923 if (mmfault->refch->mmu_nack_handled) {
925 /* We have already recovered for the same 924 /* We have already recovered for the same
926 * context, skip doing another recovery. 925 * context, skip doing another recovery.
@@ -941,19 +940,40 @@ static void gv11b_fb_handle_mmu_fault_common(struct gk20a *g,
941 */ 940 */
942 gk20a_channel_put(mmfault->refch); 941 gk20a_channel_put(mmfault->refch);
943 return; 942 return;
943 } else {
944 /* Indicate recovery is handled if mmu fault is
945 * a result of mmu nack.
946 */
947 mmfault->refch->mmu_nack_handled = true;
948 }
949
950 rc_type = RC_TYPE_MMU_FAULT;
951 if (gk20a_is_channel_marked_as_tsg(mmfault->refch)) {
952 id = mmfault->refch->tsgid;
953 if (id != FIFO_INVAL_TSG_ID)
954 id_type = ID_TYPE_TSG;
955 } else {
956 nvgpu_err(g, "bare channels not supported");
944 } 957 }
945 } else {
946 id_type = ID_TYPE_UNKNOWN;
947 } 958 }
948 if (mmfault->faulted_engine != FIFO_INVAL_ENGINE_ID) 959
960 /* engine is faulted */
961 if (mmfault->faulted_engine != FIFO_INVAL_ENGINE_ID) {
949 act_eng_bitmask = BIT(mmfault->faulted_engine); 962 act_eng_bitmask = BIT(mmfault->faulted_engine);
963 rc_type = RC_TYPE_MMU_FAULT;
964 }
950 965
951 /* Indicate recovery is handled if mmu fault is a result of 966 /* refch in mmfault is assigned at the time of copying
952 * mmu nack. 967 * fault info from snap reg or bar2 fault buf
953 */ 968 */
954 mmfault->refch->mmu_nack_handled = true; 969 if (mmfault->refch) {
955 g->ops.fifo.teardown_ch_tsg(g, act_eng_bitmask, 970 gk20a_channel_put(mmfault->refch);
956 id, id_type, RC_TYPE_MMU_FAULT, mmfault); 971 mmfault->refch = NULL;
972 }
973
974 if (rc_type != RC_TYPE_NO_RC)
975 g->ops.fifo.teardown_ch_tsg(g, act_eng_bitmask,
976 id, id_type, rc_type, mmfault);
957 } else { 977 } else {
958 if (mmfault->fault_type == gmmu_fault_type_pte_v()) { 978 if (mmfault->fault_type == gmmu_fault_type_pte_v()) {
959 nvgpu_log(g, gpu_dbg_intr, "invalid pte! try to fix"); 979 nvgpu_log(g, gpu_dbg_intr, "invalid pte! try to fix");
@@ -972,7 +992,10 @@ static void gv11b_fb_handle_mmu_fault_common(struct gk20a *g,
972 /* refch in mmfault is assigned at the time of copying 992 /* refch in mmfault is assigned at the time of copying
973 * fault info from snap reg or bar2 fault buf 993 * fault info from snap reg or bar2 fault buf
974 */ 994 */
975 gk20a_channel_put(mmfault->refch); 995 if (mmfault->refch) {
996 gk20a_channel_put(mmfault->refch);
997 mmfault->refch = NULL;
998 }
976 } 999 }
977} 1000}
978 1001
@@ -1061,8 +1084,10 @@ void gv11b_fb_handle_mmu_nonreplay_replay_fault(struct gk20a *g,
1061 next_fault_addr = mmfault->fault_addr; 1084 next_fault_addr = mmfault->fault_addr;
1062 if (prev_fault_addr == next_fault_addr) { 1085 if (prev_fault_addr == next_fault_addr) {
1063 nvgpu_log(g, gpu_dbg_intr, "pte already scanned"); 1086 nvgpu_log(g, gpu_dbg_intr, "pte already scanned");
1064 if (mmfault->refch) 1087 if (mmfault->refch) {
1065 gk20a_channel_put(mmfault->refch); 1088 gk20a_channel_put(mmfault->refch);
1089 mmfault->refch = NULL;
1090 }
1066 continue; 1091 continue;
1067 } 1092 }
1068 } 1093 }