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 <fabian.zwolinski@intel.com>
This commit is contained in:
Fabian Zwolinski 2023-03-31 11:41:17 +00:00 committed by Compute-Runtime-Automation
parent 53fe4de534
commit fd971f7a61
9 changed files with 71 additions and 2 deletions

View File

@ -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<uint64_t>(processId) << 32 |
static_cast<uint64_t>(drmContextId);
}
return 0;
}
OsContextLinux::~OsContextLinux() {
if (contextInitialized) {
for (auto drmContextId : drmContextIds) {

View File

@ -50,6 +50,8 @@ class OsContextLinux : public OsContext {
return contextHangDetected;
}
uint64_t getOfflineDumpContextId(uint32_t deviceIndex) const override;
protected:
bool initializeContext() override;

View File

@ -22,7 +22,8 @@ namespace NEO {
namespace SysCalls {
unsigned int getProcessId() {
return getpid();
static unsigned int pid = getpid();
return pid;
}
unsigned long getNumThreads() {

View File

@ -27,6 +27,7 @@ class OsContext : public ReferenceTrackedObject<OsContext> {
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; }

View File

@ -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);

View File

@ -37,6 +37,7 @@ class OsContextWin : public OsContext {
void reInitializeContext() override;
void getDeviceLuidArray(std::vector<uint8_t> &luidData, size_t arraySize);
uint32_t getDeviceNodeMask();
uint64_t getOfflineDumpContextId(uint32_t deviceIndex) const override;
protected:
bool initializeContext() override;

View File

@ -37,3 +37,41 @@ TEST(OSContextLinux, givenInitializeContextWhenContextCreateIoctlFailsThenContex
EXPECT_EQ(false, osContext.ensureContextInitialized());
delete pDrm;
}
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<DrmMockCustom> 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<uint64_t>(1u));
EXPECT_EQ(ctxId & highBitsMask, static_cast<uint64_t>(processId) << 32);
ctxId = osContext.getOfflineDumpContextId(1);
EXPECT_EQ(ctxId & lowBitsMask, static_cast<uint64_t>(3u));
EXPECT_EQ(ctxId & highBitsMask, static_cast<uint64_t>(processId) << 32);
ctxId = osContext.getOfflineDumpContextId(2);
EXPECT_EQ(ctxId & lowBitsMask, static_cast<uint64_t>(5u));
EXPECT_EQ(ctxId & highBitsMask, static_cast<uint64_t>(processId) << 32);
EXPECT_EQ(0u, osContext.getOfflineDumpContextId(10));
}

View File

@ -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>{MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get())};

View File

@ -69,6 +69,11 @@ TEST_F(OsContextWinTest, givenReinitializeContextWhenContextIsNotInitThenContext
EXPECT_NO_THROW(osContext->ensureContextInitialized());
}
TEST_F(OsContextWinTest, givenOsContextWinWhenQueryingForOfflineDumpContextIdThenCorrectValueIsReturned) {
osContext = std::make_unique<OsContextWin>(*osInterface->getDriverModel()->as<Wddm>(), 0, 0u, EngineDescriptorHelper::getDefaultDescriptor(engineTypeUsage, preemptionMode));
EXPECT_EQ(0u, osContext->getOfflineDumpContextId(0));
}
struct OsContextWinTestNoCleanup : public WddmTestWithMockGdiDllNoCleanup {
void SetUp() override {
WddmTestWithMockGdiDllNoCleanup::SetUp();