fix: add rootDeviceIndex for BufferObjectHandleWrapper

Modified sharedBoHandles to use the (boHandle, rootDeviceIndex) pair
as a key instead of boHandle, and added rootDeviceIndex variable in
the BufferObjectHandleWrapper class of drm_buffer_object.h.

Previously sharedBoHandles uses boHandle as a key. However, this will
not work with the system using multiple devices, because each devices
can return the same handle to refer different memory region.

Related-To: GSD-9024
Signed-off-by: Young Jin Yoon <young.jin.yoon@intel.com>
This commit is contained in:
Young Jin Yoon
2024-09-10 00:41:25 +00:00
committed by Compute-Runtime-Automation
parent ea5b586c37
commit 675ec13439
6 changed files with 156 additions and 49 deletions

View File

@@ -1002,30 +1002,33 @@ TEST_F(DrmBufferObjectTest, whenBoRequiresExplicitResidencyThenTheCorrespondingQ
TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperConstructedFromNonSharedHandleThenControlBlockIsNotCreatedAndInternalHandleIsStored) {
constexpr int boHandle{5};
MockBufferObjectHandleWrapper boHandleWrapper{boHandle};
MockBufferObjectHandleWrapper boHandleWrapper{boHandle, 1u};
EXPECT_EQ(nullptr, boHandleWrapper.controlBlock);
EXPECT_EQ(boHandle, boHandleWrapper.getBoHandle());
EXPECT_EQ(1u, boHandleWrapper.getRootDeviceIndex());
}
TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperConstructedFromNonSharedHandleWhenAskingIfCanBeClosedThenReturnTrue) {
constexpr int boHandle{21};
MockBufferObjectHandleWrapper boHandleWrapper{boHandle};
MockBufferObjectHandleWrapper boHandleWrapper{boHandle, 1u};
EXPECT_TRUE(boHandleWrapper.canCloseBoHandle());
}
TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperWhenSettingNewValueThenStoreIt) {
constexpr int boHandle{13};
MockBufferObjectHandleWrapper boHandleWrapper{boHandle};
MockBufferObjectHandleWrapper boHandleWrapper{boHandle, 1u};
boHandleWrapper.setBoHandle(-1);
boHandleWrapper.setRootDeviceIndex(4u);
EXPECT_EQ(-1, boHandleWrapper.getBoHandle());
EXPECT_EQ(4u, boHandleWrapper.getRootDeviceIndex());
}
TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperConstructedFromNonSharedHandleWhenMakingItSharedThenControlBlockIsCreatedAndReferenceCounterIsValid) {
constexpr int boHandle{85};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle, 1u};
MockBufferObjectHandleWrapper secondBoHandleWrapper = firstBoHandleWrapper.acquireSharedOwnership();
ASSERT_NE(nullptr, firstBoHandleWrapper.controlBlock);
@@ -1039,7 +1042,7 @@ TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperConstructedFromNonSharedHandl
TEST(DrmBufferObjectHandleWrapperTest, GivenMoreThanOneSharedHandleWrapperWhenAskingIfHandleCanBeClosedThenReturnFalse) {
constexpr int boHandle{121};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle, 1u};
MockBufferObjectHandleWrapper secondBoHandleWrapper = firstBoHandleWrapper.acquireSharedOwnership();
EXPECT_FALSE(firstBoHandleWrapper.canCloseBoHandle());
@@ -1048,7 +1051,7 @@ TEST(DrmBufferObjectHandleWrapperTest, GivenMoreThanOneSharedHandleWrapperWhenAs
TEST(DrmBufferObjectHandleWrapperTest, GivenControlBlockCreatedWhenOnlyOneReferenceLeftThenHandleCanBeClosed) {
constexpr int boHandle{121};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle, 1u};
{
MockBufferObjectHandleWrapper secondBoHandleWrapper = firstBoHandleWrapper.acquireSharedOwnership();
@@ -1065,7 +1068,7 @@ TEST(DrmBufferObjectHandleWrapperTest, GivenControlBlockCreatedWhenOnlyOneRefere
TEST(DrmBufferObjectHandleWrapperTest, GivenControlBlockCreatedWhenOnlyWeakReferencesLeftThenItIsNotDestroyed) {
constexpr int boHandle{777};
auto firstBoHandleWrapper = std::make_unique<MockBufferObjectHandleWrapper>(boHandle);
auto firstBoHandleWrapper = std::make_unique<MockBufferObjectHandleWrapper>(boHandle, 1u);
MockBufferObjectHandleWrapper weakHandleWrapper = firstBoHandleWrapper->acquireWeakOwnership();
ASSERT_NE(nullptr, firstBoHandleWrapper->controlBlock);
@@ -1080,7 +1083,7 @@ TEST(DrmBufferObjectHandleWrapperTest, GivenControlBlockCreatedWhenOnlyWeakRefer
TEST(DrmBufferObjectHandleWrapperTest, GivenControlBlockCreatedWhenWeakReferencesLeftAndOnlyOneStrongReferenceLeftThenHandleCanBeClosed) {
constexpr int boHandle{353};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle, 1u};
MockBufferObjectHandleWrapper firstWeakHandleWrapper = firstBoHandleWrapper.acquireWeakOwnership();
MockBufferObjectHandleWrapper secondWeakHandleWrapper = firstBoHandleWrapper.acquireWeakOwnership();
@@ -1099,7 +1102,7 @@ TEST(DrmBufferObjectHandleWrapperTest, GivenControlBlockCreatedWhenWeakReference
TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperWhenConstructingMoreThanTwoSharedResourcesControlBlockRemainsTheSameAndReferenceCounterIsUpdatedOnCreationAndDestruction) {
constexpr int boHandle{85};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle, 1u};
MockBufferObjectHandleWrapper secondBoHandleWrapper = firstBoHandleWrapper.acquireSharedOwnership();
ASSERT_EQ(firstBoHandleWrapper.controlBlock, secondBoHandleWrapper.controlBlock);
@@ -1121,7 +1124,7 @@ TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperWhenConstructingMoreThanTwoSh
TEST(DrmBufferObjectHandleWrapperTest, GivenWrapperWhenMoveConstructingAnotherObjectThenInternalDataIsCleared) {
constexpr int boHandle{27};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle};
MockBufferObjectHandleWrapper firstBoHandleWrapper{boHandle, 1u};
MockBufferObjectHandleWrapper secondBoHandleWrapper = firstBoHandleWrapper.acquireSharedOwnership();
auto oldControlBlock = firstBoHandleWrapper.controlBlock;
@@ -1186,4 +1189,4 @@ TEST_F(DrmBufferObjectTest, givenBufferObjectWhenSetIsLockableIsCalledThenIsLock
bo.setIsLockable(isLockable);
EXPECT_EQ(isLockable, bo.isLockable());
}
}
}

View File

@@ -1098,7 +1098,7 @@ TEST_F(DrmMemoryManagerTest, GivenAllocationWhenTryingToRegisterIpcExportedThenI
for (auto *bo : bos) {
if (bo) {
EXPECT_TRUE(bo->isBoHandleShared());
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(bo->getHandle()));
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(bo->getHandle(), rootDeviceIndex)));
}
}
@@ -1110,26 +1110,64 @@ TEST_F(DrmMemoryManagerTest, GivenEmptySharedBoHandlesContainerWhenTryingToGetSh
ASSERT_TRUE(memoryManager->sharedBoHandles.empty());
const int someNonregisteredHandle{123};
auto boHandleWrapper = memoryManager->tryToGetBoHandleWrapperWithSharedOwnership(someNonregisteredHandle);
auto boHandleWrapper = memoryManager->tryToGetBoHandleWrapperWithSharedOwnership(someNonregisteredHandle, rootDeviceIndex);
EXPECT_EQ(someNonregisteredHandle, boHandleWrapper.getBoHandle());
EXPECT_TRUE(memoryManager->sharedBoHandles.empty());
}
TEST_F(DrmMemoryManagerTest, GivenWrapperInBoHandlesContainerWhenTryingToGetSharedOwnershipOfWrappedHandleThenGetSharedOwnership) {
const int boHandle{27};
BufferObjectHandleWrapper boHandleWrapper{boHandle};
BufferObjectHandleWrapper boHandleWrapper{boHandle, rootDeviceIndex};
memoryManager->sharedBoHandles.emplace(boHandle, boHandleWrapper.acquireWeakOwnership());
ASSERT_EQ(1u, memoryManager->sharedBoHandles.count(boHandle));
memoryManager->sharedBoHandles.emplace(std::make_pair(boHandle, rootDeviceIndex), boHandleWrapper.acquireWeakOwnership());
ASSERT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex)));
{
auto newBoHandleWrapper = memoryManager->tryToGetBoHandleWrapperWithSharedOwnership(boHandle);
auto newBoHandleWrapper = memoryManager->tryToGetBoHandleWrapperWithSharedOwnership(boHandle, rootDeviceIndex);
EXPECT_EQ(boHandle, newBoHandleWrapper.getBoHandle());
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(boHandle));
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex)));
EXPECT_FALSE(newBoHandleWrapper.canCloseBoHandle());
}
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(boHandle));
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex)));
EXPECT_TRUE(boHandleWrapper.canCloseBoHandle());
}
TEST_F(DrmMemoryManagerTest, GivenWrapperInBoHandlesContainerWhenTryingToGetSharedOwnershipOfWrappedHandleWithDifferentDeviceIndexThenGetNonSharedOwnership) {
const int boHandle{27};
BufferObjectHandleWrapper boHandleWrapper{boHandle, rootDeviceIndex};
memoryManager->sharedBoHandles.emplace(std::make_pair(boHandle, rootDeviceIndex), boHandleWrapper.acquireWeakOwnership());
ASSERT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex)));
{
auto newBoHandleWrapper = memoryManager->tryToGetBoHandleWrapperWithSharedOwnership(boHandle, rootDeviceIndex + 1);
EXPECT_EQ(boHandle, newBoHandleWrapper.getBoHandle());
EXPECT_NE(rootDeviceIndex, newBoHandleWrapper.getRootDeviceIndex());
EXPECT_EQ(0u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex + 1)));
EXPECT_TRUE(newBoHandleWrapper.canCloseBoHandle());
}
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex)));
EXPECT_TRUE(boHandleWrapper.canCloseBoHandle());
}
TEST_F(DrmMemoryManagerTest, GivenWrapperInBoHandlesContainerWhenTryingToGetSharedOwnershipOfWrappedHandleWithDifferentHandleIndexPairThenGetNonSharedOwnership) {
const int boHandle{27};
BufferObjectHandleWrapper boHandleWrapper{boHandle, rootDeviceIndex};
memoryManager->sharedBoHandles.emplace(std::make_pair(boHandle, rootDeviceIndex), boHandleWrapper.acquireWeakOwnership());
ASSERT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex)));
{
auto newBoHandleWrapper = memoryManager->tryToGetBoHandleWrapperWithSharedOwnership(boHandle + 1, rootDeviceIndex + 1);
EXPECT_NE(boHandle, newBoHandleWrapper.getBoHandle());
EXPECT_NE(rootDeviceIndex, newBoHandleWrapper.getRootDeviceIndex());
EXPECT_EQ(0u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle + 1, rootDeviceIndex + 1)));
EXPECT_TRUE(newBoHandleWrapper.canCloseBoHandle());
}
EXPECT_EQ(1u, memoryManager->sharedBoHandles.count(std::make_pair(boHandle, rootDeviceIndex)));
EXPECT_TRUE(boHandleWrapper.canCloseBoHandle());
}
@@ -3992,7 +4030,7 @@ TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
EXPECT_NE(bo1, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo1->getHandle()), mock->outputHandle);
EXPECT_FALSE(bo1->isBoHandleShared());
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(mock->outputHandle);
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex));
EXPECT_EQ(boHandleWrapperIt1, std::end(memoryManager->sharedBoHandles));
memoryManager->freeGraphicsMemory(gfxAllocation1);
@@ -4019,7 +4057,7 @@ TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
EXPECT_NE(bo1, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo1->getHandle()), mock->outputHandle);
EXPECT_FALSE(bo1->isBoHandleShared());
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(mock->outputHandle);
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex));
EXPECT_EQ(boHandleWrapperIt1, std::end(memoryManager->sharedBoHandles));
memoryManager->freeGraphicsMemory(gfxAllocation1);
@@ -4046,7 +4084,7 @@ TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
EXPECT_NE(bo1, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo1->getHandle()), mock->outputHandle);
EXPECT_TRUE(bo1->isBoHandleShared());
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(mock->outputHandle);
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex));
EXPECT_NE(boHandleWrapperIt1, std::end(memoryManager->sharedBoHandles));
EXPECT_TRUE(boHandleWrapperIt1->second.canCloseBoHandle());
@@ -4059,7 +4097,7 @@ TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
EXPECT_NE(bo2, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo2->getHandle()), mock->outputHandle);
EXPECT_TRUE(bo2->isBoHandleShared());
auto boHandleWrapperIt2 = memoryManager->sharedBoHandles.find(mock->outputHandle);
auto boHandleWrapperIt2 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex));
EXPECT_EQ(boHandleWrapperIt2, boHandleWrapperIt1);
EXPECT_FALSE(boHandleWrapperIt2->second.canCloseBoHandle());
@@ -4069,6 +4107,59 @@ TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
memoryManager->freeGraphicsMemory(gfxAllocation1);
}
TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
givenIPCBoHandleAndSharedAllocationReuseDisabledWhenMultipleAllocationsCreatedFromDifferentDevicesThenBoHandlesAreClosedSeparately) {
const bool reuseSharedAllocation = false;
mock->ioctlExpected.primeFdToHandle = 1;
mock->ioctlExpected.gemWait = 1;
mock->ioctlExpected.gemClose = 1;
mock->outputHandle = 88u;
bool isHostIpcAllocation = GetParam();
AllocationProperties properties(rootDeviceIndex, false, 4096u, AllocationType::sharedBuffer, false, {});
TestedDrmMemoryManager::OsHandleData osHandleData1{11u};
auto gfxAllocation1 = memoryManager->createGraphicsAllocationFromSharedHandle(&osHandleData1, properties, false, isHostIpcAllocation, reuseSharedAllocation, nullptr);
DrmAllocation *drmAllocation1 = static_cast<DrmAllocation *>(gfxAllocation1);
ASSERT_NE(nullptr, drmAllocation1);
// BoHandle registered as shared but with WEAK ownership - GEM_CLOSE can be called on it
auto bo1 = drmAllocation1->getBO();
EXPECT_NE(bo1, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo1->getHandle()), mock->outputHandle);
EXPECT_TRUE(bo1->isBoHandleShared());
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex));
EXPECT_NE(boHandleWrapperIt1, std::end(memoryManager->sharedBoHandles));
EXPECT_TRUE(boHandleWrapperIt1->second.canCloseBoHandle());
TestedDrmMemoryManager::OsHandleData osHandleData2{12u};
// two devices in the system, rootDeviceIndex is set to 1, so set rootDeviceInext to 0
auto rootDeviceIndex2 = 0;
auto rootDeviceEnvironment2 = executionEnvironment->rootDeviceEnvironments[rootDeviceIndex2].get();
auto mock2 = static_cast<DrmMockCustom *>(rootDeviceEnvironment2->osInterface->getDriverModel()->as<Drm>());
mock2->ioctlExpected.primeFdToHandle = 1;
mock2->ioctlExpected.gemWait = 1;
mock2->ioctlExpected.gemClose = 1;
mock2->outputHandle = 88u;
AllocationProperties properties2(rootDeviceIndex2, false, 4096u, AllocationType::sharedBuffer, false, {});
auto gfxAllocation2 = memoryManager->createGraphicsAllocationFromSharedHandle(&osHandleData2, properties2, false, isHostIpcAllocation, false, nullptr);
DrmAllocation *drmAllocation2 = static_cast<DrmAllocation *>(gfxAllocation2);
ASSERT_NE(nullptr, drmAllocation2);
// BoHandle registered as shared with WEAK ownership because it's from different root devices - GEM_CLOSE can be called on it
auto bo2 = drmAllocation2->getBO();
EXPECT_NE(bo2, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo2->getHandle()), mock->outputHandle);
EXPECT_TRUE(bo2->isBoHandleShared());
auto boHandleWrapperIt2 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex2));
EXPECT_NE(boHandleWrapperIt2, boHandleWrapperIt1);
EXPECT_TRUE(boHandleWrapperIt2->second.canCloseBoHandle());
memoryManager->freeGraphicsMemory(gfxAllocation2);
memoryManager->freeGraphicsMemory(gfxAllocation1);
mock2->testIoctls();
mock2->reset();
}
TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
givenIPCBoHandleAndSharedAllocationReuseDisabledWhenMultipleAllocationsCreatedFromMultipleSharedHandlesFromSingleProcessThenBoHandleIsClosedOnlyOnce) {
const bool reuseSharedAllocation = false;
@@ -4090,7 +4181,7 @@ TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
EXPECT_NE(bo1, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo1->getHandle()), mock->outputHandle);
EXPECT_TRUE(bo1->isBoHandleShared());
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(mock->outputHandle);
auto boHandleWrapperIt1 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex));
EXPECT_NE(boHandleWrapperIt1, std::end(memoryManager->sharedBoHandles));
EXPECT_TRUE(boHandleWrapperIt1->second.canCloseBoHandle());
@@ -4103,7 +4194,7 @@ TEST_P(DrmMemoryManagerWithHostIpcAllocationParamTest,
EXPECT_NE(bo2, nullptr);
EXPECT_EQ(static_cast<uint32_t>(bo2->getHandle()), mock->outputHandle);
EXPECT_TRUE(bo2->isBoHandleShared());
auto boHandleWrapperIt2 = memoryManager->sharedBoHandles.find(mock->outputHandle);
auto boHandleWrapperIt2 = memoryManager->sharedBoHandles.find(std::make_pair(mock->outputHandle, rootDeviceIndex));
EXPECT_EQ(boHandleWrapperIt2, boHandleWrapperIt1);
EXPECT_FALSE(boHandleWrapperIt2->second.canCloseBoHandle());