fix(debugger): auto-ack vmbind on tile for module from other tiles

Related-to: NEO-8371

Signed-off-by: Brandon Yates <brandon.yates@intel.com>
This commit is contained in:
Brandon Yates
2023-09-13 22:35:50 +00:00
committed by Compute-Runtime-Automation
parent c1274cd84f
commit 513045bd90
3 changed files with 166 additions and 122 deletions

View File

@@ -1055,138 +1055,140 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
if (connection->uuidMap[vmBind->uuids[uuidIter]].classIndex == NEO::DrmResourceClass::L0ZebinModule) {
uint64_t loadAddress = 0;
auto &module = connection->uuidToModule[vmBind->uuids[uuidIter]];
auto moduleUsedOnTile = module.deviceBitfield.test(tileIndex) || module.deviceBitfield.count() == 0;
if (moduleUsedOnTile) {
if (createEvent) {
module.segmentVmBindCounter[tileIndex]++;
if (createEvent) {
module.segmentVmBindCounter[tileIndex]++;
DEBUG_BREAK_IF(module.loadAddresses[tileIndex].size() > module.segmentCount);
bool canTriggerEvent = module.loadAddresses[tileIndex].size() == (module.segmentCount - 1);
module.loadAddresses[tileIndex].insert(vmBind->va_start);
DEBUG_BREAK_IF(module.loadAddresses[tileIndex].size() > module.segmentCount);
bool canTriggerEvent = module.loadAddresses[tileIndex].size() == (module.segmentCount - 1);
module.loadAddresses[tileIndex].insert(vmBind->va_start);
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);
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 (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);
if (!tileSessionsEnabled) {
bool allInstancesEventsReceived = true;
if (module.deviceBitfield.count() > 1) {
allInstancesEventsReceived = checkAllOtherTileModuleSegmentsPresent(tileIndex, module);
}
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);
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;
}
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
shouldAckEvent = false;
}
}
}
} else {
PRINT_DEBUGGER_INFO_LOG("Zebin module = %ull has load addresses = %d", static_cast<uint64_t>(vmBind->uuids[uuidIter]), static_cast<int>(module.loadAddresses[tileIndex].size()));
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;
}
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]--;
if (module.segmentVmBindCounter[tileIndex] == 0) {
zet_debug_event_t debugEvent = {};
auto gmmHelper = connectedDevice->getNEODevice()->getGmmHelper();
auto loadAddress = gmmHelper->canonize(*std::min_element(module.loadAddresses[tileIndex].begin(), module.loadAddresses[tileIndex].end()));
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD;
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) {
auto tileAttached = static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->removeModule(debugEvent.info.module);
if (tileAttached) {
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
}
} else {
bool notifyEvent = true;
if (module.deviceBitfield.count() > 1) {
notifyEvent = checkAllOtherTileModuleSegmentsRemoved(tileIndex, module);
PRINT_DEBUGGER_INFO_LOG("Zebin module = %ull has load addresses = %d", static_cast<uint64_t>(vmBind->uuids[uuidIter]), static_cast<int>(module.loadAddresses[tileIndex].size()));
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;
}
}
}
if (notifyEvent) {
pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
{
std::lock_guard<std::mutex> lock(asyncThreadMutex);
if (!module.moduleLoadEventAcked[tileIndex]) {
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);
}
}
}
module.loadAddresses[tileIndex].clear();
module.moduleLoadEventAcked[tileIndex] = false;
} else { // destroyEvent
module.segmentVmBindCounter[tileIndex]--;
if (module.segmentVmBindCounter[tileIndex] == 0) {
zet_debug_event_t debugEvent = {};
auto gmmHelper = connectedDevice->getNEODevice()->getGmmHelper();
auto loadAddress = gmmHelper->canonize(*std::min_element(module.loadAddresses[tileIndex].begin(), module.loadAddresses[tileIndex].end()));
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD;
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) {
auto tileAttached = static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->removeModule(debugEvent.info.module);
if (tileAttached) {
static_cast<TileDebugSessionLinux *>(tileSessions[tileIndex].first)->pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
}
} else {
bool notifyEvent = true;
if (module.deviceBitfield.count() > 1) {
notifyEvent = checkAllOtherTileModuleSegmentsRemoved(tileIndex, module);
}
if (notifyEvent) {
pushApiEvent(debugEvent, vmBind->uuids[uuidIter]);
}
}
module.loadAddresses[tileIndex].clear();
module.moduleLoadEventAcked[tileIndex] = false;
}
}
}
break;

