Debugger L0 win: implement zetAcknowledgeEvent API

Related-To: NEO-6723

Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:
Igor Venevtsev 2022-07-22 15:51:33 +00:00 committed by Compute-Runtime-Automation
parent 4da6f65d1a
commit d79e799bea
4 changed files with 174 additions and 23 deletions

View File

@ -1249,7 +1249,7 @@ void ModuleImp::notifyModuleCreate() {
StackVec<NEO::GraphicsAllocation *, 32> segmentAllocs = getModuleAllocations(); StackVec<NEO::GraphicsAllocation *, 32> segmentAllocs = getModuleAllocations();
auto minAddressGpuAlloc = std::min_element(segmentAllocs.begin(), segmentAllocs.end(), [](const auto alloc1, const auto alloc2) { return alloc1->getGpuAddress() < alloc2->getGpuAddress(); }); auto minAddressGpuAlloc = std::min_element(segmentAllocs.begin(), segmentAllocs.end(), [](const auto &alloc1, const auto &alloc2) { return alloc1->getGpuAddress() < alloc2->getGpuAddress(); });
debuggerL0->notifyModuleCreate(const_cast<char *>(debugData.vIsa), debugData.vIsaSize, (*minAddressGpuAlloc)->getGpuAddress()); debuggerL0->notifyModuleCreate(const_cast<char *>(debugData.vIsa), debugData.vIsaSize, (*minAddressGpuAlloc)->getGpuAddress());
} else { } else {
for (auto &kernImmData : kernelImmDatas) { for (auto &kernImmData : kernelImmDatas) {

View File

@ -189,21 +189,30 @@ ze_result_t DebugSessionWindows::handleModuleCreateEvent(uint32_t seqNo, DBGUMD_
PRINT_DEBUGGER_INFO_LOG("DBGUMD_READ_EVENT_MODULE_CREATE_EVENT_PARAMS: hElfAddressPtr=0x%llX IsModuleCreate=%d LoadAddress=0x%llX ElfModuleSize=%d\n", PRINT_DEBUGGER_INFO_LOG("DBGUMD_READ_EVENT_MODULE_CREATE_EVENT_PARAMS: hElfAddressPtr=0x%llX IsModuleCreate=%d LoadAddress=0x%llX ElfModuleSize=%d\n",
moduleCreateParams.hElfAddressPtr, moduleCreateParams.IsModuleCreate, moduleCreateParams.LoadAddress, moduleCreateParams.ElfModulesize); moduleCreateParams.hElfAddressPtr, moduleCreateParams.IsModuleCreate, moduleCreateParams.LoadAddress, moduleCreateParams.ElfModulesize);
{
std::unique_lock<std::mutex> lock(asyncThreadMutex);
if (moduleCreateParams.IsModuleCreate) { if (moduleCreateParams.IsModuleCreate) {
Module module = {0}; Module module = {0};
module.cpuAddress = moduleCreateParams.hElfAddressPtr; module.cpuAddress = moduleCreateParams.hElfAddressPtr;
module.gpuAddress = moduleCreateParams.LoadAddress; module.gpuAddress = moduleCreateParams.LoadAddress;
module.size = moduleCreateParams.ElfModulesize; module.size = moduleCreateParams.ElfModulesize;
allModules.push_back(module); allModules.push_back(module);
PRINT_DEBUGGER_INFO_LOG("DBGUMD_READ_EVENT_MODULE_CREATE_EVENT_PARAMS: Immediately acknowledge...\n");
return acknowledgeEventImp(seqNo, DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION);
} else { } else {
auto it = std::find_if(allModules.begin(), allModules.end(), [&](auto &m) { return m.gpuAddress == moduleCreateParams.LoadAddress; }); auto it = std::find_if(allModules.begin(), allModules.end(), [&](auto &m) { return m.gpuAddress == moduleCreateParams.LoadAddress; });
if (it != allModules.end()) { if (it != allModules.end()) {
allModules.erase(it); allModules.erase(it);
} }
} }
}
zet_debug_event_t debugEvent = {};
debugEvent.type = moduleCreateParams.IsModuleCreate ? ZET_DEBUG_EVENT_TYPE_MODULE_LOAD : ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD;
debugEvent.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
debugEvent.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
debugEvent.info.module.load = moduleCreateParams.LoadAddress;
debugEvent.info.module.moduleBegin = moduleCreateParams.hElfAddressPtr;
debugEvent.info.module.moduleEnd = moduleCreateParams.hElfAddressPtr + moduleCreateParams.ElfModulesize;
pushApiEvent(debugEvent, seqNo, DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION);
return ZE_RESULT_SUCCESS; return ZE_RESULT_SUCCESS;
} }
@ -299,11 +308,11 @@ ze_result_t DebugSessionWindows::handleCreateDebugDataEvent(DBGUMD_READ_EVENT_CR
} else if (createDebugDataParams.DebugDataType == static_cast<uint32_t>(NEO::DebugDataType::CMD_QUEUE_CREATED)) { } else if (createDebugDataParams.DebugDataType == static_cast<uint32_t>(NEO::DebugDataType::CMD_QUEUE_CREATED)) {
zet_debug_event_t debugEvent = {}; zet_debug_event_t debugEvent = {};
debugEvent.type = ZET_DEBUG_EVENT_TYPE_PROCESS_ENTRY; debugEvent.type = ZET_DEBUG_EVENT_TYPE_PROCESS_ENTRY;
pushApiEvent(debugEvent); pushApiEvent(debugEvent, 0, 0);
} else if (createDebugDataParams.DebugDataType == static_cast<uint32_t>(NEO::DebugDataType::CMD_QUEUE_DESTROYED)) { } else if (createDebugDataParams.DebugDataType == static_cast<uint32_t>(NEO::DebugDataType::CMD_QUEUE_DESTROYED)) {
zet_debug_event_t debugEvent = {}; zet_debug_event_t debugEvent = {};
debugEvent.type = ZET_DEBUG_EVENT_TYPE_PROCESS_EXIT; debugEvent.type = ZET_DEBUG_EVENT_TYPE_PROCESS_EXIT;
pushApiEvent(debugEvent); pushApiEvent(debugEvent, 0, 0);
} }
return ZE_RESULT_SUCCESS; return ZE_RESULT_SUCCESS;
@ -445,7 +454,17 @@ ze_result_t DebugSessionWindows::writeMemory(ze_device_thread_t thread, const ze
} }
ze_result_t DebugSessionWindows::acknowledgeEvent(const zet_debug_event_t *event) { ze_result_t DebugSessionWindows::acknowledgeEvent(const zet_debug_event_t *event) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; std::unique_lock<std::mutex> lock(asyncThreadMutex);
ze_result_t ret = ZE_RESULT_ERROR_UNKNOWN;
auto it = std::find_if(eventsToAck.begin(), eventsToAck.end(), [&](auto &e) { return !memcmp(&e, event, sizeof(zet_debug_event_t)); });
if (it != eventsToAck.end()) {
ret = acknowledgeEventImp(it->second.first, it->second.second);
eventsToAck.erase(it);
}
return ret;
} }
ze_result_t DebugSessionWindows::resumeImp(const std::vector<EuThread::ThreadId> &threads, uint32_t deviceIndex) { ze_result_t DebugSessionWindows::resumeImp(const std::vector<EuThread::ThreadId> &threads, uint32_t deviceIndex) {

View File

@ -37,9 +37,12 @@ struct DebugSessionWindows : DebugSessionImp {
protected: protected:
ze_result_t resumeImp(const std::vector<EuThread::ThreadId> &threads, uint32_t deviceIndex) override; ze_result_t resumeImp(const std::vector<EuThread::ThreadId> &threads, uint32_t deviceIndex) override;
void pushApiEvent(zet_debug_event_t &debugEvent) { void DebugSessionWindows::pushApiEvent(zet_debug_event_t &debugEvent, uint32_t seqNo, uint32_t type) {
std::unique_lock<std::mutex> lock(asyncThreadMutex); std::unique_lock<std::mutex> lock(asyncThreadMutex);
apiEvents.push(debugEvent); apiEvents.push(debugEvent);
if (debugEvent.flags & ZET_DEBUG_EVENT_FLAG_NEED_ACK) {
eventsToAck.push_back({debugEvent, {seqNo, type}});
}
apiEventCondition.notify_all(); apiEventCondition.notify_all();
} }
@ -98,6 +101,7 @@ struct DebugSessionWindows : DebugSessionImp {
std::unordered_set<uint64_t> allContexts; std::unordered_set<uint64_t> allContexts;
std::vector<ElfRange> allElfs; std::vector<ElfRange> allElfs;
std::vector<Module> allModules; std::vector<Module> allModules;
std::vector<std::pair<zet_debug_event_t, std::pair<uint32_t, uint32_t>>> eventsToAck;
}; };
} // namespace L0 } // namespace L0

View File

@ -32,11 +32,13 @@ struct MockDebugSessionWindows : DebugSessionWindows {
using DebugSessionWindows::debugAreaVA; using DebugSessionWindows::debugAreaVA;
using DebugSessionWindows::debugHandle; using DebugSessionWindows::debugHandle;
using DebugSessionWindows::ElfRange; using DebugSessionWindows::ElfRange;
using DebugSessionWindows::eventsToAck;
using DebugSessionWindows::getSbaBufferGpuVa; using DebugSessionWindows::getSbaBufferGpuVa;
using DebugSessionWindows::initialize; using DebugSessionWindows::initialize;
using DebugSessionWindows::invalidHandle; using DebugSessionWindows::invalidHandle;
using DebugSessionWindows::moduleDebugAreaCaptured; using DebugSessionWindows::moduleDebugAreaCaptured;
using DebugSessionWindows::processId; using DebugSessionWindows::processId;
using DebugSessionWindows::pushApiEvent;
using DebugSessionWindows::readAllocationDebugData; using DebugSessionWindows::readAllocationDebugData;
using DebugSessionWindows::readAndHandleEvent; using DebugSessionWindows::readAndHandleEvent;
using DebugSessionWindows::readGpuMemory; using DebugSessionWindows::readGpuMemory;
@ -608,7 +610,7 @@ TEST_F(DebugApiWindowsTest, givenContextCreateEventTypeWhenReadAndHandleEventCal
EXPECT_EQ(0u, session->allContexts.size()); EXPECT_EQ(0u, session->allContexts.size());
} }
TEST_F(DebugApiWindowsTest, givenModuleCreateNotificationeEventTypeWhenReadAndHandleEventCalledThenModuleIsRegisteredAndEventIsAcknowledged) { TEST_F(DebugApiWindowsTest, givenModuleCreateNotificationeEventTypeWhenReadAndHandleEventCalledThenModuleIsRegisteredAndEventIsQueuedForAcknowledge) {
zet_debug_config_t config = {}; zet_debug_config_t config = {};
config.pid = 0x1234; config.pid = 0x1234;
@ -630,12 +632,24 @@ TEST_F(DebugApiWindowsTest, givenModuleCreateNotificationeEventTypeWhenReadAndHa
EXPECT_EQ(0x80000000u, session->allModules[0].gpuAddress); EXPECT_EQ(0x80000000u, session->allModules[0].gpuAddress);
EXPECT_EQ(0x1000u, session->allModules[0].size); EXPECT_EQ(0x1000u, session->allModules[0].size);
EXPECT_EQ(1u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]); EXPECT_EQ(1u, session->apiEvents.size());
EXPECT_EQ(123u, mockWddm->acknowledgeEventPassedParam.EventSeqNo); auto event = session->apiEvents.front();
EXPECT_EQ(DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION, mockWddm->acknowledgeEventPassedParam.ReadEventType); EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_LOAD, event.type);
EXPECT_EQ(ZET_DEBUG_EVENT_FLAG_NEED_ACK, event.flags);
EXPECT_EQ(ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF, event.info.module.format);
EXPECT_EQ(0x80000000u, event.info.module.load);
EXPECT_EQ(0x12345678u, event.info.module.moduleBegin);
EXPECT_EQ(0x12345678u + 0x1000, event.info.module.moduleEnd);
EXPECT_EQ(1u, session->eventsToAck.size());
EXPECT_EQ(123, session->eventsToAck[0].second.first);
EXPECT_EQ(DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION, session->eventsToAck[0].second.second);
EXPECT_EQ(0u, memcmp(&event, &session->eventsToAck[0].first, sizeof(event)));
EXPECT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]);
} }
TEST_F(DebugApiWindowsTest, givenModuleDestroyNotificationeEventTypeWhenReadAndHandleEventCalledThenModuleIsUnregisteredAndEventIsNotAcknowledged) { TEST_F(DebugApiWindowsTest, givenModuleDestroyNotificationeEventTypeWhenReadAndHandleEventCalledThenModuleIsUnregisteredAndEventIsQueuedForAcknowledge) {
zet_debug_config_t config = {}; zet_debug_config_t config = {};
config.pid = 0x1234; config.pid = 0x1234;
@ -646,6 +660,7 @@ TEST_F(DebugApiWindowsTest, givenModuleDestroyNotificationeEventTypeWhenReadAndH
mockWddm->numEvents = 1; mockWddm->numEvents = 1;
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION; mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION;
mockWddm->eventQueue[0].seqNo = 123u;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.IsModuleCreate = false; mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.IsModuleCreate = false;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.hElfAddressPtr = 0x12345678; mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.hElfAddressPtr = 0x12345678;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.ElfModulesize = 0x1000; mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.ElfModulesize = 0x1000;
@ -654,6 +669,21 @@ TEST_F(DebugApiWindowsTest, givenModuleDestroyNotificationeEventTypeWhenReadAndH
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100)); EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
EXPECT_EQ(0u, session->allModules.size()); EXPECT_EQ(0u, session->allModules.size());
EXPECT_EQ(1u, session->apiEvents.size());
auto event = session->apiEvents.front();
EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD, event.type);
EXPECT_EQ(ZET_DEBUG_EVENT_FLAG_NEED_ACK, event.flags);
EXPECT_EQ(ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF, event.info.module.format);
EXPECT_EQ(0x80000000u, event.info.module.load);
EXPECT_EQ(0x12345678u, event.info.module.moduleBegin);
EXPECT_EQ(0x12345678u + 0x1000, event.info.module.moduleEnd);
EXPECT_EQ(1u, session->eventsToAck.size());
EXPECT_EQ(123, session->eventsToAck[0].second.first);
EXPECT_EQ(DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION, session->eventsToAck[0].second.second);
EXPECT_EQ(0u, memcmp(&event, &session->eventsToAck[0].first, sizeof(event)));
EXPECT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]); EXPECT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]);
} }
@ -668,6 +698,7 @@ TEST_F(DebugApiWindowsTest, givenModuleDestroyNotificationeEventTypeWhenReadAndH
mockWddm->numEvents = 1; mockWddm->numEvents = 1;
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION; mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION;
mockWddm->eventQueue[0].seqNo = 123u;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.IsModuleCreate = false; mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.IsModuleCreate = false;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.hElfAddressPtr = 0x12345678; mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.hElfAddressPtr = 0x12345678;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.ElfModulesize = 0x1000; mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.ElfModulesize = 0x1000;
@ -678,6 +709,103 @@ TEST_F(DebugApiWindowsTest, givenModuleDestroyNotificationeEventTypeWhenReadAndH
EXPECT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]); EXPECT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]);
} }
TEST_F(DebugApiWindowsTest, givenNoEventsToAckWhenAcknowledgeEventIsCalledThenErrorUnknownReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
session->wddm = mockWddm;
zet_debug_event_t event = {};
event.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
event.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
event.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
event.info.module.load = 0x80000000u;
event.info.module.moduleBegin = 0x12345678u;
event.info.module.moduleEnd = 0x12345678u + 0x1000;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, session->acknowledgeEvent(&event));
EXPECT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]);
}
TEST_F(DebugApiWindowsTest, givenEventsToAckWhenAcknowledgeEventIsCalledAndWrongEventIsPassedForAcknowledgeThenErrorUnknownReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
session->wddm = mockWddm;
zet_debug_event_t event = {};
event.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
event.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
event.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
event.info.module.load = 0x80000000u;
event.info.module.moduleBegin = 0x12345678u;
event.info.module.moduleEnd = 0x12345678u + 0x1000;
session->eventsToAck.push_back({event, {123u, DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION}});
event.type = ZET_DEBUG_EVENT_TYPE_INVALID;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, session->acknowledgeEvent(&event));
EXPECT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]);
}
TEST_F(DebugApiWindowsTest, givenNoNeedAckFlagSetWhenPushDebugApiCalledThenEventIsNotEnqueuedForAcknowledge) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
session->wddm = mockWddm;
zet_debug_event_t event = {};
event.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
event.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
session->pushApiEvent(event, 123, ZET_DEBUG_EVENT_TYPE_MODULE_LOAD);
EXPECT_EQ(1u, session->apiEvents.size());
EXPECT_EQ(1u, session->eventsToAck.size());
}
TEST_F(DebugApiWindowsTest, givenNeedAckFlagSetWhenPushDebugApiCalledThenEventIsEnqueuedForAcknowledge) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
session->wddm = mockWddm;
zet_debug_event_t event = {};
event.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
event.flags = 0;
session->pushApiEvent(event, 123, ZET_DEBUG_EVENT_TYPE_MODULE_LOAD);
EXPECT_EQ(1u, session->apiEvents.size());
EXPECT_EQ(0u, session->eventsToAck.size());
}
TEST_F(DebugApiWindowsTest, givenEventsToAckWhenAcknowledgeEventIsCalledThenSuccessReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
session->wddm = mockWddm;
zet_debug_event_t event = {};
event.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
event.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
event.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
event.info.module.load = 0x80000000u;
event.info.module.moduleBegin = 0x12345678u;
event.info.module.moduleEnd = 0x12345678u + 0x1000;
session->eventsToAck.push_back({event, {123u, DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION}});
EXPECT_EQ(ZE_RESULT_SUCCESS, session->acknowledgeEvent(&event));
EXPECT_EQ(0u, session->eventsToAck.size());
EXPECT_EQ(1u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ACKNOWLEDGE_EVENT]);
EXPECT_EQ(123u, mockWddm->acknowledgeEventPassedParam.EventSeqNo);
EXPECT_EQ(DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION, mockWddm->acknowledgeEventPassedParam.ReadEventType);
}
TEST_F(DebugApiWindowsTest, givenAcknowledgeEventEscapeFailedWhenAcknolegeEventImpIsCalledThenResultUnknownIsReturned) { TEST_F(DebugApiWindowsTest, givenAcknowledgeEventEscapeFailedWhenAcknolegeEventImpIsCalledThenResultUnknownIsReturned) {
zet_debug_config_t config = {}; zet_debug_config_t config = {};
config.pid = 0x1234; config.pid = 0x1234;