From a3b3f3e86e115df914061a67ee2abad533a75b19 Mon Sep 17 00:00:00 2001 From: Jaime Arteaga Date: Tue, 20 Sep 2022 07:07:59 +0000 Subject: [PATCH] Add support for PRELIM_I915_PARAM_SET_PAIR This extension allows pairing two buffer objects so they can be exported using a single dma-buf handle. When imported, a single buffer object is created with a total size of the two buffer objects. Related-To: LOCI-3355 Sync to https://github.com/intel-gpu/drm-uapi-helper/releases/tag/v2.0-rc15 Signed-off-by: Jaime Arteaga --- shared/source/dll/linux/drm_neo_create.cpp | 2 + .../os_interface/linux/drm_memory_manager.cpp | 18 ++-- .../os_interface/linux/drm_memory_manager.h | 2 +- shared/source/os_interface/linux/drm_neo.cpp | 9 ++ shared/source/os_interface/linux/drm_neo.h | 4 + .../source/os_interface/linux/ioctl_helper.h | 11 ++- .../linux/ioctl_helper_prelim.cpp | 28 +++++- .../linux/ioctl_helper_upstream.cpp | 6 +- .../linux/local/dg1/ioctl_helper_dg1.cpp | 4 +- .../source/os_interface/linux/memory_info.cpp | 10 +-- .../source/os_interface/linux/memory_info.h | 4 +- shared/test/common/libult/linux/drm_mock.h | 17 ++++ .../libult/linux/drm_mock_prelim_context.cpp | 19 +++- .../libult/linux/drm_mock_prelim_context.h | 4 + .../linux/device_command_stream_fixture.cpp | 9 ++ .../linux/device_command_stream_fixture.h | 3 + .../linux/drm_memory_manager_fixture.h | 6 +- .../os_interface/linux/drm_bind_tests.cpp | 8 ++ .../linux/drm_memory_info_prelim_tests.cpp | 39 ++++++-- .../linux/drm_memory_info_tests.cpp | 4 +- ...m_memory_manager_localmem_prelim_tests.cpp | 6 +- ...memory_manager_localmem_upstream_tests.cpp | 6 +- .../linux/drm_memory_manager_tests.cpp | 88 ++++++++++++++++++- .../drm_residency_handler_prelim_tests.cpp | 42 +++++++++ .../linux/drm_with_prelim_tests.cpp | 4 +- .../linux/ioctl_helper_tests_dg1.cpp | 6 +- .../linux/ioctl_helper_tests_upstream.cpp | 4 +- third_party/uapi/prelim/drm/i915_drm_prelim.h | 5 ++ 28 files changed, 322 insertions(+), 46 deletions(-) diff --git a/shared/source/dll/linux/drm_neo_create.cpp b/shared/source/dll/linux/drm_neo_create.cpp index 8ca28e3581..0280e85504 100644 --- a/shared/source/dll/linux/drm_neo_create.cpp +++ b/shared/source/dll/linux/drm_neo_create.cpp @@ -111,6 +111,8 @@ Drm *Drm::create(std::unique_ptr &&hwDeviceId, RootDeviceEnvironm } } + drm->isSetPairAvailable(); + if (!drm->isPerContextVMRequired()) { if (!drm->createVirtualMemoryAddressSpace(HwHelper::getSubDevicesCount(rootDeviceEnvironment.getHardwareInfo()))) { printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "INFO: Device doesn't support GEM Virtual Memory\n"); diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index cfafe4c8f6..00361ce8da 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -1487,7 +1487,7 @@ GraphicsAllocation *DrmMemoryManager::allocateGraphicsMemoryInDevicePool(const A } BufferObject *DrmMemoryManager::createBufferObjectInMemoryRegion(Drm *drm, Gmm *gmm, AllocationType allocationType, uint64_t gpuAddress, - size_t size, uint32_t memoryBanks, size_t maxOsContextCount) { + size_t size, uint32_t memoryBanks, size_t maxOsContextCount, int32_t pairHandle) { auto memoryInfo = drm->getMemoryInfo(); if (!memoryInfo) { return nullptr; @@ -1500,7 +1500,7 @@ BufferObject *DrmMemoryManager::createBufferObjectInMemoryRegion(Drm *drm, Gmm * if (banks.count() > 1) { ret = memoryInfo->createGemExtWithMultipleRegions(memoryBanks, size, handle); } else { - ret = memoryInfo->createGemExtWithSingleRegion(memoryBanks, size, handle); + ret = memoryInfo->createGemExtWithSingleRegion(memoryBanks, size, handle, pairHandle); } if (ret != 0) { @@ -1536,6 +1536,8 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation, } allocation->setNumHandles(handles); + int32_t pairHandle = -1; + for (auto handleId = 0u; handleId < handles; handleId++, currentBank++) { if (currentBank == banksCnt) { currentBank = 0; @@ -1554,7 +1556,7 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation, } auto gmm = allocation->getGmm(handleId); auto boSize = alignUp(gmm->gmmResourceInfo->getSizeAllocation(), MemoryConstants::pageSize64k); - bos[handleId] = createBufferObjectInMemoryRegion(drm, gmm, allocation->getAllocationType(), boAddress, boSize, memoryBanks, maxOsContextCount); + bos[handleId] = createBufferObjectInMemoryRegion(drm, gmm, allocation->getAllocationType(), boAddress, boSize, memoryBanks, maxOsContextCount, pairHandle); if (nullptr == bos[handleId]) { return false; } @@ -1562,6 +1564,12 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation, if (storageInfo.multiStorage) { boAddress += boSize; } + + // only support pairing of handles with PRELIM_I915_PARAM_SET_PAIR for implicit scaling scenarios, which + // have 2 handles + if (AllocationType::BUFFER == allocation->getAllocationType() && handles == 2 && drm->getSetPairAvailable()) { + pairHandle = bos[handleId]->peekHandle(); + } } if (storageInfo.colouringPolicy == ColouringPolicy::MappingBased) { @@ -1672,7 +1680,7 @@ DrmAllocation *DrmMemoryManager::createAllocWithAlignment(const AllocationData & auto pointerDiff = ptrDiff(cpuPointer, cpuBasePointer); std::unique_ptr bo(this->createBufferObjectInMemoryRegion(&drm, nullptr, allocationData.type, - reinterpret_cast(cpuPointer), alignedSize, 0u, maxOsContextCount)); + reinterpret_cast(cpuPointer), alignedSize, 0u, maxOsContextCount, -1)); if (!bo) { this->munmapFunction(cpuBasePointer, totalSizeToAlloc); @@ -1801,7 +1809,7 @@ GraphicsAllocation *DrmMemoryManager::createSharedUnifiedMemoryAllocation(const createMemoryRegionsForSharedAllocation(*pHwInfo, *memoryInfo, allocationData, memRegions); uint32_t handle = 0; - auto ret = memoryInfo->createGemExt(memRegions, size, handle, {}); + auto ret = memoryInfo->createGemExt(memRegions, size, handle, {}, -1); if (ret) { return nullptr; diff --git a/shared/source/os_interface/linux/drm_memory_manager.h b/shared/source/os_interface/linux/drm_memory_manager.h index 6259266cea..ae3cdb69ef 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.h +++ b/shared/source/os_interface/linux/drm_memory_manager.h @@ -65,7 +65,7 @@ class DrmMemoryManager : public MemoryManager { AddressRange reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) override; void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) override; MOCKABLE_VIRTUAL BufferObject *createBufferObjectInMemoryRegion(Drm *drm, Gmm *gmm, AllocationType allocationType, uint64_t gpuAddress, size_t size, - uint32_t memoryBanks, size_t maxOsContextCount); + uint32_t memoryBanks, size_t maxOsContextCount, int32_t pairHandle); bool isKmdMigrationAvailable(uint32_t rootDeviceIndex) override; diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index 7b0f7e3ea9..77f4771b22 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -1263,6 +1263,15 @@ void Drm::waitForBind(uint32_t vmHandleId) { waitUserFence(0u, castToUint64(&this->pagingFence[vmHandleId]), this->fenceVal[vmHandleId], ValueWidth::U64, -1, ioctlHelper->getWaitUserFenceSoftFlag()); } +bool Drm::isSetPairAvailable() { + std::call_once(checkBindOnce, [this]() { + int ret = ioctlHelper->isSetPairAvailable(); + setPairAvailable = ret; + }); + + return setPairAvailable; +} + bool Drm::isVmBindAvailable() { std::call_once(checkBindOnce, [this]() { int ret = ioctlHelper->isVmBindAvailable(); diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 2a1c9d24ce..f52f5fc32c 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -157,6 +157,9 @@ class Drm : public DriverModel { void setDirectSubmissionActive(bool value) { this->directSubmissionActive = value; } bool isDirectSubmissionActive() const { return this->directSubmissionActive; } + MOCKABLE_VIRTUAL bool isSetPairAvailable(); + MOCKABLE_VIRTUAL bool getSetPairAvailable() { return setPairAvailable; } + bool useVMBindImmediate() const; MOCKABLE_VIRTUAL bool isVmBindAvailable(); @@ -338,6 +341,7 @@ class Drm : public DriverModel { bool requirePerContextVM = false; bool bindAvailable = false; bool directSubmissionActive = false; + bool setPairAvailable = false; bool contextDebugSupported = false; bool pageFaultSupported = false; bool completionFenceSupported = false; diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index b7b5a65440..8f61d5fd03 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -69,8 +69,9 @@ class IoctlHelper { virtual uint32_t ioctl(DrmIoctl request, void *arg); virtual bool initialize() = 0; + virtual bool isSetPairAvailable() = 0; virtual bool isVmBindAvailable() = 0; - virtual uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) = 0; + virtual uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) = 0; virtual CacheRegion closAlloc() = 0; virtual uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) = 0; virtual CacheRegion closFree(CacheRegion closIndex) = 0; @@ -144,8 +145,9 @@ class IoctlHelperUpstream : public IoctlHelper { using IoctlHelper::IoctlHelper; bool initialize() override; + bool isSetPairAvailable() override; bool isVmBindAvailable() override; - uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) override; + uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) override; CacheRegion closAlloc() override; uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) override; CacheRegion closFree(CacheRegion closIndex) override; @@ -197,7 +199,7 @@ class IoctlHelperImpl : public IoctlHelperUpstream { return std::make_unique>(drm); } - uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) override; + uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) override; std::vector translateToMemoryRegions(const std::vector ®ionInfo) override; unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest) const override; std::string getIoctlString(DrmIoctl ioctlRequest) const override; @@ -208,8 +210,9 @@ class IoctlHelperPrelim20 : public IoctlHelper { using IoctlHelper::IoctlHelper; bool initialize() override; + bool isSetPairAvailable() override; bool isVmBindAvailable() override; - uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) override; + uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) override; CacheRegion closAlloc() override; uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) override; CacheRegion closFree(CacheRegion closIndex) override; diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 28d0e1e168..669d7ae655 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -24,6 +24,18 @@ namespace NEO { +bool IoctlHelperPrelim20::isSetPairAvailable() { + int setPairSupported = 0; + GetParam getParam{}; + getParam.param = PRELIM_I915_PARAM_HAS_SET_PAIR; + getParam.value = &setPairSupported; + int retVal = IoctlHelper::ioctl(DrmIoctl::Getparam, &getParam); + if (retVal) { + return false; + } + return setPairSupported; +} + bool IoctlHelperPrelim20::isVmBindAvailable() { int vmBindSupported = 0; GetParam getParam{}; @@ -36,7 +48,7 @@ bool IoctlHelperPrelim20::isVmBindAvailable() { return vmBindSupported; } -uint32_t IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) { +uint32_t IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) { uint32_t regionsSize = static_cast(memClassInstances.size()); std::vector regions(regionsSize); for (uint32_t i = 0; i < regionsSize; i++) { @@ -53,10 +65,24 @@ uint32_t IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstance setparamRegion.param = regionParam; prelim_drm_i915_gem_create_ext_vm_private vmPrivate{}; + prelim_drm_i915_gem_create_ext_setparam pairSetparamRegion{}; + if (vmId != std::nullopt) { vmPrivate.base.name = PRELIM_I915_GEM_CREATE_EXT_VM_PRIVATE; vmPrivate.vm_id = vmId.value(); + } + + if (pairHandle != -1) { + pairSetparamRegion.base.name = PRELIM_I915_GEM_CREATE_EXT_SETPARAM; + pairSetparamRegion.param.param = PRELIM_I915_OBJECT_PARAM | PRELIM_I915_PARAM_SET_PAIR; + pairSetparamRegion.param.data = pairHandle; + } + + if (vmId != std::nullopt) { + vmPrivate.base.next_extension = reinterpret_cast(&pairSetparamRegion); setparamRegion.base.next_extension = reinterpret_cast(&vmPrivate); + } else if (pairHandle != -1) { + setparamRegion.base.next_extension = reinterpret_cast(&pairSetparamRegion); } prelim_drm_i915_gem_create_ext createExt{}; diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index b6689cb4e4..32bb91e993 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -18,11 +18,15 @@ bool IoctlHelperUpstream::initialize() { return true; } +bool IoctlHelperUpstream::isSetPairAvailable() { + return false; +} + bool IoctlHelperUpstream::isVmBindAvailable() { return false; } -uint32_t IoctlHelperUpstream::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) { +uint32_t IoctlHelperUpstream::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) { uint32_t regionsSize = static_cast(memClassInstances.size()); std::vector regions(regionsSize); for (uint32_t i = 0; i < regionsSize; i++) { diff --git a/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp b/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp index d3262e41cd..b4b646f388 100644 --- a/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp +++ b/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp @@ -21,8 +21,8 @@ constexpr static auto gfxProduct = IGFX_DG1; extern bool isQueryDrmTip(const std::vector &queryInfo); template <> -uint32_t IoctlHelperImpl::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) { - auto ret = IoctlHelperUpstream::createGemExt(memClassInstances, allocSize, handle, vmId); +uint32_t IoctlHelperImpl::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) { + auto ret = IoctlHelperUpstream::createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle); if (ret == 0) { return ret; } diff --git a/shared/source/os_interface/linux/memory_info.cpp b/shared/source/os_interface/linux/memory_info.cpp index a6b00855e7..536512f740 100644 --- a/shared/source/os_interface/linux/memory_info.cpp +++ b/shared/source/os_interface/linux/memory_info.cpp @@ -56,8 +56,8 @@ void MemoryInfo::assignRegionsFromDistances(const std::vector &dis } } -uint32_t MemoryInfo::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) { - return this->drm.getIoctlHelper()->createGemExt(memClassInstances, allocSize, handle, vmId); +uint32_t MemoryInfo::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) { + return this->drm.getIoctlHelper()->createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle); } uint32_t MemoryInfo::getTileIndex(uint32_t memoryBank, const HardwareInfo &hwInfo) { @@ -108,7 +108,7 @@ void MemoryInfo::printRegionSizes() { } } -uint32_t MemoryInfo::createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle) { +uint32_t MemoryInfo::createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle) { auto pHwInfo = this->drm.getRootDeviceEnvironment().getHardwareInfo(); auto regionClassAndInstance = getMemoryRegionClassAndInstance(memoryBanks, *pHwInfo); MemRegionsVec region = {regionClassAndInstance}; @@ -119,7 +119,7 @@ uint32_t MemoryInfo::createGemExtWithSingleRegion(uint32_t memoryBanks, size_t a vmId = this->drm.getVirtualMemoryAddressSpace(tileIndex); } } - auto ret = createGemExt(region, allocSize, handle, vmId); + auto ret = createGemExt(region, allocSize, handle, vmId, pairHandle); return ret; } @@ -137,7 +137,7 @@ uint32_t MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_ } currentBank++; } - auto ret = createGemExt(memRegions, allocSize, handle, {}); + auto ret = createGemExt(memRegions, allocSize, handle, {}, -1); return ret; } diff --git a/shared/source/os_interface/linux/memory_info.h b/shared/source/os_interface/linux/memory_info.h index 2f67373ff3..b6904484bf 100644 --- a/shared/source/os_interface/linux/memory_info.h +++ b/shared/source/os_interface/linux/memory_info.h @@ -26,7 +26,7 @@ class MemoryInfo { void assignRegionsFromDistances(const std::vector &distances); - MOCKABLE_VIRTUAL uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId); + MOCKABLE_VIRTUAL uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle); MemoryClassInstance getMemoryRegionClassAndInstance(uint32_t memoryBank, const HardwareInfo &hwInfo); @@ -36,7 +36,7 @@ class MemoryInfo { uint32_t getTileIndex(uint32_t memoryBank, const HardwareInfo &hwInfo); - MOCKABLE_VIRTUAL uint32_t createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle); + MOCKABLE_VIRTUAL uint32_t createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle); MOCKABLE_VIRTUAL uint32_t createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle); const RegionContainer &getDrmRegionInfos() const { return drmQueryRegions; } diff --git a/shared/test/common/libult/linux/drm_mock.h b/shared/test/common/libult/linux/drm_mock.h index 05bd971941..3e67de81c2 100644 --- a/shared/test/common/libult/linux/drm_mock.h +++ b/shared/test/common/libult/linux/drm_mock.h @@ -46,6 +46,7 @@ class DrmMock : public Drm { using Drm::queryAndSetVmBindPatIndexProgrammingSupport; using Drm::queryDeviceIdAndRevision; using Drm::requirePerContextVM; + using Drm::setPairAvailable; using Drm::setupIoctlHelper; using Drm::sliceCountChangeSupported; using Drm::systemInfo; @@ -137,6 +138,20 @@ class DrmMock : public Drm { return bindAvailable; } + bool isSetPairAvailable() override { + if (callBaseIsSetPairAvailable) { + return Drm::isSetPairAvailable(); + } + return setPairAvailable; + } + + bool getSetPairAvailable() override { + if (callBaseGetSetPairAvailable) { + return Drm::getSetPairAvailable(); + } + return setPairAvailable; + } + uint32_t getBaseIoctlCalls() { return ioctlCallsForHelperInitialization + static_cast(virtualMemoryIds.size()); } @@ -175,6 +190,8 @@ class DrmMock : public Drm { bool allowDebugAttachCallBase = false; bool callBaseCreateDrmContext = true; bool callBaseIsVmBindAvailable = false; + bool callBaseIsSetPairAvailable = false; + bool callBaseGetSetPairAvailable = false; bool capturedCooperativeContextRequest = false; diff --git a/shared/test/common/libult/linux/drm_mock_prelim_context.cpp b/shared/test/common/libult/linux/drm_mock_prelim_context.cpp index c7b7a0e310..df1156f62d 100644 --- a/shared/test/common/libult/linux/drm_mock_prelim_context.cpp +++ b/shared/test/common/libult/linux/drm_mock_prelim_context.cpp @@ -48,6 +48,10 @@ int DrmMockPrelimContext::handlePrelimRequest(DrmIoctl request, void *arg) { vmBindQueryCalled++; *gp->value = vmBindQueryValue; return vmBindQueryReturn; + } else if (gp->param == PRELIM_I915_PARAM_HAS_SET_PAIR) { + setPairQueryCalled++; + *gp->value = setPairQueryValue; + return setPairQueryReturn; } } break; case DrmIoctl::GemContextGetparam: { @@ -158,9 +162,18 @@ int DrmMockPrelimContext::handlePrelimRequest(DrmIoctl request, void *arg) { prelim_drm_i915_gem_create_ext_vm_private *vmPrivateExt = nullptr; if (extension->base.next_extension != 0) { - vmPrivateExt = reinterpret_cast(extension->base.next_extension); - if (vmPrivateExt->base.name != PRELIM_I915_GEM_CREATE_EXT_VM_PRIVATE) { - return EINVAL; + + prelim_drm_i915_gem_create_ext_setparam *pairSetparamRegion = nullptr; + pairSetparamRegion = reinterpret_cast(extension->base.next_extension); + if (pairSetparamRegion->base.name == PRELIM_I915_GEM_CREATE_EXT_SETPARAM) { + if ((pairSetparamRegion->base.name & PRELIM_I915_PARAM_SET_PAIR) == 0) { + return EINVAL; + } + } else { + vmPrivateExt = reinterpret_cast(extension->base.next_extension); + if (vmPrivateExt->base.name != PRELIM_I915_GEM_CREATE_EXT_VM_PRIVATE) { + return EINVAL; + } } } diff --git a/shared/test/common/libult/linux/drm_mock_prelim_context.h b/shared/test/common/libult/linux/drm_mock_prelim_context.h index 91d222809e..b1255e745c 100644 --- a/shared/test/common/libult/linux/drm_mock_prelim_context.h +++ b/shared/test/common/libult/linux/drm_mock_prelim_context.h @@ -98,6 +98,10 @@ struct DrmMockPrelimContext { uint64_t receivedSetContextParamCtxId{0}; uint64_t receivedContextCreateExtSetParamRunaloneCount{0}; + size_t setPairQueryCalled{0}; + int setPairQueryValue{0}; + int setPairQueryReturn{0}; + size_t vmBindQueryCalled{0}; int vmBindQueryValue{0}; int vmBindQueryReturn{0}; diff --git a/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp b/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp index 72746c1dd8..0d76265e74 100644 --- a/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp +++ b/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp @@ -238,3 +238,12 @@ bool DrmMockCustom::isVmBindAvailable() { return isVmBindAvailableCall.returnValue; } } + +bool DrmMockCustom::getSetPairAvailable() { + getSetPairAvailableCall.called++; + if (getSetPairAvailableCall.callParent) { + return Drm::getSetPairAvailable(); + } else { + return getSetPairAvailableCall.returnValue; + } +} diff --git a/shared/test/common/os_interface/linux/device_command_stream_fixture.h b/shared/test/common/os_interface/linux/device_command_stream_fixture.h index 12d1e66c98..55cc4c1452 100644 --- a/shared/test/common/os_interface/linux/device_command_stream_fixture.h +++ b/shared/test/common/os_interface/linux/device_command_stream_fixture.h @@ -127,6 +127,8 @@ class DrmMockCustom : public Drm { int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) override; + bool getSetPairAvailable() override; + bool isVmBindAvailable() override; bool completionFenceSupport() override { @@ -161,6 +163,7 @@ class DrmMockCustom : public Drm { IoctlResExt NONE = {-1, 0}; WaitUserFenceCall waitUserFenceCall{}; + IsVmBindAvailableCall getSetPairAvailableCall{}; IsVmBindAvailableCall isVmBindAvailableCall{}; std::atomic ioctl_res; diff --git a/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h b/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h index 0e45f5e385..4585a10eb1 100644 --- a/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h +++ b/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h @@ -69,18 +69,19 @@ struct MockedMemoryInfo : public NEO::MemoryInfo { size_t getMemoryRegionSize(uint32_t memoryBank) override { return 1024u; } - uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId) override { + uint32_t createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) override { if (allocSize == 0) { return EINVAL; } handle = 1u; return 0u; } - uint32_t createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle) override { + uint32_t createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle) override { if (allocSize == 0) { return EINVAL; } handle = 1u; + pairHandlePassed = pairHandle; return 0u; } uint32_t createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle) override { @@ -92,6 +93,7 @@ struct MockedMemoryInfo : public NEO::MemoryInfo { return 0u; } uint32_t banks = 0; + int32_t pairHandlePassed = -1; }; class DrmMemoryManagerFixtureWithoutQuietIoctlExpectation { diff --git a/shared/test/unit_test/os_interface/linux/drm_bind_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_bind_tests.cpp index 59180ada1d..18ccd693f1 100644 --- a/shared/test/unit_test/os_interface/linux/drm_bind_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_bind_tests.cpp @@ -61,3 +61,11 @@ TEST(DrmBindTest, whenCheckingVmBindAvailabilityThenIoctlHelperSupportIsUsed) { EXPECT_EQ(drm.isVmBindAvailable(), drm.getIoctlHelper()->isVmBindAvailable()); } + +TEST(DrmBindTest, whenCheckingSetPairAvailabilityThenIoctlHelperSupportIsUsed) { + auto executionEnvironment = std::make_unique(); + DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + drm.callBaseIsSetPairAvailable = true; + + EXPECT_EQ(drm.isSetPairAvailable(), drm.getIoctlHelper()->isSetPairAvailable()); +} diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp index fa017cc641..24debbeec3 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp @@ -371,7 +371,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemWithExtensionsThenRetu auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}); + auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -395,7 +395,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithSingleRegionThe auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -407,6 +407,35 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithSingleRegionThe EXPECT_EQ(1024u, drm->context.receivedCreateGemExt->size); } +TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithPairHandleThenReturnCorrectValues) { + DebugManagerStateRestore restorer; + DebugManager.flags.EnableLocalMemory.set(1); + + std::vector regionInfo(2); + regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0}; + regionInfo[0].probedSize = 8 * GB; + regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}; + regionInfo[1].probedSize = 16 * GB; + + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + drm->context.setPairQueryValue = 1; + drm->context.setPairQueryReturn = 1; + + uint32_t pairHandle = 0; + auto memoryInfo = std::make_unique(regionInfo, *drm); + ASSERT_NE(nullptr, memoryInfo); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, pairHandle, -1); + EXPECT_EQ(0u, ret); + EXPECT_EQ(1u, drm->ioctlCallsCount); + + uint32_t handle = 0; + ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, pairHandle); + EXPECT_EQ(0u, ret); + EXPECT_EQ(2u, drm->ioctlCallsCount); +} + TEST(MemoryInfo, givenMemoryInfoWithRegionsAndPrivateBOSupportWhenCreatingGemExtWithSingleRegionThenValidVmIdIsSet) { DebugManagerStateRestore restorer; DebugManager.flags.EnableLocalMemory.set(1); @@ -426,7 +455,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsAndPrivateBOSupportWhenCreatingGemExt ASSERT_NE(nullptr, memoryInfo); uint32_t handle = 0; - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -456,7 +485,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsAndNoPrivateBOSupportWhenCreatingGemE ASSERT_NE(nullptr, memoryInfo); uint32_t handle = 0; - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -485,7 +514,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsAndPrivateBOSupportedAndIsPerContextV ASSERT_NE(nullptr, memoryInfo); uint32_t handle = 0; - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp index a92ab91afd..a732f9ca06 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp @@ -233,7 +233,7 @@ HWTEST2_F(MemoryInfoTest, givenMemoryInfoWithRegionsWhenCreatingGemWithExtension uint32_t handle = 0; MemRegionsVec memClassInstance = {regionInfo[0].region, regionInfo[1].region}; - auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}); + auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -256,7 +256,7 @@ HWTEST2_F(MemoryInfoTest, givenMemoryInfoWithRegionsWhenCreatingGemExtWithSingle auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp index 7d37480e82..c5e09802c1 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp @@ -57,7 +57,8 @@ TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, givenDrmMemoryManagerWithPrelimSup gpuAddress, size, (1 << (MemoryBanks::getBankForLocalMemory(0) - 1)), - 1)); + 1, + -1)); ASSERT_NE(nullptr, bo); EXPECT_EQ(1u, mock->ioctlCallsCount); @@ -1253,7 +1254,8 @@ TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, givenPrintBOCreateDestroyResultFla gpuAddress, size, (1 << (MemoryBanks::getBankForLocalMemory(0) - 1)), - 1)); + 1, + -1)); EXPECT_NE(nullptr, bo); std::string output = testing::internal::GetCapturedStdout(); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp index fb9eaa4337..fbdfa78034 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp @@ -121,7 +121,8 @@ HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenDrmMemoryManagerWhenCreateBuffer gpuAddress, size, (1 << (MemoryBanks::getBankForLocalMemory(0) - 1)), - 1)); + 1, + -1)); ASSERT_NE(nullptr, bo); EXPECT_EQ(1u, mock->ioctlCallsCount); EXPECT_EQ(1u, mock->createExt.handle); @@ -441,7 +442,8 @@ class DrmMemoryManagerLocalMemoryMemoryBankMock : public TestedDrmMemoryManager uint64_t gpuAddress, size_t size, uint32_t memoryBanks, - size_t maxOsContextCount) override { + size_t maxOsContextCount, + int32_t pairHandle) override { memoryBankIsOne = (memoryBanks == 1) ? true : false; return nullptr; } diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index fe1cfafcff..4b35108594 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -4233,7 +4233,7 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenDrmMemor auto gpuAddress = 0x1234u; auto size = MemoryConstants::pageSize; - auto bo = std::unique_ptr(memoryManager->createBufferObjectInMemoryRegion(&memoryManager->getDrm(0), nullptr, AllocationType::BUFFER, gpuAddress, size, MemoryBanks::MainBank, 1)); + auto bo = std::unique_ptr(memoryManager->createBufferObjectInMemoryRegion(&memoryManager->getDrm(0), nullptr, AllocationType::BUFFER, gpuAddress, size, MemoryBanks::MainBank, 1, -1)); EXPECT_EQ(nullptr, bo); } @@ -4241,7 +4241,7 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenDrmMemor auto gpuAddress = 0x1234u; auto size = 0u; - auto bo = std::unique_ptr(memoryManager->createBufferObjectInMemoryRegion(&memoryManager->getDrm(0), nullptr, AllocationType::BUFFER, gpuAddress, size, MemoryBanks::MainBank, 1)); + auto bo = std::unique_ptr(memoryManager->createBufferObjectInMemoryRegion(&memoryManager->getDrm(0), nullptr, AllocationType::BUFFER, gpuAddress, size, MemoryBanks::MainBank, 1, -1)); EXPECT_EQ(nullptr, bo); } @@ -4265,6 +4265,90 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenUseKmdMi memoryManager->freeGraphicsMemory(allocation); } +TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenMemoryAllocationWithNoSetPairAndOneHandleAndCommandBufferTypeThenNoPairHandleIsPassed) { + VariableBackup backupSetPairCallParent{&mock->getSetPairAvailableCall.callParent, false}; + VariableBackup backupSetPairReturnValue{&mock->getSetPairAvailableCall.returnValue, true}; + + MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success; + AllocationData allocData; + allocData.allFlags = 0; + allocData.size = MemoryConstants::pageSize; + allocData.type = AllocationType::COMMAND_BUFFER; + allocData.rootDeviceIndex = rootDeviceIndex; + allocData.storageInfo.memoryBanks = 0b01; + + auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status); + EXPECT_NE(nullptr, allocation); + EXPECT_EQ(MemoryManager::AllocationStatus::Success, status); + + EXPECT_EQ(-1, static_cast(mock->getMemoryInfo())->pairHandlePassed); + + memoryManager->freeGraphicsMemory(allocation); +} + +TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenMemoryAllocationWithSetPairAndOneHandleThenThenNoPairHandleIsPassed) { + VariableBackup backupSetPairCallParent{&mock->getSetPairAvailableCall.callParent, false}; + VariableBackup backupSetPairReturnValue{&mock->getSetPairAvailableCall.returnValue, true}; + + MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success; + AllocationData allocData; + allocData.allFlags = 0; + allocData.size = MemoryConstants::pageSize; + allocData.type = AllocationType::BUFFER; + allocData.rootDeviceIndex = rootDeviceIndex; + allocData.storageInfo.memoryBanks = 0b01; + + auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status); + EXPECT_NE(nullptr, allocation); + EXPECT_EQ(MemoryManager::AllocationStatus::Success, status); + + EXPECT_EQ(-1, static_cast(mock->getMemoryInfo())->pairHandlePassed); + + memoryManager->freeGraphicsMemory(allocation); +} + +TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenMemoryAllocationWithSetPairAndTwoHandlesThenPairHandleIsPassed) { + VariableBackup backupSetPairCallParent{&mock->getSetPairAvailableCall.callParent, false}; + VariableBackup backupSetPairReturnValue{&mock->getSetPairAvailableCall.returnValue, true}; + + MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success; + AllocationData allocData; + allocData.allFlags = 0; + allocData.size = MemoryConstants::pageSize; + allocData.type = AllocationType::BUFFER; + allocData.rootDeviceIndex = rootDeviceIndex; + allocData.storageInfo.memoryBanks = 0b11; + + auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status); + EXPECT_NE(nullptr, allocation); + EXPECT_EQ(MemoryManager::AllocationStatus::Success, status); + + EXPECT_NE(-1, static_cast(mock->getMemoryInfo())->pairHandlePassed); + + memoryManager->freeGraphicsMemory(allocation); +} + +TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenMemoryAllocationWithNoSetPairAndTwoHandlesThenPairHandleIsPassed) { + VariableBackup backupSetPairCallParent{&mock->getSetPairAvailableCall.callParent, false}; + VariableBackup backupSetPairReturnValue{&mock->getSetPairAvailableCall.returnValue, false}; + + MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success; + AllocationData allocData; + allocData.allFlags = 0; + allocData.size = MemoryConstants::pageSize; + allocData.type = AllocationType::BUFFER; + allocData.rootDeviceIndex = rootDeviceIndex; + allocData.storageInfo.memoryBanks = 0b11; + + auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status); + EXPECT_NE(nullptr, allocation); + EXPECT_EQ(MemoryManager::AllocationStatus::Success, status); + + EXPECT_EQ(-1, static_cast(mock->getMemoryInfo())->pairHandlePassed); + + memoryManager->freeGraphicsMemory(allocation); +} + TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenUseSystemMemoryFlagWhenGraphicsAllocationInDevicePoolIsAllocatedThenNullptrIsReturned) { MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success; AllocationData allocData; diff --git a/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp index 8042a8b6cc..4737ec6206 100644 --- a/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp @@ -1085,3 +1085,45 @@ TEST(DrmResidencyHandlerTests, givenDebugFlagUseVmBindSetDefaultWhenQueryingIsVm EXPECT_FALSE(drm.bindAvailable); EXPECT_EQ(1u, drm.context.vmBindQueryCalled); } + +TEST(DrmResidencyHandlerTests, whenQueryingForSetPairAvailableAndNoSupportAvailableThenExpectedValueIsReturned) { + auto executionEnvironment = std::make_unique(); + DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + drm.context.setPairQueryValue = 0; + drm.context.setPairQueryReturn = 0; + EXPECT_FALSE(drm.setPairAvailable); + + EXPECT_EQ(0u, drm.context.setPairQueryCalled); + drm.callBaseIsSetPairAvailable = true; + EXPECT_FALSE(drm.isSetPairAvailable()); + EXPECT_FALSE(drm.setPairAvailable); + EXPECT_EQ(1u, drm.context.setPairQueryCalled); +} + +TEST(DrmResidencyHandlerTests, whenQueryingForSetPairAvailableAndSupportAvailableThenExpectedValueIsReturned) { + auto executionEnvironment = std::make_unique(); + DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + drm.context.setPairQueryValue = 1; + drm.context.setPairQueryReturn = 0; + EXPECT_FALSE(drm.setPairAvailable); + + EXPECT_EQ(0u, drm.context.setPairQueryCalled); + drm.callBaseIsSetPairAvailable = true; + EXPECT_TRUE(drm.isSetPairAvailable()); + EXPECT_TRUE(drm.setPairAvailable); + EXPECT_EQ(1u, drm.context.setPairQueryCalled); +} + +TEST(DrmResidencyHandlerTests, whenQueryingForSetPairAvailableAndFailureInQueryThenValueIsReturned) { + auto executionEnvironment = std::make_unique(); + DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + drm.context.setPairQueryValue = 1; + drm.context.setPairQueryReturn = 1; + EXPECT_FALSE(drm.setPairAvailable); + + EXPECT_EQ(0u, drm.context.setPairQueryCalled); + drm.callBaseIsSetPairAvailable = true; + EXPECT_FALSE(drm.isSetPairAvailable()); + EXPECT_FALSE(drm.setPairAvailable); + EXPECT_EQ(1u, drm.context.setPairQueryCalled); +} \ No newline at end of file diff --git a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp index 05420c6e5e..02f4029f5b 100644 --- a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp @@ -112,7 +112,7 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtThenReturnSuccess) auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0u, ret); @@ -127,7 +127,7 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithDebugFlagThenPr auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}); + ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, param: 0x1000000010001, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT has returned: 0 BO-1 with size: 1024\n"); diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp index c3283bb88f..aff9960a16 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp @@ -26,7 +26,7 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WhenCreateGemExtThenReturnCorrectValue) { auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, handle); @@ -47,7 +47,7 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WithDrmTipWhenCreateGemExtWithDebugFlagTh auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT with EXT_MEMORY_REGIONS has returned: 0 BO-1 with size: 1024\n"); @@ -68,7 +68,7 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WhenCreateGemExtWithDebugFlagThenPrintDeb auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT with EXT_MEMORY_REGIONS has returned: -1 BO-0 with size: 1024\nGEM_CREATE_EXT with EXT_SETPARAM has returned: 0 BO-1 with size: 1024\n"); diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp index ace72a1f75..03c81d55b7 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp @@ -204,7 +204,7 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenCreateGemExtThenReturnCorrectVal auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1); EXPECT_EQ(0u, ret); EXPECT_EQ(1u, handle); @@ -224,7 +224,7 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenCreateGemExtWithDebugFlagThenPri auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}); + ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT with EXT_MEMORY_REGIONS has returned: 0 BO-1 with size: 1024\n"); diff --git a/third_party/uapi/prelim/drm/i915_drm_prelim.h b/third_party/uapi/prelim/drm/i915_drm_prelim.h index 9d6c30d3ae..d7984dd048 100644 --- a/third_party/uapi/prelim/drm/i915_drm_prelim.h +++ b/third_party/uapi/prelim/drm/i915_drm_prelim.h @@ -248,6 +248,10 @@ struct prelim_drm_i915_gem_context_create_ext_clone { /* Recoverable pagefault support */ #define PRELIM_I915_PARAM_HAS_PAGE_FAULT (PRELIM_I915_PARAM | 7) + +/* Implicit scale support */ +#define PRELIM_I915_PARAM_HAS_SET_PAIR (PRELIM_I915_PARAM | 8) + /* End getparam */ struct prelim_drm_i915_gem_create_ext { @@ -301,6 +305,7 @@ struct prelim_drm_i915_gem_object_param { * .param = PRELIM_I915_OBJECT_PARAM | PRELIM_I915_PARAM_MEMORY_REGIONS */ #define PRELIM_I915_PARAM_MEMORY_REGIONS ((1 << 16) | 0x1) +#define PRELIM_I915_PARAM_SET_PAIR ((1 << 17) | 0x1) __u64 param; /* Data value or pointer */