L0 debugger - reports process ENTER/EXIT events for zeCommandQueues

- PROCESS_ENTRY - triggered by first zeCommandQueueCreate()
- PROCESS_EXIT  - triggered by last zeCommandQueueDestroy()

Resolves: NEO-6503

Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:
Igor Venevtsev
2022-02-10 11:13:59 +00:00
committed by Compute-Runtime-Automation
parent dbe1779e4b
commit 60d6505932
11 changed files with 105 additions and 4 deletions

View File

@@ -57,6 +57,9 @@ ze_result_t CommandQueueImp::initialize(bool copyOnly, bool isInternal) {
if (!isInternal) {
partitionCount = csr->getActivePartitions();
}
if (NEO::Debugger::isDebugEnabled(internalUsage) && device->getL0Debugger()) {
device->getL0Debugger()->notifyCommandQueueCreated();
}
}
return returnValue;
}

View File

@@ -56,6 +56,9 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::destroy() {
commandStream = nullptr;
}
buffers.destroy(this->getDevice());
if (NEO::Debugger::isDebugEnabled(internalUsage) && device->getL0Debugger()) {
device->getL0Debugger()->notifyCommandQueueDestroyed();
}
delete this;
return ZE_RESULT_SUCCESS;
}

View File

@@ -86,6 +86,8 @@ class DebuggerL0 : public NEO::Debugger, NEO::NonCopyableOrMovableClass {
void captureStateBaseAddress(NEO::CommandContainer &container, SbaAddresses sba) override;
void printTrackedAddresses(uint32_t contextId);
MOCKABLE_VIRTUAL void registerElf(NEO::DebugData *debugData, NEO::GraphicsAllocation *isaAllocation);
MOCKABLE_VIRTUAL void notifyCommandQueueCreated();
MOCKABLE_VIRTUAL void notifyCommandQueueDestroyed();
virtual size_t getSbaTrackingCommandsSize(size_t trackedAddressCount) = 0;
virtual void programSbaTrackingCommands(NEO::LinearStream &cmdStream, const SbaAddresses &sba) = 0;
@@ -108,6 +110,8 @@ class DebuggerL0 : public NEO::Debugger, NEO::NonCopyableOrMovableClass {
std::unordered_map<uint32_t, NEO::GraphicsAllocation *> perContextSbaAllocations;
NEO::AddressRange sbaTrackingGpuVa;
NEO::GraphicsAllocation *moduleDebugArea = nullptr;
std::atomic<uint32_t> commandQueueCount = 0u;
uint32_t uuidL0CommandQueueHandle = 0;
};
using DebugerL0CreateFn = DebuggerL0 *(*)(NEO::Device *device);
@@ -132,4 +136,4 @@ struct DebuggerL0PopulateFactory {
}
};
} // namespace L0
} // namespace L0

View File

@@ -58,4 +58,23 @@ bool DebuggerL0::removeZebinModule(uint32_t moduleHandle) {
drm->unregisterResource(moduleHandle);
return true;
}
void DebuggerL0::notifyCommandQueueCreated() {
if (device->getRootDeviceEnvironment().osInterface.get() != nullptr) {
if (++commandQueueCount == 1) {
auto drm = device->getRootDeviceEnvironment().osInterface->getDriverModel()->as<NEO::Drm>();
uuidL0CommandQueueHandle = drm->notifyFirstCommandQueueCreated();
}
}
}
void DebuggerL0::notifyCommandQueueDestroyed() {
if (device->getRootDeviceEnvironment().osInterface.get() != nullptr) {
if (--commandQueueCount == 0) {
auto drm = device->getRootDeviceEnvironment().osInterface->getDriverModel()->as<NEO::Drm>();
drm->notifyLastCommandQueueDestroyed(uuidL0CommandQueueHandle);
}
}
}
} // namespace L0

View File

@@ -27,4 +27,10 @@ bool DebuggerL0::removeZebinModule(uint32_t moduleHandle) {
return false;
}
void DebuggerL0::notifyCommandQueueCreated() {
}
void DebuggerL0::notifyCommandQueueDestroyed() {
}
} // namespace L0

View File

@@ -57,15 +57,28 @@ class MockDebuggerL0Hw : public L0::DebuggerL0Hw<GfxFamily> {
}
return L0::DebuggerL0Hw<GfxFamily>::attachZebinModuleToSegmentAllocations(allocs, moduleHandle);
}
bool removeZebinModule(uint32_t moduleHandle) override {
removedZebinModuleHandle = moduleHandle;
return L0::DebuggerL0Hw<GfxFamily>::removeZebinModule(moduleHandle);
}
void notifyCommandQueueCreated() override {
commandQueueCreatedCount++;
L0::DebuggerL0Hw<GfxFamily>::notifyCommandQueueCreated();
}
void notifyCommandQueueDestroyed() override {
commandQueueDestroyedCount++;
L0::DebuggerL0Hw<GfxFamily>::notifyCommandQueueDestroyed();
}
uint32_t captureStateBaseAddressCount = 0;
uint32_t programSbaTrackingCommandsCount = 0;
uint32_t getSbaTrackingCommandsSizeCount = 0;
uint32_t registerElfCount = 0;
uint32_t commandQueueCreatedCount = 0;
uint32_t commandQueueDestroyedCount = 0;
const char *lastReceivedElf = nullptr;
uint32_t segmentCountWithAttachedModuleHandle = 0;

View File

@@ -12,6 +12,7 @@
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/test_macros/test.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h"
#include "level_zero/core/test/unit_tests/sources/debugger/l0_debugger_fixture.h"
#include <algorithm>
@@ -219,5 +220,30 @@ TEST_F(L0DebuggerLinuxTest, givenModuleHandleWhenRemoveZebinModuleIsCalledThenHa
EXPECT_EQ(20u, drmMock->unregisteredHandle);
}
HWTEST_F(L0DebuggerLinuxTest, givenDebuggingEnabledAndCommandQueuesAreCreatedAndDestroyedThanDebuggerL0IsNotified) {
auto debuggerL0Hw = static_cast<MockDebuggerL0Hw<FamilyType> *>(device->getL0Debugger());
neoDevice->getDefaultEngine().commandStreamReceiver->getOsContext().ensureContextInitialized();
drmMock->ioctlCallsCount = 0;
ze_command_queue_desc_t queueDesc = {};
ze_result_t returnValue;
auto commandQueue1 = CommandQueue::create(productFamily, device, neoDevice->getDefaultEngine().commandStreamReceiver, &queueDesc, false, false, returnValue);
EXPECT_EQ(1u, drmMock->ioctlCallsCount);
EXPECT_EQ(1u, debuggerL0Hw->commandQueueCreatedCount);
auto commandQueue2 = CommandQueue::create(productFamily, device, neoDevice->getDefaultEngine().commandStreamReceiver, &queueDesc, false, false, returnValue);
EXPECT_EQ(1u, drmMock->ioctlCallsCount);
EXPECT_EQ(2u, debuggerL0Hw->commandQueueCreatedCount);
commandQueue1->destroy();
EXPECT_EQ(1u, drmMock->ioctlCallsCount);
EXPECT_EQ(1u, debuggerL0Hw->commandQueueDestroyedCount);
commandQueue2->destroy();
EXPECT_EQ(1u, drmMock->unregisterCalledCount);
EXPECT_EQ(2u, debuggerL0Hw->commandQueueDestroyedCount);
}
} // namespace ult
} // namespace L0