feature(debugger): Discard stale ATT events

Related-to: NEO-10922

Signed-off-by: Brandon Yates <brandon.yates@intel.com>
This commit is contained in:
Brandon Yates
2024-05-15 01:01:46 +00:00
committed by Compute-Runtime-Automation
parent e9b81037a9
commit 80a5d6255e
4 changed files with 43 additions and 2 deletions

View File

@@ -126,6 +126,9 @@ void DebugSessionLinuxXe::readInternalEventsAsync() {
if (result == ZE_RESULT_SUCCESS) { if (result == ZE_RESULT_SUCCESS) {
std::lock_guard<std::mutex> lock(internalEventThreadMutex); std::lock_guard<std::mutex> lock(internalEventThreadMutex);
if (event->type == DRM_XE_EUDEBUG_EVENT_EU_ATTENTION) {
newestAttSeqNo.store(event->seqno);
}
auto memory = std::make_unique<uint64_t[]>(maxEventSize / sizeof(uint64_t)); auto memory = std::make_unique<uint64_t[]>(maxEventSize / sizeof(uint64_t));
memcpy(memory.get(), event, maxEventSize); memcpy(memory.get(), event, maxEventSize);
@@ -253,7 +256,11 @@ void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *event) {
PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type: DRM_XE_EUDEBUG_EVENT_EU_ATTENTION client_handle = %llu flags = %llu bitmask_size = %lu exec_queue_handle = %llu lrc_handle = %llu\n", PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type: DRM_XE_EUDEBUG_EVENT_EU_ATTENTION client_handle = %llu flags = %llu bitmask_size = %lu exec_queue_handle = %llu lrc_handle = %llu\n",
(uint64_t)attention->client_handle, (uint64_t)attention->flags, (uint64_t)attention->client_handle, (uint64_t)attention->flags,
(uint32_t)attention->bitmask_size, uint64_t(attention->exec_queue_handle), uint64_t(attention->lrc_handle)); (uint32_t)attention->bitmask_size, uint64_t(attention->exec_queue_handle), uint64_t(attention->lrc_handle));
handleAttentionEvent(attention); if (attention->base.seqno < newestAttSeqNo.load()) {
PRINT_DEBUGGER_INFO_LOG("Dropping stale ATT event seqno=%llu\n", (uint64_t)attention->base.seqno);
} else {
handleAttentionEvent(attention);
}
} break; } break;
case DRM_XE_EUDEBUG_EVENT_VM_BIND: { case DRM_XE_EUDEBUG_EVENT_VM_BIND: {

View File

@@ -67,7 +67,7 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
int threadControlInterruptAll(drm_xe_eudebug_eu_control &euControl); int threadControlInterruptAll(drm_xe_eudebug_eu_control &euControl);
int threadControlResume(const std::vector<EuThread::ThreadId> &threads, drm_xe_eudebug_eu_control &euControl); int threadControlResume(const std::vector<EuThread::ThreadId> &threads, drm_xe_eudebug_eu_control &euControl);
int threadControlStopped(drm_xe_eudebug_eu_control &euControl, std::unique_ptr<uint8_t[]> &bitmaskOut, size_t &bitmaskSizeOut); int threadControlStopped(drm_xe_eudebug_eu_control &euControl, std::unique_ptr<uint8_t[]> &bitmaskOut, size_t &bitmaskSizeOut);
void handleAttentionEvent(drm_xe_eudebug_event_eu_attention *attention); MOCKABLE_VIRTUAL void handleAttentionEvent(drm_xe_eudebug_event_eu_attention *attention);
void handleMetadataEvent(drm_xe_eudebug_event_metadata *pMetaData); void handleMetadataEvent(drm_xe_eudebug_event_metadata *pMetaData);
bool handleMetadataOpEvent(drm_xe_eudebug_event_vm_bind_op_metadata *vmBindOpMetadata); bool handleMetadataOpEvent(drm_xe_eudebug_event_vm_bind_op_metadata *vmBindOpMetadata);
void updateContextAndLrcHandlesForThreadsWithAttention(EuThread::ThreadId threadId, AttentionEventFields &attention) override; void updateContextAndLrcHandlesForThreadsWithAttention(EuThread::ThreadId threadId, AttentionEventFields &attention) override;
@@ -158,6 +158,7 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
ze_result_t readEventImp(drm_xe_eudebug_event *drmDebugEvent); ze_result_t readEventImp(drm_xe_eudebug_event *drmDebugEvent);
int ioctl(unsigned long request, void *arg); int ioctl(unsigned long request, void *arg);
std::atomic<bool> processEntryEventGenerated = false; std::atomic<bool> processEntryEventGenerated = false;
std::atomic<uint64_t> newestAttSeqNo = 0;
}; };
} // namespace L0 } // namespace L0

View File

