feature: Bind command buffer allocations as read only

Related-To: NEO-10398
Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
This commit is contained in:
Plewka, Maciej
2024-03-29 10:17:04 +00:00
committed by Compute-Runtime-Automation
parent f0a24a650c
commit 5c15aaf48a
7 changed files with 115 additions and 13 deletions

View File

@@ -365,11 +365,11 @@ bool DirectSubmissionHw<GfxFamily, Dispatcher>::allocateResources() {
allocations.push_back(deferredTasksListAllocation);
const AllocationProperties relaxedOrderingSchedulerAllocationProperties(rootDeviceIndex,
true, MemoryConstants::pageSize64k,
AllocationType::commandBuffer,
isMultiOsContextCapable, false, osContext.getDeviceBitfield());
AllocationProperties relaxedOrderingSchedulerAllocationProperties(rootDeviceIndex,
true, MemoryConstants::pageSize64k,
AllocationType::commandBuffer,
isMultiOsContextCapable, false, osContext.getDeviceBitfield());
relaxedOrderingSchedulerAllocationProperties.flags.cantBeReadOnly = true;
relaxedOrderingSchedulerAllocation = memoryManager->allocateGraphicsMemoryWithProperties(relaxedOrderingSchedulerAllocationProperties);
UNRECOVERABLE_IF(relaxedOrderingSchedulerAllocation == nullptr);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Intel Corporation
* Copyright (C) 2019-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -28,7 +28,8 @@ struct AllocationProperties {
uint32_t use32BitFrontWindow : 1;
uint32_t forceSystemMemory : 1;
uint32_t preferCompressed : 1;
uint32_t reserved : 18;
uint32_t cantBeReadOnly : 1;
uint32_t reserved : 17;
} flags;
uint32_t allFlags = 0;
};

View File

