refactor: Move common attention handling EuDebug code out of prelim

Move common attention handling code from prelim in common linux
debug_session(.h/.cpp) files.
This common code could be shared to handle attention events for
prelim and xe driver based Eu Debug

Related-To: NEO-9673
Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
Jitendra Sharma
2024-02-19 06:31:12 +00:00
committed by Compute-Runtime-Automation
parent f404f3ceb1
commit f56babb2a9
11 changed files with 236 additions and 80 deletions

View File

@@ -649,4 +649,77 @@ ze_result_t DebugSessionLinux::getElfOffset(const zet_debug_memory_space_desc_t
return status;
}
void DebugSessionLinux::updateStoppedThreadsAndCheckTriggerEvents(AttentionEventFields &attention, uint32_t tileIndex) {
auto vmHandle = getVmHandleFromClientAndlrcHandle(attention.clientHandle, attention.lrcHandle);
if (vmHandle == invalidHandle) {
return;
}
auto hwInfo = connectedDevice->getHwInfo();
auto &l0GfxCoreHelper = connectedDevice->getL0GfxCoreHelper();
std::vector<EuThread::ThreadId> threadsWithAttention;
if (interruptSent) {
std::unique_ptr<uint8_t[]> bitmask;
size_t bitmaskSize;
auto attReadResult = threadControl({}, tileIndex, ThreadControlCmd::stopped, bitmask, bitmaskSize);
if (attReadResult == 0) {
threadsWithAttention = l0GfxCoreHelper.getThreadsFromAttentionBitmask(hwInfo, tileIndex, bitmask.get(), bitmaskSize);
}
}
if (threadsWithAttention.size() == 0) {
threadsWithAttention = l0GfxCoreHelper.getThreadsFromAttentionBitmask(hwInfo, tileIndex, attention.bitmask, attention.bitmaskSize);
printBitmask(attention.bitmask, attention.bitmaskSize);
}
PRINT_DEBUGGER_THREAD_LOG("ATTENTION for tile = %d thread count = %d\n", tileIndex, (int)threadsWithAttention.size());
if (threadsWithAttention.size() > 0) {
auto gpuVa = getContextStateSaveAreaGpuVa(vmHandle);
auto stateSaveAreaSize = getContextStateSaveAreaSize(vmHandle);
auto stateSaveReadResult = ZE_RESULT_ERROR_UNKNOWN;
std::unique_lock<std::mutex> lock;
if (tileSessionsEnabled) {
lock = getThreadStateMutexForTileSession(tileIndex);
} else {
lock = std::unique_lock<std::mutex>(threadStateMutex);
}
if (gpuVa != 0 && stateSaveAreaSize != 0) {
std::vector<EuThread::ThreadId> newThreads;
getNotStoppedThreads(threadsWithAttention, newThreads);
if (newThreads.size() > 0) {
allocateStateSaveAreaMemory(stateSaveAreaSize);
stateSaveReadResult = readGpuMemory(vmHandle, stateSaveAreaMemory.data(), stateSaveAreaSize, gpuVa);
}
} else {
PRINT_DEBUGGER_ERROR_LOG("Context state save area bind info invalid\n", "");
DEBUG_BREAK_IF(true);
}
if (stateSaveReadResult == ZE_RESULT_SUCCESS) {
for (auto &threadId : threadsWithAttention) {
PRINT_DEBUGGER_THREAD_LOG("ATTENTION event for thread: %s\n", EuThread::toString(threadId).c_str());
if (tileSessionsEnabled) {
addThreadToNewlyStoppedFromRaisedAttentionForTileSession(threadId, vmHandle, stateSaveAreaMemory.data(), tileIndex);
} else {
addThreadToNewlyStoppedFromRaisedAttention(threadId, vmHandle, stateSaveAreaMemory.data());
}
}
}
}
if (tileSessionsEnabled) {
checkTriggerEventsForAttentionForTileSession(tileIndex);
} else {
checkTriggerEventsForAttention();
}
}
} // namespace L0

View File

