diff --git a/level_zero/tools/source/debug/linux/xe/debug_session.cpp b/level_zero/tools/source/debug/linux/xe/debug_session.cpp index 92505b47c6..cf5e70612a 100644 --- a/level_zero/tools/source/debug/linux/xe/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/xe/debug_session.cpp @@ -318,7 +318,7 @@ void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *event) { vmBindOpData.vmBindOp = *vmBindOp; vmBindData.pendingNumBinds--; clientHandleToConnection[clientHandle]->vmBindIdentifierMap[vmBindOp->base.seqno] = vmBindOp->vm_bind_ref_seqno; - handleVmBindWithoutUfence(vmBindData, vmBindOpData); + handleVmBind(vmBindData); } break; case DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE: { @@ -331,7 +331,8 @@ void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *event) { UNRECOVERABLE_IF(vmBindMap.find(vmBindUfence->vm_bind_ref_seqno) == vmBindMap.end()); uint32_t uFenceRequired = vmBindMap[vmBindUfence->vm_bind_ref_seqno].vmBind.flags & DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE; UNRECOVERABLE_IF(!uFenceRequired); - UNRECOVERABLE_IF(vmBindMap[vmBindUfence->vm_bind_ref_seqno].pendingNumBinds); + UNRECOVERABLE_IF(vmBindMap[vmBindUfence->vm_bind_ref_seqno].uFenceReceived); // Dont expect multiple UFENCE for same vm_bind + vmBindMap[vmBindUfence->vm_bind_ref_seqno].uFenceReceived = true; vmBindMap[vmBindUfence->vm_bind_ref_seqno].vmBindUfence = *vmBindUfence; handleVmBind(vmBindMap[vmBindUfence->vm_bind_ref_seqno]); } break; @@ -361,7 +362,7 @@ void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *event) { UNRECOVERABLE_IF(!vmBindOpData.pendingNumExtensions); vmBindOpData.vmBindOpMetadataVec.push_back(*vmBindOpMetadata); vmBindOpData.pendingNumExtensions--; - handleVmBindWithoutUfence(vmBindMap[vmBindSeqNo], vmBindOpData); + handleVmBind(vmBindMap[vmBindSeqNo]); } break; default: @@ -370,18 +371,29 @@ void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *event) { } } -void DebugSessionLinuxXe::handleVmBindWithoutUfence(VmBindData &vmBindData, VmBindOpData &vmBindOpData) { +bool DebugSessionLinuxXe::canHandleVmBind(VmBindData &vmBindData) const { + if (vmBindData.pendingNumBinds) { + return false; + } + for (const auto &vmBindOpData : vmBindData.vmBindOpMap) { + if (vmBindOpData.second.pendingNumExtensions) { + return false; + } + } uint32_t uFenceRequired = vmBindData.vmBind.flags & DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE; if (uFenceRequired) { - return; + if (!vmBindData.uFenceReceived) { + return false; + } } - if (vmBindData.pendingNumBinds || vmBindOpData.pendingNumExtensions) { - return; - } - handleVmBind(vmBindData); + + return true; } void DebugSessionLinuxXe::handleVmBind(VmBindData &vmBindData) { + if (!canHandleVmBind(vmBindData)) { + return; + } bool shouldAckEvent = vmBindData.vmBind.flags & DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE; auto connection = clientHandleToConnection[clientHandle].get(); auto elfHandleInVmBind = invalidHandle; @@ -390,7 +402,6 @@ void DebugSessionLinuxXe::handleVmBind(VmBindData &vmBindData) { bool triggerModuleLoadEvent = false; for (auto &vmBindOpData : vmBindData.vmBindOpMap) { - UNRECOVERABLE_IF(vmBindOpData.second.pendingNumExtensions); for (const auto &vmBindOpMetadata : vmBindOpData.second.vmBindOpMetadataVec) { auto &vmBindOp = vmBindOpData.second.vmBindOp; auto &metaDataEntry = connection->metaDataMap[vmBindOpMetadata.metadata_handle]; diff --git a/level_zero/tools/source/debug/linux/xe/debug_session.h b/level_zero/tools/source/debug/linux/xe/debug_session.h index 46a4f963aa..824d77c6a2 100644 --- a/level_zero/tools/source/debug/linux/xe/debug_session.h +++ b/level_zero/tools/source/debug/linux/xe/debug_session.h @@ -115,6 +115,7 @@ struct DebugSessionLinuxXe : DebugSessionLinux { struct VmBindData { uint64_t pendingNumBinds = 0; drm_xe_eudebug_event_vm_bind vmBind; + bool uFenceReceived = false; drm_xe_eudebug_event_vm_bind_ufence vmBindUfence; std::unordered_map vmBindOpMap; }; @@ -132,6 +133,7 @@ struct DebugSessionLinuxXe : DebugSessionLinux { std::unordered_map vmBindIdentifierMap; }; std::unordered_map> clientHandleToConnection; + bool canHandleVmBind(VmBindData &vmBindData) const; void handleVmBind(VmBindData &vmBindData); void handleVmBindWithoutUfence(VmBindData &vmBindData, VmBindOpData &vmBindOpData); diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp index d8d8522099..e03592d5f3 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp @@ -1359,30 +1359,31 @@ TEST_F(DebugApiLinuxTestXe, GivenVmBindOpMetadataCreateEventAndUfenceForProgramM vmBindOp.vm_bind_ref_seqno = vmBind.base.seqno; session->handleEvent(reinterpret_cast(&vmBindOp.base)); + drm_xe_eudebug_event_vm_bind_ufence vmBindUfence{}; + vmBindUfence.base.type = DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE; + vmBindUfence.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE | DRM_XE_EUDEBUG_EVENT_NEED_ACK; + vmBindUfence.base.len = sizeof(drm_xe_eudebug_event_vm_bind_ufence); + vmBindUfence.base.seqno = 3; + vmBindUfence.vm_bind_ref_seqno = vmBind.base.seqno; + session->handleEvent(reinterpret_cast(&vmBindUfence.base)); + auto &vmBindOpData = vmBindMap[vmBindOp.vm_bind_ref_seqno].vmBindOpMap[vmBindOp.base.seqno]; drm_xe_eudebug_event_vm_bind_op_metadata vmBindOpMetadata{}; vmBindOpMetadata.base.type = DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA; vmBindOpMetadata.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE; vmBindOpMetadata.base.len = sizeof(drm_xe_eudebug_event_vm_bind_op_metadata); - vmBindOpMetadata.base.seqno = 3; + vmBindOpMetadata.base.seqno = 4; vmBindOpMetadata.vm_bind_op_ref_seqno = vmBindOp.base.seqno; vmBindOpMetadata.metadata_handle = 10; session->handleEvent(reinterpret_cast(&vmBindOpMetadata.base)); - vmBindOpMetadata.base.seqno = 4; + vmBindOpMetadata.base.seqno = 5; vmBindOpMetadata.metadata_handle = 11; session->handleEvent(reinterpret_cast(&vmBindOpMetadata.base)); EXPECT_EQ(vmBindOpData.pendingNumExtensions, 0ull); EXPECT_EQ(vmBindOpData.vmBindOpMetadataVec.size(), 2ull); - drm_xe_eudebug_event_vm_bind_ufence vmBindUfence{}; - vmBindUfence.base.type = DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE; - vmBindUfence.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE | DRM_XE_EUDEBUG_EVENT_NEED_ACK; - vmBindUfence.base.len = sizeof(drm_xe_eudebug_event_vm_bind_ufence); - vmBindUfence.base.seqno = 5; - vmBindUfence.vm_bind_ref_seqno = vmBind.base.seqno; - session->handleEvent(reinterpret_cast(&vmBindUfence.base)); EXPECT_EQ(connection->metaDataToModule[10].ackEvents->size(), 1ull); EXPECT_EQ(connection->metaDataToModule[10].ackEvents[0][0].seqno, vmBindUfence.base.seqno); EXPECT_EQ(connection->metaDataToModule[10].ackEvents[0][0].type, vmBindUfence.base.type);