Skip to content

Commit 1ce4d0f

Browse files
JemaleCompute-Runtime-Automation
authored andcommitted
feature: Add sync host event handling on windows
Resolves: NEO-13744 Signed-off-by: Jemale Lockett <jemale.lockett@intel.com>
1 parent 584eb9b commit 1ce4d0f

File tree

10 files changed

+144
-62
lines changed

10 files changed

+144
-62
lines changed

level_zero/tools/source/debug/debug_session_imp.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1682,7 +1682,9 @@ ze_result_t DebugSessionImp::isValidNode(uint64_t vmHandle, uint64_t gpuVa, SIP:
16821682

16831683
ze_result_t DebugSessionImp::readFifo(uint64_t vmHandle, std::vector<EuThread::ThreadId> &threadsWithAttention) {
16841684
auto stateSaveAreaHeader = getStateSaveAreaHeader();
1685-
if (stateSaveAreaHeader->versionHeader.version.major != 3) {
1685+
if (!stateSaveAreaHeader) {
1686+
return ZE_RESULT_ERROR_UNKNOWN;
1687+
} else if (stateSaveAreaHeader->versionHeader.version.major != 3) {
16861688
return ZE_RESULT_SUCCESS;
16871689
}
16881690

level_zero/tools/source/debug/debug_session_imp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ struct DebugSessionImp : DebugSession {
180180
int64_t interruptTimeout = 2000;
181181
std::unordered_map<uint64_t, AttentionEventFields> attentionEventContext{};
182182
std::chrono::milliseconds lastFifoReadTime = std::chrono::milliseconds(0);
183-
virtual void updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) = 0;
183+
virtual ze_result_t updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) = 0;
184184

185185
std::chrono::high_resolution_clock::time_point interruptTime;
186186
std::atomic<bool> interruptSent = false;

level_zero/tools/source/debug/linux/debug_session.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,10 +684,10 @@ ze_result_t DebugSessionLinux::getElfOffset(const zet_debug_memory_space_desc_t
684684
return status;
685685
}
686686

687-
void DebugSessionLinux::updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) {
687+
ze_result_t DebugSessionLinux::updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) {
688688
auto vmHandle = getVmHandleFromClientAndlrcHandle(attention.clientHandle, attention.lrcHandle);
689689
if (vmHandle == invalidHandle) {
690-
return;
690+
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
691691
}
692692

693693
auto hwInfo = connectedDevice->getHwInfo();
@@ -745,6 +745,7 @@ void DebugSessionLinux::updateStoppedThreadsAndCheckTriggerEvents(const Attentio
745745
} else {
746746
checkTriggerEventsForAttention();
747747
}
748+
return ZE_RESULT_SUCCESS;
748749
}
749750

750751
ze_result_t DebugSessionLinux::getISAVMHandle(uint32_t deviceIndex, const zet_debug_memory_space_desc_t *desc, size_t size, uint64_t &vmHandle) {

level_zero/tools/source/debug/linux/debug_session.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ struct DebugSessionLinux : DebugSessionImp {
253253
return allInstancesRemoved;
254254
}
255255

256-
void updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) override;
256+
ze_result_t updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) override;
257257
virtual void updateContextAndLrcHandlesForThreadsWithAttention(EuThread::ThreadId threadId, const AttentionEventFields &attention) = 0;
258258
virtual uint64_t getVmHandleFromClientAndlrcHandle(uint64_t clientHandle, uint64_t lrcHandle) = 0;
259259
virtual std::unique_lock<std::mutex> getThreadStateMutexForTileSession(uint32_t tileIndex) = 0;

level_zero/tools/source/debug/linux/prelim/debug_session.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ void DebugSessionLinuxi915::handleAttentionEvent(prelim_drm_i915_debug_event_eu_
10031003
attentionEventFields.contextHandle = attention->ctx_handle;
10041004
attentionEventFields.lrcHandle = attention->lrc_handle;
10051005

1006-
return updateStoppedThreadsAndCheckTriggerEvents(attentionEventFields, tileIndex, threadsWithAttention);
1006+
updateStoppedThreadsAndCheckTriggerEvents(attentionEventFields, tileIndex, threadsWithAttention);
10071007
}
10081008