@@ -120,6 +120,23 @@ struct DebugSessionLinux : DebugSessionImp {
interruptAll
};
struct AttentionEventFields {
uint64_t clientHandle;
uint64_t contextHandle;
uint64_t lrcHandle;
uint32_t bitmaskSize;
uint8_t *bitmask;
};
void updateStoppedThreadsAndCheckTriggerEvents(AttentionEventFields &attention, uint32_t tileIndex);
virtual uint64_t getVmHandleFromClientAndlrcHandle(uint64_t clientHandle, uint64_t lrcHandle) = 0;
virtual std::unique_lock<std::mutex> getThreadStateMutexForTileSession(uint32_t tileIndex) = 0;
virtual void checkTriggerEventsForAttentionForTileSession(uint32_t tileIndex) = 0;
virtual void addThreadToNewlyStoppedFromRaisedAttentionForTileSession(EuThread::ThreadId threadId,
uint64_t memoryHandle,
const void *stateSaveArea,
uint32_t tileIndex) = 0;
virtual int euControlIoctl(ThreadControlCmd threadCmd,
const NEO::EngineClassInstance *classInstance,
std::unique_ptr<uint8_t[]> &bitmask,

View File

@@ -1092,83 +1092,32 @@ void DebugSessionLinuxi915::handleAttentionEvent(prelim_drm_i915_debug_event_eu_
return;
}
newAttentionRaised(
tileIndex);
auto vmHandle = getVmHandleFromClientAndlrcHandle(attention->client_handle, attention->lrc_handle);
if (vmHandle == invalidHandle) {
return;
}
newAttentionRaised();
if (!connectedDevice->getNEODevice()->getDeviceBitfield().test(tileIndex)) {
return;
}
auto hwInfo = connectedDevice->getHwInfo();
auto &l0GfxCoreHelper = connectedDevice->getL0GfxCoreHelper();
AttentionEventFields attentionEventFields;
attentionEventFields.bitmask = attention->bitmask;
attentionEventFields.bitmaskSize = attention->bitmask_size;
attentionEventFields.clientHandle = attention->client_handle;
attentionEventFields.contextHandle = attention->ctx_handle;
attentionEventFields.lrcHandle = attention->lrc_handle;
std::vector<EuThread::ThreadId> threadsWithAttention;
if (interruptSent) {
std::unique_ptr<uint8_t[]> bitmask;
size_t bitmaskSize;
auto attReadResult = threadControl({}, tileIndex, ThreadControlCmd::stopped, bitmask, bitmaskSize);
if (attReadResult == 0) {
threadsWithAttention = l0GfxCoreHelper.getThreadsFromAttentionBitmask(hwInfo, tileIndex, bitmask.get(), bitmaskSize);
}
}
return updateStoppedThreadsAndCheckTriggerEvents(attentionEventFields, tileIndex);
}
if (threadsWithAttention.size() == 0) {
threadsWithAttention = l0GfxCoreHelper.getThreadsFromAttentionBitmask(hwInfo, tileIndex, attention->bitmask, attention->bitmask_size);
printBitmask(attention->bitmask, attention->bitmask_size);
}
PRINT_DEBUGGER_THREAD_LOG("ATTENTION for tile = %d thread count = %d\n", tileIndex, (int)threadsWithAttention.size());
if (threadsWithAttention.size() > 0) {
auto gpuVa = getContextStateSaveAreaGpuVa(vmHandle);
auto stateSaveAreaSize = getContextStateSaveAreaSize(vmHandle);
auto stateSaveReadResult = ZE_RESULT_ERROR_UNKNOWN;
std::unique_lock<std::mutex> lock;
if (tileSessionsEnabled) {
lock = std::unique_lock<std::mutex>(static_cast<TileDebugSessionLinuxi915 *>(tileSessions[tileIndex].first)->threadStateMutex);
} else {
lock = std::unique_lock<std::mutex>(threadStateMutex);
}
if (gpuVa != 0 && stateSaveAreaSize != 0) {
std::vector<EuThread::ThreadId> newThreads;
getNotStoppedThreads(threadsWithAttention, newThreads);
if (newThreads.size() > 0) {
allocateStateSaveAreaMemory(stateSaveAreaSize);
stateSaveReadResult = readGpuMemory(vmHandle, stateSaveAreaMemory.data(), stateSaveAreaSize, gpuVa);
}
} else {
PRINT_DEBUGGER_ERROR_LOG("Context state save area bind info invalid\n", "");
DEBUG_BREAK_IF(true);
}
if (stateSaveReadResult == ZE_RESULT_SUCCESS) {
for (auto &threadId : threadsWithAttention) {
PRINT_DEBUGGER_THREAD_LOG("ATTENTION event for thread: %s\n", EuThread::toString(threadId).c_str());
if (tileSessionsEnabled) {
static_cast<TileDebugSessionLinuxi915 *>(tileSessions[tileIndex].first)->addThreadToNewlyStoppedFromRaisedAttention(threadId, vmHandle, stateSaveAreaMemory.data());
} else {
addThreadToNewlyStoppedFromRaisedAttention(threadId, vmHandle, stateSaveAreaMemory.data());
}
}
}
}
if (tileSessionsEnabled) {
static_cast<TileDebugSessionLinuxi915 *>(tileSessions[tileIndex].first)->checkTriggerEventsForAttention();
} else {
checkTriggerEventsForAttention();
}
std::unique_lock<std::mutex> DebugSessionLinuxi915::getThreadStateMutexForTileSession(uint32_t tileIndex) {
return std::unique_lock<std::mutex>(static_cast<TileDebugSessionLinuxi915 *>(tileSessions[tileIndex].first)->threadStateMutex);
}
void DebugSessionLinuxi915::checkTriggerEventsForAttentionForTileSession(uint32_t tileIndex) {
static_cast<TileDebugSessionLinuxi915 *>(tileSessions[tileIndex].first)->checkTriggerEventsForAttention();
}
void DebugSessionLinuxi915::addThreadToNewlyStoppedFromRaisedAttentionForTileSession(EuThread::ThreadId threadId,
uint64_t memoryHandle,
const void *stateSaveArea,
uint32_t tileIndex) {
static_cast<TileDebugSessionLinuxi915 *>(tileSessions[tileIndex].first)->addThreadToNewlyStoppedFromRaisedAttention(threadId, memoryHandle, stateSaveAreaMemory.data());
}
void DebugSessionLinuxi915::handlePageFaultEvent(prelim_drm_i915_debug_event_page_fault *pf) {

View File

@@ -172,7 +172,7 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
void handleEventsAsync();
uint64_t getVmHandleFromClientAndlrcHandle(uint64_t clientHandle, uint64_t lrcHandle);
uint64_t getVmHandleFromClientAndlrcHandle(uint64_t clientHandle, uint64_t lrcHandle) override;
bool handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *vmBind);
void handleContextParamEvent(prelim_drm_i915_debug_event_context_param *contextParam);
void handleAttentionEvent(prelim_drm_i915_debug_event_eu_attention *attention);
@@ -183,6 +183,13 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
MOCKABLE_VIRTUAL void processPendingVmBindEvents();
std::unique_lock<std::mutex> getThreadStateMutexForTileSession(uint32_t tileIndex) override;
void checkTriggerEventsForAttentionForTileSession(uint32_t tileIndex) override;
void addThreadToNewlyStoppedFromRaisedAttentionForTileSession(EuThread::ThreadId threadId,
uint64_t memoryHandle,
const void *stateSaveArea,
uint32_t tileIndex) override;
void attachTile() override {
UNRECOVERABLE_IF(true);
}

