From f3d36d335058673cd740b9c93c8cb930392f906c Mon Sep 17 00:00:00 2001 From: Maciej Plewka Date: Tue, 26 Mar 2024 12:22:28 +0000 Subject: [PATCH] feature: bind resources as read only Related-to: NEO-10398 Signed-off-by: Maciej Plewka --- .../memory_manager/graphics_allocation.cpp | 10 +++ .../memory_manager/graphics_allocation.h | 2 + .../source/memory_manager/memory_manager.cpp | 8 ++ .../os_interface/linux/drm_allocation.cpp | 9 ++ .../os_interface/linux/drm_allocation.h | 1 + .../os_interface/linux/drm_buffer_object.h | 9 ++ shared/source/os_interface/linux/drm_neo.cpp | 4 +- .../source/os_interface/linux/ioctl_helper.h | 6 +- .../linux/ioctl_helper_prelim.cpp | 5 +- .../linux/ioctl_helper_upstream.cpp | 2 +- .../os_interface/linux/xe/ioctl_helper_xe.cpp | 4 +- .../os_interface/linux/xe/ioctl_helper_xe.h | 2 +- shared/source/os_interface/product_helper.h | 1 + shared/source/os_interface/product_helper.inl | 5 ++ .../source/os_interface/product_helper_hw.h | 1 + .../pvc/os_agnostic_product_helper_pvc.inl | 5 ++ .../common/mocks/mock_graphics_allocation.h | 5 +- .../test/common/mocks/mock_memory_manager.cpp | 4 + .../test/common/mocks/mock_memory_manager.h | 5 +- .../test/common/mocks/mock_product_helper.h | 4 +- .../graphics_allocation_tests.cpp | 31 +++++++ ...nager_allocate_in_preferred_pool_tests.cpp | 85 +++++++++++++++++++ .../linux/ioctl_helper_tests_prelim.cpp | 34 +++++--- .../linux/ioctl_helper_tests_upstream.cpp | 6 +- .../linux/xe/ioctl_helper_xe_tests.cpp | 5 +- .../os_interface/product_helper_tests.cpp | 3 + .../xe_hpc_core/excludes_xe_hpc_core.cpp | 3 +- .../pvc/test_product_helper_pvc.cpp | 3 + 28 files changed, 230 insertions(+), 32 deletions(-) diff --git a/shared/source/memory_manager/graphics_allocation.cpp b/shared/source/memory_manager/graphics_allocation.cpp index a5dc3b5920..4a4cd13578 100644 --- a/shared/source/memory_manager/graphics_allocation.cpp +++ b/shared/source/memory_manager/graphics_allocation.cpp @@ -138,6 +138,16 @@ void GraphicsAllocation::updateCompletionDataForAllocationAndFragments(uint64_t } } +bool GraphicsAllocation::hasAllocationReadOnlyType() { + if (getAllocationType() == AllocationType::kernelIsa || + getAllocationType() == AllocationType::kernelIsaInternal || + getAllocationType() == AllocationType::commandBuffer || + getAllocationType() == AllocationType::linearStream) { + return true; + } + return false; +} + constexpr TaskCountType GraphicsAllocation::objectNotUsed; constexpr TaskCountType GraphicsAllocation::objectNotResident; constexpr TaskCountType GraphicsAllocation::objectAlwaysResident; diff --git a/shared/source/memory_manager/graphics_allocation.h b/shared/source/memory_manager/graphics_allocation.h index c9ff1c19ec..b81f90cef1 100644 --- a/shared/source/memory_manager/graphics_allocation.h +++ b/shared/source/memory_manager/graphics_allocation.h @@ -155,6 +155,7 @@ class GraphicsAllocation : public IDNode { AllocationType getAllocationType() const { return allocationType; } MemoryPool getMemoryPool() const { return memoryPool; } + virtual void setAsReadOnly(){}; bool isUsed() const { return registeredContextsNum > 0; } bool isUsedByManyOsContexts() const { return registeredContextsNum > 1u; } @@ -316,6 +317,7 @@ class GraphicsAllocation : public IDNode { MOCKABLE_VIRTUAL void updateCompletionDataForAllocationAndFragments(uint64_t newFenceValue, uint32_t contextId); void setShareableHostMemory(bool shareableHostMemory) { this->shareableHostMemory = shareableHostMemory; } bool isShareableHostMemory() const { return shareableHostMemory; } + MOCKABLE_VIRTUAL bool hasAllocationReadOnlyType(); OsHandleStorage fragmentsStorage; StorageInfo storageInfo = {}; diff --git a/shared/source/memory_manager/memory_manager.cpp b/shared/source/memory_manager/memory_manager.cpp index 7c51194d3d..371502e132 100644 --- a/shared/source/memory_manager/memory_manager.cpp +++ b/shared/source/memory_manager/memory_manager.cpp @@ -642,6 +642,14 @@ GraphicsAllocation *MemoryManager::allocateGraphicsMemoryInPreferredPool(const A return nullptr; } + auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex]; + auto &productHelper = rootDeviceEnvironment.getProductHelper(); + if (productHelper.supportReadOnlyAllocations() && + allocation->hasAllocationReadOnlyType() && + !productHelper.isBlitCopyRequiredForLocalMemory(rootDeviceEnvironment, *allocation)) { + allocation->setAsReadOnly(); + } + fileLoggerInstance().logAllocation(allocation); registerAllocationInOs(allocation); return allocation; diff --git a/shared/source/os_interface/linux/drm_allocation.cpp b/shared/source/os_interface/linux/drm_allocation.cpp index b29cfd94b6..d4d2d26d1f 100644 --- a/shared/source/os_interface/linux/drm_allocation.cpp +++ b/shared/source/os_interface/linux/drm_allocation.cpp @@ -339,6 +339,15 @@ void DrmAllocation::registerBOBindExtHandle(Drm *drm) { drm->getIoctlHelper()->registerBOBindHandle(drm, this); } +void DrmAllocation::setAsReadOnly() { + auto &bos = getBOs(); + for (auto bo : bos) { + if (bo) { + bo->setAsReadOnly(true); + } + } +} + void DrmAllocation::linkWithRegisteredHandle(uint32_t handle) { auto &bos = getBOs(); for (auto bo : bos) { diff --git a/shared/source/os_interface/linux/drm_allocation.h b/shared/source/os_interface/linux/drm_allocation.h index 19837a2212..9916b386be 100644 --- a/shared/source/os_interface/linux/drm_allocation.h +++ b/shared/source/os_interface/linux/drm_allocation.h @@ -148,6 +148,7 @@ class DrmAllocation : public GraphicsAllocation { MOCKABLE_VIRTUAL void markForCapture(); MOCKABLE_VIRTUAL bool shouldAllocationPageFault(const Drm *drm); void registerMemoryToUnmap(void *pointer, size_t size, MemoryUnmapFunction unmapFunction); + void setAsReadOnly() override; protected: OsContextLinux *osContext = nullptr; diff --git a/shared/source/os_interface/linux/drm_buffer_object.h b/shared/source/os_interface/linux/drm_buffer_object.h index b6596be8c7..4254e40519 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.h +++ b/shared/source/os_interface/linux/drm_buffer_object.h @@ -164,6 +164,14 @@ class BufferObject { bool isImmediateBindingRequired() { return requiresImmediateBinding; } + bool isReadOnlyGpuResource() { + return readOnlyGpuResource; + } + + void setAsReadOnly(bool isReadOnly) { + readOnlyGpuResource = isReadOnly; + } + void requireImmediateBinding(bool required) { requiresImmediateBinding = required; } @@ -260,5 +268,6 @@ class BufferObject { bool requiresExplicitResidency = false; bool chunked = false; bool isReused = false; + bool readOnlyGpuResource = false; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index e23e8965fc..6f7a814fa8 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -1309,11 +1309,13 @@ int changeBufferObjectBinding(Drm *drm, OsContext *osContext, uint32_t vmHandleI bool bindCapture = bo->isMarkedForCapture(); bool bindImmediate = bo->isImmediateBindingRequired(); bool bindMakeResident = false; + bool readOnlyResource = bo->isReadOnlyGpuResource(); + if (drm->useVMBindImmediate()) { bindMakeResident = bo->isExplicitResidencyRequired(); bindImmediate = true; } - flags |= ioctlHelper->getFlagsForVmBind(bindCapture, bindImmediate, bindMakeResident); + flags |= ioctlHelper->getFlagsForVmBind(bindCapture, bindImmediate, bindMakeResident, readOnlyResource); } auto &bindAddresses = bo->getColourAddresses(); diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index 3bfc3a8dd4..4806247a58 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -116,7 +116,7 @@ class IoctlHelper { virtual bool getGemTiling(void *setTiling) = 0; virtual uint32_t getDirectSubmissionFlag() = 0; virtual std::unique_ptr prepareVmBindExt(const StackVec &bindExtHandles) = 0; - virtual uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) = 0; + virtual uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool readOnlyResource) = 0; virtual int queryDistances(std::vector &queryItems, std::vector &distanceInfos) = 0; virtual uint16_t getWaitUserFenceSoftFlag() = 0; virtual int execBuffer(ExecBuffer *execBuffer, uint64_t completionGpuAddress, TaskCountType counterValue) = 0; @@ -259,7 +259,7 @@ class IoctlHelperUpstream : public IoctlHelperI915 { bool setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) override; uint32_t getDirectSubmissionFlag() override; std::unique_ptr prepareVmBindExt(const StackVec &bindExtHandles) override; - uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) override; + uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool readOnlyResource) override; int queryDistances(std::vector &queryItems, std::vector &distanceInfos) override; uint16_t getWaitUserFenceSoftFlag() override; int execBuffer(ExecBuffer *execBuffer, uint64_t completionGpuAddress, TaskCountType counterValue) override; @@ -336,7 +336,7 @@ class IoctlHelperPrelim20 : public IoctlHelperI915 { bool setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) override; uint32_t getDirectSubmissionFlag() override; std::unique_ptr prepareVmBindExt(const StackVec &bindExtHandles) override; - uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) override; + uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool readOnlyResource) override; int queryDistances(std::vector &queryItems, std::vector &distanceInfos) override; uint16_t getWaitUserFenceSoftFlag() override; int execBuffer(ExecBuffer *execBuffer, uint64_t completionGpuAddress, TaskCountType counterValue) override; diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 59cd64b584..bfce00e61d 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -507,7 +507,7 @@ std::unique_ptr IoctlHelperPrelim20::prepareVmBindExt(const StackVec< return extensionsBuffer; } -uint64_t IoctlHelperPrelim20::getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) { +uint64_t IoctlHelperPrelim20::getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool readOnlyResource) { uint64_t flags = 0u; if (bindCapture) { flags |= PRELIM_I915_GEM_VM_BIND_CAPTURE; @@ -518,6 +518,9 @@ uint64_t IoctlHelperPrelim20::getFlagsForVmBind(bool bindCapture, bool bindImmed if (bindMakeResident) { flags |= PRELIM_I915_GEM_VM_BIND_MAKE_RESIDENT; } + if (readOnlyResource) { + flags |= PRELIM_I915_GEM_VM_BIND_READONLY; + } return flags; } diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index 839d483526..1e4cbf9941 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -168,7 +168,7 @@ std::unique_ptr IoctlHelperUpstream::prepareVmBindExt(const StackVec< return {}; } -uint64_t IoctlHelperUpstream::getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) { +uint64_t IoctlHelperUpstream::getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool readOnlyResource) { return 0u; } diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index 082da786f9..f0eec814e2 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -748,9 +748,9 @@ bool IoctlHelperXe::completionFenceExtensionSupported(const bool isVmBindAvailab return isVmBindAvailable; } -uint64_t IoctlHelperXe::getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) { +uint64_t IoctlHelperXe::getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool readOnlyResource) { uint64_t ret = 0; - xeLog(" -> IoctlHelperXe::%s %d %d %d\n", __FUNCTION__, bindCapture, bindImmediate, bindMakeResident); + xeLog(" -> IoctlHelperXe::%s %d %d %d\n", __FUNCTION__, bindCapture, bindImmediate, bindMakeResident, readOnlyResource); if (bindCapture) { ret |= XE_NEO_BIND_CAPTURE_FLAG; } diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h index c93a49299c..3dcf37fa23 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h @@ -76,7 +76,7 @@ class IoctlHelperXe : public IoctlHelper { bool getGemTiling(void *setTiling) override; uint32_t getDirectSubmissionFlag() override; std::unique_ptr prepareVmBindExt(const StackVec &bindExtHandles) override; - uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) override; + uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool readOnlyResource) override; int queryDistances(std::vector &queryItems, std::vector &distanceInfos) override; uint16_t getWaitUserFenceSoftFlag() override; int execBuffer(ExecBuffer *execBuffer, uint64_t completionGpuAddress, TaskCountType counterValue) override; diff --git a/shared/source/os_interface/product_helper.h b/shared/source/os_interface/product_helper.h index 2238764946..1eb80ab66e 100644 --- a/shared/source/os_interface/product_helper.h +++ b/shared/source/os_interface/product_helper.h @@ -231,6 +231,7 @@ class ProductHelper { virtual bool isCachingOnCpuAvailable() const = 0; virtual bool isNewCoherencyModelSupported() const = 0; virtual const std::vector getSupportedLocalDispatchSizes() const = 0; + virtual bool supportReadOnlyAllocations() const = 0; virtual ~ProductHelper() = default; diff --git a/shared/source/os_interface/product_helper.inl b/shared/source/os_interface/product_helper.inl index f48c8f6b0e..9b6b9d85d5 100644 --- a/shared/source/os_interface/product_helper.inl +++ b/shared/source/os_interface/product_helper.inl @@ -867,6 +867,11 @@ bool ProductHelperHw::isNewCoherencyModelSupported() const { return false; } +template +bool ProductHelperHw::supportReadOnlyAllocations() const { + return false; +} + template const std::vector ProductHelperHw::getSupportedLocalDispatchSizes() const { return {}; diff --git a/shared/source/os_interface/product_helper_hw.h b/shared/source/os_interface/product_helper_hw.h index b338ec42e1..39114de276 100644 --- a/shared/source/os_interface/product_helper_hw.h +++ b/shared/source/os_interface/product_helper_hw.h @@ -175,6 +175,7 @@ class ProductHelperHw : public ProductHelper { std::optional getPreferredAllocationMethod(AllocationType allocationType) const override; bool isCachingOnCpuAvailable() const override; bool isNewCoherencyModelSupported() const override; + bool supportReadOnlyAllocations() const override; const std::vector getSupportedLocalDispatchSizes() const override; ~ProductHelperHw() override = default; diff --git a/shared/source/xe_hpc_core/pvc/os_agnostic_product_helper_pvc.inl b/shared/source/xe_hpc_core/pvc/os_agnostic_product_helper_pvc.inl index 8e7a0b0a06..ac49ce8aa3 100644 --- a/shared/source/xe_hpc_core/pvc/os_agnostic_product_helper_pvc.inl +++ b/shared/source/xe_hpc_core/pvc/os_agnostic_product_helper_pvc.inl @@ -237,4 +237,9 @@ bool ProductHelperHw::isSkippingStatefulInformationRequired(const Ke return isGeneratedByNgen; } +template <> +bool ProductHelperHw::supportReadOnlyAllocations() const { + return true; +} + } // namespace NEO diff --git a/shared/test/common/mocks/mock_graphics_allocation.h b/shared/test/common/mocks/mock_graphics_allocation.h index c017be08fe..2043d9b3bd 100644 --- a/shared/test/common/mocks/mock_graphics_allocation.h +++ b/shared/test/common/mocks/mock_graphics_allocation.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -19,6 +19,7 @@ inline constexpr DeviceBitfield mockDeviceBitfield(0b1); class MockGraphicsAllocation : public MemoryAllocation { public: + using BaseClass = MemoryAllocation; using MemoryAllocation::allocationOffset; using MemoryAllocation::allocationType; using MemoryAllocation::aubInfo; @@ -62,6 +63,8 @@ class MockGraphicsAllocation : public MemoryAllocation { updateCompletionDataForAllocationAndFragmentsCalledtimes++; MemoryAllocation::updateCompletionDataForAllocationAndFragments(newFenceValue, contextId); } + ADDMETHOD(hasAllocationReadOnlyType, bool, false, false, (), ()); + ADDMETHOD_VOIDRETURN(setAsReadOnly, false, (), ()); uint64_t updateCompletionDataForAllocationAndFragmentsCalledtimes = 0; int peekInternalHandleResult = 0; diff --git a/shared/test/common/mocks/mock_memory_manager.cpp b/shared/test/common/mocks/mock_memory_manager.cpp index 3e44ac7712..038f545084 100644 --- a/shared/test/common/mocks/mock_memory_manager.cpp +++ b/shared/test/common/mocks/mock_memory_manager.cpp @@ -143,6 +143,10 @@ GraphicsAllocation *MockMemoryManager::allocateGraphicsMemory64kb(const Allocati } GraphicsAllocation *MockMemoryManager::allocateGraphicsMemoryInDevicePool(const AllocationData &allocationData, AllocationStatus &status) { + if (returnMockGAFromDevicePool) { + status = AllocationStatus::Success; + return mockGa; + } if (failInDevicePool) { status = AllocationStatus::RetryInNonDevicePool; return nullptr; diff --git a/shared/test/common/mocks/mock_memory_manager.h b/shared/test/common/mocks/mock_memory_manager.h index 7157d5d7fc..2ad1e40330 100644 --- a/shared/test/common/mocks/mock_memory_manager.h +++ b/shared/test/common/mocks/mock_memory_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -11,6 +11,7 @@ #include "shared/source/memory_manager/multi_graphics_allocation.h" #include "shared/source/memory_manager/os_agnostic_memory_manager.h" #include "shared/test/common/mocks/mock_execution_environment.h" +#include "shared/test/common/mocks/mock_graphics_allocation.h" #include "shared/test/common/test_macros/mock_method_macros.h" namespace NEO { @@ -212,6 +213,7 @@ class MockMemoryManager : public MemoryManagerCreate { return OsAgnosticMemoryManager::mapPhysicalToVirtualMemory(physicalAllocation, gpuRange, bufferSize); }; + MockGraphicsAllocation *mockGa; uint32_t copyMemoryToAllocationBanksCalled = 0u; uint32_t populateOsHandlesCalled = 0u; uint32_t allocateGraphicsMemoryForNonSvmHostPtrCalled = 0u; @@ -261,6 +263,7 @@ class MockMemoryManager : public MemoryManagerCreate { bool callBasePopulateOsHandles = true; bool callBaseAllocateGraphicsMemoryForNonSvmHostPtr = true; bool failMapPhysicalToVirtualMemory = false; + bool returnMockGAFromDevicePool = false; std::unique_ptr mockExecutionEnvironment; DeviceBitfield recentlyPassedDeviceBitfield{}; std::unique_ptr waitAllocations = nullptr; diff --git a/shared/test/common/mocks/mock_product_helper.h b/shared/test/common/mocks/mock_product_helper.h index 5fa89d0f94..438f90ec05 100644 --- a/shared/test/common/mocks/mock_product_helper.h +++ b/shared/test/common/mocks/mock_product_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Intel Corporation + * Copyright (C) 2023-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -18,5 +18,7 @@ struct MockProductHelper : ProductHelperHw { ADDMETHOD_CONST_NOBASE(is48bResourceNeededForRayTracing, bool, true, ()); ADDMETHOD_CONST_NOBASE(overrideAllocationCacheable, bool, false, (const AllocationData &allocationData)); ADDMETHOD_NOBASE(configureHwInfoWddm, int, 0, (const HardwareInfo *inHwInfo, HardwareInfo *outHwInfo, const RootDeviceEnvironment &rootDeviceEnvironment)); + ADDMETHOD_CONST_NOBASE(supportReadOnlyAllocations, bool, false, ()); + ADDMETHOD_CONST_NOBASE(isBlitCopyRequiredForLocalMemory, bool, true, (const RootDeviceEnvironment &rootDeviceEnvironment, const GraphicsAllocation &allocation)); }; } // namespace NEO diff --git a/shared/test/unit_test/memory_manager/graphics_allocation_tests.cpp b/shared/test/unit_test/memory_manager/graphics_allocation_tests.cpp index 662c9498b3..6decfe6b65 100644 --- a/shared/test/unit_test/memory_manager/graphics_allocation_tests.cpp +++ b/shared/test/unit_test/memory_manager/graphics_allocation_tests.cpp @@ -560,3 +560,34 @@ TEST(GraphicsAllocationTest, givenGraphicsAllocationsWithFragmentsWhenCallingFor EXPECT_EQ(residencyData->getFenceValueForContextId(contextId), newFenceValue); } } +TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsKernelIsaThenAllocationHasReadonlyType) { + MockGraphicsAllocation graphicsAllocation; + graphicsAllocation.hasAllocationReadOnlyTypeCallBase = true; + graphicsAllocation.allocationType = AllocationType::kernelIsa; + EXPECT_TRUE(graphicsAllocation.hasAllocationReadOnlyType()); +} + +TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsInternalIsaThenAllocationHasReadonlyType) { + MockGraphicsAllocation graphicsAllocation; + graphicsAllocation.hasAllocationReadOnlyTypeCallBase = true; + graphicsAllocation.allocationType = AllocationType::kernelIsaInternal; + EXPECT_TRUE(graphicsAllocation.hasAllocationReadOnlyType()); +} +TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsCommandBufferThenAllocationHasReadonlyType) { + MockGraphicsAllocation graphicsAllocation; + graphicsAllocation.hasAllocationReadOnlyTypeCallBase = true; + graphicsAllocation.allocationType = AllocationType::commandBuffer; + EXPECT_TRUE(graphicsAllocation.hasAllocationReadOnlyType()); +} +TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsLinearStreamThenAllocationHasReadonlyType) { + MockGraphicsAllocation graphicsAllocation; + graphicsAllocation.hasAllocationReadOnlyTypeCallBase = true; + graphicsAllocation.allocationType = AllocationType::linearStream; + EXPECT_TRUE(graphicsAllocation.hasAllocationReadOnlyType()); +} +TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsBufferThenAllocationHasNotReadonlyType) { + MockGraphicsAllocation graphicsAllocation; + graphicsAllocation.hasAllocationReadOnlyTypeCallBase = true; + graphicsAllocation.allocationType = AllocationType::buffer; + EXPECT_FALSE(graphicsAllocation.hasAllocationReadOnlyType()); +} \ No newline at end of file diff --git a/shared/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.cpp b/shared/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.cpp index b26b6a1a60..2f8edf53a5 100644 --- a/shared/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.cpp +++ b/shared/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.cpp @@ -18,6 +18,7 @@ #include "shared/test/common/mocks/mock_graphics_allocation.h" #include "shared/test/common/mocks/mock_memory_manager.h" #include "shared/test/common/mocks/mock_os_context.h" +#include "shared/test/common/mocks/mock_product_helper.h" #include "shared/test/common/mocks/ult_device_factory.h" #include "shared/test/common/test_macros/hw_test.h" @@ -1013,6 +1014,90 @@ TEST(MemoryManagerTest, givenPropertiesWithGpuAddressWhenGetAllocationDataIsCall EXPECT_EQ(properties.gpuAddress, allocData.gpuAddress); } +TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndPlatrormSupportReadOnlyAllocationAndBliterTransferNotRequiredThenAllocationIsSetAsReadOnly) { + MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); + auto mockProductHelper = std::make_unique(); + mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = false; + mockProductHelper->supportReadOnlyAllocationsResult = true; + std::unique_ptr productHelper = std::move(mockProductHelper); + std::swap(executionEnvironment.rootDeviceEnvironments[0]->productHelper, productHelper); + MockMemoryManager memoryManager(false, true, executionEnvironment); + MockGraphicsAllocation mockGa; + + mockGa.hasAllocationReadOnlyTypeResult = true; + + memoryManager.mockGa = &mockGa; + memoryManager.returnMockGAFromDevicePool = true; + + auto allocation = memoryManager.allocateGraphicsMemoryInPreferredPool({mockRootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, mockDeviceBitfield}, + nullptr); + EXPECT_EQ(allocation, &mockGa); + EXPECT_EQ(mockGa.setAsReadOnlyCalled, 1u); +} + +TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndSupportReadOnlyButPtlatformDoesNotAndBliterTransferNotRequiredThenAllocationIsNotSetAsReadOnly) { + MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); + auto mockProductHelper = std::make_unique(); + mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = false; + mockProductHelper->supportReadOnlyAllocationsResult = false; + std::unique_ptr productHelper = std::move(mockProductHelper); + std::swap(executionEnvironment.rootDeviceEnvironments[0]->productHelper, productHelper); + MockMemoryManager memoryManager(false, true, executionEnvironment); + MockGraphicsAllocation mockGa; + + mockGa.hasAllocationReadOnlyTypeResult = true; + + memoryManager.mockGa = &mockGa; + memoryManager.returnMockGAFromDevicePool = true; + + auto allocation = memoryManager.allocateGraphicsMemoryInPreferredPool({mockRootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, mockDeviceBitfield}, + nullptr); + EXPECT_EQ(allocation, &mockGa); + EXPECT_EQ(mockGa.setAsReadOnlyCalled, 0u); +} + +TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndPlatrormSupportReadOnlyAllocationAndBliterTransferRequiredThenAllocationIsNotSetAsReadOnly) { + MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); + auto mockProductHelper = std::make_unique(); + mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = true; + mockProductHelper->supportReadOnlyAllocationsResult = true; + std::unique_ptr productHelper = std::move(mockProductHelper); + std::swap(executionEnvironment.rootDeviceEnvironments[0]->productHelper, productHelper); + MockMemoryManager memoryManager(false, true, executionEnvironment); + MockGraphicsAllocation mockGa; + + mockGa.hasAllocationReadOnlyTypeResult = true; + + memoryManager.mockGa = &mockGa; + memoryManager.returnMockGAFromDevicePool = true; + + auto allocation = memoryManager.allocateGraphicsMemoryInPreferredPool({mockRootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, mockDeviceBitfield}, + nullptr); + EXPECT_EQ(allocation, &mockGa); + EXPECT_EQ(mockGa.setAsReadOnlyCalled, 0u); +} + +TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndDoesNotSupportReadOnlyButPtlatformDoesAndBliterTransferNotRequiredThenAllocationIsNotSetAsReadOnly) { + MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); + auto mockProductHelper = std::make_unique(); + mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = false; + mockProductHelper->supportReadOnlyAllocationsResult = true; + std::unique_ptr productHelper = std::move(mockProductHelper); + std::swap(executionEnvironment.rootDeviceEnvironments[0]->productHelper, productHelper); + MockMemoryManager memoryManager(false, true, executionEnvironment); + MockGraphicsAllocation mockGa; + + mockGa.hasAllocationReadOnlyTypeResult = false; + + memoryManager.mockGa = &mockGa; + memoryManager.returnMockGAFromDevicePool = true; + + auto allocation = memoryManager.allocateGraphicsMemoryInPreferredPool({mockRootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, mockDeviceBitfield}, + nullptr); + EXPECT_EQ(allocation, &mockGa); + EXPECT_EQ(mockGa.setAsReadOnlyCalled, 0u); +} + TEST(MemoryManagerTest, givenEnableLocalMemoryAndMemoryManagerWhenBufferTypeIsPassedThenAllocateGraphicsMemoryInPreferredPool) { MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); MockMemoryManager memoryManager(false, true, executionEnvironment); diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp index 0b494985f9..8b95cd0ef8 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp @@ -266,20 +266,26 @@ TEST_F(IoctlPrelimHelperTests, whenGettingFlagsForVmBindThenProperValuesAreRetur for (auto &bindCapture : ::testing::Bool()) { for (auto &bindImmediate : ::testing::Bool()) { for (auto &bindMakeResident : ::testing::Bool()) { - auto flags = ioctlHelper.getFlagsForVmBind(bindCapture, bindImmediate, bindMakeResident); - if (bindCapture) { - EXPECT_EQ(PRELIM_I915_GEM_VM_BIND_CAPTURE, (flags & PRELIM_I915_GEM_VM_BIND_CAPTURE)); - } - if (bindImmediate) { - EXPECT_EQ(PRELIM_I915_GEM_VM_BIND_IMMEDIATE, (flags & PRELIM_I915_GEM_VM_BIND_IMMEDIATE)); - } - if (bindMakeResident) { - EXPECT_EQ(PRELIM_I915_GEM_VM_BIND_MAKE_RESIDENT, (flags & PRELIM_I915_GEM_VM_BIND_MAKE_RESIDENT)); - } - if (flags == 0) { - EXPECT_FALSE(bindCapture); - EXPECT_FALSE(bindImmediate); - EXPECT_FALSE(bindMakeResident); + for (auto &readOnlyResource : ::testing::Bool()) { + auto flags = ioctlHelper.getFlagsForVmBind(bindCapture, bindImmediate, bindMakeResident, readOnlyResource); + if (bindCapture) { + EXPECT_EQ(PRELIM_I915_GEM_VM_BIND_CAPTURE, (flags & PRELIM_I915_GEM_VM_BIND_CAPTURE)); + } + if (bindImmediate) { + EXPECT_EQ(PRELIM_I915_GEM_VM_BIND_IMMEDIATE, (flags & PRELIM_I915_GEM_VM_BIND_IMMEDIATE)); + } + if (bindMakeResident) { + EXPECT_EQ(PRELIM_I915_GEM_VM_BIND_MAKE_RESIDENT, (flags & PRELIM_I915_GEM_VM_BIND_MAKE_RESIDENT)); + } + if (readOnlyResource) { + EXPECT_EQ(PRELIM_I915_GEM_VM_BIND_READONLY, (flags & PRELIM_I915_GEM_VM_BIND_READONLY)); + } + if (flags == 0) { + EXPECT_FALSE(bindCapture); + EXPECT_FALSE(bindImmediate); + EXPECT_FALSE(bindMakeResident); + EXPECT_FALSE(readOnlyResource); + } } } } 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 8f3a079c32..d5d2321965 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 @@ -318,8 +318,10 @@ TEST(IoctlHelperUpstreamTest, whenGettingFlagsForVmBindThenZeroIsReturned) { for (auto &bindCapture : ::testing::Bool()) { for (auto &bindImmediate : ::testing::Bool()) { for (auto &bindMakeResident : ::testing::Bool()) { - auto flags = ioctlHelper.getFlagsForVmBind(bindCapture, bindImmediate, bindMakeResident); - EXPECT_EQ(0u, flags); + for (auto &readOnlyResource : ::testing::Bool()) { + auto flags = ioctlHelper.getFlagsForVmBind(bindCapture, bindImmediate, bindMakeResident, readOnlyResource); + EXPECT_EQ(0u, flags); + } } } } diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp index 5adbbce278..e0b6c768dd 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp @@ -263,8 +263,7 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe EXPECT_EQ(0u, xeIoctlHelper->getDirectSubmissionFlag()); - EXPECT_EQ(0u, xeIoctlHelper->getFlagsForVmBind(false, false, false)); - + EXPECT_EQ(0u, xeIoctlHelper->getFlagsForVmBind(false, false, false, false)); std::vector queryItems; std::vector distanceInfos; EXPECT_EQ(0, xeIoctlHelper->queryDistances(queryItems, distanceInfos)); @@ -407,7 +406,7 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe EXPECT_EQ(static_cast(XE_NEO_BIND_CAPTURE_FLAG | XE_NEO_BIND_IMMEDIATE_FLAG | XE_NEO_BIND_MAKERESIDENT_FLAG), - xeIoctlHelper->getFlagsForVmBind(true, true, true)); + xeIoctlHelper->getFlagsForVmBind(true, true, true, true)); uint32_t fabricId = 0, latency = 0, bandwidth = 0; EXPECT_FALSE(xeIoctlHelper->getFabricLatency(fabricId, latency, bandwidth)); diff --git a/shared/test/unit_test/os_interface/product_helper_tests.cpp b/shared/test/unit_test/os_interface/product_helper_tests.cpp index c7a826c1fd..5486a519fc 100644 --- a/shared/test/unit_test/os_interface/product_helper_tests.cpp +++ b/shared/test/unit_test/os_interface/product_helper_tests.cpp @@ -912,4 +912,7 @@ HWTEST_F(ProductHelperTest, givenProductHelperWhenAskingForExtraKerneCapabilitie uint32_t extraKernelCapabilities = 0u; productHelper->getKernelCapabilitiesExtra(extraKernelCapabilities); EXPECT_EQ(0u, extraKernelCapabilities); +} +HWTEST_F(ProductHelperTest, givenProductHelperWhenAskingForReadOnlyResourceSupportThenFalseReturned) { + EXPECT_FALSE(productHelper->supportReadOnlyAllocations()); } \ No newline at end of file diff --git a/shared/test/unit_test/xe_hpc_core/excludes_xe_hpc_core.cpp b/shared/test/unit_test/xe_hpc_core/excludes_xe_hpc_core.cpp index e92e6b9723..82e4d69dae 100644 --- a/shared/test/unit_test/xe_hpc_core/excludes_xe_hpc_core.cpp +++ b/shared/test/unit_test/xe_hpc_core/excludes_xe_hpc_core.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 Intel Corporation + * Copyright (C) 2021-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -46,3 +46,4 @@ HWTEST_EXCLUDE_PRODUCT(GetAllocationDataTestHw, givenSemaphoreBufferAllocationWh HWTEST_EXCLUDE_PRODUCT(MemoryManagerGetAlloctionDataTests, givenCommandBufferAllocationTypeWhenGetAllocationDataIsCalledThenSystemMemoryIsRequested, IGFX_XE_HPC_CORE); HWTEST_EXCLUDE_PRODUCT(ProductHelperTest, givenProductHelperWhenAskedIfPatIndexProgrammingSupportedThenReturnFalse, IGFX_XE_HPC_CORE); HWTEST_EXCLUDE_PRODUCT(ProductHelperTest, givenProductHelperWhenAskedIfPageFaultIsSupportedThenReturnFalse, IGFX_XE_HPC_CORE); +HWTEST_EXCLUDE_PRODUCT(ProductHelperTest, givenProductHelperWhenAskingForReadOnlyResourceSupportThenFalseReturned, IGFX_XE_HPC_CORE); diff --git a/shared/test/unit_test/xe_hpc_core/pvc/test_product_helper_pvc.cpp b/shared/test/unit_test/xe_hpc_core/pvc/test_product_helper_pvc.cpp index 0ca0c2002a..504cd77d2a 100644 --- a/shared/test/unit_test/xe_hpc_core/pvc/test_product_helper_pvc.cpp +++ b/shared/test/unit_test/xe_hpc_core/pvc/test_product_helper_pvc.cpp @@ -332,3 +332,6 @@ PVCTEST_F(PvcProductHelper, whenQueryingMaxNumSamplersThenReturnZero) { PVCTEST_F(PvcProductHelper, whenCheckingIfDummyBlitWaIsRequiredThenTrueIsReturned) { EXPECT_TRUE(productHelper->isDummyBlitWaRequired()); } +PVCTEST_F(PvcProductHelper, givenProductHelperWhenAskingForReadOnlyResourceSupportThenTrueReturned) { + EXPECT_TRUE(productHelper->supportReadOnlyAllocations()); +}