@@ -12,6 +12,7 @@
#include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/bit_helpers.h"
#include "shared/source/memory_manager/allocation_properties.h"
#include "shared/source/memory_manager/memory_manager.h"
#include "shared/source/os_interface/os_context.h"
#include "shared/source/utilities/logger.h"
@@ -140,9 +141,11 @@ void GraphicsAllocation::updateCompletionDataForAllocationAndFragments(uint64_t
bool GraphicsAllocation::hasAllocationReadOnlyType() {
if (allocationType == AllocationType::kernelIsa ||
allocationType == AllocationType::kernelIsaInternal) {
allocationType == AllocationType::kernelIsaInternal ||
allocationType == AllocationType::commandBuffer) {
return true;
}
if (debugManager.flags.ReadOnlyAllocationsTypeMask.get() != 0) {
UNRECOVERABLE_IF(allocationType == AllocationType::unknown);
auto maskVal = debugManager.flags.ReadOnlyAllocationsTypeMask.get();
@@ -153,6 +156,15 @@ bool GraphicsAllocation::hasAllocationReadOnlyType() {
return false;
}
void GraphicsAllocation::checkAllocationTypeReadOnlyRestrictions(const AllocationProperties &properties) {
if (getAllocationType() == AllocationType::commandBuffer &&
(properties.flags.cantBeReadOnly | properties.flags.multiOsContextCapable)) {
setAsCantBeReadOnly(true);
return;
}
setAsCantBeReadOnly(!hasAllocationReadOnlyType());
}
constexpr TaskCountType GraphicsAllocation::objectNotUsed;
constexpr TaskCountType GraphicsAllocation::objectNotResident;
constexpr TaskCountType GraphicsAllocation::objectAlwaysResident;

View File

@@ -37,6 +37,8 @@ class MemoryManager;
class CommandStreamReceiver;
class GraphicsAllocation;
struct AllocationProperties;
struct AubInfo {
uint32_t aubWritable = std::numeric_limits<uint32_t>::max();
uint32_t tbxWritable = std::numeric_limits<uint32_t>::max();
@@ -316,10 +318,17 @@ class GraphicsAllocation : public IDNode<GraphicsAllocation> {
SurfaceStateInHeapInfo getBindlessInfo() {
return bindlessInfo;
}
bool canBeReadOnly() {
return !cantBeReadOnly;
}
void setAsCantBeReadOnly(bool cantBeReadOnly) {
this->cantBeReadOnly = cantBeReadOnly;
}
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();
MOCKABLE_VIRTUAL void checkAllocationTypeReadOnlyRestrictions(const AllocationProperties &properties);
OsHandleStorage fragmentsStorage;
StorageInfo storageInfo = {};
@@ -396,5 +405,6 @@ class GraphicsAllocation : public IDNode<GraphicsAllocation> {
ResidencyData residency;
std::atomic<uint32_t> registeredContextsNum{0};
bool shareableHostMemory = false;
bool cantBeReadOnly = false;
};
} // namespace NEO

View File

@@ -43,6 +43,7 @@
#include "shared/source/page_fault_manager/cpu_page_fault_manager.h"
#include <algorithm>
#include <iostream>
namespace NEO {
uint32_t MemoryManager::maxOsContextCount = 0u;
@@ -641,12 +642,13 @@ GraphicsAllocation *MemoryManager::allocateGraphicsMemoryInPreferredPool(const A
if (!allocation) {
return nullptr;
}
allocation->checkAllocationTypeReadOnlyRestrictions(properties);
auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex];
auto &productHelper = rootDeviceEnvironment.getProductHelper();
if (productHelper.supportReadOnlyAllocations() &&
allocation->hasAllocationReadOnlyType() &&
!productHelper.isBlitCopyRequiredForLocalMemory(rootDeviceEnvironment, *allocation)) {
!productHelper.isBlitCopyRequiredForLocalMemory(rootDeviceEnvironment, *allocation) &&
allocation->canBeReadOnly()) {
allocation->setAsReadOnly();
}

View File

@@ -623,14 +623,14 @@ TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsInterna
graphicsAllocation.allocationType = AllocationType::kernelIsaInternal;
EXPECT_TRUE(graphicsAllocation.hasAllocationReadOnlyType());
}
TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsCommandBufferAndMaskDoesNotSupportItThenAllocationHasNotReadonlyType) {
TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsCommandBufferAndMaskDoesNotSupportItThenAllocationHasReadonlyType) {
DebugManagerStateRestore restorer;
auto mask = 1llu << (static_cast<int64_t>(AllocationType::kernelIsaInternal) - 1);
debugManager.flags.ReadOnlyAllocationsTypeMask.set(mask);
MockGraphicsAllocation graphicsAllocation;
graphicsAllocation.hasAllocationReadOnlyTypeCallBase = true;
graphicsAllocation.allocationType = AllocationType::commandBuffer;
EXPECT_FALSE(graphicsAllocation.hasAllocationReadOnlyType());
EXPECT_TRUE(graphicsAllocation.hasAllocationReadOnlyType());
}
TEST(GraphicsAllocationTest, givenGraphicsAllocationsWhenAllocationTypeIsLinearStreamAndMaskDoesNotSupportItThenAllocationHasNotReadonlyType) {
DebugManagerStateRestore restorer;

View File

@@ -1077,7 +1077,7 @@ TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndPlatrormSupportRe
EXPECT_EQ(mockGa.setAsReadOnlyCalled, 0u);
}
TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndDoesNotSupportReadOnlyButPtlatformDoesAndBliterTransferNotRequiredThenAllocationIsNotSetAsReadOnly) {
TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeDoesNotSupportReadOnlyButPtlatformDoesAndBliterTransferNotRequiredThenAllocationIsNotSetAsReadOnly) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
auto mockProductHelper = std::make_unique<MockProductHelper>();
mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = false;
@@ -1098,6 +1098,83 @@ TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndDoesNotSupportRea
EXPECT_EQ(mockGa.setAsReadOnlyCalled, 0u);
}
TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationIsCommandBufferAndItIsSetAsNotReadOnlyThenAllocationIsNotSetAsReadOnly) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
auto mockProductHelper = std::make_unique<MockProductHelper>();
mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = false;
mockProductHelper->supportReadOnlyAllocationsResult = true;
std::unique_ptr<ProductHelper> productHelper = std::move(mockProductHelper);
std::swap(executionEnvironment.rootDeviceEnvironments[0]->productHelper, productHelper);
MockMemoryManager memoryManager(false, true, executionEnvironment);
MockGraphicsAllocation mockGa;
mockGa.setAllocationType(AllocationType::commandBuffer);
mockGa.hasAllocationReadOnlyTypeResult = true;
memoryManager.mockGa = &mockGa;
memoryManager.returnMockGAFromDevicePool = true;
AllocationProperties properties(mockRootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, mockDeviceBitfield);
properties.flags.cantBeReadOnly = true;
properties.flags.multiOsContextCapable = false;
auto allocation = memoryManager.allocateGraphicsMemoryInPreferredPool(properties,
nullptr);
EXPECT_EQ(allocation, &mockGa);
EXPECT_EQ(mockGa.setAsReadOnlyCalled, 0u);
}
TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationIsCommandBufferAndMultiContextCapableIsTrueThenAllocationIsNotSetAsReadOnly) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
auto mockProductHelper = std::make_unique<MockProductHelper>();
mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = false;
mockProductHelper->supportReadOnlyAllocationsResult = true;
std::unique_ptr<ProductHelper> productHelper = std::move(mockProductHelper);
std::swap(executionEnvironment.rootDeviceEnvironments[0]->productHelper, productHelper);
MockMemoryManager memoryManager(false, true, executionEnvironment);
MockGraphicsAllocation mockGa;
mockGa.setAllocationType(AllocationType::commandBuffer);
mockGa.hasAllocationReadOnlyTypeResult = true;
memoryManager.mockGa = &mockGa;
memoryManager.returnMockGAFromDevicePool = true;
AllocationProperties properties(mockRootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, mockDeviceBitfield);
properties.flags.cantBeReadOnly = false;
properties.flags.multiOsContextCapable = true;
auto allocation = memoryManager.allocateGraphicsMemoryInPreferredPool(properties,
nullptr);
EXPECT_EQ(allocation, &mockGa);
EXPECT_EQ(mockGa.setAsReadOnlyCalled, 0u);
}
TEST(MemoryManagerTest, givenMemoryManagerWhenAllocationTypeAndPlatrormSupportReadOnlyAllocationBliterAndAllocationTypeOtherThanCmdBufferTransferNotRequiredThenAllocationIsSetAsReadOnly) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
auto mockProductHelper = std::make_unique<MockProductHelper>();
mockProductHelper->isBlitCopyRequiredForLocalMemoryResult = false;
mockProductHelper->supportReadOnlyAllocationsResult = true;
std::unique_ptr<ProductHelper> productHelper = std::move(mockProductHelper);
std::swap(executionEnvironment.rootDeviceEnvironments[0]->productHelper, productHelper);
MockMemoryManager memoryManager(false, true, executionEnvironment);
MockGraphicsAllocation mockGa;
mockGa.setAllocationType(AllocationType::buffer);
mockGa.hasAllocationReadOnlyTypeResult = true;
memoryManager.mockGa = &mockGa;
memoryManager.returnMockGAFromDevicePool = true;
AllocationProperties properties(mockRootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, mockDeviceBitfield);
properties.flags.cantBeReadOnly = true;
properties.flags.multiOsContextCapable = true;
auto allocation = memoryManager.allocateGraphicsMemoryInPreferredPool(properties,
nullptr);
EXPECT_EQ(allocation, &mockGa);
EXPECT_EQ(mockGa.setAsReadOnlyCalled, 1u);
}
TEST(MemoryManagerTest, givenEnableLocalMemoryAndMemoryManagerWhenBufferTypeIsPassedThenAllocateGraphicsMemoryInPreferredPool) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
MockMemoryManager memoryManager(false, true, executionEnvironment);