diff --git a/level_zero/core/source/cmdlist/cmdlist_hw.inl b/level_zero/core/source/cmdlist/cmdlist_hw.inl index 6108372f0c..b50e4faa64 100644 --- a/level_zero/core/source/cmdlist/cmdlist_hw.inl +++ b/level_zero/core/source/cmdlist/cmdlist_hw.inl @@ -1469,8 +1469,11 @@ inline AlignedAllocationData CommandListCoreFamily::getAlignedAll if (srcAllocFound == false) { alloc = device->getDriverHandle()->findHostPointerAllocation(ptr, static_cast(bufferSize), device->getRootDeviceIndex()); if (alloc != nullptr) { - alignedPtr = static_cast(alloc->getGpuAddress()); - offset = reinterpret_cast(ptr) - reinterpret_cast(alloc->getUnderlyingBuffer()); + alignedPtr = static_cast(alignDown(alloc->getGpuAddress(), NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment())); + //get offset from GPUVA of allocation to align down GPU address + offset = static_cast(alloc->getGpuAddress()) - alignedPtr; + //get offset from base of allocation to arg address + offset += reinterpret_cast(ptr) - reinterpret_cast(alloc->getUnderlyingBuffer()); } else { alloc = getHostPtrAlloc(buffer, bufferSize); alignedPtr = static_cast(alignDown(alloc->getGpuAddress(), NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment())); diff --git a/level_zero/core/source/driver/host_pointer_manager.cpp b/level_zero/core/source/driver/host_pointer_manager.cpp index 20809479d2..ec55acfadb 100644 --- a/level_zero/core/source/driver/host_pointer_manager.cpp +++ b/level_zero/core/source/driver/host_pointer_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -61,39 +61,36 @@ HostPointerManager::~HostPointerManager() { } ze_result_t HostPointerManager::createHostPointerMultiAllocation(std::vector &devices, void *ptr, size_t size) { - if (size == 0) { + if (size == 0 || ptr == nullptr) { return ZE_RESULT_ERROR_INVALID_ARGUMENT; } - void *basePtr = alignDown(ptr, MemoryConstants::pageSize); size_t endAddress = reinterpret_cast(ptr) + size; - endAddress = alignUp(endAddress, MemoryConstants::pageSize); - size_t totalSize = endAddress - reinterpret_cast(basePtr); std::unique_lock lock(this->mtx); - auto baseAllocation = hostPointerAllocations.get(basePtr); + auto beginAllocation = hostPointerAllocations.get(ptr); auto endingAllocation = hostPointerAllocations.get(reinterpret_cast(endAddress - 1)); - if (baseAllocation != nullptr && baseAllocation == endingAllocation) { + if (beginAllocation != nullptr && beginAllocation == endingAllocation) { return ZE_RESULT_SUCCESS; } - if (baseAllocation != nullptr) { + if (beginAllocation != nullptr) { if (endingAllocation != nullptr) { return ZE_RESULT_ERROR_OVERLAPPING_REGIONS; } return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE; } if (endingAllocation != nullptr) { - UNRECOVERABLE_IF(endingAllocation->basePtr == basePtr); + UNRECOVERABLE_IF(endingAllocation->basePtr == ptr); return ZE_RESULT_ERROR_INVALID_SIZE; } HostPointerData hostData(static_cast(devices.size() - 1)); - hostData.basePtr = basePtr; - hostData.size = totalSize; + hostData.basePtr = ptr; + hostData.size = size; for (auto device : devices) { NEO::GraphicsAllocation *gfxAlloc = createHostPointerAllocation(device->getRootDeviceIndex(), - basePtr, - totalSize, + ptr, + size, device->getNEODevice()->getDeviceBitfield()); if (gfxAlloc == nullptr) { auto allocations = hostData.hostPtrAllocations.getGraphicsAllocations(); diff --git a/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_3.cpp b/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_3.cpp index da1c653959..a2c2c0c580 100644 --- a/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_3.cpp +++ b/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_3.cpp @@ -1141,31 +1141,37 @@ HWTEST2_F(HostPointerManagerCommandListTest, auto commandList = std::make_unique<::L0::ult::CommandListCoreFamily>(); commandList->initialize(device, NEO::EngineGroupType::RenderCompute); - size_t pointerSize = MemoryConstants::pageSize; - size_t offset = 100; - void *offsetPointer = ptrOffset(heapPointer, offset); + size_t mainOffset = 100; + size_t importSize = 100; + void *importPointer = ptrOffset(heapPointer, mainOffset); - auto ret = hostDriverHandle->importExternalPointer(offsetPointer, offset); + auto ret = hostDriverHandle->importExternalPointer(importPointer, importSize); EXPECT_EQ(ZE_RESULT_SUCCESS, ret); - auto hostAllocation = hostDriverHandle->findHostPointerAllocation(heapPointer, pointerSize, device->getRootDeviceIndex()); + auto hostAllocation = hostDriverHandle->findHostPointerAllocation(importPointer, importSize, device->getRootDeviceIndex()); ASSERT_NE(nullptr, hostAllocation); - AlignedAllocationData outData = commandList->getAlignedAllocation(device, heapPointer, pointerSize); - auto expectedAlignedAddress = static_cast(hostAllocation->getGpuAddress()); - EXPECT_EQ(heapPointer, hostAllocation->getUnderlyingBuffer()); + size_t allocOffset = 10; + size_t offsetSize = 20; + void *offsetPointer = ptrOffset(importPointer, allocOffset); + + AlignedAllocationData outData = commandList->getAlignedAllocation(device, importPointer, importSize); + auto gpuBaseAddress = static_cast(hostAllocation->getGpuAddress()); + auto expectedAlignedAddress = alignDown(gpuBaseAddress, NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment()); + size_t expectedOffset = gpuBaseAddress - expectedAlignedAddress; + EXPECT_EQ(importPointer, hostAllocation->getUnderlyingBuffer()); EXPECT_EQ(expectedAlignedAddress, outData.alignedAllocationPtr); EXPECT_EQ(hostAllocation, outData.alloc); - EXPECT_EQ(0u, outData.offset); + EXPECT_EQ(expectedOffset, outData.offset); - outData = commandList->getAlignedAllocation(device, offsetPointer, 2u); - expectedAlignedAddress = static_cast(hostAllocation->getGpuAddress()); - EXPECT_EQ(heapPointer, hostAllocation->getUnderlyingBuffer()); + outData = commandList->getAlignedAllocation(device, offsetPointer, offsetSize); + expectedOffset += allocOffset; + EXPECT_EQ(importPointer, hostAllocation->getUnderlyingBuffer()); EXPECT_EQ(expectedAlignedAddress, outData.alignedAllocationPtr); EXPECT_EQ(hostAllocation, outData.alloc); - EXPECT_EQ(offset, outData.offset); + EXPECT_EQ(expectedOffset, outData.offset); - ret = hostDriverHandle->releaseImportedPointer(heapPointer); + ret = hostDriverHandle->releaseImportedPointer(importPointer); EXPECT_EQ(ZE_RESULT_SUCCESS, ret); } diff --git a/level_zero/core/test/unit_tests/sources/driver/host_pointer_manager_tests.cpp b/level_zero/core/test/unit_tests/sources/driver/host_pointer_manager_tests.cpp index 4ca5136508..096615395f 100644 --- a/level_zero/core/test/unit_tests/sources/driver/host_pointer_manager_tests.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/host_pointer_manager_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -164,6 +164,11 @@ TEST_F(HostPointerManagerTest, WhenSizeIsZeroThenExpectInvalidArgument) { EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result); } +TEST_F(HostPointerManagerTest, WhenPointerIsNullThenExpectInvalidArgument) { + auto result = hostDriverHandle->importExternalPointer(nullptr, 0x10); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result); +} + TEST_F(HostPointerManagerTest, givenNoPointerWhenImportAddressThenRegisterNewHostData) { void *testPtr = heapPointer; void *baseAddress; @@ -193,7 +198,7 @@ TEST_F(HostPointerManagerTest, givenNoPointerWhenImportMisalignedAddressThenRegi testPtr = reinterpret_cast(reinterpret_cast(testPtr) + 0x10); size_t size = 0x10; - void *baseAddress; + void *baseAddress = nullptr; auto result = hostDriverHandle->getHostPointerBaseAddress(testPtr, nullptr); EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result); @@ -206,10 +211,10 @@ TEST_F(HostPointerManagerTest, givenNoPointerWhenImportMisalignedAddressThenRegi result = hostDriverHandle->getHostPointerBaseAddress(testPtr, &baseAddress); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - EXPECT_EQ(heapPointer, baseAddress); + EXPECT_EQ(testPtr, baseAddress); auto hostPointerData = openHostPointerManager->hostPointerAllocations.get(testPtr); ASSERT_NE(nullptr, hostPointerData); - EXPECT_EQ(MemoryConstants::pageSize, hostPointerData->size); + EXPECT_EQ(size, hostPointerData->size); result = hostDriverHandle->releaseImportedPointer(testPtr); EXPECT_EQ(ZE_RESULT_SUCCESS, result); @@ -307,29 +312,41 @@ TEST_F(HostPointerManagerTest, givenPointerUsesTwoPagesThenBothPagesAreAvailable testPtr = reinterpret_cast(reinterpret_cast(testPtr) + 0x10); size_t size = MemoryConstants::pageSize; - void *baseAddress; + void *baseAddress = nullptr; auto result = hostDriverHandle->importExternalPointer(testPtr, size); EXPECT_EQ(ZE_RESULT_SUCCESS, result); result = hostDriverHandle->getHostPointerBaseAddress(testPtr, &baseAddress); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - EXPECT_EQ(heapPointer, baseAddress); + EXPECT_EQ(testPtr, baseAddress); auto hostPointerData = openHostPointerManager->hostPointerAllocations.get(testPtr); ASSERT_NE(nullptr, hostPointerData); - EXPECT_EQ(2 * MemoryConstants::pageSize, hostPointerData->size); + EXPECT_EQ(size, hostPointerData->size); - testPtr = reinterpret_cast(reinterpret_cast(testPtr) + MemoryConstants::pageSize); + void *testPtr2 = reinterpret_cast(reinterpret_cast(testPtr) + MemoryConstants::pageSize); size = 0x010; - result = hostDriverHandle->importExternalPointer(testPtr, size); + result = hostDriverHandle->importExternalPointer(testPtr2, size); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - result = hostDriverHandle->getHostPointerBaseAddress(testPtr, &baseAddress); + result = hostDriverHandle->getHostPointerBaseAddress(testPtr2, &baseAddress); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - EXPECT_EQ(heapPointer, baseAddress); + EXPECT_EQ(testPtr2, baseAddress); + auto hostPointerData2 = openHostPointerManager->hostPointerAllocations.get(testPtr2); + ASSERT_NE(nullptr, hostPointerData2); + EXPECT_EQ(size, hostPointerData2->size); + + EXPECT_EQ(hostPointerData->hostPtrAllocations.getGraphicsAllocations().size(), hostPointerData2->hostPtrAllocations.getGraphicsAllocations().size()); + for (uint32_t i = 0; i < hostPointerData->hostPtrAllocations.getGraphicsAllocations().size(); i++) { + auto hostPointerAllocation = hostPointerData->hostPtrAllocations.getGraphicsAllocation(i); + auto hostPointerAllocation2 = hostPointerData2->hostPtrAllocations.getGraphicsAllocation(i); + EXPECT_NE(hostPointerAllocation, hostPointerAllocation2); + } result = hostDriverHandle->releaseImportedPointer(testPtr); EXPECT_EQ(ZE_RESULT_SUCCESS, result); + result = hostDriverHandle->releaseImportedPointer(testPtr2); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); } TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenSizeFitsThenReturnGraphicsAllocation) { @@ -410,5 +427,30 @@ TEST_F(HostPointerManagerTest, givenHostAllocationImportedWhenMakingResidentAddr EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result); } +TEST_F(HostPointerManagerTest, givenMisalignedPointerRegisteredWhenGettingRelativeOffsetAddressThenRetrieveMisalignedPointerAsBaseAddress) { + size_t mainOffset = 0x10; + void *testPtr = reinterpret_cast(reinterpret_cast(heapPointer) + mainOffset); + size_t size = MemoryConstants::pageSize + 0x10; + + auto result = hostDriverHandle->importExternalPointer(testPtr, size); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + size_t relativeOffset = 0x20; + void *relativeAddress = ptrOffset(testPtr, relativeOffset); + void *baseAddress = nullptr; + result = hostDriverHandle->getHostPointerBaseAddress(relativeAddress, &baseAddress); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(testPtr, baseAddress); + + auto gfxAllocation = hostDriverHandle->findHostPointerAllocation(testPtr, 0x10u, device->getRootDeviceIndex()); + ASSERT_NE(nullptr, gfxAllocation); + size_t gpuVA = static_cast(gfxAllocation->getGpuAddress()); + size_t gpuAddressOffset = gpuVA - alignDown(gpuVA, MemoryConstants::pageSize); + EXPECT_EQ(mainOffset, gpuAddressOffset); + + result = hostDriverHandle->releaseImportedPointer(testPtr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + } // namespace ult } // namespace L0