@@ -171,6 +171,7 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe {
using L0::DebugSessionLinuxXe::internalEventThread; using L0::DebugSessionLinuxXe::internalEventThread;
using L0::DebugSessionLinuxXe::invalidClientHandle; using L0::DebugSessionLinuxXe::invalidClientHandle;
using L0::DebugSessionLinuxXe::ioctlHandler; using L0::DebugSessionLinuxXe::ioctlHandler;
using L0::DebugSessionLinuxXe::newestAttSeqNo;
using L0::DebugSessionLinuxXe::newlyStoppedThreads; using L0::DebugSessionLinuxXe::newlyStoppedThreads;
using L0::DebugSessionLinuxXe::pendingInterrupts; using L0::DebugSessionLinuxXe::pendingInterrupts;
using L0::DebugSessionLinuxXe::readEventImp; using L0::DebugSessionLinuxXe::readEventImp;
@@ -203,6 +204,11 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe {
return DebugSessionLinuxXe::initialize(); return DebugSessionLinuxXe::initialize();
} }
void handleAttentionEvent(drm_xe_eudebug_event_eu_attention *attention) override {
handleAttentionEventCalled++;
return DebugSessionLinuxXe::handleAttentionEvent(attention);
}
int threadControl(const std::vector<EuThread::ThreadId> &threads, uint32_t tile, ThreadControlCmd threadCmd, std::unique_ptr<uint8_t[]> &bitmask, size_t &bitmaskSize) override { int threadControl(const std::vector<EuThread::ThreadId> &threads, uint32_t tile, ThreadControlCmd threadCmd, std::unique_ptr<uint8_t[]> &bitmask, size_t &bitmaskSize) override {
numThreadsPassedToThreadControl = threads.size(); numThreadsPassedToThreadControl = threads.size();
return L0::DebugSessionLinuxXe::threadControl(threads, tile, threadCmd, bitmask, bitmaskSize); return L0::DebugSessionLinuxXe::threadControl(threads, tile, threadCmd, bitmask, bitmaskSize);
@@ -266,6 +272,7 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe {
std::unordered_map<uint64_t, uint8_t> stoppedThreads; std::unordered_map<uint64_t, uint8_t> stoppedThreads;
uint32_t countToAddThreadToNewlyStoppedFromRaisedAttentionForTileSession = 0; uint32_t countToAddThreadToNewlyStoppedFromRaisedAttentionForTileSession = 0;
int64_t returnTimeDiff = -1; int64_t returnTimeDiff = -1;
uint32_t handleAttentionEventCalled = 0;
}; };
struct MockAsyncThreadDebugSessionLinuxXe : public MockDebugSessionLinuxXe { struct MockAsyncThreadDebugSessionLinuxXe : public MockDebugSessionLinuxXe {

View File

@@ -2099,6 +2099,32 @@ TEST_F(DebugApiLinuxTestXe, GivenSentInterruptWhenHandlingAttEventThenAttBitsAre
EXPECT_EQ(0u, sessionMock->readSystemRoutineIdentCallCount); EXPECT_EQ(0u, sessionMock->readSystemRoutineIdentCallCount);
} }
TEST_F(DebugApiLinuxTestXe, GivenStaleAttentionEventThenEventNotHandled) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto sessionMock = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
ASSERT_NE(nullptr, sessionMock);
sessionMock->clientHandle = MockDebugSessionLinuxXe::mockClientHandle;
sessionMock->newestAttSeqNo.store(10);
drm_xe_eudebug_event_eu_attention attention = {};
attention.base.type = DRM_XE_EUDEBUG_EVENT_EU_ATTENTION;
attention.base.flags = DRM_XE_EUDEBUG_EVENT_STATE_CHANGE;
attention.base.len = sizeof(drm_xe_eudebug_event_eu_attention);
attention.base.seqno = 2;
attention.client_handle = MockDebugSessionLinuxXe::mockClientHandle;
attention.lrc_handle = 0;
attention.flags = 0;
attention.exec_queue_handle = 0;
attention.bitmask_size = 0;
uint8_t data[sizeof(drm_xe_eudebug_event_eu_attention) + 128];
memcpy(data, &attention, sizeof(drm_xe_eudebug_event_eu_attention));
sessionMock->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(data));
EXPECT_EQ(sessionMock->handleAttentionEventCalled, 0u);
}
TEST_F(DebugApiLinuxTestXe, GivenInterruptedThreadsWhenAttentionEventReceivedThenEventsTriggeredAfterExpectedAttentionEventCount) { TEST_F(DebugApiLinuxTestXe, GivenInterruptedThreadsWhenAttentionEventReceivedThenEventsTriggeredAfterExpectedAttentionEventCount) {
zet_debug_config_t config = {}; zet_debug_config_t config = {};
config.pid = 0x1234; config.pid = 0x1234;