mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 06:49:52 +08:00
L0Debug - add support for blocking VM BIND on fence
Related-To: NEO-7454 Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
e0370d25b9
commit
5c23d05312
@@ -9,7 +9,7 @@
|
||||
#include <level_zero/ze_api.h>
|
||||
namespace L0 {
|
||||
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd) {
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd, void *params) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,19 @@
|
||||
|
||||
namespace L0 {
|
||||
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd);
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd, void *params);
|
||||
|
||||
DebugSessionLinux::DebugSessionLinux(const zet_debug_config_t &config, Device *device, int debugFd) : DebugSessionImp(config, device), fd(debugFd) {
|
||||
DebugSessionLinux::DebugSessionLinux(const zet_debug_config_t &config, Device *device, int debugFd, void *params) : DebugSessionImp(config, device), fd(debugFd) {
|
||||
ioctlHandler.reset(new IoctlHandler);
|
||||
|
||||
if (params) {
|
||||
this->i915DebuggerVersion = reinterpret_cast<prelim_drm_i915_debugger_open_param *>(params)->version;
|
||||
}
|
||||
|
||||
if (this->i915DebuggerVersion >= 3) {
|
||||
this->blockOnFenceMode = true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < arrayCount(euControlInterruptSeqno); i++) {
|
||||
euControlInterruptSeqno[i] = invalidHandle;
|
||||
}
|
||||
@@ -56,13 +64,14 @@ DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *dev
|
||||
struct prelim_drm_i915_debugger_open_param open = {};
|
||||
open.pid = config.pid;
|
||||
open.events = 0;
|
||||
open.version = 0;
|
||||
|
||||
auto debugFd = DrmHelper::ioctl(device, NEO::DrmIoctl::DebuggerOpen, &open);
|
||||
if (debugFd >= 0) {
|
||||
PRINT_DEBUGGER_INFO_LOG("PRELIM_DRM_IOCTL_I915_DEBUGGER_OPEN: open.pid: %d, open.events: %d, debugFd: %d\n",
|
||||
open.pid, open.events, debugFd);
|
||||
|
||||
auto debugSession = createDebugSessionHelper(config, device, debugFd);
|
||||
auto debugSession = createDebugSessionHelper(config, device, debugFd, &open);
|
||||
debugSession->setAttachMode(isRootAttach);
|
||||
result = debugSession->initialize();
|
||||
|
||||
@@ -428,11 +437,11 @@ void DebugSessionLinux::readInternalEventsAsync() {
|
||||
if (tileSessionsEnabled) {
|
||||
auto numTiles = connectedDevice->getNEODevice()->getNumSubDevices();
|
||||
for (uint32_t tileIndex = 0; tileIndex < numTiles; tileIndex++) {
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, nullptr);
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent);
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->detached = true;
|
||||
}
|
||||
} else {
|
||||
pushApiEvent(debugEvent, nullptr);
|
||||
pushApiEvent(debugEvent);
|
||||
}
|
||||
detached = true;
|
||||
} else if (numberOfFds > 0) {
|
||||
@@ -538,10 +547,11 @@ void DebugSessionLinux::handleEvent(prelim_drm_i915_debug_event *event) {
|
||||
debugEvent.type = ZET_DEBUG_EVENT_TYPE_PROCESS_EXIT;
|
||||
|
||||
if (tileSessionsEnabled) {
|
||||
reinterpret_cast<TileDebugSessionLinux *>(tileSessions[deviceIndex].first)->processExit();
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[deviceIndex].first)->pushApiEvent(debugEvent, nullptr);
|
||||
auto tileSession = reinterpret_cast<TileDebugSessionLinux *>(tileSessions[deviceIndex].first);
|
||||
tileSession->processExit();
|
||||
tileSession->pushApiEvent(debugEvent);
|
||||
} else if (uuidL0CommandQueueHandleToDevice.size() == 0) {
|
||||
pushApiEvent(debugEvent, nullptr);
|
||||
pushApiEvent(debugEvent);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -582,10 +592,11 @@ void DebugSessionLinux::handleEvent(prelim_drm_i915_debug_event *event) {
|
||||
|
||||
if (tileSessionsEnabled) {
|
||||
UNRECOVERABLE_IF(uuidL0CommandQueueHandleToDevice.find(uuid->handle) != uuidL0CommandQueueHandleToDevice.end());
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[deviceIndex].first)->processEntry();
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[deviceIndex].first)->pushApiEvent(debugEvent, nullptr);
|
||||
auto tileSession = static_cast<TileDebugSessionLinux *>(tileSessions[deviceIndex].first);
|
||||
tileSession->processEntry();
|
||||
tileSession->pushApiEvent(debugEvent);
|
||||
} else if (uuidL0CommandQueueHandleToDevice.size() == 0) {
|
||||
pushApiEvent(debugEvent, nullptr);
|
||||
pushApiEvent(debugEvent);
|
||||
}
|
||||
uuidL0CommandQueueHandleToDevice[uuid->handle] = deviceIndex;
|
||||
}
|
||||
@@ -620,9 +631,11 @@ void DebugSessionLinux::handleEvent(prelim_drm_i915_debug_event *event) {
|
||||
|
||||
auto &newModule = connection->uuidToModule[handle];
|
||||
newModule.segmentCount = 0;
|
||||
newModule.moduleUuidHandle = handle;
|
||||
for (uint32_t i = 0; i < NEO::EngineLimits::maxHandleCount; i++) {
|
||||
newModule.segmentVmBindCounter[i] = 0;
|
||||
newModule.loadAddresses[i].clear();
|
||||
newModule.moduleLoadEventAcked[i] = false;
|
||||
}
|
||||
}
|
||||
extractUuidData(uuid->client_handle, uuidData);
|
||||
@@ -957,7 +970,7 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
if (tileSessionsEnabled) {
|
||||
auto tileAttached = static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->insertModule(debugEvent.info.module);
|
||||
if (tileAttached) {
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, nullptr);
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -965,7 +978,7 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
allInstancesEventsReceived = checkAllOtherTileIsaAllocationsPresent(tileIndex, vmBind->va_start);
|
||||
}
|
||||
if (allInstancesEventsReceived) {
|
||||
pushApiEvent(debugEvent, nullptr);
|
||||
pushApiEvent(debugEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -973,10 +986,16 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
|
||||
if (createEvent) {
|
||||
std::lock_guard<std::mutex> lock(asyncThreadMutex);
|
||||
if (allInstancesEventsReceived && !connection->isaMap[tileIndex][vmBind->va_start]->moduleLoadEventAck && perKernelModules) {
|
||||
PRINT_DEBUGGER_INFO_LOG("Add event to ack, seqno = %llu", (uint64_t)vmBind->base.seqno);
|
||||
connection->isaMap[tileIndex][vmBind->va_start]->ackEvents.push_back(vmBind->base);
|
||||
shouldAckEvent = false;
|
||||
|
||||
if (!connection->isaMap[tileIndex][vmBind->va_start]->moduleLoadEventAck && perKernelModules) {
|
||||
bool doNotAutoAckEvent = (!blockOnFenceMode && allInstancesEventsReceived); // in block on CPU mode - do not auto-ack last event for isa instance
|
||||
doNotAutoAckEvent |= blockOnFenceMode; // in block on fence mode - do not auto-ack any events
|
||||
|
||||
if (doNotAutoAckEvent) {
|
||||
PRINT_DEBUGGER_INFO_LOG("Add event to ack, seqno = %llu", (uint64_t)vmBind->base.seqno);
|
||||
connection->isaMap[tileIndex][vmBind->va_start]->ackEvents.push_back(vmBind->base);
|
||||
shouldAckEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
connection->isaMap[tileIndex][vmBind->va_start]->vmBindCounter++;
|
||||
@@ -1002,14 +1021,14 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
if (perKernelModules) {
|
||||
if (tileSessionsEnabled) {
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->removeModule(debugEvent.info.module);
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, nullptr);
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent);
|
||||
} else {
|
||||
bool notifyEvent = true;
|
||||
if (isa->deviceBitfield.count() > 1) {
|
||||
notifyEvent = checkAllOtherTileIsaAllocationsRemoved(tileIndex, vmBind->va_start);
|
||||
}
|
||||
if (notifyEvent) {
|
||||
pushApiEvent(debugEvent, nullptr);
|
||||
pushApiEvent(debugEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1032,37 +1051,93 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
bool canTriggerEvent = module.loadAddresses[tileIndex].size() == (module.segmentCount - 1);
|
||||
module.loadAddresses[tileIndex].insert(vmBind->va_start);
|
||||
|
||||
if (canTriggerEvent && module.loadAddresses[tileIndex].size() == module.segmentCount) {
|
||||
auto gmmHelper = connectedDevice->getNEODevice()->getGmmHelper();
|
||||
loadAddress = gmmHelper->canonize(*std::min_element(module.loadAddresses[tileIndex].begin(), module.loadAddresses[tileIndex].end()));
|
||||
PRINT_DEBUGGER_INFO_LOG("Zebin module loaded at: %p, with %u isa allocations", (void *)loadAddress, module.segmentCount);
|
||||
if (!blockOnFenceMode) {
|
||||
if (canTriggerEvent && module.loadAddresses[tileIndex].size() == module.segmentCount) {
|
||||
auto gmmHelper = connectedDevice->getNEODevice()->getGmmHelper();
|
||||
loadAddress = gmmHelper->canonize(*std::min_element(module.loadAddresses[tileIndex].begin(), module.loadAddresses[tileIndex].end()));
|
||||
PRINT_DEBUGGER_INFO_LOG("Zebin module loaded at: %p, with %u isa allocations", (void *)loadAddress, module.segmentCount);
|
||||
|
||||
zet_debug_event_t debugEvent = {};
|
||||
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
|
||||
debugEvent.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
|
||||
debugEvent.info.module.load = loadAddress;
|
||||
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfUuidHandle].ptr;
|
||||
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfUuidHandle].ptr + connection->uuidMap[module.elfUuidHandle].dataSize;
|
||||
zet_debug_event_t debugEvent = {};
|
||||
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
|
||||
debugEvent.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
|
||||
debugEvent.info.module.load = loadAddress;
|
||||
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfUuidHandle].ptr;
|
||||
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfUuidHandle].ptr + connection->uuidMap[module.elfUuidHandle].dataSize;
|
||||
|
||||
if (!tileSessionsEnabled) {
|
||||
bool allInstancesEventsReceived = true;
|
||||
if (module.deviceBitfield.count() > 1) {
|
||||
allInstancesEventsReceived = checkAllOtherTileModuleSegmentsPresent(tileIndex, module);
|
||||
if (!tileSessionsEnabled) {
|
||||
bool allInstancesEventsReceived = true;
|
||||
if (module.deviceBitfield.count() > 1) {
|
||||
allInstancesEventsReceived = checkAllOtherTileModuleSegmentsPresent(tileIndex, module);
|
||||
}
|
||||
if (allInstancesEventsReceived) {
|
||||
if (vmBind->base.flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK) {
|
||||
debugEvent.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
|
||||
module.ackEvents[tileIndex].push_back(vmBind->base);
|
||||
}
|
||||
pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
|
||||
shouldAckEvent = false;
|
||||
}
|
||||
} else {
|
||||
auto tileAttached = static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->insertModule(debugEvent.info.module);
|
||||
|
||||
if (tileAttached) {
|
||||
if (vmBind->base.flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK) {
|
||||
debugEvent.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
|
||||
module.ackEvents[tileIndex].push_back(vmBind->base);
|
||||
}
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
|
||||
shouldAckEvent = false;
|
||||
}
|
||||
}
|
||||
if (allInstancesEventsReceived) {
|
||||
pushApiEvent(debugEvent, &vmBind->base);
|
||||
}
|
||||
} else {
|
||||
if (canTriggerEvent && module.loadAddresses[tileIndex].size() == module.segmentCount) {
|
||||
auto gmmHelper = connectedDevice->getNEODevice()->getGmmHelper();
|
||||
loadAddress = gmmHelper->canonize(*std::min_element(module.loadAddresses[tileIndex].begin(), module.loadAddresses[tileIndex].end()));
|
||||
PRINT_DEBUGGER_INFO_LOG("Zebin module loaded at: %p, with %u isa allocations", (void *)loadAddress, module.segmentCount);
|
||||
|
||||
zet_debug_event_t debugEvent = {};
|
||||
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
|
||||
debugEvent.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
|
||||
debugEvent.info.module.load = loadAddress;
|
||||
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfUuidHandle].ptr;
|
||||
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfUuidHandle].ptr + connection->uuidMap[module.elfUuidHandle].dataSize;
|
||||
if (vmBind->base.flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK) {
|
||||
debugEvent.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
|
||||
}
|
||||
|
||||
if (!tileSessionsEnabled) {
|
||||
bool allInstancesEventsReceived = true;
|
||||
if (module.deviceBitfield.count() > 1) {
|
||||
allInstancesEventsReceived = checkAllOtherTileModuleSegmentsPresent(tileIndex, module);
|
||||
}
|
||||
if (allInstancesEventsReceived) {
|
||||
pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
|
||||
shouldAckEvent = false;
|
||||
}
|
||||
} else {
|
||||
auto tileAttached = static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->insertModule(debugEvent.info.module);
|
||||
if (tileAttached) {
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
|
||||
shouldAckEvent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(asyncThreadMutex);
|
||||
if (!module.moduleLoadEventAcked[tileIndex]) {
|
||||
shouldAckEvent = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
auto tileAttached = static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->insertModule(debugEvent.info.module);
|
||||
|
||||
if (tileAttached) {
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, &vmBind->base);
|
||||
shouldAckEvent = false;
|
||||
if (tileSessionsEnabled && !static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->isAttached) {
|
||||
shouldAckEvent = true;
|
||||
}
|
||||
if (!shouldAckEvent && (vmBind->base.flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK)) {
|
||||
module.ackEvents[tileIndex].push_back(vmBind->base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else { // destroyEvent
|
||||
|
||||
module.segmentVmBindCounter[tileIndex]--;
|
||||
@@ -1084,7 +1159,7 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
auto tileAttached = static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->removeModule(debugEvent.info.module);
|
||||
|
||||
if (tileAttached) {
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, nullptr);
|
||||
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -1093,10 +1168,11 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
notifyEvent = checkAllOtherTileModuleSegmentsRemoved(tileIndex, module);
|
||||
}
|
||||
if (notifyEvent) {
|
||||
pushApiEvent(debugEvent, nullptr);
|
||||
pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
|
||||
}
|
||||
}
|
||||
module.loadAddresses[tileIndex].clear();
|
||||
module.moduleLoadEventAcked[tileIndex] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1745,6 +1821,32 @@ bool DebugSessionLinux::ackIsaEvents(uint32_t deviceIndex, uint64_t isaVa) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugSessionLinux::ackModuleEvents(uint32_t deviceIndex, uint64_t moduleUuidHandle) {
|
||||
std::lock_guard<std::mutex> lock(asyncThreadMutex);
|
||||
|
||||
auto connection = clientHandleToConnection[clientHandle].get();
|
||||
|
||||
if (connection->uuidToModule.find(moduleUuidHandle) != connection->uuidToModule.end()) {
|
||||
auto &module = connection->uuidToModule[moduleUuidHandle];
|
||||
for (auto &event : module.ackEvents[deviceIndex]) {
|
||||
|
||||
prelim_drm_i915_debug_event_ack eventToAck = {};
|
||||
eventToAck.type = event.type;
|
||||
eventToAck.seqno = event.seqno;
|
||||
eventToAck.flags = 0;
|
||||
|
||||
auto ret = ioctl(PRELIM_I915_DEBUG_IOCTL_ACK_EVENT, &eventToAck);
|
||||
PRINT_DEBUGGER_INFO_LOG("PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu, ret = %d errno = %d\n", (uint64_t)event.seqno, ret, ret != 0 ? errno : 0);
|
||||
}
|
||||
module.ackEvents[deviceIndex].clear();
|
||||
module.moduleLoadEventAcked[deviceIndex] = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
DEBUG_BREAK_IF(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebugSessionLinux::cleanRootSessionAfterDetach(uint32_t deviceIndex) {
|
||||
auto connection = clientHandleToConnection[clientHandle].get();
|
||||
|
||||
@@ -1772,18 +1874,23 @@ ze_result_t DebugSessionLinux::acknowledgeEvent(const zet_debug_event_t *event)
|
||||
|
||||
const zet_debug_event_t apiEventToAck = *event;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(asyncThreadMutex);
|
||||
std::unique_lock<std::mutex> lock(asyncThreadMutex);
|
||||
|
||||
for (size_t i = 0; i < eventsToAck.size(); i++) {
|
||||
if (apiEventCompare(apiEventToAck, eventsToAck[i].first)) {
|
||||
|
||||
auto eventToAck = eventsToAck[i].second;
|
||||
auto ret = ioctl(PRELIM_I915_DEBUG_IOCTL_ACK_EVENT, &eventToAck);
|
||||
PRINT_DEBUGGER_INFO_LOG("PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu, ret = %d errno = %d\n", (uint64_t)eventToAck.seqno, ret, ret != 0 ? errno : 0);
|
||||
|
||||
auto moduleUUID = eventsToAck[i].second;
|
||||
auto iter = eventsToAck.begin() + i;
|
||||
eventsToAck.erase(iter);
|
||||
|
||||
lock.unlock();
|
||||
|
||||
for (uint32_t i = 0; i < NEO::EngineLimits::maxHandleCount; i++) {
|
||||
if (connectedDevice->getNEODevice()->getDeviceBitfield().test(i)) {
|
||||
ackModuleEvents(i, moduleUUID);
|
||||
}
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -1909,17 +2016,19 @@ void TileDebugSessionLinux::attachTile() {
|
||||
}
|
||||
|
||||
void TileDebugSessionLinux::detachTile() {
|
||||
std::vector<uint64_t> moduleUuids;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(asyncThreadMutex);
|
||||
isAttached = false;
|
||||
|
||||
for (size_t i = 0; i < eventsToAck.size(); i++) {
|
||||
|
||||
auto eventToAck = eventsToAck[i].second;
|
||||
auto ret = ioctl(PRELIM_I915_DEBUG_IOCTL_ACK_EVENT, &eventToAck);
|
||||
PRINT_DEBUGGER_INFO_LOG("PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu, ret = %d errno = %d\n", (uint64_t)eventToAck.seqno, ret, ret != 0 ? errno : 0);
|
||||
for (const auto &eventToAck : eventsToAck) {
|
||||
auto moduleUUID = eventToAck.second;
|
||||
moduleUuids.push_back(moduleUUID);
|
||||
}
|
||||
eventsToAck.clear();
|
||||
isAttached = false;
|
||||
}
|
||||
|
||||
for (const auto &uuid : moduleUuids) {
|
||||
rootDebugSession->ackModuleEvents(this->tileIndex, uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
friend struct TileDebugSessionLinux;
|
||||
|
||||
~DebugSessionLinux() override;
|
||||
DebugSessionLinux(const zet_debug_config_t &config, Device *device, int debugFd);
|
||||
DebugSessionLinux(const zet_debug_config_t &config, Device *device, int debugFd, void *params);
|
||||
|
||||
ze_result_t initialize() override;
|
||||
|
||||
@@ -129,10 +129,14 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
|
||||
struct Module {
|
||||
std::unordered_set<uint64_t> loadAddresses[NEO::EngineLimits::maxHandleCount];
|
||||
uint64_t moduleUuidHandle;
|
||||
uint64_t elfUuidHandle;
|
||||
uint32_t segmentCount;
|
||||
NEO::DeviceBitfield deviceBitfield;
|
||||
int segmentVmBindCounter[NEO::EngineLimits::maxHandleCount];
|
||||
|
||||
std::vector<prelim_drm_i915_debug_event> ackEvents[NEO::EngineLimits::maxHandleCount];
|
||||
bool moduleLoadEventAcked[NEO::EngineLimits::maxHandleCount];
|
||||
};
|
||||
|
||||
static bool apiEventCompare(const zet_debug_event_t &event1, const zet_debug_event_t &event2) {
|
||||
@@ -183,21 +187,19 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
ze_result_t interruptImp(uint32_t deviceIndex) override;
|
||||
|
||||
void enqueueApiEvent(zet_debug_event_t &debugEvent) override {
|
||||
pushApiEvent(debugEvent, nullptr);
|
||||
pushApiEvent(debugEvent);
|
||||
}
|
||||
|
||||
void pushApiEvent(zet_debug_event_t &debugEvent, prelim_drm_i915_debug_event *baseEvent) {
|
||||
void pushApiEvent(zet_debug_event_t &debugEvent) {
|
||||
return pushApiEvent(debugEvent, invalidHandle);
|
||||
}
|
||||
|
||||
void pushApiEvent(zet_debug_event_t &debugEvent, uint64_t moduleUuidHandle) {
|
||||
std::unique_lock<std::mutex> lock(asyncThreadMutex);
|
||||
|
||||
if (baseEvent && (baseEvent->flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK)) {
|
||||
prelim_drm_i915_debug_event_ack eventToAck = {};
|
||||
eventToAck.type = baseEvent->type;
|
||||
eventToAck.seqno = baseEvent->seqno;
|
||||
eventToAck.flags = 0;
|
||||
debugEvent.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
|
||||
|
||||
if (moduleUuidHandle != invalidHandle && (debugEvent.flags & ZET_DEBUG_EVENT_FLAG_NEED_ACK)) {
|
||||
eventsToAck.push_back(
|
||||
std::pair<zet_debug_event_t, prelim_drm_i915_debug_event_ack>(debugEvent, eventToAck));
|
||||
std::pair<zet_debug_event_t, uint64_t>(debugEvent, moduleUuidHandle));
|
||||
}
|
||||
|
||||
apiEvents.push(debugEvent);
|
||||
@@ -241,6 +243,8 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
void handleAttentionEvent(prelim_drm_i915_debug_event_eu_attention *attention);
|
||||
void handleEnginesEvent(prelim_drm_i915_debug_event_engines *engines);
|
||||
virtual bool ackIsaEvents(uint32_t deviceIndex, uint64_t isaVa);
|
||||
virtual bool ackModuleEvents(uint32_t deviceIndex, uint64_t moduleUuidHandle);
|
||||
|
||||
MOCKABLE_VIRTUAL void processPendingVmBindEvents();
|
||||
|
||||
void attachTile() override {
|
||||
@@ -343,10 +347,11 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
std::mutex internalEventThreadMutex;
|
||||
std::condition_variable internalEventCondition;
|
||||
std::queue<std::unique_ptr<uint64_t[]>> internalEventQueue;
|
||||
std::vector<std::pair<zet_debug_event_t, prelim_drm_i915_debug_event_ack>> eventsToAck;
|
||||
std::vector<std::pair<zet_debug_event_t, uint64_t>> eventsToAck; // debug event, uuid handle to module
|
||||
std::vector<std::unique_ptr<uint64_t[]>> pendingVmBindEvents;
|
||||
|
||||
int fd = 0;
|
||||
uint32_t i915DebuggerVersion = 0;
|
||||
virtual int ioctl(unsigned long request, void *arg);
|
||||
std::unique_ptr<IoctlHandler> ioctlHandler;
|
||||
std::atomic<bool> detached{false};
|
||||
@@ -358,10 +363,12 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
|
||||
std::unordered_map<uint64_t, std::unique_ptr<ClientConnection>> clientHandleToConnection;
|
||||
std::atomic<bool> internalThreadHasStarted{false};
|
||||
bool blockOnFenceMode = false; // false - blocking VM_BIND on CPU - autoack events until last blocking event
|
||||
// true - blocking on fence - do not auto-ack events
|
||||
};
|
||||
|
||||
struct TileDebugSessionLinux : DebugSessionLinux {
|
||||
TileDebugSessionLinux(zet_debug_config_t config, Device *device, DebugSessionImp *rootDebugSession) : DebugSessionLinux(config, device, 0),
|
||||
TileDebugSessionLinux(zet_debug_config_t config, Device *device, DebugSessionImp *rootDebugSession) : DebugSessionLinux(config, device, 0, nullptr),
|
||||
rootDebugSession(reinterpret_cast<DebugSessionLinux *>(rootDebugSession)) {
|
||||
tileIndex = Math::log2(static_cast<uint32_t>(connectedDevice->getNEODevice()->getDeviceBitfield().to_ulong()));
|
||||
}
|
||||
@@ -381,6 +388,8 @@ struct TileDebugSessionLinux : DebugSessionLinux {
|
||||
void attachTile() override;
|
||||
void detachTile() override;
|
||||
|
||||
bool isAttached = false;
|
||||
|
||||
protected:
|
||||
void startAsyncThread() override { UNRECOVERABLE_IF(true); };
|
||||
void cleanRootSessionAfterDetach(uint32_t deviceIndex) override { UNRECOVERABLE_IF(true); };
|
||||
@@ -418,6 +427,10 @@ struct TileDebugSessionLinux : DebugSessionLinux {
|
||||
return rootDebugSession->ackIsaEvents(this->tileIndex, isaVa);
|
||||
}
|
||||
|
||||
bool ackModuleEvents(uint32_t deviceIndex, uint64_t moduleUuidHandle) override {
|
||||
return rootDebugSession->ackModuleEvents(this->tileIndex, moduleUuidHandle);
|
||||
}
|
||||
|
||||
ze_result_t readGpuMemory(uint64_t vmHandle, char *output, size_t size, uint64_t gpuVa) override {
|
||||
return rootDebugSession->readGpuMemory(vmHandle, output, size, gpuVa);
|
||||
}
|
||||
@@ -436,7 +449,6 @@ struct TileDebugSessionLinux : DebugSessionLinux {
|
||||
|
||||
DebugSessionLinux *rootDebugSession = nullptr;
|
||||
uint32_t tileIndex = std::numeric_limits<uint32_t>::max();
|
||||
bool isAttached = false;
|
||||
bool processEntryState = false;
|
||||
|
||||
std::unordered_map<uint64_t, zet_debug_event_info_module_t> modules;
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <level_zero/ze_api.h>
|
||||
namespace L0 {
|
||||
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd) {
|
||||
return new DebugSessionLinux(config, device, debugFd);
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd, void *params) {
|
||||
return new DebugSessionLinux(config, device, debugFd, params);
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace L0 {
|
||||
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd);
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd, void *params);
|
||||
|
||||
DebugSessionWindows::~DebugSessionWindows() {
|
||||
closeAsyncThread();
|
||||
@@ -29,7 +29,7 @@ DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *dev
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto debugSession = createDebugSessionHelper(config, device, 0);
|
||||
auto debugSession = createDebugSessionHelper(config, device, 0, nullptr);
|
||||
debugSession->setAttachMode(isRootAttach);
|
||||
result = debugSession->initialize();
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <level_zero/ze_api.h>
|
||||
namespace L0 {
|
||||
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd) {
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd, void *params) {
|
||||
return new DebugSessionWindows(config, device);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user