From 10753387bf47f0c19f0b137557ed51484c44c791 Mon Sep 17 00:00:00 2001 From: Jitendra Sharma Date: Wed, 8 Jan 2025 10:09:44 +0000 Subject: [PATCH] feature: Introduce processPendingVmBindEvents in eu debug Related-To: NEO-11104 Signed-off-by: Jitendra Sharma --- .../source/debug/linux/xe/debug_session.cpp | 42 +++- .../source/debug/linux/xe/debug_session.h | 6 +- .../xe/debug_session_fixtures_linux_xe.h | 9 + .../linux/xe/test_debug_api_linux_xe.cpp | 233 +++++++++++++++++- 4 files changed, 279 insertions(+), 11 deletions(-) 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 dc713e10b0..18b3187f8f 100644 --- a/level_zero/tools/source/debug/linux/xe/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/xe/debug_session.cpp @@ -73,6 +73,12 @@ bool DebugSessionLinuxXe::handleInternalEvent() { auto debugEvent = reinterpret_cast(eventMemory.get()); handleEvent(debugEvent); + if (debugEvent->type == euDebugInterface->getParamValue(NEO::EuDebugParam::eventTypeExecQueuePlacements) || + debugEvent->type == euDebugInterface->getParamValue(NEO::EuDebugParam::eventTypeVmBindOp) || + debugEvent->type == euDebugInterface->getParamValue(NEO::EuDebugParam::eventTypeVmBindUfence) || + debugEvent->type == euDebugInterface->getParamValue(NEO::EuDebugParam::eventTypeVmBindOpMetadata)) { + processPendingVmBindEvents(); + } return true; } @@ -302,7 +308,6 @@ void DebugSessionLinuxXe::handleEvent(NEO::EuDebugEvent *event) { vmBindOpData.vmBindOp = *vmBindOp; vmBindData.pendingNumBinds--; clientHandleToConnection[clientHandle]->vmBindIdentifierMap[vmBindOp->base.seqno] = vmBindOp->vmBindRefSeqno; - handleVmBind(vmBindData); } else if (type == euDebugInterface->getParamValue(NEO::EuDebugParam::eventTypeVmBindUfence)) { NEO::EuDebugEventVmBindUfence *vmBindUfence = reinterpret_cast(event); @@ -316,7 +321,6 @@ void DebugSessionLinuxXe::handleEvent(NEO::EuDebugEvent *event) { UNRECOVERABLE_IF(vmBindMap[vmBindUfence->vmBindRefSeqno].uFenceReceived); // Dont expect multiple UFENCE for same vm_bind vmBindMap[vmBindUfence->vmBindRefSeqno].uFenceReceived = true; vmBindMap[vmBindUfence->vmBindRefSeqno].vmBindUfence = *vmBindUfence; - handleVmBind(vmBindMap[vmBindUfence->vmBindRefSeqno]); } else if (type == euDebugInterface->getParamValue(NEO::EuDebugParam::eventTypeMetadata)) { NEO::EuDebugEventMetadata *metaData = reinterpret_cast(event); if (clientHandle == invalidClientHandle) { @@ -343,7 +347,6 @@ void DebugSessionLinuxXe::handleEvent(NEO::EuDebugEvent *event) { UNRECOVERABLE_IF(!vmBindOpData.pendingNumExtensions); vmBindOpData.vmBindOpMetadataVec.push_back(*vmBindOpMetadata); vmBindOpData.pendingNumExtensions--; - handleVmBind(vmBindMap[vmBindSeqNo]); } else if (type == euDebugInterface->getParamValue(NEO::EuDebugParam::eventTypeExecQueuePlacements)) { NEO::EuDebugEventExecQueuePlacements *execQueuePlacements = reinterpret_cast(event); @@ -382,6 +385,21 @@ void DebugSessionLinuxXe::handleEvent(NEO::EuDebugEvent *event) { } } +void DebugSessionLinuxXe::processPendingVmBindEvents() { + std::vectorvmBindMap)::key_type> keysToDelete; + auto &vmBindMap = clientHandleToConnection[clientHandle]->vmBindMap; + for (auto &pair : vmBindMap) { + auto &vmBindData = pair.second; + if (handleVmBind(vmBindData) == false) { + break; + } + keysToDelete.push_back(pair.first); + } + for (const auto &key : keysToDelete) { + vmBindMap.erase(key); + } +} + bool DebugSessionLinuxXe::canHandleVmBind(VmBindData &vmBindData) const { if (vmBindData.pendingNumBinds) { return false; @@ -401,9 +419,9 @@ bool DebugSessionLinuxXe::canHandleVmBind(VmBindData &vmBindData) const { return true; } -void DebugSessionLinuxXe::handleVmBind(VmBindData &vmBindData) { +bool DebugSessionLinuxXe::handleVmBind(VmBindData &vmBindData) { if (!canHandleVmBind(vmBindData)) { - return; + return false; } bool shouldAckEvent = vmBindData.vmBind.flags & euDebugInterface->getParamValue(NEO::EuDebugParam::eventVmBindFlagUfence); auto connection = clientHandleToConnection[clientHandle].get(); @@ -414,9 +432,17 @@ void DebugSessionLinuxXe::handleVmBind(VmBindData &vmBindData) { bool triggerModuleLoadEvent = false; uint32_t tileIndex = 0; - if (connection->vmToTile.find(vmBindData.vmBind.vmHandle) != connection->vmToTile.end()) { - tileIndex = connection->vmToTile[vmBindData.vmBind.vmHandle]; + auto numTiles = connectedDevice->getNEODevice()->getNumSubDevices(); + if (numTiles > 0) { + if (connection->vmToTile.find(vmBindData.vmBind.vmHandle) != connection->vmToTile.end()) { + tileIndex = connection->vmToTile[vmBindData.vmBind.vmHandle]; + PRINT_DEBUGGER_INFO_LOG("handleVmBind: tileIndex = %d for vmHandle = %" SCNx64 " \n", tileIndex, vmBindData.vmBind.vmHandle); + } else { + PRINT_DEBUGGER_ERROR_LOG("handleVmBind: tileIndex not found for vmHandle = %" SCNx64 " \n", vmBindData.vmBind.vmHandle); + return false; + } } + for (auto &vmBindOpData : vmBindData.vmBindOpMap) { auto &vmBindOp = vmBindOpData.second.vmBindOp; for (const auto &vmBindOpMetadata : vmBindOpData.second.vmBindOpMetadataVec) { @@ -574,6 +600,8 @@ void DebugSessionLinuxXe::handleVmBind(VmBindData &vmBindData) { EventToAck ackEvent(vmBindData.vmBindUfence.base.seqno, vmBindData.vmBindUfence.base.type); eventAckIoctl(ackEvent); } + + return true; } void DebugSessionLinuxXe::handleMetadataEvent(NEO::EuDebugEventMetadata *metaData) { 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 298e7ce67e..1dbf862b92 100644 --- a/level_zero/tools/source/debug/linux/xe/debug_session.h +++ b/level_zero/tools/source/debug/linux/xe/debug_session.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -82,6 +82,7 @@ struct DebugSessionLinuxXe : DebugSessionLinux { void startAsyncThread() override; static void *asyncThreadFunction(void *arg); bool handleInternalEvent() override; + MOCKABLE_VIRTUAL void processPendingVmBindEvents(); DebugSessionImp *createTileSession(const zet_debug_config_t &config, Device *device, DebugSessionImp *rootDebugSession) override { return nullptr; } @@ -131,11 +132,10 @@ struct DebugSessionLinuxXe : DebugSessionLinux { }; std::unordered_map> clientHandleToConnection; bool canHandleVmBind(VmBindData &vmBindData) const; - void handleVmBind(VmBindData &vmBindData); + bool handleVmBind(VmBindData &vmBindData); void handleVmBindWithoutUfence(VmBindData &vmBindData, VmBindOpData &vmBindOpData); void extractMetaData(uint64_t client, const MetaData &metaData); - std::vector> pendingVmBindEvents; bool checkAllEventsCollected(); MOCKABLE_VIRTUAL void handleEvent(NEO::EuDebugEvent *event); void additionalEvents(NEO::EuDebugEvent *event); diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h index 4af19365f6..cd70643510 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h @@ -172,6 +172,7 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe { using L0::DebugSessionLinuxXe::addThreadToNewlyStoppedFromRaisedAttentionForTileSession; using L0::DebugSessionLinuxXe::asyncThread; using L0::DebugSessionLinuxXe::asyncThreadFunction; + using L0::DebugSessionLinuxXe::canHandleVmBind; using L0::DebugSessionLinuxXe::checkStoppedThreadsAndGenerateEvents; using L0::DebugSessionLinuxXe::checkTriggerEventsForAttentionForTileSession; using L0::DebugSessionLinuxXe::ClientConnectionXe; @@ -184,6 +185,8 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe { using L0::DebugSessionLinuxXe::getThreadStateMutexForTileSession; using L0::DebugSessionLinuxXe::getVmHandleFromClientAndlrcHandle; using L0::DebugSessionLinuxXe::handleEvent; + using L0::DebugSessionLinuxXe::handleInternalEvent; + using L0::DebugSessionLinuxXe::handleVmBind; using L0::DebugSessionLinuxXe::internalEventQueue; using L0::DebugSessionLinuxXe::internalEventThread; using L0::DebugSessionLinuxXe::invalidClientHandle; @@ -226,6 +229,11 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe { return DebugSessionLinuxXe::handleAttentionEvent(attention); } + void processPendingVmBindEvents() override { + processPendingVmBindEventsCallCount++; + return DebugSessionLinuxXe::processPendingVmBindEvents(); + } + int threadControl(const std::vector &threads, uint32_t tile, ThreadControlCmd threadCmd, std::unique_ptr &bitmask, size_t &bitmaskSize) override { numThreadsPassedToThreadControl = threads.size(); return L0::DebugSessionLinuxXe::threadControl(threads, tile, threadCmd, bitmask, bitmaskSize); @@ -294,6 +302,7 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe { } uint32_t readSystemRoutineIdentCallCount = 0; + uint32_t processPendingVmBindEventsCallCount = 0; uint32_t addThreadToNewlyStoppedFromRaisedAttentionCallCount = 0; uint32_t readSystemRoutineIdentFromMemoryCallCount = 0; size_t numThreadsPassedToThreadControl = 0; 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 8688e32cf5..ac45809f6a 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 @@ -1313,6 +1313,7 @@ TEST_P(DebugApiLinuxTestXeMetadataOpEventTest, GivenVmBindOpMetadataEventForMeta NEO::EuDebugEventVmBindUfence vmBindUfence{}; createUfenceEvent(vmBindUfence, seqNo, vmBind.base.seqno); session->handleEvent(reinterpret_cast(&vmBindUfence.base)); + session->processPendingVmBindEvents(); if (metadataType == static_cast(NEO::EuDebugParam::metadataSbaArea)) { EXPECT_EQ(connection->vmToStateBaseAreaBindInfo[vmHandle].gpuVa, vmBindOp.addr); @@ -1349,6 +1350,226 @@ INSTANTIATE_TEST_SUITE_P( DebugApiLinuxTestXeMetadataOpEventTest, testing::ValuesIn(metadataTypes)); +TEST_F(DebugApiLinuxTestXe, GivenPendingNumBindsWhenCanHandleVmBindCalledThenFalseIsReturned) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + auto &vmBindData = session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->vmBindMap[1]; + vmBindData.pendingNumBinds = 1; + EXPECT_FALSE(session->canHandleVmBind(vmBindData)); +} + +TEST_F(DebugApiLinuxTestXe, GivenPendingNumExtensionsForVmBindOpWhenCanHandleVmBindCalledThenFalseIsReturned) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + auto &vmBindData = session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->vmBindMap[1]; + vmBindData.pendingNumBinds = 1; + + auto &vmBindOpData1 = vmBindData.vmBindOpMap[10]; + vmBindOpData1.pendingNumExtensions = 1; + vmBindData.pendingNumBinds--; + + EXPECT_FALSE(session->canHandleVmBind(vmBindData)); +} + +TEST_F(DebugApiLinuxTestXe, GivenUfenceNotRequiredAndNoPendingVmBindWhenCanHandleVmBindCalledThenTrueIsReturned) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + auto &vmBindData = session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->vmBindMap[1]; + vmBindData.pendingNumBinds = 0; + vmBindData.vmBind.flags = 0; + EXPECT_TRUE(session->canHandleVmBind(vmBindData)); +} + +TEST_F(DebugApiLinuxTestXe, GivenUfenceRequiredButUfenceNotReceiveddWhenCanHandleVmBindCalledThenFalseIsReturned) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + auto &vmBindData = session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->vmBindMap[1]; + vmBindData.pendingNumBinds = 0; + vmBindData.vmBind.flags = static_cast(NEO::EuDebugParam::eventVmBindFlagUfence); + vmBindData.uFenceReceived = false; + EXPECT_FALSE(session->canHandleVmBind(vmBindData)); +} + +TEST_F(DebugApiLinuxTestXe, GivenCanHandleVmBindReturnFalsedWhenHandleVmBindCalledThenFalseIsReturned) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + auto &vmBindData = session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->vmBindMap[1]; + vmBindData.pendingNumBinds = 1; + EXPECT_FALSE(session->canHandleVmBind(vmBindData)); + EXPECT_FALSE(session->handleVmBind(vmBindData)); +} + +TEST_F(DebugApiLinuxTestXe, GivenNoEventRelatedToVmBindHandlingWhenHandleInternalEventCalledThenTrueIsReturned) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + + session->clientHandleToConnection.clear(); + + uint8_t eventClientData[sizeof(NEO::EuDebugEventClient)]; + auto client = reinterpret_cast(&eventClientData); + client->base.type = static_cast(NEO::EuDebugParam::eventTypeOpen); + client->base.flags = static_cast(NEO::shiftLeftBy(static_cast(NEO::EuDebugParam::eventBitCreate))); + client->base.len = sizeof(NEO::EuDebugEventClient); + client->clientHandle = 0x123456789; + auto memory = std::make_unique(sizeof(NEO::EuDebugEventClient) / sizeof(uint64_t)); + memcpy(memory.get(), client, sizeof(NEO::EuDebugEventClient)); + + // Clear the event queue before using it + while (!session->internalEventQueue.empty()) { + session->internalEventQueue.pop(); + } + session->internalEventQueue.push(std::move(memory)); + EXPECT_TRUE(session->handleInternalEvent()); +} + +TEST_F(DebugApiLinuxTestXe, GivenEventTypeExecQueuePlacementsWhenHandleInternalEventCalledThenProcessPendingVmBindEventsCalled) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + + auto &vmBindData = session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->vmBindMap[1]; + vmBindData.pendingNumBinds = 1; + + constexpr uint64_t vmHandle = 10; + // Allocate memory for the structure including the flexible array member + constexpr auto size = sizeof(NEO::EuDebugEventExecQueuePlacements) + sizeof(drm_xe_engine_class_instance) * 1; + + uint8_t memoryExecQueuePlacements[size]; + auto execQueuePlacements = reinterpret_cast(memoryExecQueuePlacements); + memset(execQueuePlacements, 0, size); + execQueuePlacements->base.type = static_cast(NEO::EuDebugParam::eventTypeExecQueuePlacements); + execQueuePlacements->base.len = sizeof(NEO::EuDebugEventExecQueuePlacements); + execQueuePlacements->clientHandle = MockDebugSessionLinuxXe::mockClientHandle; + execQueuePlacements->vmHandle = vmHandle; + execQueuePlacements->execQueueHandle = 200; + execQueuePlacements->lrcHandle = 10; + execQueuePlacements->numPlacements = 1; + + auto engineClassInstance = reinterpret_cast(&(execQueuePlacements->instances[0])); + engineClassInstance[0].engine_class = 0; + engineClassInstance[0].engine_instance = 1; + engineClassInstance[0].gt_id = 1; + + auto memory = std::make_unique(size / sizeof(uint64_t)); + memcpy(memory.get(), memoryExecQueuePlacements, size); + + // Clear the event queue before using it + while (!session->internalEventQueue.empty()) { + session->internalEventQueue.pop(); + } + session->internalEventQueue.push(std::move(memory)); + EXPECT_TRUE(session->handleInternalEvent()); + EXPECT_EQ(session->processPendingVmBindEventsCallCount, 1u); +} + +TEST_F(DebugApiLinuxTestXe, + GivenEventTypeVmBindOpOrEventTypeVmBindOpMetadataOrUfenceWhenHandleInternalEventCalledThenProcessPendingVmBindEventsCalled) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + ASSERT_NE(nullptr, session); + + session->clientHandleToConnection.clear(); + NEO::EuDebugEventClient client1; + client1.base.type = static_cast(NEO::EuDebugParam::eventTypeOpen); + client1.base.flags = static_cast(NEO::shiftLeftBy(static_cast(NEO::EuDebugParam::eventBitCreate))); + client1.clientHandle = MockDebugSessionLinuxXe::mockClientHandle; + session->handleEvent(reinterpret_cast(&client1)); + + NEO::EuDebugEventVmBind vmBind{}; + vmBind.base.type = static_cast(NEO::EuDebugParam::eventTypeVmBind); + vmBind.base.flags = static_cast(NEO::shiftLeftBy(static_cast(NEO::EuDebugParam::eventBitStateChange))); + vmBind.base.len = sizeof(NEO::EuDebugEventVmBind); + vmBind.base.seqno = 1; + vmBind.clientHandle = client1.clientHandle; + vmBind.flags = static_cast(NEO::EuDebugParam::eventVmBindFlagUfence); + vmBind.numBinds = 2; + + auto &vmBindMap = session->clientHandleToConnection[client1.clientHandle]->vmBindMap; + EXPECT_EQ(vmBindMap.size(), 0u); + session->handleEvent(reinterpret_cast(&vmBind.base)); + EXPECT_EQ(vmBindMap.size(), 1u); + EXPECT_EQ(vmBindMap[vmBind.base.seqno].pendingNumBinds, 2ull); + + constexpr auto sizeEuDebugEventVmBindOp = sizeof(NEO::EuDebugEventVmBindOp); + + uint8_t memoryEuDebugEventVmBindOp[sizeEuDebugEventVmBindOp]; + auto vmBindOp = reinterpret_cast(memoryEuDebugEventVmBindOp); + memset(vmBindOp, 0, sizeEuDebugEventVmBindOp); + vmBindOp->base.type = static_cast(NEO::EuDebugParam::eventTypeVmBindOp); + vmBindOp->base.flags = static_cast(NEO::shiftLeftBy(static_cast(NEO::EuDebugParam::eventBitCreate))); + vmBindOp->base.len = sizeof(NEO::EuDebugEventVmBindOp); + vmBindOp->base.seqno = 2; + vmBindOp->numExtensions = 2; + vmBindOp->addr = 0xffff1234; + vmBindOp->range = 65536; + vmBindOp->vmBindRefSeqno = vmBind.base.seqno; + + auto memoryEvent1 = std::make_unique(sizeEuDebugEventVmBindOp / sizeof(uint64_t)); + memcpy(memoryEvent1.get(), vmBindOp, sizeEuDebugEventVmBindOp); + + constexpr auto sizeEuDebugEventVmBindOpMetadata = sizeof(NEO::EuDebugEventVmBindOpMetadata); + uint8_t memoryEuDebugEventVmBindOpMetadata[sizeEuDebugEventVmBindOpMetadata]; + auto vmBindOpMetadata = reinterpret_cast(memoryEuDebugEventVmBindOpMetadata); + memset(vmBindOpMetadata, 0, sizeEuDebugEventVmBindOpMetadata); + vmBindOpMetadata->base.type = static_cast(NEO::EuDebugParam::eventTypeVmBindOpMetadata); + vmBindOpMetadata->base.flags = static_cast(NEO::shiftLeftBy(static_cast(NEO::EuDebugParam::eventBitCreate))); + vmBindOpMetadata->base.len = sizeof(NEO::EuDebugEventVmBindOpMetadata); + vmBindOpMetadata->base.seqno = 3; + vmBindOpMetadata->vmBindOpRefSeqno = vmBindOp->base.seqno; + vmBindOpMetadata->metadataHandle = 10; + auto memoryEvent2 = std::make_unique(sizeEuDebugEventVmBindOpMetadata / sizeof(uint64_t)); + memcpy(memoryEvent2.get(), vmBindOpMetadata, sizeEuDebugEventVmBindOpMetadata); + + constexpr auto sizeEuDebugEventVmBindUfence = sizeof(NEO::EuDebugEventVmBindUfence); + uint8_t memoryEuDebugEventVmBindUfence[sizeEuDebugEventVmBindUfence]; + auto vmBindUfence = reinterpret_cast(memoryEuDebugEventVmBindUfence); + memset(vmBindUfence, 0, sizeEuDebugEventVmBindUfence); + vmBindUfence->base.type = static_cast(NEO::EuDebugParam::eventTypeVmBindUfence); + vmBindUfence->base.flags = static_cast(NEO::shiftLeftBy(static_cast(NEO::EuDebugParam::eventBitCreate))) | static_cast(NEO::shiftLeftBy(static_cast(NEO::EuDebugParam::eventBitNeedAck))); + vmBindUfence->base.len = sizeof(NEO::EuDebugEventVmBindUfence); + vmBindUfence->base.seqno = 4; + vmBindUfence->vmBindRefSeqno = vmBind.base.seqno; + auto memoryEvent3 = std::make_unique(sizeEuDebugEventVmBindUfence / sizeof(uint64_t)); + memcpy(memoryEvent3.get(), vmBindUfence, sizeEuDebugEventVmBindUfence); + + // Clear the event queue before using it + while (!session->internalEventQueue.empty()) { + session->internalEventQueue.pop(); + } + session->internalEventQueue.push(std::move(memoryEvent1)); + session->internalEventQueue.push(std::move(memoryEvent2)); + session->internalEventQueue.push(std::move(memoryEvent3)); + + EXPECT_TRUE(session->handleInternalEvent()); + EXPECT_EQ(session->processPendingVmBindEventsCallCount, 1u); + EXPECT_TRUE(session->handleInternalEvent()); + EXPECT_EQ(session->processPendingVmBindEventsCallCount, 2u); + EXPECT_TRUE(session->handleInternalEvent()); + EXPECT_EQ(session->processPendingVmBindEventsCallCount, 3u); +} + TEST_F(DebugApiLinuxTestXe, GivenVmBindOpMetadataCreateEventAndUfenceForProgramModuleWhenHandlingEventThenEventIsAcked) { zet_debug_config_t config = {}; config.pid = 0x1234; @@ -1442,6 +1663,7 @@ TEST_F(DebugApiLinuxTestXe, GivenVmBindOpMetadataCreateEventAndUfenceForProgramM EXPECT_EQ(vmBindOpData.pendingNumExtensions, 0ull); EXPECT_EQ(vmBindOpData.vmBindOpMetadataVec.size(), 2ull); + session->processPendingVmBindEvents(); EXPECT_TRUE(session->pushApiEventAckEventsFound); @@ -1544,9 +1766,9 @@ TEST_F(DebugApiLinuxTestXe, GivenVmUnbindForLastIsaSegmentThenL0ModuleUnloadEven vmBindOpMetadata.base.seqno = seqno++; vmBindOpMetadata.metadataHandle = 11; session->handleEvent(reinterpret_cast(&vmBindOpMetadata.base)); - ASSERT_EQ(vmBindOpData.pendingNumExtensions, 0ull); ASSERT_EQ(vmBindOpData.vmBindOpMetadataVec.size(), 2ull); + session->processPendingVmBindEvents(); EXPECT_EQ(session->apiEvents.size(), 0u); // Now bind 2nd segment @@ -1571,6 +1793,7 @@ TEST_F(DebugApiLinuxTestXe, GivenVmUnbindForLastIsaSegmentThenL0ModuleUnloadEven vmBindUfence.base.seqno = seqno++; vmBindUfence.vmBindRefSeqno = vmBind.base.seqno; session->handleEvent(reinterpret_cast(&vmBindUfence.base)); + session->processPendingVmBindEvents(); auto event = session->apiEvents.front(); ASSERT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_LOAD, event.type); @@ -1591,6 +1814,7 @@ TEST_F(DebugApiLinuxTestXe, GivenVmUnbindForLastIsaSegmentThenL0ModuleUnloadEven vmBindUfence.base.seqno = seqno++; vmBindUfence.vmBindRefSeqno = vmBind.base.seqno; session->handleEvent(reinterpret_cast(&vmBindUfence.base)); + session->processPendingVmBindEvents(); EXPECT_EQ(session->apiEvents.size(), 0u); vmBind.base.seqno = seqno++; @@ -1606,6 +1830,7 @@ TEST_F(DebugApiLinuxTestXe, GivenVmUnbindForLastIsaSegmentThenL0ModuleUnloadEven vmBindUfence.base.seqno = seqno++; vmBindUfence.vmBindRefSeqno = vmBind.base.seqno; session->handleEvent(reinterpret_cast(&vmBindUfence.base)); + session->processPendingVmBindEvents(); // Unmatched vmHandle should not trigger any events EXPECT_EQ(session->apiEvents.size(), 0u); @@ -1624,6 +1849,7 @@ TEST_F(DebugApiLinuxTestXe, GivenVmUnbindForLastIsaSegmentThenL0ModuleUnloadEven vmBindUfence.base.seqno = seqno++; vmBindUfence.vmBindRefSeqno = vmBind.base.seqno; session->handleEvent(reinterpret_cast(&vmBindUfence.base)); + session->processPendingVmBindEvents(); event = session->apiEvents.front(); EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD, event.type); @@ -2459,6 +2685,7 @@ TEST_F(DebugApiLinuxTestXe, GivenSharedModuleDebugAreaWhenVmBindDebugAreaThenIsa vmBindUfence.base.seqno = 4; vmBindUfence.vmBindRefSeqno = vmBindEvent.base.seqno; session->handleEvent(reinterpret_cast(&vmBindUfence.base)); + session->processPendingVmBindEvents(); } DebugAreaHeader debugArea; @@ -2805,6 +3032,7 @@ TEST_F(DebugApiLinuxMultiDeviceVmBindTestXe, GivenVmBindForProgramModuleWhenHand auto &vmBindOpData = vmBindMap[vmBindOp1.vmBindRefSeqno].vmBindOpMap[vmBindOp1.base.seqno]; EXPECT_EQ(vmBindOpData.pendingNumExtensions, 0ull); EXPECT_EQ(vmBindOpData.vmBindOpMetadataVec.size(), 2ull); + session->processPendingVmBindEvents(); } EXPECT_FALSE(session->pushApiEventAckEventsFound); EXPECT_TRUE(connection->metaDataToModule[metadataHandle1].ackEvents->empty()); @@ -2835,6 +3063,7 @@ TEST_F(DebugApiLinuxMultiDeviceVmBindTestXe, GivenVmBindForProgramModuleWhenHand auto &vmBindOpData = vmBindMap[vmBindOp2.vmBindRefSeqno].vmBindOpMap[vmBindOp2.base.seqno]; EXPECT_EQ(vmBindOpData.pendingNumExtensions, 0ull); EXPECT_EQ(vmBindOpData.vmBindOpMetadataVec.size(), 2ull); + session->processPendingVmBindEvents(); } EXPECT_TRUE(session->pushApiEventAckEventsFound); @@ -2862,6 +3091,7 @@ TEST_F(DebugApiLinuxMultiDeviceVmBindTestXe, GivenVmBindForProgramModuleWhenHand createUfenceEvent(vmBindUfence3, seqNo, vmBind3.base.seqno); session->handleEvent(reinterpret_cast(&vmBindUfence3.base)); + session->processPendingVmBindEvents(); EXPECT_TRUE(session->apiEvents.empty()); } @@ -2877,6 +3107,7 @@ TEST_F(DebugApiLinuxMultiDeviceVmBindTestXe, GivenVmBindForProgramModuleWhenHand createUfenceEvent(vmBindUfence4, seqNo, vmBind4.base.seqno); session->handleEvent(reinterpret_cast(&vmBindUfence4.base)); + session->processPendingVmBindEvents(); } event = session->apiEvents.front(); EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD, event.type);