10091009
std::unique_lock<std::mutex> DebugSessionLinuxi915::getThreadStateMutexForTileSession(uint32_t tileIndex) {

level_zero/tools/source/debug/linux/xe/debug_session.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ void DebugSessionLinuxXe::handleAttentionEvent(NEO::EuDebugEventEuAttention *att
749749
attentionEventFields.contextHandle = attention->execQueueHandle;
750750
attentionEventFields.lrcHandle = attention->lrcHandle;
751751

752-
return updateStoppedThreadsAndCheckTriggerEvents(attentionEventFields, 0, threadsWithAttention);
752+
updateStoppedThreadsAndCheckTriggerEvents(attentionEventFields, 0, threadsWithAttention);
753753
}
754754

755755
int DebugSessionLinuxXe::threadControlInterruptAll() {

level_zero/tools/source/debug/windows/debug_session.cpp

Lines changed: 89 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ void *DebugSessionWindows::asyncThreadFunction(void *arg) {
126126

127127
while (self->asyncThread.threadActive) {
128128
self->readAndHandleEvent(100);
129+
self->pollFifo();
129130
self->generateEventsAndResumeStoppedThreads();
130131
self->sendInterrupts();
131132
}
@@ -195,6 +196,8 @@ ze_result_t DebugSessionWindows::readAndHandleEvent(uint64_t timeoutMs) {
195196
return handleDeviceCreateDestroyEvent(eventParamsBuffer.eventParamsBuffer.DeviceCreateDestroyEventParams);
196197
case DBGUMD_READ_EVENT_CREATE_DEBUG_DATA:
197198
return handleCreateDebugDataEvent(eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams);
199+
case DBGUMD_READ_EVENT_SYNC_HOST:
200+
return handleSyncHostEvent(eventParamsBuffer.eventParamsBuffer.SyncHostDataParams);
198201
default:
199202
break;
200203
}
@@ -242,57 +245,15 @@ ze_result_t DebugSessionWindows::handleEuAttentionBitsEvent(DBGUMD_READ_EVENT_EU
242245
euAttentionBitsParams.hContextHandle, euAttentionBitsParams.LRCA,
243246
euAttentionBitsParams.BitMaskSizeInBytes, &euAttentionBitsParams.BitmaskArrayPtr);
244247

245-
auto hwInfo = connectedDevice->getHwInfo();
246-
auto &l0GfxCoreHelper = connectedDevice->getNEODevice()->getRootDeviceEnvironment().getHelper<L0GfxCoreHelper>();
247-
248-
auto threadsWithAttention = l0GfxCoreHelper.getThreadsFromAttentionBitmask(hwInfo, 0u,
249-
reinterpret_cast<uint8_t *>(&euAttentionBitsParams.BitmaskArrayPtr),
250-
euAttentionBitsParams.BitMaskSizeInBytes);
251-
252-
printBitmask(reinterpret_cast<uint8_t *>(&euAttentionBitsParams.BitmaskArrayPtr), euAttentionBitsParams.BitMaskSizeInBytes);
253-
254-
PRINT_DEBUGGER_THREAD_LOG("ATTENTION received for thread count = %d\n", (int)threadsWithAttention.size());
255-
256-
if (threadsWithAttention.size() > 0) {
257-
258-
uint64_t memoryHandle = DebugSessionWindows::invalidHandle;
259-
{
260-
if (allContexts.empty()) {
261-
return ZE_RESULT_ERROR_UNINITIALIZED;
262-
}
263-
memoryHandle = *allContexts.begin();
264-
}
265-
266-
auto gpuVa = getContextStateSaveAreaGpuVa(memoryHandle);
267-
auto stateSaveAreaSize = getContextStateSaveAreaSize(memoryHandle);
268-
auto stateSaveReadResult = ZE_RESULT_ERROR_UNKNOWN;
269-
270-
std::unique_lock<std::mutex> lock(threadStateMutex);
271-
272-
if (gpuVa != 0 && stateSaveAreaSize != 0) {
273-
std::vector<EuThread::ThreadId> newThreads;
274-
getNotStoppedThreads(threadsWithAttention, newThreads);
275-
if (newThreads.size() > 0) {
276-
allocateStateSaveAreaMemory(stateSaveAreaSize);
277-
stateSaveReadResult = readGpuMemory(memoryHandle, stateSaveAreaMemory.data(), stateSaveAreaSize, gpuVa);
278-
}
279-
} else {
280-
PRINT_DEBUGGER_ERROR_LOG("Context state save area bind info invalid\n", "");
281-
DEBUG_BREAK_IF(true);
282-
}
283-
284-
if (stateSaveReadResult == ZE_RESULT_SUCCESS) {
248+
std::vector<EuThread::ThreadId> threadsWithAttention;
249+
newAttentionRaised();
250+
AttentionEventFields attentionEventFields;
251+
attentionEventFields.bitmask = reinterpret_cast<uint8_t *>(&euAttentionBitsParams.BitmaskArrayPtr);
252+
attentionEventFields.bitmaskSize = euAttentionBitsParams.BitMaskSizeInBytes;
253+
attentionEventFields.contextHandle = euAttentionBitsParams.hContextHandle;
254+
attentionEventFields.lrcHandle = euAttentionBitsParams.LRCA;
285255

286-
for (auto &threadId : threadsWithAttention) {
287-
PRINT_DEBUGGER_THREAD_LOG("ATTENTION event for thread: %s\n", EuThread::toString(threadId).c_str());
288-
addThreadToNewlyStoppedFromRaisedAttention(threadId, memoryHandle, stateSaveAreaMemory.data());
289-
}
290-
}
291-
}
292-
293-
checkTriggerEventsForAttention();
294-
295-
return ZE_RESULT_SUCCESS;
256+
return updateStoppedThreadsAndCheckTriggerEvents(attentionEventFields, 0, threadsWithAttention);
296257
}
297258

298259
ze_result_t DebugSessionWindows::handleAllocationDataEvent(uint32_t seqNo, DBGUMD_READ_EVENT_READ_ALLOCATION_DATA_PARAMS &allocationDataParams) {
@@ -395,6 +356,84 @@ ze_result_t DebugSessionWindows::handleCreateDebugDataEvent(DBGUMD_READ_EVENT_CR
395356
return ZE_RESULT_SUCCESS;
396357
}
397358

359+
ze_result_t DebugSessionWindows::handleSyncHostEvent(DBGUMD_READ_EVENT_SYNC_HOST_DATA_PARAMS &readEventSyncHostDataParams) {
360+
PRINT_DEBUGGER_INFO_LOG("DBGUMD_READ_EVENT_SYNC_HOST: hContextHandle=0x%llX\n",
361+
readEventSyncHostDataParams.hContextHandle);
362+
363+
uint64_t memoryHandle = DebugSessionWindows::invalidHandle;
364+
{
365+
std::unique_lock<std::mutex> lock(asyncThreadMutex);
366+
if (allContexts.empty()) {
367+
return ZE_RESULT_ERROR_UNINITIALIZED;
368+
}
369+
memoryHandle = *allContexts.begin();
370+
}
371+
372+
AttentionEventFields attentionEventFields = {};
373+
attentionEventFields.clientHandle = debugHandle;
374+
attentionEventFields.contextHandle = readEventSyncHostDataParams.hContextHandle;
375+
376+
attentionEventContext[memoryHandle] = attentionEventFields;
377+
378+
handleStoppedThreads();
379+
return ZE_RESULT_SUCCESS;
380+
}
381+
382+
ze_result_t DebugSessionWindows::updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) {
383+
auto hwInfo = connectedDevice->getHwInfo();
384+
auto &l0GfxCoreHelper = connectedDevice->getL0GfxCoreHelper();
385+
386+
if (threadsWithAttention.size() == 0) {
387+
threadsWithAttention = l0GfxCoreHelper.getThreadsFromAttentionBitmask(hwInfo, 0u,
388+
attention.bitmask, attention.bitmaskSize);
389+
390+
printBitmask(attention.bitmask, attention.bitmaskSize);
391+
}
392+
393+
PRINT_DEBUGGER_THREAD_LOG("ATTENTION for tile = %d thread count = %d\n", tileIndex, (int)threadsWithAttention.size());
394+
395+
if (threadsWithAttention.size() > 0) {
396+
397+
uint64_t memoryHandle = DebugSessionWindows::invalidHandle;
398+
{
399+
if (allContexts.empty()) {
400+
PRINT_DEBUGGER_ERROR_LOG("No contexts found\n", "");
401+
return ZE_RESULT_ERROR_UNINITIALIZED;
402+
}
403+
memoryHandle = *allContexts.begin();
404+
}
405+
406+
auto gpuVa = getContextStateSaveAreaGpuVa(memoryHandle);
407+
auto stateSaveAreaSize = getContextStateSaveAreaSize(memoryHandle);
408+
auto stateSaveReadResult = ZE_RESULT_ERROR_UNKNOWN;
409+
410+
std::unique_lock<std::mutex> lock(threadStateMutex);
411+
412+
if (gpuVa != 0 && stateSaveAreaSize != 0) {
413+
std::vector<EuThread::ThreadId> newThreads;
414+
getNotStoppedThreads(threadsWithAttention, newThreads);
415+
if (newThreads.size() > 0) {
416+
allocateStateSaveAreaMemory(stateSaveAreaSize);
417+
stateSaveReadResult = readGpuMemory(memoryHandle, stateSaveAreaMemory.data(), stateSaveAreaSize, gpuVa);
418+
}
419+
} else {
420+
PRINT_DEBUGGER_ERROR_LOG("Context state save area bind info invalid\n", "");
421+
DEBUG_BREAK_IF(true);
422+
}
423+
424+
if (stateSaveReadResult == ZE_RESULT_SUCCESS) {
425+
426+
for (auto &threadId : threadsWithAttention) {
427+
PRINT_DEBUGGER_THREAD_LOG("ATTENTION event for thread: %s\n", EuThread::toString(threadId).c_str());
428+
addThreadToNewlyStoppedFromRaisedAttention(threadId, memoryHandle, stateSaveAreaMemory.data());
429+
}
430+
}
431+
}
432+
433+
checkTriggerEventsForAttention();
434+
return ZE_RESULT_SUCCESS;
435+
}
436+
398437
ze_result_t DebugSessionWindows::acknowledgeEventImp(uint32_t seqNo, uint32_t eventType) {
399438
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_ACKNOWLEDGE_EVENT: seqNo: %d eventType: %d\n", seqNo, eventType);
400439
KM_ESCAPE_INFO escapeInfo = {};

level_zero/tools/source/debug/windows/debug_session.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2022-2024 Intel Corporation
2+
* Copyright (C) 2022-2025 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -78,6 +78,7 @@ struct DebugSessionWindows : DebugSessionImp {
7878
ze_result_t handleContextCreateDestroyEvent(DBGUMD_READ_EVENT_CONTEXT_CREATE_DESTROY_EVENT_PARAMS &contextCreateDestroyParams);
7979
ze_result_t handleDeviceCreateDestroyEvent(DBGUMD_READ_EVENT_DEVICE_CREATE_DESTROY_EVENT_PARAMS &deviceCreateDestroyParams);
8080
ze_result_t handleCreateDebugDataEvent(DBGUMD_READ_EVENT_CREATE_DEBUG_DATA_PARAMS &createDebugDataParams);
81+
ze_result_t handleSyncHostEvent(DBGUMD_READ_EVENT_SYNC_HOST_DATA_PARAMS &syncHostDataParams);
8182
ze_result_t readAllocationDebugData(uint32_t seqNo, uint64_t umdDataBufferPtr, void *outBuf, size_t outBufSize);
8283

8384
void enqueueApiEvent(zet_debug_event_t &debugEvent) override;
@@ -95,7 +96,7 @@ struct DebugSessionWindows : DebugSessionImp {
9596
UNRECOVERABLE_IF(true);
9697
}
9798

98-
void updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) override {}
99+
ze_result_t updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) override;
99100

100101
static void *asyncThreadFunction(void *arg);
101102

level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2021-2024 Intel Corporation
2+
* Copyright (C) 2021-2025 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -351,7 +351,7 @@ struct MockDebugSession : public L0::DebugSessionImp {
351351
return DebugSessionImp::readThreadScratchRegisters(thread, start, count, pRegisterValues);
352352
}
353353

354-
void updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) override {}
354+
ze_result_t updateStoppedThreadsAndCheckTriggerEvents(const AttentionEventFields &attention, uint32_t tileIndex, std::vector<EuThread::ThreadId> &threadsWithAttention) override { return ZE_RESULT_SUCCESS; }
355355
void resumeAccidentallyStoppedThreads(const std::vector<EuThread::ThreadId> &threadIds) override {
356356
resumeAccidentallyStoppedCalled++;
357357
return DebugSessionImp::resumeAccidentallyStoppedThreads(threadIds);

level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2021-2024 Intel Corporation
2+
* Copyright (C) 2021-2025 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -33,6 +33,7 @@ struct MockDebugSessionWindows : DebugSessionWindows {
3333
using DebugSessionWindows::allModules;
3434
using DebugSessionWindows::allThreads;
3535
using DebugSessionWindows::asyncThread;
36+
using DebugSessionWindows::attentionEventContext;
3637
using DebugSessionWindows::calculateThreadSlotOffset;
3738
using DebugSessionWindows::closeAsyncThread;
3839
using DebugSessionWindows::debugArea;
@@ -2021,5 +2022,43 @@ TEST_F(DebugApiWindowsTest, GivenResumeImpCalledThenBitmaskIsCorrect) {
20212022
EXPECT_EQ(0u, bitmask[4]);
20222023
}
20232024

2025+
TEST_F(DebugApiWindowsTest, givenSyncHostEventReceivedThenEventIsHandledAndAttentionEventContextUpdated) {
2026+
zet_debug_config_t config = {};
2027+
config.pid = 0x1234;
2028+
2029+
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
2030+
session->wddm = mockWddm;
2031+
2032+
session->allContexts = {};
2033+
session->allContexts.insert(0x01);
2034+
auto &l0GfxCoreHelper = neoDevice->getRootDeviceEnvironment().getHelper<L0GfxCoreHelper>();
2035+
if (l0GfxCoreHelper.threadResumeRequiresUnlock()) {
2036+
mockWddm->numEvents = 1;
2037+
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_SYNC_HOST;
2038+
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.SyncHostDataParams.hContextHandle = 0x12345;
2039+
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
2040+
EXPECT_EQ(1u, session->attentionEventContext.size());
2041+
}
2042+
}
2043+
2044+
TEST_F(DebugApiWindowsTest, givenErrorCasesWhenHandlingSyncHostThenErrorIsReturned) {
2045+
zet_debug_config_t config = {};
2046+
config.pid = 0x1234;
2047+
2048+
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
2049+
session->wddm = mockWddm;
2050+
2051+
session->allContexts = {};
2052+
2053+
auto &l0GfxCoreHelper = neoDevice->getRootDeviceEnvironment().getHelper<L0GfxCoreHelper>();
2054+
if (l0GfxCoreHelper.threadResumeRequiresUnlock()) {
2055+
mockWddm->numEvents = 1;
2056+
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_SYNC_HOST;
2057+
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.SyncHostDataParams.hContextHandle = 0x12345;
2058+
2059+
EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, session->readAndHandleEvent(100));
2060+
}
2061+
}
2062+
20242063
} // namespace ult
20252064
} // namespace L0

0 commit comments

Comments
 (0)