View File

@@ -303,6 +303,20 @@ int DebugSessionLinuxXe::flushVmCache(int vmfd) {
return retVal;
}
uint64_t DebugSessionLinuxXe::getVmHandleFromClientAndlrcHandle(uint64_t clientHandle, uint64_t lrcHandle) {
if (clientHandleToConnection.find(clientHandle) == clientHandleToConnection.end()) {
return invalidHandle;
}
auto &clientConnection = clientHandleToConnection[clientHandle];
if (clientConnection->lrcHandleToVmHandle.find(lrcHandle) == clientConnection->lrcHandleToVmHandle.end()) {
return invalidHandle;
}
return clientConnection->lrcHandleToVmHandle[lrcHandle];
}
int DebugSessionLinuxXe::euControlIoctl(ThreadControlCmd threadCmd,
const NEO::EngineClassInstance *classInstance,
std::unique_ptr<uint8_t[]> &bitmask,

View File

@@ -162,6 +162,19 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
std::atomic<bool> detached{false};
uint64_t getVmHandleFromClientAndlrcHandle(uint64_t clientHandle, uint64_t lrcHandle) override;
void checkTriggerEventsForAttentionForTileSession(uint32_t tileIndex) override {}
std::unique_lock<std::mutex> getThreadStateMutexForTileSession(uint32_t tileIndex) override {
std::mutex m;
std::unique_lock<std::mutex> lock(m);
lock.release();
return lock;
}
void addThreadToNewlyStoppedFromRaisedAttentionForTileSession(EuThread::ThreadId threadId,
uint64_t memoryHandle,
const void *stateSaveArea,
uint32_t tileIndex) override {}
ze_result_t readEventImp(drm_xe_eudebug_event *drmDebugEvent);
int ioctl(unsigned long request, void *arg);
std::atomic<bool> processEntryEventGenerated = false;