From fd971f7a61d4182c426879e72f0a2bcdd626beda Mon Sep 17 00:00:00 2001 From: Fabian Zwolinski Date: Fri, 31 Mar 2023 11:41:17 +0000 Subject: [PATCH] Generate Offline Dump Context ID On linux OfflineDumpContextId consists of 32b processId in bits 63:32 32b drmContestId in bits 31:0 Also cache linux implementation of getProcessId since the value is constant. Related-To: NEO-7630 Signed-off-by: Fabian Zwolinski --- .../os_interface/linux/os_context_linux.cpp | 11 +++++ .../os_interface/linux/os_context_linux.h | 2 + .../os_interface/linux/sys_calls_linux.cpp | 3 +- shared/source/os_interface/os_context.h | 1 + .../os_interface/windows/os_context_win.cpp | 4 ++ .../os_interface/windows/os_context_win.h | 1 + .../linux/os_context_linux_tests.cpp | 40 ++++++++++++++++++- .../os_interface/os_context_tests.cpp | 6 +++ .../windows/os_context_win_tests.cpp | 5 +++ 9 files changed, 71 insertions(+), 2 deletions(-) diff --git a/shared/source/os_interface/linux/os_context_linux.cpp b/shared/source/os_interface/linux/os_context_linux.cpp index 2f5f424f43..ce8c32abb8 100644 --- a/shared/source/os_interface/linux/os_context_linux.cpp +++ b/shared/source/os_interface/linux/os_context_linux.cpp @@ -17,6 +17,7 @@ #include "shared/source/os_interface/os_context.h" #include "shared/source/os_interface/os_interface.h" #include "shared/source/os_interface/product_helper.h" +#include "shared/source/os_interface/sys_calls_common.h" namespace NEO { @@ -94,6 +95,16 @@ void OsContextLinux::waitForPagingFence() { void OsContextLinux::reInitializeContext() {} +uint64_t OsContextLinux::getOfflineDumpContextId(uint32_t deviceIndex) const { + if (deviceIndex < drmContextIds.size()) { + const auto processId = SysCalls::getProcessId(); + const auto drmContextId = drmContextIds[deviceIndex]; + return static_cast(processId) << 32 | + static_cast(drmContextId); + } + return 0; +} + OsContextLinux::~OsContextLinux() { if (contextInitialized) { for (auto drmContextId : drmContextIds) { diff --git a/shared/source/os_interface/linux/os_context_linux.h b/shared/source/os_interface/linux/os_context_linux.h index 076775cac1..fa32de0995 100644 --- a/shared/source/os_interface/linux/os_context_linux.h +++ b/shared/source/os_interface/linux/os_context_linux.h @@ -50,6 +50,8 @@ class OsContextLinux : public OsContext { return contextHangDetected; } + uint64_t getOfflineDumpContextId(uint32_t deviceIndex) const override; + protected: bool initializeContext() override; diff --git a/shared/source/os_interface/linux/sys_calls_linux.cpp b/shared/source/os_interface/linux/sys_calls_linux.cpp index 4c28ec2f3a..f3f3596d44 100644 --- a/shared/source/os_interface/linux/sys_calls_linux.cpp +++ b/shared/source/os_interface/linux/sys_calls_linux.cpp @@ -22,7 +22,8 @@ namespace NEO { namespace SysCalls { unsigned int getProcessId() { - return getpid(); + static unsigned int pid = getpid(); + return pid; } unsigned long getNumThreads() { diff --git a/shared/source/os_interface/os_context.h b/shared/source/os_interface/os_context.h index c6cc9ea953..c6a69240c5 100644 --- a/shared/source/os_interface/os_context.h +++ b/shared/source/os_interface/os_context.h @@ -27,6 +27,7 @@ class OsContext : public ReferenceTrackedObject { bool ensureContextInitialized(); uint32_t getContextId() const { return contextId; } + virtual uint64_t getOfflineDumpContextId(uint32_t deviceIndex) const { return 0; }; uint32_t getNumSupportedDevices() const { return numSupportedDevices; } DeviceBitfield getDeviceBitfield() const { return deviceBitfield; } PreemptionMode getPreemptionMode() const { return preemptionMode; } diff --git a/shared/source/os_interface/windows/os_context_win.cpp b/shared/source/os_interface/windows/os_context_win.cpp index ef0162e2f8..181c46a4bf 100644 --- a/shared/source/os_interface/windows/os_context_win.cpp +++ b/shared/source/os_interface/windows/os_context_win.cpp @@ -77,6 +77,10 @@ uint32_t OsContextWin::getDeviceNodeMask() { return hwDeviceID->getAdapterNodeMask(); } +uint64_t OsContextWin::getOfflineDumpContextId(uint32_t deviceIndex) const { + return 0; +} + OsContextWin::~OsContextWin() { if (contextInitialized && (false == this->wddm.skipResourceCleanup())) { wddm.getWddmInterface()->destroyHwQueue(hardwareQueue.handle); diff --git a/shared/source/os_interface/windows/os_context_win.h b/shared/source/os_interface/windows/os_context_win.h index 6b15ae9d9f..85f1b8785c 100644 --- a/shared/source/os_interface/windows/os_context_win.h +++ b/shared/source/os_interface/windows/os_context_win.h @@ -37,6 +37,7 @@ class OsContextWin : public OsContext { void reInitializeContext() override; void getDeviceLuidArray(std::vector &luidData, size_t arraySize); uint32_t getDeviceNodeMask(); + uint64_t getOfflineDumpContextId(uint32_t deviceIndex) const override; protected: bool initializeContext() override; diff --git a/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp b/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp index 7d3f55edbc..438345aad3 100644 --- a/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp @@ -36,4 +36,42 @@ TEST(OSContextLinux, givenInitializeContextWhenContextCreateIoctlFailsThenContex OsContextLinux osContext(*pDrm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor()); EXPECT_EQ(false, osContext.ensureContextInitialized()); delete pDrm; -} \ No newline at end of file +} + +TEST(OSContextLinux, givenOsContextLinuxWhenQueryingForOfflineDumpContextIdThenCorrectValueIsReturned) { + class OsContextLinuxMock : public OsContextLinux { + public: + using OsContextLinux::drmContextIds; + + OsContextLinuxMock(Drm &drm, uint32_t rootDeviceIndex, uint32_t contextId, const EngineDescriptor &engineDescriptor) + : OsContextLinux(drm, rootDeviceIndex, contextId, engineDescriptor) {} + }; + + MockExecutionEnvironment executionEnvironment; + std::unique_ptr mock(new DrmMockCustom(*executionEnvironment.rootDeviceEnvironments[0])); + executionEnvironment.rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock.get(), 0u); + OsContextLinuxMock osContext(*mock, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor()); + + osContext.drmContextIds.clear(); + osContext.drmContextIds.push_back(1u); + osContext.drmContextIds.push_back(3u); + osContext.drmContextIds.push_back(5u); + + const auto processId = 0xABCEDF; + const uint64_t highBitsMask = 0xffffffff00000000; + const uint64_t lowBitsMask = 0x00000000ffffffff; + + auto ctxId = osContext.getOfflineDumpContextId(0); + EXPECT_EQ(ctxId & lowBitsMask, static_cast(1u)); + EXPECT_EQ(ctxId & highBitsMask, static_cast(processId) << 32); + + ctxId = osContext.getOfflineDumpContextId(1); + EXPECT_EQ(ctxId & lowBitsMask, static_cast(3u)); + EXPECT_EQ(ctxId & highBitsMask, static_cast(processId) << 32); + + ctxId = osContext.getOfflineDumpContextId(2); + EXPECT_EQ(ctxId & lowBitsMask, static_cast(5u)); + EXPECT_EQ(ctxId & highBitsMask, static_cast(processId) << 32); + + EXPECT_EQ(0u, osContext.getOfflineDumpContextId(10)); +} diff --git a/shared/test/unit_test/os_interface/os_context_tests.cpp b/shared/test/unit_test/os_interface/os_context_tests.cpp index d9d0e122ed..693c9a48e7 100644 --- a/shared/test/unit_test/os_interface/os_context_tests.cpp +++ b/shared/test/unit_test/os_interface/os_context_tests.cpp @@ -81,6 +81,12 @@ TEST(OSContext, givenSetPowerHintThenGetPowerHintShowsTheSameValue) { delete pOsContext; } +TEST(OSContext, givenOsContextWhenQueryingForOfflineDumpContextIdThenCorrectValueIsReturned) { + OsContext *osContext = OsContext::create(nullptr, 0, 0, EngineDescriptorHelper::getDefaultDescriptor()); + EXPECT_EQ(0u, osContext->getOfflineDumpContextId(0)); + delete osContext; +} + struct DeferredOsContextCreationTests : ::testing::Test { void SetUp() override { device = std::unique_ptr{MockDevice::createWithNewExecutionEnvironment(defaultHwInfo.get())}; diff --git a/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp b/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp index 17c12eadeb..b656e77f74 100644 --- a/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp @@ -69,6 +69,11 @@ TEST_F(OsContextWinTest, givenReinitializeContextWhenContextIsNotInitThenContext EXPECT_NO_THROW(osContext->ensureContextInitialized()); } +TEST_F(OsContextWinTest, givenOsContextWinWhenQueryingForOfflineDumpContextIdThenCorrectValueIsReturned) { + osContext = std::make_unique(*osInterface->getDriverModel()->as(), 0, 0u, EngineDescriptorHelper::getDefaultDescriptor(engineTypeUsage, preemptionMode)); + EXPECT_EQ(0u, osContext->getOfflineDumpContextId(0)); +} + struct OsContextWinTestNoCleanup : public WddmTestWithMockGdiDllNoCleanup { void SetUp() override { WddmTestWithMockGdiDllNoCleanup::SetUp();