mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 12:23:05 +08:00
fix(zebin): fix module load/unload events while debugging
- do not trigger incorrect / spurious events from internal modules for debugger - do not register Elf for internal modules Related-To: NEO-7605 Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
af81c79076
commit
ee499d689b
@@ -616,6 +616,7 @@ ze_result_t ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neo
|
||||
}
|
||||
|
||||
registerElfInDebuggerL0();
|
||||
|
||||
this->maxGroupSize = static_cast<uint32_t>(neoDevice->getDeviceInfo().maxWorkGroupSize);
|
||||
|
||||
checkIfPrivateMemoryPerDispatchIsNeeded();
|
||||
@@ -1279,7 +1280,7 @@ ze_result_t ModuleImp::destroy() {
|
||||
void ModuleImp::registerElfInDebuggerL0() {
|
||||
auto debuggerL0 = device->getL0Debugger();
|
||||
|
||||
if (!debuggerL0) {
|
||||
if (this->type != ModuleType::User || !debuggerL0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -519,6 +519,48 @@ HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWithRelocationsWhenInitializing
|
||||
EXPECT_EQ(reinterpret_cast<char *>(kernelInfo->kernelDescriptor.external.relocatedDebugData.get()), getMockDebuggerL0Hw<FamilyType>()->lastReceivedElf);
|
||||
}
|
||||
|
||||
HWTEST_F(ModuleWithDebuggerL0Test, GivenBuiltinModuleWhenInitializingModuleThenModuleAndElfNOtificationsAreNotCalled) {
|
||||
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
|
||||
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface.reset(cip);
|
||||
|
||||
uint8_t binary[10];
|
||||
ze_module_desc_t moduleDesc = {};
|
||||
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
|
||||
moduleDesc.pInputModule = binary;
|
||||
moduleDesc.inputSize = 10;
|
||||
ModuleBuildLog *moduleBuildLog = nullptr;
|
||||
|
||||
std::unique_ptr<MockModule> moduleMock = std::make_unique<MockModule>(device, moduleBuildLog, ModuleType::Builtin);
|
||||
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
|
||||
|
||||
uint32_t kernelHeap = 0;
|
||||
auto kernelInfo = new KernelInfo();
|
||||
kernelInfo->heapInfo.KernelHeapSize = 1;
|
||||
kernelInfo->heapInfo.pKernelHeap = &kernelHeap;
|
||||
|
||||
Mock<::L0::Kernel> kernelMock;
|
||||
kernelMock.module = moduleMock.get();
|
||||
kernelMock.immutableData.kernelInfo = kernelInfo;
|
||||
kernelInfo->kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful = 0;
|
||||
moduleMock->kernelImmData = &kernelMock.immutableData;
|
||||
moduleMock->translationUnit->programInfo.kernelInfos.push_back(kernelInfo);
|
||||
kernelInfo->kernelDescriptor.external.debugData = std::make_unique<NEO::DebugData>();
|
||||
|
||||
auto debugData = MockElfEncoder<>::createRelocateableDebugDataElf();
|
||||
kernelInfo->kernelDescriptor.external.debugData->vIsaSize = static_cast<uint32_t>(debugData.size());
|
||||
kernelInfo->kernelDescriptor.external.debugData->vIsa = reinterpret_cast<char *>(debugData.data());
|
||||
kernelInfo->kernelDescriptor.external.debugData->genIsa = nullptr;
|
||||
kernelInfo->kernelDescriptor.external.debugData->genIsaSize = 0;
|
||||
|
||||
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
|
||||
EXPECT_EQ(moduleMock->initialize(&moduleDesc, neoDevice), ZE_RESULT_SUCCESS);
|
||||
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfAndLinkCount);
|
||||
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleCreateCount);
|
||||
|
||||
EXPECT_NE(nullptr, kernelInfo->kernelDescriptor.external.relocatedDebugData.get());
|
||||
EXPECT_EQ(nullptr, getMockDebuggerL0Hw<FamilyType>()->lastReceivedElf);
|
||||
}
|
||||
|
||||
HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWithoutRelocationsWhenInitializingModuleThenRegisterElfWithUnrelocatedElfAndModuleCreateNotified) {
|
||||
|
||||
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
|
||||
|
||||
@@ -1032,6 +1032,8 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
}
|
||||
}
|
||||
|
||||
if (handleEvent) {
|
||||
|
||||
for (uint32_t uuidIter = 0; uuidIter < vmBind->num_uuids; uuidIter++) {
|
||||
if (connection->uuidMap[vmBind->uuids[uuidIter]].classIndex == NEO::DrmResourceClass::L0ZebinModule) {
|
||||
uint64_t loadAddress = 0;
|
||||
@@ -1168,6 +1170,8 @@ bool DebugSessionLinux::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bind *v
|
||||
module.moduleLoadEventAcked[tileIndex] = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3911,6 +3911,59 @@ TEST_F(DebugApiLinuxVmBindTest, GivenTwoPendingEventsWhenAcknowledgeEventCalledT
|
||||
EXPECT_EQ(1u, session->eventsToAck.size());
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxVmBindTest, GivenNoIsaUUIDAndZebinModuleForDataSegmentWhenHandlingVmBindEventThenModuleLoadAndUnloadEventsAreTriggered) {
|
||||
setupVmToTile(session.get());
|
||||
|
||||
uint64_t vmBindIsaData[(sizeof(prelim_drm_i915_debug_event_vm_bind) + 2 * sizeof(typeOfUUID) + sizeof(uint64_t)) / sizeof(uint64_t)];
|
||||
prelim_drm_i915_debug_event_vm_bind *vmBindIsa = reinterpret_cast<prelim_drm_i915_debug_event_vm_bind *>(&vmBindIsaData);
|
||||
|
||||
vmBindIsa->base.type = PRELIM_DRM_I915_DEBUG_EVENT_VM_BIND;
|
||||
vmBindIsa->base.flags = PRELIM_DRM_I915_DEBUG_EVENT_CREATE;
|
||||
vmBindIsa->base.flags |= PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK;
|
||||
vmBindIsa->base.size = sizeof(prelim_drm_i915_debug_event_vm_bind) + 2 * sizeof(typeOfUUID);
|
||||
vmBindIsa->base.seqno = 10;
|
||||
vmBindIsa->client_handle = MockDebugSessionLinux::mockClientHandle;
|
||||
vmBindIsa->va_start = isaGpuVa;
|
||||
|
||||
DebugSessionLinux::UuidData zebinModuleUuidData = {
|
||||
.handle = zebinModuleUUID,
|
||||
.classHandle = zebinModuleClassHandle,
|
||||
.classIndex = NEO::DrmResourceClass::L0ZebinModule,
|
||||
.data = std::make_unique<char[]>(sizeof(1)),
|
||||
.dataSize = sizeof(1)};
|
||||
|
||||
session->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidMap.emplace(zebinModuleUUID, std::move(zebinModuleUuidData));
|
||||
session->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidToModule[zebinModuleUUID].segmentCount = 1;
|
||||
|
||||
vmBindIsa->va_length = isaSize;
|
||||
vmBindIsa->vm_handle = vm0;
|
||||
vmBindIsa->num_uuids = 2;
|
||||
auto *uuids = reinterpret_cast<typeOfUUID *>(ptrOffset(vmBindIsaData, sizeof(prelim_drm_i915_debug_event_vm_bind)));
|
||||
typeOfUUID uuidsTemp[2];
|
||||
uuidsTemp[0] = static_cast<typeOfUUID>(elfUUID);
|
||||
uuidsTemp[1] = static_cast<typeOfUUID>(zebinModuleUUID);
|
||||
|
||||
memcpy_s(uuids, 2 * sizeof(typeOfUUID), uuidsTemp, sizeof(uuidsTemp));
|
||||
session->handleEvent(&vmBindIsa->base);
|
||||
|
||||
EXPECT_EQ(1u, session->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidToModule[zebinModuleUUID].ackEvents[0].size());
|
||||
EXPECT_EQ(1u, session->apiEvents.size());
|
||||
EXPECT_EQ(1u, session->eventsToAck.size());
|
||||
|
||||
zet_debug_event_t event0 = {};
|
||||
auto result = session->readEvent(0, &event0);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_LOAD, event0.type);
|
||||
|
||||
vmBindIsa->base.flags = PRELIM_DRM_I915_DEBUG_EVENT_DESTROY;
|
||||
session->handleEvent(&vmBindIsa->base);
|
||||
|
||||
EXPECT_EQ(1u, session->apiEvents.size());
|
||||
result = session->readEvent(0, &event0);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD, event0.type);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxVmBindTest, GivenBlockOnFenceAndTwoPendingEventsWhenAcknowledgeEventCalledThenCorrectEventIsAcked) {
|
||||
session->blockOnFenceMode = true;
|
||||
setupVmToTile(session.get());
|
||||
@@ -4670,6 +4723,61 @@ TEST_F(DebugApiLinuxVmBindTest, GivenMultipleSegmentsInL0ZebinModuleWhenLoadAddr
|
||||
EXPECT_EQ(0u, session->apiEvents.size());
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxVmBindTest, GivenMultipleSegmentsInL0ZebinModuleWhenLoadAddressCountReachesSegmentsCountThenModuleLoadEventIsTriggered) {
|
||||
const uint64_t isaGpuVa = 0x345000;
|
||||
const uint64_t dataGpuVa = 0x333000;
|
||||
const uint64_t isaSize = 0x2000;
|
||||
const uint64_t dataSize = 0x2000;
|
||||
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);
|
||||
|
||||
const uint32_t segmentCount = 2;
|
||||
DebugSessionLinux::UuidData zebinModuleUuidData = {
|
||||
.handle = zebinModuleUUID,
|
||||
.classHandle = zebinModuleClassHandle,
|
||||
.classIndex = NEO::DrmResourceClass::L0ZebinModule,
|
||||
.data = std::make_unique<char[]>(sizeof(segmentCount)),
|
||||
.dataSize = sizeof(segmentCount)};
|
||||
|
||||
memcpy(zebinModuleUuidData.data.get(), &segmentCount, sizeof(segmentCount));
|
||||
|
||||
session->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->classHandleToIndex[zebinModuleClassHandle] = {"L0_ZEBIN_MODULE", static_cast<uint32_t>(NEO::DrmResourceClass::L0ZebinModule)};
|
||||
session->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidMap.emplace(zebinModuleUUID, std::move(zebinModuleUuidData));
|
||||
session->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidToModule[zebinModuleUUID].segmentCount = segmentCount;
|
||||
session->clientHandleToConnection[MockDebugSessionLinux::mockClientHandle]->uuidMap[elfUUID].ptr = 0x1000;
|
||||
|
||||
vmBindIsa->base.type = PRELIM_DRM_I915_DEBUG_EVENT_VM_BIND;
|
||||
vmBindIsa->base.flags = PRELIM_DRM_I915_DEBUG_EVENT_CREATE;
|
||||
vmBindIsa->base.size = sizeof(prelim_drm_i915_debug_event_vm_bind) + 3 * sizeof(typeOfUUID);
|
||||
vmBindIsa->client_handle = MockDebugSessionLinux::mockClientHandle;
|
||||
vmBindIsa->va_start = isaGpuVa;
|
||||
vmBindIsa->va_length = isaSize;
|
||||
vmBindIsa->vm_handle = vmHandleForVmBind;
|
||||
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));
|
||||
session->handleEvent(&vmBindIsa->base);
|
||||
|
||||
vmBindIsa->num_uuids = 1;
|
||||
vmBindIsa->va_start = dataGpuVa;
|
||||
vmBindIsa->va_length = dataSize;
|
||||
vmBindIsa->base.size = sizeof(prelim_drm_i915_debug_event_vm_bind) + 1 * sizeof(typeOfUUID);
|
||||
uuidsTemp[0] = static_cast<typeOfUUID>(zebinModuleUUID); // only module UUID attached
|
||||
|
||||
memcpy(uuids, uuidsTemp, sizeof(typeOfUUID));
|
||||
|
||||
session->handleEvent(&vmBindIsa->base);
|
||||
|
||||
EXPECT_EQ(1u, session->apiEvents.size());
|
||||
EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_MODULE_LOAD, session->apiEvents.front().type);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxVmBindTest, GivenMultipleBindEventsWithZebinModuleWhenHandlingEventsThenModuleLoadIsReportedOnceOnly) {
|
||||
uint64_t isaGpuVa = 0x345000;
|
||||
uint64_t isaSize = 0x2000;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2022 Intel Corporation
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -58,6 +58,8 @@ bool DebuggerL0::attachZebinModuleToSegmentAllocations(const StackVec<NEO::Graph
|
||||
|
||||
for (auto &allocation : allocs) {
|
||||
auto drmAllocation = static_cast<NEO::DrmAllocation *>(allocation);
|
||||
|
||||
DEBUG_BREAK_IF(allocation->getAllocationType() == AllocationType::KERNEL_ISA_INTERNAL);
|
||||
drmAllocation->linkWithRegisteredHandle(elfHandle);
|
||||
drmAllocation->linkWithRegisteredHandle(moduleHandle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user