View File

@@ -643,7 +643,13 @@ struct MockDebugSessionLinuxHelper {
DebugSessionLinux::UuidData isaUuidData = {
.handle = isaUUID,
.classHandle = isaClassHandle,
.classIndex = NEO::DrmResourceClass::Isa};
.classIndex = NEO::DrmResourceClass::Isa,
.data = std::make_unique<char[]>(4),
.dataSize = 4};
DeviceBitfield bitfield;
auto deviceBitfield = static_cast<uint32_t>(bitfield.to_ulong());
memcpy(isaUuidData.data.get(), &deviceBitfield, sizeof(deviceBitfield));
DebugSessionLinux::UuidData elfUuidData = {
.handle = elfUUID,
.classHandle = elfClassHandle,

View File

@@ -1200,6 +1200,42 @@ TEST_F(TileAttachTest, GivenEventWithL0ZebinModuleWhenHandlingEventThenModuleLoa
}
}
TEST_F(TileAttachTest, GivenZebinModuleVmBindForModuleFromDifferentTileThenVmBindIsAutoacked) {
auto handler = new MockIoctlHandler;
rootSession->ioctlHandler.reset(handler);
auto &isaUuidData = rootSession->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidMap.find(isaUUID)->second;
DeviceBitfield bitfield;
bitfield.set(1);
auto deviceBitfield = static_cast<uint32_t>(bitfield.to_ulong());
memcpy(isaUuidData.data.get(), &deviceBitfield, sizeof(deviceBitfield));
uint64_t vmBindIsaData[sizeof(prelim_drm_i915_debug_event_vm_bind) / sizeof(uint64_t) + 3 * sizeof(typeOfUUID)];
prelim_drm_i915_debug_event_vm_bind *vmBindIsa = reinterpret_cast<prelim_drm_i915_debug_event_vm_bind *>(&vmBindIsaData);
uint64_t vmHandle = vm0;
vmBindIsa->base.type = PRELIM_DRM_I915_DEBUG_EVENT_VM_BIND;
vmBindIsa->base.flags = PRELIM_DRM_I915_DEBUG_EVENT_CREATE | PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK;
vmBindIsa->base.size = sizeof(prelim_drm_i915_debug_event_vm_bind) + 3 * sizeof(typeOfUUID);
vmBindIsa->base.seqno = 10;
vmBindIsa->client_handle = MockDebugSessionLinux::mockClientHandle;
vmBindIsa->va_start = isaGpuVa;
vmBindIsa->va_length = isaSize;
vmBindIsa->vm_handle = vmHandle;
vmBindIsa->num_uuids = 4;
auto *uuids = reinterpret_cast<typeOfUUID *>(ptrOffset(vmBindIsaData, sizeof(prelim_drm_i915_debug_event_vm_bind)));
typeOfUUID uuidsTemp[4];
uuidsTemp[0] = static_cast<typeOfUUID>(isaUUID);
uuidsTemp[1] = static_cast<typeOfUUID>(cookieUUID);
uuidsTemp[2] = static_cast<typeOfUUID>(elfUUID);
uuidsTemp[3] = static_cast<typeOfUUID>(zebinModuleUUID);
memcpy(uuids, uuidsTemp, sizeof(uuidsTemp));
EXPECT_EQ(handler->ackCount, 0u);
rootSession->handleEvent(&vmBindIsa->base);
EXPECT_EQ(handler->ackCount, 1u);
}
TEST_F(TileAttachTest, GivenZebinModuleDestroyedBeforeAttachWhenAttachingThenModuleLoadEventIsNotReported) {
uint64_t isaGpuVa2 = 0x340000;
uint64_t vmBindIsaData[sizeof(prelim_drm_i915_debug_event_vm_bind) / sizeof(uint64_t) + 3 * sizeof(typeOfUUID)];
@@ -1231,7 +1267,7 @@ TEST_F(TileAttachTest, GivenZebinModuleDestroyedBeforeAttachWhenAttachingThenMod
rootSession->handleEvent(&vmBindIsa->base);
EXPECT_EQ(1u, rootSession->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidToModule.size());
EXPECT_EQ(1u, tileSessions[1]->modules.size());
ASSERT_EQ(1u, tileSessions[1]->modules.size());
EXPECT_EQ(isaGpuVa2, tileSessions[1]->modules.begin()->second.load);
vmBindIsa->base.flags = PRELIM_DRM_I915_DEBUG_EVENT_DESTROY;