diff --git a/runtime/os_interface/linux/drm_buffer_object.cpp b/runtime/os_interface/linux/drm_buffer_object.cpp index 958850b70d..f3364e6c2b 100644 --- a/runtime/os_interface/linux/drm_buffer_object.cpp +++ b/runtime/os_interface/linux/drm_buffer_object.cpp @@ -107,67 +107,35 @@ void BufferObject::fillExecObject(drm_i915_gem_exec_object2 &execObject, uint32_ execObject.rsvd2 = 0; } -void BufferObject::processRelocs(int &idx, uint32_t drmContextId, ResidencyVector &residency, drm_i915_gem_exec_object2 *execObjectsStorage) { - for (size_t i = 0; i < residency.size(); i++) { - residency[i]->fillExecObject(execObjectsStorage[idx], drmContextId); - idx++; +int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, 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], drmContextId); } -} - -int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, uint32_t drmContextId, ResidencyVector &residency, drm_i915_gem_exec_object2 *execObjectsStorage) { - drm_i915_gem_execbuffer2 execbuf = {}; - - int idx = 0; - processRelocs(idx, drmContextId, residency, execObjectsStorage); - this->fillExecObject(execObjectsStorage[idx], drmContextId); - idx++; + this->fillExecObject(execObjectsStorage[residencyCount], drmContextId); + drm_i915_gem_execbuffer2 execbuf{}; execbuf.buffers_ptr = reinterpret_cast(execObjectsStorage); - execbuf.buffer_count = idx; + execbuf.buffer_count = static_cast(residencyCount + 1u); execbuf.batch_start_offset = static_cast(startOffset); execbuf.batch_len = alignUp(used, 8); execbuf.flags = flags; execbuf.rsvd1 = drmContextId; int ret = this->drm->ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - if (ret != 0) { - int err = errno; - printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_EXECBUFFER2) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); - UNRECOVERABLE_IF(true); - } - - return ret; -} - -int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, uint32_t drmContextId) { - drm_i915_gem_execbuffer2 execbuf = {}; - StackVec execObject; - - reinterpret_cast(this->gpuAddress)[0] = 0x05000000; - reinterpret_cast(this->gpuAddress)[1] = 0x00000000; - - execObject.resize(numberOfBos + 1); - - uint32_t boIndex = 0; - for (boIndex = 0; boIndex < (uint32_t)numberOfBos; boIndex++) { - boToPin[boIndex]->fillExecObject(execObject[boIndex], drmContextId); - } - - this->fillExecObject(execObject[boIndex], drmContextId); - - execbuf.buffers_ptr = reinterpret_cast(&execObject[0]); - execbuf.buffer_count = boIndex + 1; - execbuf.batch_len = alignUp(static_cast(sizeof(uint32_t)), 8); - execbuf.rsvd1 = drmContextId; - - int err = 0; - int ret = this->drm->ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - if (ret != 0) { - err = this->drm->getErrno(); - printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_EXECBUFFER2) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + if (ret == 0) { + return 0; } + int err = this->drm->getErrno(); + printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_EXECBUFFER2) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); return err; } +int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, uint32_t drmContextId) { + reinterpret_cast(this->gpuAddress)[0] = 0x05000000; + reinterpret_cast(this->gpuAddress)[1] = 0x00000000; + StackVec execObject(numberOfBos + 1); + return this->exec(4u, 0u, 0u, false, drmContextId, boToPin, numberOfBos, &execObject[0]); +} + } // namespace NEO diff --git a/runtime/os_interface/linux/drm_buffer_object.h b/runtime/os_interface/linux/drm_buffer_object.h index 5295f1d8cf..59440c98cf 100644 --- a/runtime/os_interface/linux/drm_buffer_object.h +++ b/runtime/os_interface/linux/drm_buffer_object.h @@ -7,11 +7,8 @@ #pragma once #include -#include -#include -#include +#include #include -#include struct drm_i915_gem_exec_object2; struct drm_i915_gem_relocation_entry; @@ -35,14 +32,13 @@ class BufferObject { friend DrmMemoryManager; public: - using ResidencyVector = std::vector; MOCKABLE_VIRTUAL ~BufferObject(){}; bool setTiling(uint32_t mode, uint32_t stride); MOCKABLE_VIRTUAL int pin(BufferObject *const boToPin[], size_t numberOfBos, uint32_t drmContextId); - int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, uint32_t drmContextId, ResidencyVector &residency, drm_i915_gem_exec_object2 *execObjectsStorage); + int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, uint32_t drmContextId, BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage); int wait(int64_t timeoutNs); bool close(); @@ -80,7 +76,6 @@ class BufferObject { uint32_t stride; MOCKABLE_VIRTUAL void fillExecObject(drm_i915_gem_exec_object2 &execObject, uint32_t drmContextId); - void processRelocs(int &idx, uint32_t drmContextId, ResidencyVector &residency, drm_i915_gem_exec_object2 *execObjectsStorage); uint64_t gpuAddress = 0llu; diff --git a/runtime/os_interface/linux/drm_command_stream.inl b/runtime/os_interface/linux/drm_command_stream.inl index 257305e194..6c6600331d 100644 --- a/runtime/os_interface/linux/drm_command_stream.inl +++ b/runtime/os_interface/linux/drm_command_stream.inl @@ -44,17 +44,15 @@ DrmCommandStreamReceiver::DrmCommandStreamReceiver(ExecutionEnvironme template FlushStamp DrmCommandStreamReceiver::flush(BatchBuffer &batchBuffer, ResidencyContainer &allocationsForResidency) { - unsigned int engineFlag = static_cast(osContext)->getEngineFlag(); - DrmAllocation *alloc = static_cast(batchBuffer.commandBufferAllocation); DEBUG_BREAK_IF(!alloc); - size_t alignedStart = (reinterpret_cast(batchBuffer.commandBufferAllocation->getUnderlyingBuffer()) & (MemoryConstants::allocationAlignment - 1)) + batchBuffer.startOffset; BufferObject *bb = alloc->getBO(); FlushStamp flushStamp = 0; if (bb) { flushStamp = bb->peekHandle(); + unsigned int engineFlag = static_cast(osContext)->getEngineFlag(); this->processResidency(allocationsForResidency); // Residency hold all allocation except command buffer, hence + 1 auto requiredSize = this->residency.size() + 1; @@ -62,12 +60,13 @@ FlushStamp DrmCommandStreamReceiver::flush(BatchBuffer &batchBuffer, this->execObjectsStorage.resize(requiredSize); } - bb->exec(static_cast(alignUp(batchBuffer.usedSize - batchBuffer.startOffset, 8)), - alignedStart, engineFlag | I915_EXEC_NO_RELOC, - batchBuffer.requiresCoherency, - static_cast(osContext)->getDrmContextId(), - this->residency, - this->execObjectsStorage.data()); + int err = bb->exec(static_cast(alignUp(batchBuffer.usedSize - batchBuffer.startOffset, 8)), + batchBuffer.startOffset, engineFlag | I915_EXEC_NO_RELOC, + batchBuffer.requiresCoherency, + static_cast(osContext)->getDrmContextIds()[0], + this->residency.data(), this->residency.size(), + this->execObjectsStorage.data()); + UNRECOVERABLE_IF(err != 0); this->residency.clear(); diff --git a/runtime/os_interface/linux/drm_memory_manager.cpp b/runtime/os_interface/linux/drm_memory_manager.cpp index b9ab0251c3..bd04b73983 100644 --- a/runtime/os_interface/linux/drm_memory_manager.cpp +++ b/runtime/os_interface/linux/drm_memory_manager.cpp @@ -176,8 +176,7 @@ NEO::BufferObject *DrmMemoryManager::allocUserptr(uintptr_t address, size_t size void DrmMemoryManager::emitPinningRequest(BufferObject *bo, const AllocationData &allocationData) const { if (forcePinEnabled && pinBB != nullptr && allocationData.flags.forcePin && allocationData.size >= this->pinThreshold) { - auto &osContextLinux = static_cast(getDefaultCommandStreamReceiver(0)->getOsContext()); - pinBB->pin(&bo, 1, osContextLinux.getDrmContextId()); + pinBB->pin(&bo, 1, getDefaultDrmContextId()); } } @@ -600,8 +599,7 @@ MemoryManager::AllocationStatus DrmMemoryManager::populateOsHandles(OsHandleStor } if (validateHostPtrMemory) { - auto &osContextLinux = static_cast(getDefaultCommandStreamReceiver(0)->getOsContext()); - int result = pinBB->pin(allocatedBos, numberOfBosAllocated, osContextLinux.getDrmContextId()); + int result = pinBB->pin(allocatedBos, numberOfBosAllocated, getDefaultDrmContextId()); if (result == EFAULT) { for (uint32_t i = 0; i < numberOfBosAllocated; i++) { @@ -723,4 +721,9 @@ int DrmMemoryManager::obtainFdFromHandle(int boHandle) { return openFd.fd; } + +uint32_t DrmMemoryManager::getDefaultDrmContextId() const { + auto &osContextLinux = static_cast(getDefaultCommandStreamReceiver(0)->getOsContext()); + return osContextLinux.getDrmContextIds()[0]; +} } // namespace NEO diff --git a/runtime/os_interface/linux/drm_memory_manager.h b/runtime/os_interface/linux/drm_memory_manager.h index 88c8db089c..d64e636819 100644 --- a/runtime/os_interface/linux/drm_memory_manager.h +++ b/runtime/os_interface/linux/drm_memory_manager.h @@ -66,6 +66,7 @@ class DrmMemoryManager : public MemoryManager { uint64_t acquireGpuRange(size_t &size, StorageAllocatorType &allocType, bool requireSpecificBitness); void releaseGpuRange(void *address, size_t unmapSize, StorageAllocatorType allocatorType); void emitPinningRequest(BufferObject *bo, const AllocationData &allocationData) const; + uint32_t getDefaultDrmContextId() const; DrmAllocation *createGraphicsAllocation(OsHandleStorage &handleStorage, const AllocationData &allocationData) override; DrmAllocation *allocateGraphicsMemoryForNonSvmHostPtr(const AllocationData &allocationData) override; diff --git a/runtime/os_interface/linux/os_context_linux.h b/runtime/os_interface/linux/os_context_linux.h index adbe2971c5..913838cc51 100644 --- a/runtime/os_interface/linux/os_context_linux.h +++ b/runtime/os_interface/linux/os_context_linux.h @@ -20,7 +20,7 @@ class OsContextLinux : public OsContext { aub_stream::EngineType engineType, PreemptionMode preemptionMode, bool lowPriority); unsigned int getEngineFlag() const { return engineFlag; } - uint32_t getDrmContextId() const { return drmContextIds[0]; } + const std::vector &getDrmContextIds() const { return drmContextIds; } protected: unsigned int engineFlag = 0; diff --git a/unit_tests/mocks/linux/mock_drm_memory_manager.h b/unit_tests/mocks/linux/mock_drm_memory_manager.h index 66525e79a5..ee9dc9afc8 100644 --- a/unit_tests/mocks/linux/mock_drm_memory_manager.h +++ b/unit_tests/mocks/linux/mock_drm_memory_manager.h @@ -50,6 +50,7 @@ class TestedDrmMemoryManager : public MemoryManagerCreate { using DrmMemoryManager::AllocationData; using DrmMemoryManager::allocUserptr; using DrmMemoryManager::createGraphicsAllocation; + using DrmMemoryManager::getDefaultDrmContextId; using DrmMemoryManager::gfxPartition; using DrmMemoryManager::pinThreshold; using DrmMemoryManager::setDomainCpu; diff --git a/unit_tests/os_interface/linux/drm_buffer_object_tests.cpp b/unit_tests/os_interface/linux/drm_buffer_object_tests.cpp index 8256e8b2d5..149ba1d3e8 100644 --- a/unit_tests/os_interface/linux/drm_buffer_object_tests.cpp +++ b/unit_tests/os_interface/linux/drm_buffer_object_tests.cpp @@ -66,9 +66,8 @@ TEST_F(DrmBufferObjectTest, exec) { mock->ioctl_expected.total = 1; mock->ioctl_res = 0; - BufferObject::ResidencyVector residency; drm_i915_gem_exec_object2 execObjectsStorage = {}; - auto ret = bo->exec(0, 0, 0, false, 1, residency, &execObjectsStorage); + auto ret = bo->exec(0, 0, 0, false, 1, nullptr, 0u, &execObjectsStorage); EXPECT_EQ(mock->ioctl_res, ret); EXPECT_EQ(0u, mock->execBuffer.flags); } @@ -76,9 +75,9 @@ TEST_F(DrmBufferObjectTest, exec) { TEST_F(DrmBufferObjectTest, exec_ioctlFailed) { mock->ioctl_expected.total = 1; mock->ioctl_res = -1; - BufferObject::ResidencyVector residency; + mock->errnoValue = EFAULT; drm_i915_gem_exec_object2 execObjectsStorage = {}; - EXPECT_THROW(bo->exec(0, 0, 0, false, 1, residency, &execObjectsStorage), std::exception); + EXPECT_EQ(EFAULT, bo->exec(0, 0, 0, false, 1, nullptr, 0u, &execObjectsStorage)); } TEST_F(DrmBufferObjectTest, setTiling_success) { diff --git a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp index b8f116728c..1c517d8e6d 100644 --- a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp @@ -165,8 +165,7 @@ TEST_F(DrmMemoryManagerTest, givenDrmContextIdWhenAllocationIsCreatedThenPinWith mock->ioctl_expected.gemClose = 2; auto memoryManager = std::make_unique(false, true, false, *executionEnvironment); - auto &osContextLinux = static_cast(memoryManager->getDefaultCommandStreamReceiver(0)->getOsContext()); - auto drmContextId = osContextLinux.getDrmContextId(); + auto drmContextId = memoryManager->getDefaultDrmContextId(); ASSERT_NE(nullptr, memoryManager->getPinBB()); EXPECT_NE(0u, drmContextId); diff --git a/unit_tests/os_interface/linux/drm_tests.cpp b/unit_tests/os_interface/linux/drm_tests.cpp index d176dea42b..8823efacc3 100644 --- a/unit_tests/os_interface/linux/drm_tests.cpp +++ b/unit_tests/os_interface/linux/drm_tests.cpp @@ -180,13 +180,15 @@ TEST(DrmTest, givenDrmWhenOsContextIsCreatedThenCreateAndDestroyNewDrmOsContext) drmMock.StoredCtxId = drmContextId1; OsContextLinux osContext1(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false); - EXPECT_EQ(drmContextId1, osContext1.getDrmContextId()); + EXPECT_EQ(1u, osContext1.getDrmContextIds().size()); + EXPECT_EQ(drmContextId1, osContext1.getDrmContextIds()[0]); EXPECT_EQ(0u, drmMock.receivedDestroyContextId); { drmMock.StoredCtxId = drmContextId2; OsContextLinux osContext2(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false); - EXPECT_EQ(drmContextId2, osContext2.getDrmContextId()); + EXPECT_EQ(1u, osContext2.getDrmContextIds().size()); + EXPECT_EQ(drmContextId2, osContext2.getDrmContextIds()[0]); EXPECT_EQ(0u, drmMock.receivedDestroyContextId); } EXPECT_EQ(drmContextId2, drmMock.receivedDestroyContextId);