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 3b6bad74ec..16ab8b8fea 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 @@ -145,7 +145,7 @@ TEST_F(DrmBufferObjectTest, onPinIoctlFailed) { bo->setAddress(reinterpret_cast(buff.get())); BufferObject *boArray[1] = {boToPin.get()}; - auto ret = bo->pin(boArray, 1, osContext.get(), 0, 1); + auto ret = bo->pin(boArray, 1, osContext.get(), 0, 1, true); EXPECT_EQ(EINVAL, ret); } @@ -161,7 +161,7 @@ TEST_F(DrmBufferObjectTest, givenResidentBOWhenPrintExecutionBufferIsSetToTrueTh BufferObject *boArray[1] = {bo.get()}; testing::internal::CaptureStdout(); - auto ret = bo->pin(boArray, 1, osContext.get(), 0, 1); + auto ret = bo->pin(boArray, 1, osContext.get(), 0, 1, true); EXPECT_EQ(0, ret); std::string output = testing::internal::GetCapturedStdout(); @@ -210,6 +210,7 @@ TEST_F(DrmBufferObjectTest, whenPrintExecutionBufferIsSetToTrueThenMessageFoundI TEST(DrmBufferObjectSimpleTest, givenInvalidBoWhenPinIsCalledThenErrorIsReturned) { std::unique_ptr buff(new uint32_t[256]); std::unique_ptr mock(new DrmMockCustom); + OsContextLinux osContext(*mock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false, false, false); ASSERT_NE(nullptr, mock.get()); std::unique_ptr bo(new TestedBufferObject(mock.get())); ASSERT_NE(nullptr, bo.get()); @@ -224,8 +225,9 @@ TEST(DrmBufferObjectSimpleTest, givenInvalidBoWhenPinIsCalledThenErrorIsReturned mock->errnoValue = EFAULT; BufferObject *boArray[1] = {boToPin.get()}; - auto ret = bo->pin(boArray, 1, nullptr, 0, 1); + auto ret = bo->pin(boArray, 1, &osContext, 0, 1, true); EXPECT_EQ(EFAULT, ret); + mock->ioctl_res = 0; } TEST(DrmBufferObjectSimpleTest, givenBufferObjectWhenConstructedWithASizeThenTheSizeIsInitialized) { @@ -256,7 +258,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, &osContext, 0, 1); + auto ret = bo->pin(array, 3, &osContext, 0, 1, true); EXPECT_EQ(mock->ioctl_res, ret); EXPECT_LT(0u, mock->execBuffer.batch_len); 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 52f6bcc0fb..1e6220d9da 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 @@ -3118,7 +3118,7 @@ TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenDisabledForcePinAndEna PinBufferObject(Drm *drm) : BufferObject(drm, 1, 0, 1) { } - int pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override { + int pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, bool validateHostptr) override { for (size_t i = 0; i < numberOfBos; i++) { pinnedBoArray[i] = boToPin[i]; } diff --git a/shared/source/command_stream/command_stream_receiver_hw_base.inl b/shared/source/command_stream/command_stream_receiver_hw_base.inl index e4ecf1a640..7442994138 100644 --- a/shared/source/command_stream/command_stream_receiver_hw_base.inl +++ b/shared/source/command_stream/command_stream_receiver_hw_base.inl @@ -1114,6 +1114,7 @@ inline bool CommandStreamReceiverHw::initDirectSubmission(Device &dev ret = directSubmission->initialize(submitOnInit); this->dispatchMode = DispatchMode::ImmediateDispatch; } + osContext.setDirectSubmissionActive(); } } return ret; diff --git a/shared/source/os_interface/linux/drm_buffer_object.cpp b/shared/source/os_interface/linux/drm_buffer_object.cpp index 2a388463b3..fca889dfe8 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.cpp +++ b/shared/source/os_interface/linux/drm_buffer_object.cpp @@ -104,6 +104,10 @@ bool BufferObject::setTiling(uint32_t mode, uint32_t stride) { return set_tiling.tiling_mode == mode; } +uint32_t BufferObject::getOsContextId(OsContext *osContext) { + return perContextVmsUsed ? osContext->getContextId() : 0u; +} + 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 @@ -146,7 +150,7 @@ int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bo } void BufferObject::bind(OsContext *osContext, uint32_t vmHandleId) { - auto contextId = perContextVmsUsed ? osContext->getContextId() : 0; + auto contextId = getOsContextId(osContext); if (!this->bindInfo[contextId][vmHandleId]) { auto ret = this->drm->bindBufferObject(osContext, vmHandleId, this); auto err = this->drm->getErrno(); @@ -157,7 +161,7 @@ void BufferObject::bind(OsContext *osContext, uint32_t vmHandleId) { } void BufferObject::unbind(OsContext *osContext, uint32_t vmHandleId) { - auto contextId = perContextVmsUsed ? osContext->getContextId() : 0; + auto contextId = getOsContextId(osContext); if (this->bindInfo[contextId][vmHandleId]) { auto ret = this->drm->unbindBufferObject(osContext, vmHandleId, this); auto err = this->drm->getErrno(); @@ -195,13 +199,19 @@ void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const std::cout << logger.str() << std::endl; } -int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) { +int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, bool validateHostPtr) { auto retVal = 0; - if (this->drm->isBindAvailable()) { + + if ((validateHostPtr && osContext->isDirectSubmissionActive()) || + (!validateHostPtr && this->drm->isBindAvailable())) { for (auto drmIterator = 0u; drmIterator < osContext->getDeviceBitfield().size(); drmIterator++) { if (osContext->getDeviceBitfield().test(drmIterator)) { for (size_t i = 0; i < numberOfBos; i++) { - boToPin[i]->bind(osContext, drmIterator); + retVal |= this->drm->bindBufferObject(osContext, drmIterator, boToPin[i]); + if (!retVal) { + auto contextId = getOsContextId(osContext); + boToPin[i]->bindInfo[contextId][drmIterator] = true; + } } } } @@ -209,6 +219,7 @@ int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, OsConte StackVec execObject(numberOfBos + 1); retVal = this->exec(4u, 0u, 0u, false, osContext, vmHandleId, drmContextId, boToPin, numberOfBos, &execObject[0]); } + return retVal; } diff --git a/shared/source/os_interface/linux/drm_buffer_object.h b/shared/source/os_interface/linux/drm_buffer_object.h index 6c1874b3f7..9badc8e832 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.h +++ b/shared/source/os_interface/linux/drm_buffer_object.h @@ -43,7 +43,7 @@ class BufferObject { bool setTiling(uint32_t mode, uint32_t stride); - MOCKABLE_VIRTUAL int pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId); + MOCKABLE_VIRTUAL int pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, bool validateHostptr); 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); @@ -91,6 +91,7 @@ class BufferObject { uint32_t tiling_mode; bool allowCapture = false; + uint32_t getOsContextId(OsContext *osContext); 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); diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index a5c9cb0c6c..7cccedf72d 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -199,7 +199,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, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId()); + pinBBs.at(allocationData.rootDeviceIndex)->pin(&bo, 1, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId(), false); } } @@ -344,7 +344,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, osContextLinux, 0, osContextLinux->getDrmContextIds()[0]); + pinBBs.at(allocationData.rootDeviceIndex)->pin(&boPtr, 1, osContextLinux, 0, osContextLinux->getDrmContextIds()[0], false); } auto allocation = new DrmAllocation(allocationData.rootDeviceIndex, allocationData.type, bo.get(), res, bo->gpuAddress, alignedSize, MemoryPool::System4KBPages); @@ -378,7 +378,7 @@ DrmAllocation *DrmMemoryManager::allocateGraphicsMemoryForNonSvmHostPtr(const Al if (validateHostPtrMemory) { auto boPtr = bo.get(); - int result = pinBBs.at(allocationData.rootDeviceIndex)->pin(&boPtr, 1, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId()); + int result = pinBBs.at(allocationData.rootDeviceIndex)->pin(&boPtr, 1, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId(), true); if (result != SUCCESS) { unreference(bo.release(), true); releaseGpuRange(reinterpret_cast(gpuVirtualAddress), alignedSize, allocationData.rootDeviceIndex); @@ -745,7 +745,7 @@ MemoryManager::AllocationStatus DrmMemoryManager::populateOsHandles(OsHandleStor } if (validateHostPtrMemory) { - int result = pinBBs.at(rootDeviceIndex)->pin(allocatedBos, numberOfBosAllocated, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId()); + int result = pinBBs.at(rootDeviceIndex)->pin(allocatedBos, numberOfBosAllocated, registeredEngines[defaultEngineIndex].osContext, 0, getDefaultDrmContextId(), true); if (result == EFAULT) { for (uint32_t i = 0; i < numberOfBosAllocated; i++) { diff --git a/shared/source/os_interface/os_context.h b/shared/source/os_interface/os_context.h index 284bdffa7a..100e5cfa30 100644 --- a/shared/source/os_interface/os_context.h +++ b/shared/source/os_interface/os_context.h @@ -35,6 +35,8 @@ class OsContext : public ReferenceTrackedObject { virtual bool isInitialized() const { return true; } bool isDefaultContext() const { return defaultContext; } void setDefaultContext(bool value) { defaultContext = value; } + bool isDirectSubmissionActive() { return directSubmissionActive; } + void setDirectSubmissionActive() { directSubmissionActive = true; } protected: OsContext(uint32_t contextId, DeviceBitfield deviceBitfield, aub_stream::EngineType engineType, PreemptionMode preemptionMode, @@ -57,5 +59,6 @@ class OsContext : public ReferenceTrackedObject { const bool internalEngine = false; const bool rootDevice = false; bool defaultContext = false; + bool directSubmissionActive = false; }; } // namespace NEO