drm/amdkfd: check both client id and src id in interrupt handlers
authorAlex Deucher <alexander.deucher@amd.com>
Fri, 18 Dec 2020 21:31:18 +0000 (16:31 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 23 Dec 2020 20:07:40 +0000 (15:07 -0500)
We can have the same src ids for different client ids so make sure to
check both the client id and the source id when handling interrupts.

Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c

index 241bd6f..0ca0327 100644 (file)
@@ -44,6 +44,21 @@ static bool event_interrupt_isr_v9(struct kfd_dev *dev,
        client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry);
        pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
 
+       /* Only handle clients we care about */
+       if (client_id != SOC15_IH_CLIENTID_GRBM_CP &&
+           client_id != SOC15_IH_CLIENTID_SDMA0 &&
+           client_id != SOC15_IH_CLIENTID_SDMA1 &&
+           client_id != SOC15_IH_CLIENTID_SDMA2 &&
+           client_id != SOC15_IH_CLIENTID_SDMA3 &&
+           client_id != SOC15_IH_CLIENTID_SDMA4 &&
+           client_id != SOC15_IH_CLIENTID_SDMA5 &&
+           client_id != SOC15_IH_CLIENTID_SDMA6 &&
+           client_id != SOC15_IH_CLIENTID_SDMA7 &&
+           client_id != SOC15_IH_CLIENTID_VMC &&
+           client_id != SOC15_IH_CLIENTID_VMC1 &&
+           client_id != SOC15_IH_CLIENTID_UTCL2)
+               return false;
+
        /* This is a known issue for gfx9. Under non HWS, pasid is not set
         * in the interrupt payload, so we need to find out the pasid on our
         * own.
@@ -96,17 +111,26 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev,
        vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry);
        context_id = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry);
 
-       if (source_id == SOC15_INTSRC_CP_END_OF_PIPE)
-               kfd_signal_event_interrupt(pasid, context_id, 32);
-       else if (source_id == SOC15_INTSRC_SDMA_TRAP)
-               kfd_signal_event_interrupt(pasid, context_id & 0xfffffff, 28);
-       else if (source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG)
-               kfd_signal_event_interrupt(pasid, context_id & 0xffffff, 24);
-       else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE)
-               kfd_signal_hw_exception_event(pasid);
-       else if (client_id == SOC15_IH_CLIENTID_VMC ||
-               client_id == SOC15_IH_CLIENTID_VMC1 ||
-                client_id == SOC15_IH_CLIENTID_UTCL2) {
+       if (client_id == SOC15_IH_CLIENTID_GRBM_CP) {
+               if (source_id == SOC15_INTSRC_CP_END_OF_PIPE)
+                       kfd_signal_event_interrupt(pasid, context_id, 32);
+               else if (source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG)
+                       kfd_signal_event_interrupt(pasid, context_id & 0xffffff, 24);
+               else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE)
+                       kfd_signal_hw_exception_event(pasid);
+       } else if (client_id == SOC15_IH_CLIENTID_SDMA0 ||
+                  client_id == SOC15_IH_CLIENTID_SDMA1 ||
+                  client_id == SOC15_IH_CLIENTID_SDMA2 ||
+                  client_id == SOC15_IH_CLIENTID_SDMA3 ||
+                  client_id == SOC15_IH_CLIENTID_SDMA4 ||
+                  client_id == SOC15_IH_CLIENTID_SDMA5 ||
+                  client_id == SOC15_IH_CLIENTID_SDMA6 ||
+                  client_id == SOC15_IH_CLIENTID_SDMA7) {
+               if (source_id == SOC15_INTSRC_SDMA_TRAP)
+                       kfd_signal_event_interrupt(pasid, context_id & 0xfffffff, 28);
+       } else if (client_id == SOC15_IH_CLIENTID_VMC ||
+                  client_id == SOC15_IH_CLIENTID_VMC1 ||
+                  client_id == SOC15_IH_CLIENTID_UTCL2) {
                struct kfd_vm_fault_info info = {0};
                uint16_t ring_id = SOC15_RING_ID_FROM_IH_ENTRY(ih_ring_entry);