fix: create VMs with correct flags when perContextVms used

Related-To: NEO-7813

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2023-03-17 11:50:23 +00:00
committed by Compute-Runtime-Automation
parent 322c89cd1e
commit d8f99161dd
8 changed files with 112 additions and 27 deletions

View File

@@ -107,7 +107,7 @@ class Drm : public DriverModel {
return adapterBDF;
}
int queryAdapterBDF();
int createDrmVirtualMemory(uint32_t &drmVmId);
MOCKABLE_VIRTUAL int createDrmVirtualMemory(uint32_t &drmVmId);
void destroyDrmVirtualMemory(uint32_t drmVmId);
MOCKABLE_VIRTUAL int createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bool isCooperativeContextRequested);
void destroyDrmContext(uint32_t drmContextId);

View File

@@ -49,21 +49,26 @@ bool OsContextLinux::initializeContext() {
for (auto deviceIndex = 0u; deviceIndex < deviceBitfield.size(); deviceIndex++) {
if (deviceBitfield.test(deviceIndex)) {
auto drmVmId = drm.getVirtualMemoryAddressSpace(deviceIndex);
if (drm.isPerContextVMRequired()) {
drmVmId = deviceIndex;
[[maybe_unused]] auto ret = drm.createDrmVirtualMemory(drmVmId);
DEBUG_BREAK_IF(drmVmId == 0);
DEBUG_BREAK_IF(ret != 0);
if (ret != 0) {
return false;
}
UNRECOVERABLE_IF(this->drmVmIds.size() <= deviceIndex);
this->drmVmIds[deviceIndex] = drmVmId;
}
auto drmContextId = drm.getIoctlHelper()->createDrmContext(drm, *this, drmVmId, deviceIndex);
if (drmContextId < 0) {
return false;
}
this->drmContextIds.push_back(drmContextId);
if (drm.isPerContextVMRequired()) {
[[maybe_unused]] auto ret = drm.queryVmId(drmContextId, drmVmId);
DEBUG_BREAK_IF(drmVmId == 0);
DEBUG_BREAK_IF(ret != 0);
UNRECOVERABLE_IF(this->drmVmIds.size() <= deviceIndex);
this->drmVmIds[deviceIndex] = drmVmId;
}
}
}
return true;

View File

@@ -121,6 +121,11 @@ class DrmMock : public Drm {
return 0;
}
int createDrmVirtualMemory(uint32_t &drmVmId) override {
createDrmVmCalled++;
return Drm::createDrmVirtualMemory(drmVmId);
}
bool isVmBindAvailable() override {
if (callBaseIsVmBindAvailable) {
return Drm::isVmBindAvailable();
@@ -201,6 +206,7 @@ class DrmMock : public Drm {
GemContextParam receivedContextParamRequest = {};
uint64_t receivedRecoverableContextValue = std::numeric_limits<uint64_t>::max();
uint64_t requestSetVmId = std::numeric_limits<uint64_t>::max();
int createDrmVmCalled = 0;
bool queryPageFaultSupportCalled = false;

View File

@@ -392,8 +392,10 @@ TEST(DrmBufferObject, givenDrmIoctlReturnsErrorNotSupportedThenBufferObjectRetur
executionEnvironment->calculateMaxOsContextCount();
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
DrmMockReturnErrorNotSupported *drm = new DrmMockReturnErrorNotSupported(*executionEnvironment->rootDeviceEnvironments[0]);
DrmMock *drm = new DrmMock(*executionEnvironment->rootDeviceEnvironments[0]);
drm->execBufferResult = -1;
drm->errnoRetVal = EOPNOTSUPP;
drm->baseErrno = false;
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, 0u);
@@ -463,6 +465,7 @@ TEST(DrmBufferObject, givenPrintBOBindingResultWhenBOBindAndUnbindSucceedsThenPr
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
auto drm = new DrmMockToSucceedBindBufferObject(*executionEnvironment->rootDeviceEnvironments[0]);
drm->latestCreatedVmId = 1;
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, 0u);
@@ -484,15 +487,18 @@ TEST(DrmBufferObject, givenPrintBOBindingResultWhenBOBindAndUnbindSucceedsThenPr
EXPECT_TRUE(bo.bindInfo[contextId][0]);
std::string bindOutput = testing::internal::GetCapturedStdout();
EXPECT_STREQ(bindOutput.c_str(), "bind BO-0 to VM 0, drmVmId = 1, range: 0 - 0, size: 0, result: 0\n");
std::stringstream expected;
expected << "bind BO-0 to VM 0, drmVmId = " << drm->latestCreatedVmId << ", range: 0 - 0, size: 0, result: 0\n";
EXPECT_STREQ(bindOutput.c_str(), expected.str().c_str()) << bindOutput;
expected.str("");
testing::internal::CaptureStdout();
bo.unbind(osContext, 0);
EXPECT_FALSE(bo.bindInfo[contextId][0]);
std::string unbindOutput = testing::internal::GetCapturedStdout();
EXPECT_STREQ(unbindOutput.c_str(), "unbind BO-0 from VM 0, drmVmId = 1, range: 0 - 0, size: 0, result: 0\n");
expected << "unbind BO-0 from VM 0, drmVmId = " << drm->latestCreatedVmId << ", range: 0 - 0, size: 0, result: 0\n";
EXPECT_STREQ(unbindOutput.c_str(), expected.str().c_str()) << unbindOutput;
}
TEST(DrmBufferObject, givenPrintBOBindingResultWhenBOBindAndUnbindFailsThenPrintDebugInformationAboutBOBindingResultWithErrno) {
@@ -516,6 +522,7 @@ TEST(DrmBufferObject, givenPrintBOBindingResultWhenBOBindAndUnbindFailsThenPrint
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
auto drm = new DrmMockToFailBindBufferObject(*executionEnvironment->rootDeviceEnvironments[0]);
drm->latestCreatedVmId = 1;
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, 0u);
@@ -537,8 +544,10 @@ TEST(DrmBufferObject, givenPrintBOBindingResultWhenBOBindAndUnbindFailsThenPrint
EXPECT_FALSE(bo.bindInfo[contextId][0]);
std::string bindOutput = testing::internal::GetCapturedStderr();
EXPECT_TRUE(hasSubstr(bindOutput, "bind BO-0 to VM 0, drmVmId = 1, range: 0 - 0, size: 0, result: -1, errno: 22"));
std::stringstream expected;
expected << "bind BO-0 to VM 0, drmVmId = " << drm->latestCreatedVmId << ", range: 0 - 0, size: 0, result: -1, errno: 22\n";
EXPECT_TRUE(hasSubstr(expected.str(), expected.str())) << bindOutput;
expected.str("");
testing::internal::CaptureStderr();
bo.bindInfo[contextId][0] = true;
@@ -546,7 +555,8 @@ TEST(DrmBufferObject, givenPrintBOBindingResultWhenBOBindAndUnbindFailsThenPrint
EXPECT_TRUE(bo.bindInfo[contextId][0]);
std::string unbindOutput = testing::internal::GetCapturedStderr();
EXPECT_TRUE(hasSubstr(unbindOutput, "unbind BO-0 from VM 0, drmVmId = 1, range: 0 - 0, size: 0, result: -1, errno: 22"));
expected << "unbind BO-0 from VM 0, drmVmId = " << drm->latestCreatedVmId << ", range: 0 - 0, size: 0, result: -1, errno: 22";
EXPECT_TRUE(hasSubstr(unbindOutput, expected.str())) << unbindOutput;
}
TEST(DrmBufferObject, whenBindExtHandleAddedThenItIsStored) {

View File

@@ -356,7 +356,7 @@ TEST(DrmPrelimTest, givenProgramDebuggingAndContextDebugAvailableAndCCSEnginesWh
EXPECT_EQ(0u, drm->passedContextDebugId);
if (executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled > 0) {
EXPECT_EQ(4u, drm->receivedContextParamRequestCount);
EXPECT_EQ(3u, drm->receivedContextParamRequestCount);
EXPECT_EQ(1u, drm->context.receivedContextCreateExtSetParamRunaloneCount);
} else {
EXPECT_EQ(3u, drm->receivedContextParamRequestCount);

View File

@@ -427,6 +427,23 @@ TEST(DrmBufferObjectTestPrelim, givenPageFaultSupportedWhenVmBindIsAvailableThen
}
}
TEST(DrmBufferObjectTestPrelim, givenContextWhenQueryingVmIdThenIoctlIsCalled) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
executionEnvironment->initializeMemoryManager();
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
BufferObjectMock bo(&drm, 3, 1, 0, 1);
OsContextLinux osContext(drm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor());
osContext.ensureContextInitialized();
uint32_t vmId = 0;
drm.storedRetValForVmId = 10;
drm.queryVmId(0, vmId);
EXPECT_EQ(static_cast<uint64_t>(I915_CONTEXT_PARAM_VM), drm.receivedContextParamRequest.param);
EXPECT_EQ(static_cast<uint32_t>(drm.storedRetValForVmId), vmId);
}
TEST(DrmBufferObjectTestPrelim, givenBufferObjectMarkedForCaptureWhenBindingThenCaptureFlagIsSet) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->rootDeviceEnvironments[0]->initGmm();

View File

@@ -681,7 +681,7 @@ TEST(DrmTest, givenDrmWithPerContextVMRequiredWhenCreatingOsContextsThenImplicit
osContext2.ensureContextInitialized();
}
TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsThenImplicitVmIdPerContextIsQueriedAndStored) {
TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsThenExplicitVmIsCreated) {
MockExecutionEnvironment executionEnvironment{};
auto &rootEnv = *executionEnvironment.rootDeviceEnvironments[0];
rootEnv.executionEnvironment.setDebuggingMode(NEO::DebuggingMode::Online);
@@ -698,10 +698,32 @@ TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsThenImplicitVmIdPer
auto &drmVmIds = osContext.getDrmVmIds();
EXPECT_EQ(4u, drmVmIds.size());
EXPECT_EQ(20u, drmVmIds[0]);
EXPECT_NE(20u, drmVmIds[0]);
EXPECT_EQ(1, drmMock.ioctlCount.gemVmCreate);
EXPECT_EQ(0u, drmMock.receivedGemVmControl.vmId);
EXPECT_EQ(drmMock.latestCreatedVmId, drmVmIds[0]);
EXPECT_EQ(1, drmMock.createDrmVmCalled);
}
TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextForSubDeviceThenImplicitVmIdPerContextIsQueriedAndStoredAtSubDeviceIndex) {
TEST(DrmTest, givenPerContextVMRequiredWhenVmIdCreationFailsThenContextInitializationReturnsFalse) {
MockExecutionEnvironment executionEnvironment{};
auto &rootEnv = *executionEnvironment.rootDeviceEnvironments[0];
DrmMock drmMock(rootEnv);
drmMock.setPerContextVMRequired(true);
drmMock.storedRetValForVmCreate = -1;
OsContextLinux osContext(drmMock, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor());
drmMock.createDrmVmCalled = 0;
auto status = osContext.ensureContextInitialized();
EXPECT_EQ(1, drmMock.createDrmVmCalled);
EXPECT_FALSE(status);
}
TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextForSubDeviceThenVmIdPerContextIsCreateddAndStoredAtSubDeviceIndex) {
MockExecutionEnvironment executionEnvironment{};
auto &rootEnv = *executionEnvironment.rootDeviceEnvironments[0];
rootEnv.executionEnvironment.setDebuggingMode(NEO::DebuggingMode::Online);
@@ -719,13 +741,13 @@ TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextForSubDeviceThenImpl
auto &drmVmIds = osContext.getDrmVmIds();
EXPECT_EQ(4u, drmVmIds.size());
EXPECT_EQ(4u, drmVmIds[3]);
EXPECT_EQ(drmMock.latestCreatedVmId, drmVmIds[3]);
EXPECT_EQ(0u, drmVmIds[0]);
EXPECT_EQ(0u, drmVmIds[2]);
}
TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsForRootDeviceThenImplicitVmIdsPerContextAreQueriedAndStoredAtSubDeviceIndices) {
TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsForRootDeviceThenVmIdsPerContextAreCreatedAndStoredAtSubDeviceIndices) {
MockExecutionEnvironment executionEnvironment{};
auto &rootEnv = *executionEnvironment.rootDeviceEnvironments[0];
rootEnv.executionEnvironment.setDebuggingMode(NEO::DebuggingMode::Online);
@@ -743,8 +765,8 @@ TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsForRootDeviceThenIm
auto &drmVmIds = osContext.getDrmVmIds();
EXPECT_EQ(4u, drmVmIds.size());
EXPECT_EQ(4u, drmVmIds[0]);
EXPECT_EQ(4u, drmVmIds[1]);
EXPECT_EQ(drmMock.latestCreatedVmId - 1, drmVmIds[0]);
EXPECT_EQ(drmMock.latestCreatedVmId, drmVmIds[1]);
EXPECT_EQ(0u, drmVmIds[2]);
}

View File

@@ -509,7 +509,6 @@ TEST_F(IoctlHelperPrelimFixture, givenProgramDebuggingAndContextDebugSupportedWh
if (executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled > 0) {
EXPECT_TRUE(drm->capturedCooperativeContextRequest);
} else {
EXPECT_FALSE(drm->capturedCooperativeContextRequest);
}
OsContextLinux osContext2(*drm, 0, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::Cooperative}));
@@ -519,6 +518,32 @@ TEST_F(IoctlHelperPrelimFixture, givenProgramDebuggingAndContextDebugSupportedWh
EXPECT_TRUE(drm->capturedCooperativeContextRequest);
}
TEST(IoctlHelperPrelimTest, givenProgramDebuggingAndContextDebugSupportedWhenInitializingContextThenVmIsCreatedWithAllNecessaryFlags) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->setDebuggingMode(NEO::DebuggingMode::Online);
auto drm = std::make_unique<DrmPrelimMock>(*executionEnvironment->rootDeviceEnvironments[0]);
drm->ioctlHelper = std::make_unique<IoctlHelperPrelim20>(*drm);
drm->contextDebugSupported = true;
drm->callBaseCreateDrmContext = false;
drm->bindAvailable = true;
drm->setPerContextVMRequired(true);
executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo()->platform.eProductFamily = defaultHwInfo->platform.eProductFamily;
OsContextLinux osContext(*drm, 0, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::Regular}));
osContext.ensureContextInitialized();
EXPECT_FALSE(drm->receivedGemVmControl.flags & PRELIM_I915_VM_CREATE_FLAGS_DISABLE_SCRATCH);
EXPECT_TRUE(drm->receivedGemVmControl.flags & PRELIM_I915_VM_CREATE_FLAGS_USE_VM_BIND);
if (drm->hasPageFaultSupport()) {
EXPECT_TRUE(drm->receivedGemVmControl.flags & PRELIM_I915_VM_CREATE_FLAGS_ENABLE_PAGE_FAULT);
} else {
EXPECT_FALSE(drm->receivedGemVmControl.flags & PRELIM_I915_VM_CREATE_FLAGS_ENABLE_PAGE_FAULT);
}
EXPECT_EQ(1, drm->createDrmVmCalled);
}
TEST_F(IoctlHelperPrelimFixture, givenIoctlHelperWhenInitializatedThenIpVersionIsSet) {
auto &ipVersion = executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo()->ipVersion;
ipVersion = {};