diff --git a/opencl/source/os_interface/linux/drm_command_stream.inl b/opencl/source/os_interface/linux/drm_command_stream.inl index 99259ad98e..21700f4557 100644 --- a/opencl/source/os_interface/linux/drm_command_stream.inl +++ b/opencl/source/os_interface/linux/drm_command_stream.inl @@ -110,6 +110,7 @@ void DrmCommandStreamReceiver::exec(const BatchBuffer &batchBuffer, u int err = bb->exec(static_cast(alignUp(batchBuffer.usedSize - batchBuffer.startOffset, 8)), batchBuffer.startOffset, execFlags, batchBuffer.requiresCoherency, + this->osContext, vmHandleId, drmContextId, this->residency.data(), this->residency.size(), @@ -123,7 +124,7 @@ template void DrmCommandStreamReceiver::processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) { for (auto &alloc : inputAllocationsForResidency) { auto drmAlloc = static_cast(alloc); - drmAlloc->makeBOsResident(osContext->getContextId(), handleId, &this->residency, false); + drmAlloc->makeBOsResident(osContext, handleId, &this->residency, false); } } diff --git a/opencl/test/unit_test/mocks/linux/mock_drm_allocation.h b/opencl/test/unit_test/mocks/linux/mock_drm_allocation.h index d3acd5b800..d04c94adc9 100644 --- a/opencl/test/unit_test/mocks/linux/mock_drm_allocation.h +++ b/opencl/test/unit_test/mocks/linux/mock_drm_allocation.h @@ -13,9 +13,10 @@ namespace NEO { class MockBufferObject : public BufferObject { public: + using BufferObject::bindInfo; using BufferObject::handle; - MockBufferObject() : BufferObject(nullptr, 0, 0) { + MockBufferObject(Drm *drm) : BufferObject(drm, 0, 0) { } }; diff --git a/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp index c282002d77..a5ca77cbd6 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp @@ -6,9 +6,15 @@ */ #include "shared/source/os_interface/linux/drm_buffer_object.h" +#include "shared/source/os_interface/linux/drm_memory_operations_handler_default.h" +#include "shared/source/os_interface/linux/os_context_linux.h" +#include "shared/source/os_interface/linux/os_interface.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" +#include "shared/test/unit_test/mocks/mock_device.h" +#include "opencl/test/unit_test/mocks/linux/mock_drm_allocation.h" #include "opencl/test/unit_test/os_interface/linux/device_command_stream_fixture.h" +#include "opencl/test/unit_test/os_interface/linux/drm_mock.h" #include "test.h" #include "drm/i915_drm.h" @@ -26,8 +32,8 @@ class TestedBufferObject : public BufferObject { this->tiling_mode = mode; } - void fillExecObject(drm_i915_gem_exec_object2 &execObject, uint32_t vmHandleId, uint32_t drmContextId) override { - BufferObject::fillExecObject(execObject, vmHandleId, drmContextId); + void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override { + BufferObject::fillExecObject(execObject, osContext, vmHandleId, drmContextId); execObjectPointerFilled = &execObject; } @@ -43,10 +49,13 @@ class DrmBufferObjectFixture { std::unique_ptr mock; TestedBufferObject *bo; drm_i915_gem_exec_object2 execObjectsStorage[256]; + std::unique_ptr osContext; void SetUp() { this->mock = std::make_unique(); ASSERT_NE(nullptr, this->mock); + osContext.reset(new OsContextLinux(*this->mock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false, false, false)); + this->mock->reset(); bo = new TestedBufferObject(this->mock.get()); ASSERT_NE(nullptr, bo); } @@ -56,6 +65,9 @@ class DrmBufferObjectFixture { if (this->mock->ioctl_expected.total >= 0) { EXPECT_EQ(this->mock->ioctl_expected.total, this->mock->ioctl_cnt.total); } + mock->reset(); + osContext.reset(nullptr); + mock.reset(nullptr); } }; @@ -66,7 +78,7 @@ TEST_F(DrmBufferObjectTest, exec) { mock->ioctl_res = 0; drm_i915_gem_exec_object2 execObjectsStorage = {}; - auto ret = bo->exec(0, 0, 0, false, 0, 1, nullptr, 0u, &execObjectsStorage); + auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage); EXPECT_EQ(mock->ioctl_res, ret); EXPECT_EQ(0u, mock->execBuffer.flags); } @@ -76,7 +88,7 @@ TEST_F(DrmBufferObjectTest, exec_ioctlFailed) { mock->ioctl_res = -1; mock->errnoValue = EFAULT; drm_i915_gem_exec_object2 execObjectsStorage = {}; - EXPECT_EQ(EFAULT, bo->exec(0, 0, 0, false, 0, 1, nullptr, 0u, &execObjectsStorage)); + EXPECT_EQ(EFAULT, bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage)); } TEST_F(DrmBufferObjectTest, setTiling_success) { @@ -105,7 +117,7 @@ TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedCrosses32BitBoundaryW memset(&execObject, 0, sizeof(execObject)); bo->setAddress(((uint64_t)1u << 32) - 0x1000u); bo->setSize(0x1000); - bo->fillExecObject(execObject, 0, 1); + bo->fillExecObject(execObject, osContext.get(), 0, 1); //base address + size > size of 32bit address space EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS); } @@ -116,7 +128,7 @@ TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedWithin32BitBoundaryWh memset(&execObject, 0, sizeof(execObject)); bo->setAddress(((uint64_t)1u << 32) - 0x1000u); bo->setSize(0xFFF); - bo->fillExecObject(execObject, 0, 1); + bo->fillExecObject(execObject, osContext.get(), 0, 1); //base address + size < size of 32bit address space EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS); } @@ -133,7 +145,7 @@ TEST_F(DrmBufferObjectTest, onPinIoctlFailed) { bo->setAddress(reinterpret_cast(buff.get())); BufferObject *boArray[1] = {boToPin.get()}; - auto ret = bo->pin(boArray, 1, 0, 1); + auto ret = bo->pin(boArray, 1, osContext.get(), 0, 1); EXPECT_EQ(EINVAL, ret); } @@ -144,7 +156,7 @@ TEST_F(DrmBufferObjectTest, whenPrintExecutionBufferIsSetToTrueThenMessageFoundI drm_i915_gem_exec_object2 execObjectsStorage = {}; testing::internal::CaptureStdout(); - auto ret = bo->exec(0, 0, 0, false, 0, 1, nullptr, 0u, &execObjectsStorage); + auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage); EXPECT_EQ(0, ret); std::string output = testing::internal::GetCapturedStdout(); @@ -170,7 +182,7 @@ TEST(DrmBufferObjectSimpleTest, givenInvalidBoWhenPinIsCalledThenErrorIsReturned mock->errnoValue = EFAULT; BufferObject *boArray[1] = {boToPin.get()}; - auto ret = bo->pin(boArray, 1, 0, 1); + auto ret = bo->pin(boArray, 1, nullptr, 0, 1); EXPECT_EQ(EFAULT, ret); } @@ -185,6 +197,8 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenPinnedThenAllBosArePinned) { std::unique_ptr buff(new uint32_t[256]); std::unique_ptr mock(new DrmMockCustom); ASSERT_NE(nullptr, mock.get()); + OsContextLinux osContext(*mock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false, false, false); + std::unique_ptr bo(new TestedBufferObject(mock.get())); ASSERT_NE(nullptr, bo.get()); mock->ioctl_res = 0; @@ -200,7 +214,7 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenPinnedThenAllBosArePinned) { BufferObject *array[3] = {boToPin.get(), boToPin2.get(), boToPin3.get()}; bo->setAddress(reinterpret_cast(buff.get())); - auto ret = bo->pin(array, 3, 0, 1); + auto ret = bo->pin(array, 3, &osContext, 0, 1); EXPECT_EQ(mock->ioctl_res, ret); EXPECT_LT(0u, mock->execBuffer.batch_len); @@ -224,3 +238,51 @@ TEST_F(DrmBufferObjectTest, givenDeleterWhenBufferObjectIsCreatedAndDeletedThenC mock->ioctl_cnt.reset(); mock->ioctl_expected.reset(); } + +TEST(DrmBufferObject, givenPerContextVmRequiredWhenBoCreatedThenBindInfoIsInitializedToOsContextCount) { + auto device = std::unique_ptr(MockDevice::createWithNewExecutionEnvironment(nullptr)); + device->getRootDeviceEnvironment().executionEnvironment.setPerContextMemorySpace(); + + DrmMock drm(*(device->getExecutionEnvironment()->rootDeviceEnvironments[0].get())); + EXPECT_TRUE(drm.isPerContextVMRequired()); + MockBufferObject bo(&drm); + + auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount(); + EXPECT_EQ(osContextCount, bo.bindInfo.size()); + + for (auto &iter : bo.bindInfo) { + for (uint32_t i = 0; i < EngineLimits::maxHandleCount; i++) { + EXPECT_FALSE(iter[i]); + } + } +} + +TEST(DrmBufferObject, givenPerContextVmRequiredWhenBoBoundAndUnboundThenCorrectBindInfoIsUpdated) { + auto executionEnvironment = new ExecutionEnvironment; + executionEnvironment->setPerContextMemorySpace(); + executionEnvironment->prepareRootDeviceEnvironments(1); + executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(defaultHwInfo.get()); + executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique(); + executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(); + + DrmMockNonFailing *drm = new DrmMockNonFailing(*executionEnvironment->rootDeviceEnvironments[0]); + EXPECT_TRUE(drm->isPerContextVMRequired()); + + executionEnvironment->rootDeviceEnvironments[0]->osInterface->get()->setDrm(drm); + + std::unique_ptr device(MockDevice::createWithExecutionEnvironment(defaultHwInfo.get(), executionEnvironment, 0)); + + MockBufferObject bo(drm); + + auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount(); + EXPECT_EQ(osContextCount, bo.bindInfo.size()); + + auto contextId = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount() / 2; + auto osContext = device->getExecutionEnvironment()->memoryManager->getRegisteredEngines()[contextId].osContext; + + bo.bind(osContext, 0); + EXPECT_TRUE(bo.bindInfo[contextId][0]); + + bo.unbind(osContext, 0); + EXPECT_FALSE(bo.bindInfo[contextId][0]); +} \ No newline at end of file diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h b/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h index b774f5566e..8bca35e321 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h @@ -127,8 +127,8 @@ class DrmCommandStreamEnhancedTemplate : public ::testing::Test { } template - void makeResidentBufferObjects(DrmAllocation *drmAllocation) { - drmAllocation->bindBOs(0u, &static_cast *>(csr)->residency, false); + void makeResidentBufferObjects(OsContext *osContext, DrmAllocation *drmAllocation) { + drmAllocation->bindBOs(osContext, 0u, &static_cast *>(csr)->residency, false); } template diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp index 4ec0f478ed..df2fcd1a1a 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp @@ -1486,7 +1486,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenAllocationWithSingleBuffer auto allocation = new DrmAllocation(0, GraphicsAllocation::AllocationType::UNKNOWN, bos, nullptr, 0u, size, MemoryPool::LocalMemory); EXPECT_EQ(bo, allocation->getBO()); - makeResidentBufferObjects(allocation); + makeResidentBufferObjects(&csr->getOsContext(), allocation); EXPECT_TRUE(isResident(bo)); mm->freeGraphicsMemory(allocation); diff --git a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index e4c064bb20..f4a5472748 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -2984,7 +2984,7 @@ TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenDisabledForcePinAndEna PinBufferObject(Drm *drm) : BufferObject(drm, 1, 0) { } - int pin(BufferObject *const boToPin[], size_t numberOfBos, uint32_t vmHandleId, uint32_t drmContextId) override { + int pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override { for (size_t i = 0; i < numberOfBos; i++) { pinnedBoArray[i] = boToPin[i]; } diff --git a/opencl/test/unit_test/os_interface/linux/drm_mock.h b/opencl/test/unit_test/os_interface/linux/drm_mock.h index ddc05dbe13..88d2f56eb1 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_mock.h +++ b/opencl/test/unit_test/os_interface/linux/drm_mock.h @@ -140,3 +140,9 @@ class DrmMock : public Drm { virtual int handleRemainingRequests(unsigned long request, void *arg) { return -1; } }; + +class DrmMockNonFailing : public DrmMock { + public: + using DrmMock::DrmMock; + int handleRemainingRequests(unsigned long request, void *arg) override { return 0; } +}; diff --git a/opencl/test/unit_test/os_interface/linux/file_logger_linux_tests.cpp b/opencl/test/unit_test/os_interface/linux/file_logger_linux_tests.cpp index 1a11f9ad70..6b5d57dfc6 100644 --- a/opencl/test/unit_test/os_interface/linux/file_logger_linux_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/file_logger_linux_tests.cpp @@ -8,6 +8,7 @@ #include "shared/source/debug_settings/debug_settings_manager.h" #include "opencl/test/unit_test/mocks/linux/mock_drm_allocation.h" +#include "opencl/test/unit_test/os_interface/linux/drm_mock.h" #include "opencl/test/unit_test/utilities/file_logger_tests.h" #include "test.h" @@ -22,10 +23,10 @@ TEST(FileLogger, GivenLogAllocationMemoryPoolFlagThenLogsCorrectInfo) { // Log file not created bool logFileCreated = fileExists(fileLogger.getLogFileName()); EXPECT_FALSE(logFileCreated); - + DrmMock drm{}; MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::System64KBPages); - MockBufferObject bo; + MockBufferObject bo(&drm); bo.handle = 4; allocation.bufferObjects[0] = &bo; diff --git a/shared/source/direct_submission/linux/drm_direct_submission.inl b/shared/source/direct_submission/linux/drm_direct_submission.inl index c1a64e927b..9896ea9234 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.inl +++ b/shared/source/direct_submission/linux/drm_direct_submission.inl @@ -61,6 +61,7 @@ bool DrmDirectSubmission::submit(uint64_t gpuAddress, siz 0, execFlags, false, + &this->osContext, drmIterator, drmContextIds[drmIterator], nullptr, diff --git a/shared/source/os_interface/linux/drm_allocation.cpp b/shared/source/os_interface/linux/drm_allocation.cpp index 8adf307d3e..c22e7c2712 100644 --- a/shared/source/os_interface/linux/drm_allocation.cpp +++ b/shared/source/os_interface/linux/drm_allocation.cpp @@ -10,6 +10,7 @@ #include "shared/source/memory_manager/residency.h" #include "shared/source/os_interface/linux/drm_buffer_object.h" #include "shared/source/os_interface/linux/drm_memory_manager.h" +#include "shared/source/os_interface/os_context.h" #include @@ -28,20 +29,20 @@ uint64_t DrmAllocation::peekInternalHandle(MemoryManager *memoryManager) { return static_cast((static_cast(memoryManager))->obtainFdFromHandle(getBO()->peekHandle(), this->rootDeviceIndex)); } -void DrmAllocation::makeBOsResident(uint32_t osContextId, uint32_t vmHandleId, std::vector *bufferObjects, bool bind) { +void DrmAllocation::makeBOsResident(OsContext *osContext, uint32_t vmHandleId, std::vector *bufferObjects, bool bind) { if (this->fragmentsStorage.fragmentCount) { for (unsigned int f = 0; f < this->fragmentsStorage.fragmentCount; f++) { - if (!this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContextId]) { - bindBO(this->fragmentsStorage.fragmentStorageData[f].osHandleStorage->bo, vmHandleId, bufferObjects, bind); - this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContextId] = true; + if (!this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContext->getContextId()]) { + bindBO(this->fragmentsStorage.fragmentStorageData[f].osHandleStorage->bo, osContext, vmHandleId, bufferObjects, bind); + this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContext->getContextId()] = true; } } } else { - bindBOs(vmHandleId, bufferObjects, bind); + bindBOs(osContext, vmHandleId, bufferObjects, bind); } } -void DrmAllocation::bindBO(BufferObject *bo, uint32_t vmHandleId, std::vector *bufferObjects, bool bind) { +void DrmAllocation::bindBO(BufferObject *bo, OsContext *osContext, uint32_t vmHandleId, std::vector *bufferObjects, bool bind) { if (bo) { if (bufferObjects) { if (bo->peekIsReusableAllocation()) { @@ -56,9 +57,9 @@ void DrmAllocation::bindBO(BufferObject *bo, uint32_t vmHandleId, std::vectorbind(vmHandleId); + bo->bind(osContext, vmHandleId); } else { - bo->unbind(vmHandleId); + bo->unbind(osContext, vmHandleId); } } } diff --git a/shared/source/os_interface/linux/drm_allocation.h b/shared/source/os_interface/linux/drm_allocation.h index 2901b302dc..d2765d4842 100644 --- a/shared/source/os_interface/linux/drm_allocation.h +++ b/shared/source/os_interface/linux/drm_allocation.h @@ -10,6 +10,7 @@ namespace NEO { class BufferObject; +class OsContext; struct OsHandle { BufferObject *bo = nullptr; @@ -60,9 +61,9 @@ class DrmAllocation : public GraphicsAllocation { uint64_t peekInternalHandle(MemoryManager *memoryManager) override; - void makeBOsResident(uint32_t osContextId, uint32_t vmHandleId, std::vector *bufferObjects, bool bind); - void bindBO(BufferObject *bo, uint32_t vmHandleId, std::vector *bufferObjects, bool bind); - void bindBOs(uint32_t vmHandleId, std::vector *bufferObjects, bool bind); + void makeBOsResident(OsContext *osContext, uint32_t vmHandleId, std::vector *bufferObjects, bool bind); + void bindBO(BufferObject *bo, OsContext *osContext, uint32_t vmHandleId, std::vector *bufferObjects, bool bind); + void bindBOs(OsContext *osContext, uint32_t vmHandleId, std::vector *bufferObjects, bool bind); protected: BufferObjects bufferObjects{}; diff --git a/shared/source/os_interface/linux/drm_allocation_extended.cpp b/shared/source/os_interface/linux/drm_allocation_extended.cpp index 9e8840f82b..3e2cf16a6a 100644 --- a/shared/source/os_interface/linux/drm_allocation_extended.cpp +++ b/shared/source/os_interface/linux/drm_allocation_extended.cpp @@ -7,12 +7,13 @@ #include "shared/source/os_interface/linux/drm_allocation.h" #include "shared/source/os_interface/linux/drm_buffer_object.h" +#include "shared/source/os_interface/os_context.h" namespace NEO { -void DrmAllocation::bindBOs(uint32_t vmHandleId, std::vector *bufferObjects, bool bind) { +void DrmAllocation::bindBOs(OsContext *osContext, uint32_t vmHandleId, std::vector *bufferObjects, bool bind) { auto bo = this->getBO(); - bindBO(bo, vmHandleId, bufferObjects, bind); + bindBO(bo, osContext, vmHandleId, bufferObjects, bind); } } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_buffer_object.cpp b/shared/source/os_interface/linux/drm_buffer_object.cpp index 2e5c463e7e..aadc33f4c7 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.cpp +++ b/shared/source/os_interface/linux/drm_buffer_object.cpp @@ -12,6 +12,7 @@ #include "shared/source/os_interface/linux/drm_memory_manager.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/source/os_interface/linux/os_time_linux.h" +#include "shared/source/os_interface/os_context.h" #include "shared/source/utilities/stackvec.h" #include "drm/i915_drm.h" @@ -32,7 +33,18 @@ namespace NEO { BufferObject::BufferObject(Drm *drm, int handle, size_t size) : drm(drm), refCount(1), handle(handle), size(size), isReused(false) { this->tiling_mode = I915_TILING_NONE; this->lockedAddress = nullptr; - bindInfo.fill(false); + + perContextVmsUsed = drm->isPerContextVMRequired(); + + if (perContextVmsUsed) { + bindInfo.resize(MemoryManager::maxOsContextCount); + for (auto &iter : bindInfo) { + iter.fill(false); + } + } else { + bindInfo.resize(1); + bindInfo[0].fill(false); + } } uint32_t BufferObject::getRefCount() const { @@ -90,7 +102,7 @@ bool BufferObject::setTiling(uint32_t mode, uint32_t stride) { return set_tiling.tiling_mode == mode; } -void BufferObject::fillExecObject(drm_i915_gem_exec_object2 &execObject, uint32_t vmHandleId, uint32_t drmContextId) { +void BufferObject::fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) { execObject.handle = this->handle; execObject.relocation_count = 0; //No relocations, we are SoftPinning execObject.relocs_ptr = 0ul; @@ -100,14 +112,14 @@ void BufferObject::fillExecObject(drm_i915_gem_exec_object2 &execObject, uint32_ execObject.rsvd1 = drmContextId; execObject.rsvd2 = 0; - this->fillExecObjectImpl(execObject, vmHandleId); + this->fillExecObjectImpl(execObject, osContext, vmHandleId); } -int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, uint32_t vmHandleId, uint32_t drmContextId, BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage) { +int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage) { for (size_t i = 0; i < residencyCount; i++) { - residency[i]->fillExecObject(execObjectsStorage[i], vmHandleId, drmContextId); + residency[i]->fillExecObject(execObjectsStorage[i], osContext, vmHandleId, drmContextId); } - this->fillExecObject(execObjectsStorage[residencyCount], vmHandleId, drmContextId); + this->fillExecObject(execObjectsStorage[residencyCount], osContext, vmHandleId, drmContextId); drm_i915_gem_execbuffer2 execbuf{}; execbuf.buffers_ptr = reinterpret_cast(execObjectsStorage); @@ -131,23 +143,25 @@ int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bo return err; } -void BufferObject::bind(uint32_t vmHandleId) { - if (!this->bindInfo[vmHandleId]) { - auto ret = this->drm->bindBufferObject(vmHandleId, this); +void BufferObject::bind(OsContext *osContext, uint32_t vmHandleId) { + auto contextId = perContextVmsUsed ? osContext->getContextId() : 0; + if (!this->bindInfo[contextId][vmHandleId]) { + auto ret = this->drm->bindBufferObject(osContext, vmHandleId, this); auto err = this->drm->getErrno(); printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "bind buffer object returned with %d. errno=%d(%s)\n", ret, err, strerror(err)); UNRECOVERABLE_IF(ret != 0); - this->bindInfo[vmHandleId] = true; + this->bindInfo[contextId][vmHandleId] = true; } } -void BufferObject::unbind(uint32_t vmHandleId) { - if (this->bindInfo[vmHandleId]) { - auto ret = this->drm->unbindBufferObject(vmHandleId, this); +void BufferObject::unbind(OsContext *osContext, uint32_t vmHandleId) { + auto contextId = perContextVmsUsed ? osContext->getContextId() : 0; + if (this->bindInfo[contextId][vmHandleId]) { + auto ret = this->drm->unbindBufferObject(osContext, vmHandleId, this); auto err = this->drm->getErrno(); printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "unbind buffer object returned with %d. errno=%d(%s)\n", ret, err, strerror(err)); UNRECOVERABLE_IF(ret != 0); - this->bindInfo[vmHandleId] = false; + this->bindInfo[contextId][vmHandleId] = false; } } @@ -178,9 +192,9 @@ void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const std::cout << logger << std::endl; } -int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, uint32_t vmHandleId, uint32_t drmContextId) { +int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) { StackVec execObject(numberOfBos + 1); - return this->exec(4u, 0u, 0u, false, vmHandleId, drmContextId, boToPin, numberOfBos, &execObject[0]); + return this->exec(4u, 0u, 0u, false, osContext, vmHandleId, drmContextId, boToPin, numberOfBos, &execObject[0]); } } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_buffer_object.h b/shared/source/os_interface/linux/drm_buffer_object.h index d8f0ab6561..1dfc8637de 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.h +++ b/shared/source/os_interface/linux/drm_buffer_object.h @@ -14,6 +14,7 @@ #include #include #include +#include struct drm_i915_gem_exec_object2; struct drm_i915_gem_relocation_entry; @@ -22,6 +23,7 @@ namespace NEO { class DrmMemoryManager; class Drm; +class OsContext; class BufferObject { friend DrmMemoryManager; @@ -39,12 +41,12 @@ class BufferObject { bool setTiling(uint32_t mode, uint32_t stride); - MOCKABLE_VIRTUAL int pin(BufferObject *const boToPin[], size_t numberOfBos, uint32_t vmHandleId, uint32_t drmContextId); + MOCKABLE_VIRTUAL int pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId); - int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, uint32_t vmHandleId, uint32_t drmContextId, BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage); + int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage); - void bind(uint32_t vmHandleId); - void unbind(uint32_t vmHandleId); + void bind(OsContext *osContext, uint32_t vmHandleId); + void unbind(OsContext *osContext, uint32_t vmHandleId); void printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage); @@ -68,7 +70,7 @@ class BufferObject { protected: Drm *drm = nullptr; - + bool perContextVmsUsed = false; std::atomic refCount; int handle; // i915 gem object handle @@ -78,8 +80,8 @@ class BufferObject { //Tiling uint32_t tiling_mode; - MOCKABLE_VIRTUAL void fillExecObject(drm_i915_gem_exec_object2 &execObject, uint32_t vmHandleId, uint32_t drmContextId); - void fillExecObjectImpl(drm_i915_gem_exec_object2 &execObject, uint32_t vmHandleId); + MOCKABLE_VIRTUAL void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId); + void fillExecObjectImpl(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId); uint64_t gpuAddress = 0llu; @@ -87,6 +89,6 @@ class BufferObject { uint64_t unmapSize = 0; - std::array bindInfo; + std::vector> bindInfo; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_buffer_object_extended.cpp b/shared/source/os_interface/linux/drm_buffer_object_extended.cpp index 9363ad2086..7db8840c6d 100644 --- a/shared/source/os_interface/linux/drm_buffer_object_extended.cpp +++ b/shared/source/os_interface/linux/drm_buffer_object_extended.cpp @@ -9,6 +9,6 @@ namespace NEO { -void BufferObject::fillExecObjectImpl(drm_i915_gem_exec_object2 &execObject, uint32_t vmHandleId) {} +void BufferObject::fillExecObjectImpl(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId) {} } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index 6f3e5d4b28..fed051d22a 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -187,7 +187,7 @@ NEO::BufferObject *DrmMemoryManager::allocUserptr(uintptr_t address, size_t size void DrmMemoryManager::emitPinningRequest(BufferObject *bo, const AllocationData &allocationData) const { if (forcePinEnabled && pinBBs.at(allocationData.rootDeviceIndex) != nullptr && allocationData.flags.forcePin && allocationData.size >= this->pinThreshold) { - pinBBs.at(allocationData.rootDeviceIndex)->pin(&bo, 1, 0, getDefaultDrmContextId()); + pinBBs.at(allocationData.rootDeviceIndex)->pin(&bo, 1, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId()); } } @@ -282,7 +282,7 @@ GraphicsAllocation *DrmMemoryManager::allocateGraphicsMemoryWithGpuVa(const Allo BufferObject *boPtr = bo.get(); if (forcePinEnabled && pinBBs.at(allocationData.rootDeviceIndex) != nullptr && alignedSize >= this->pinThreshold) { - pinBBs.at(allocationData.rootDeviceIndex)->pin(&boPtr, 1, 0, osContextLinux->getDrmContextIds()[0]); + pinBBs.at(allocationData.rootDeviceIndex)->pin(&boPtr, 1, osContextLinux, 0, osContextLinux->getDrmContextIds()[0]); } auto allocation = new DrmAllocation(allocationData.rootDeviceIndex, allocationData.type, bo.get(), res, bo->gpuAddress, alignedSize, MemoryPool::System4KBPages); @@ -316,7 +316,7 @@ DrmAllocation *DrmMemoryManager::allocateGraphicsMemoryForNonSvmHostPtr(const Al if (validateHostPtrMemory) { auto boPtr = bo.get(); - int result = pinBBs.at(allocationData.rootDeviceIndex)->pin(&boPtr, 1, 0, getDefaultDrmContextId()); + int result = pinBBs.at(allocationData.rootDeviceIndex)->pin(&boPtr, 1, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId()); if (result != SUCCESS) { unreference(bo.release(), true); releaseGpuRange(reinterpret_cast(gpuVirtualAddress), alignedSize, allocationData.rootDeviceIndex); @@ -672,7 +672,7 @@ MemoryManager::AllocationStatus DrmMemoryManager::populateOsHandles(OsHandleStor } if (validateHostPtrMemory) { - int result = pinBBs.at(rootDeviceIndex)->pin(allocatedBos, numberOfBosAllocated, 0, getDefaultDrmContextId()); + int result = pinBBs.at(rootDeviceIndex)->pin(allocatedBos, numberOfBosAllocated, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId()); if (result == EFAULT) { for (uint32_t i = 0; i < numberOfBosAllocated; i++) { diff --git a/shared/source/os_interface/linux/drm_memory_operations_handler_bind.cpp b/shared/source/os_interface/linux/drm_memory_operations_handler_bind.cpp index ab277ecdec..5d8579d416 100644 --- a/shared/source/os_interface/linux/drm_memory_operations_handler_bind.cpp +++ b/shared/source/os_interface/linux/drm_memory_operations_handler_bind.cpp @@ -36,7 +36,7 @@ MemoryOperationsStatus DrmMemoryOperationsHandlerBind::makeResidentWithinOsConte auto drmAllocation = static_cast(*gfxAllocation); auto &drmContextIds = static_cast(osContext)->getDrmContextIds(); for (uint32_t drmIterator = 0u; drmIterator < drmContextIds.size(); drmIterator++) { - drmAllocation->makeBOsResident(osContext->getContextId(), drmIterator, nullptr, true); + drmAllocation->makeBOsResident(osContext, drmIterator, nullptr, true); } drmAllocation->updateResidencyTaskCount(GraphicsAllocation::objectAlwaysResident, osContext->getContextId()); } @@ -62,7 +62,7 @@ MemoryOperationsStatus DrmMemoryOperationsHandlerBind::evictWithinOsContext(OsCo auto drmAllocation = static_cast(&gfxAllocation); auto &drmContextIds = static_cast(osContext)->getDrmContextIds(); for (uint32_t drmIterator = 0u; drmIterator < drmContextIds.size(); drmIterator++) { - drmAllocation->makeBOsResident(osContext->getContextId(), drmIterator, nullptr, false); + drmAllocation->makeBOsResident(osContext, drmIterator, nullptr, false); } drmAllocation->updateResidencyTaskCount(GraphicsAllocation::objectNotResident, osContext->getContextId()); } @@ -92,7 +92,7 @@ void DrmMemoryOperationsHandlerBind::mergeWithResidencyContainer(OsContext *osCo auto drmAllocation = static_cast(*gfxAllocation); auto &drmContextIds = static_cast(osContext)->getDrmContextIds(); for (uint32_t drmIterator = 0u; drmIterator < drmContextIds.size(); drmIterator++) { - drmAllocation->makeBOsResident(osContext->getContextId(), drmIterator, nullptr, true); + drmAllocation->makeBOsResident(osContext, drmIterator, nullptr, true); } drmAllocation->updateResidencyTaskCount(GraphicsAllocation::objectAlwaysResident, osContext->getContextId()); gfxAllocation = residencyContainer.erase(gfxAllocation); diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 9fe201eb63..30896eb631 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -31,6 +31,7 @@ namespace NEO { class BufferObject; class DeviceFactory; +class OsContext; struct HardwareInfo; struct RootDeviceEnvironment; @@ -87,8 +88,8 @@ class Drm { bool createVirtualMemoryAddressSpace(uint32_t vmCount); void destroyVirtualMemoryAddressSpace(); uint32_t getVirtualMemoryAddressSpace(uint32_t vmId); - int bindBufferObject(uint32_t vmHandleId, BufferObject *bo); - int unbindBufferObject(uint32_t vmHandleId, BufferObject *bo); + int bindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo); + int unbindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo); int setupHardwareInfo(DeviceDescriptor *, bool); bool areNonPersistentContextsSupported() const { return nonPersistentContextsSupported; } diff --git a/shared/source/os_interface/linux/drm_query.cpp b/shared/source/os_interface/linux/drm_query.cpp index 4ea94e90b1..ea5742ec7c 100644 --- a/shared/source/os_interface/linux/drm_query.cpp +++ b/shared/source/os_interface/linux/drm_query.cpp @@ -41,11 +41,11 @@ unsigned int Drm::bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, au return DrmEngineMapper::engineNodeMap(engineType); } -int Drm::bindBufferObject(uint32_t vmHandleId, BufferObject *bo) { +int Drm::bindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo) { return 0; } -int Drm::unbindBufferObject(uint32_t vmHandleId, BufferObject *bo) { +int Drm::unbindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo) { return 0; } diff --git a/shared/source/os_interface/linux/drm_query_dg1.cpp b/shared/source/os_interface/linux/drm_query_dg1.cpp index 982856676f..92f284dbc3 100644 --- a/shared/source/os_interface/linux/drm_query_dg1.cpp +++ b/shared/source/os_interface/linux/drm_query_dg1.cpp @@ -13,6 +13,7 @@ #include namespace NEO { +class OsContext; int Drm::getMaxGpuFrequency(HardwareInfo &hwInfo, int &maxGpuFrequency) { maxGpuFrequency = 0; @@ -49,11 +50,11 @@ unsigned int Drm::bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, au return DrmEngineMapper::engineNodeMap(engineType); } -int Drm::bindBufferObject(uint32_t vmHandleId, BufferObject *bo) { +int Drm::bindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo) { return 0; } -int Drm::unbindBufferObject(uint32_t vmHandleId, BufferObject *bo) { +int Drm::unbindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo) { return 0; }