Add advise for atomic and preferred location

If supported, allow atomic and preferred location
advises. Hide this logic under IoctlHelper.

Signed-off-by: Szymon Morek <szymon.morek@intel.com>
This commit is contained in:
Szymon Morek
2021-12-14 14:09:19 +00:00
committed by Compute-Runtime-Automation
parent ee18008750
commit 242b08d72b
7 changed files with 174 additions and 11 deletions

View File

@ -10,6 +10,7 @@
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/default_hw_info.h"
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/test_macros/test.h"
using namespace NEO;
@ -194,3 +195,65 @@ TEST(IoctlHelperTestsPrelim, givenPrelimsWhenGetHwConfigIoctlValThenCorrectValue
uint32_t ioctlVal = (1 << 16) | 6;
EXPECT_EQ(ioctlVal, IoctlHelper::get(drm.get())->getHwConfigIoctlVal());
}
TEST(IoctlHelperTestsPrelim, givenDrmAllocationWhenSetMemAdviseFailsThenDontUpdateMemAdviceFlags) {
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
DrmPrelimMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
drm.ioctlRetVal = -1;
MockBufferObject bo(&drm, 0, 0, 1);
MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::LocalMemory);
allocation.bufferObjects[0] = &bo;
MemAdviseFlags memAdviseFlags{};
memAdviseFlags.non_atomic = 1;
allocation.setMemAdvise(&drm, memAdviseFlags);
EXPECT_EQ(1u, drm.ioctlCallsCount);
EXPECT_NE(memAdviseFlags.memadvise_flags, allocation.enabledMemAdviseFlags.memadvise_flags);
}
TEST(IoctlHelperTestsPrelim, givenDrmAllocationWhenSetMemAdviseWithNonAtomicIsCalledThenUpdateTheCorrespondingVmAdviceForBufferObject) {
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
DrmPrelimMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
MockBufferObject bo(&drm, 0, 0, 1);
MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::LocalMemory);
allocation.bufferObjects[0] = &bo;
MemAdviseFlags memAdviseFlags{};
for (auto nonAtomic : {true, false}) {
memAdviseFlags.non_atomic = nonAtomic;
EXPECT_TRUE(allocation.setMemAdvise(&drm, memAdviseFlags));
EXPECT_EQ(memAdviseFlags.memadvise_flags, allocation.enabledMemAdviseFlags.memadvise_flags);
}
EXPECT_EQ(2u, drm.ioctlCallsCount);
}
TEST(IoctlHelperTestsPrelim, givenDrmAllocationWhenSetMemAdviseWithDevicePreferredLocationIsCalledThenUpdateTheCorrespondingVmAdviceForBufferObject) {
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
DrmPrelimMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
MockBufferObject bo(&drm, 0, 0, 1);
MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::LocalMemory);
allocation.bufferObjects[0] = &bo;
MemAdviseFlags memAdviseFlags{};
for (auto devicePreferredLocation : {true, false}) {
memAdviseFlags.device_preferred_location = devicePreferredLocation;
EXPECT_TRUE(allocation.setMemAdvise(&drm, memAdviseFlags));
EXPECT_EQ(memAdviseFlags.memadvise_flags, allocation.enabledMemAdviseFlags.memadvise_flags);
}
EXPECT_EQ(2u, drm.ioctlCallsCount);
}

View File

@ -91,3 +91,23 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenClosAllocWaysThenReturnZeroWays)
EXPECT_EQ(0, cacheRegion);
}
TEST(IoctlHelperTestsUpstream, givenUpstreamWhenGetAdviseThenReturnCorrectValue) {
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
auto ioctlHelper = IoctlHelper::get(drm.get());
EXPECT_EQ(0u, ioctlHelper->getAtomicAdvise(false));
EXPECT_EQ(0u, ioctlHelper->getAtomicAdvise(true));
EXPECT_EQ(0u, ioctlHelper->getPreferredLocationAdvise());
}
TEST(IoctlHelperTestsUpstream, givenUpstreamWhenSetVmBoAdviseThenReturnTrue) {
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
auto ioctlHelper = IoctlHelper::get(drm.get());
EXPECT_TRUE(ioctlHelper->setVmBoAdvise(drm.get(), 0, 0, nullptr));
}

View File

@ -10,6 +10,7 @@
#include "shared/source/memory_manager/residency.h"
#include "shared/source/os_interface/linux/drm_buffer_object.h"
#include "shared/source/os_interface/linux/drm_memory_manager.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include "shared/source/os_interface/os_context.h"
#include <sstream>
@ -167,4 +168,46 @@ void DrmAllocation::markForCapture() {
}
}
}
bool DrmAllocation::setMemAdvise(Drm *drm, MemAdviseFlags flags) {
bool success = true;
if (flags.cached_memory != enabledMemAdviseFlags.cached_memory) {
CachePolicy memType = flags.cached_memory ? CachePolicy::WriteBack : CachePolicy::Uncached;
setCachePolicy(memType);
}
auto ioctlHelper = IoctlHelper::get(drm);
if (flags.non_atomic != enabledMemAdviseFlags.non_atomic) {
for (auto bo : bufferObjects) {
if (bo != nullptr) {
success &= ioctlHelper->setVmBoAdvise(drm, bo->peekHandle(), ioctlHelper->getAtomicAdvise(flags.non_atomic), nullptr);
}
}
}
if (flags.device_preferred_location != enabledMemAdviseFlags.device_preferred_location) {
drm_i915_gem_memory_class_instance region{};
for (auto handleId = 0u; handleId < EngineLimits::maxHandleCount; handleId++) {
auto bo = bufferObjects[handleId];
if (bo != nullptr) {
if (flags.device_preferred_location) {
region.memory_class = I915_MEMORY_CLASS_DEVICE;
region.memory_instance = handleId;
} else {
region.memory_class = -1;
region.memory_instance = 0;
}
success &= ioctlHelper->setVmBoAdvise(drm, bo->peekHandle(), ioctlHelper->getPreferredLocationAdvise(), &region);
}
}
}
if (success) {
enabledMemAdviseFlags = flags;
}
return success;
}
} // namespace NEO

View File

@ -31,17 +31,6 @@ bool DrmAllocation::setCacheRegion(Drm *drm, CacheRegion regionIndex) {
return setCacheAdvice(drm, 0, regionIndex);
}
bool DrmAllocation::setMemAdvise(Drm *drm, MemAdviseFlags flags) {
if (flags.cached_memory != enabledMemAdviseFlags.cached_memory) {
CachePolicy memType = flags.cached_memory ? CachePolicy::WriteBack : CachePolicy::Uncached;
setCachePolicy(memType);
}
enabledMemAdviseFlags = flags;
return true;
}
bool DrmAllocation::shouldAllocationPageFault(const Drm *drm) {
return false;
}

View File

@ -33,6 +33,9 @@ class IoctlHelper {
virtual int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) = 0;
virtual uint32_t getHwConfigIoctlVal() = 0;
virtual uint32_t getAtomicAdvise(bool isNonAtomic) = 0;
virtual uint32_t getPreferredLocationAdvise() = 0;
virtual bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) = 0;
};
class IoctlHelperUpstream : public IoctlHelper {
@ -45,6 +48,9 @@ class IoctlHelperUpstream : public IoctlHelper {
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
uint32_t getHwConfigIoctlVal() override;
uint32_t getAtomicAdvise(bool isNonAtomic) override;
uint32_t getPreferredLocationAdvise() override;
bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) override;
};
template <PRODUCT_FAMILY gfxProduct>
@ -68,6 +74,9 @@ class IoctlHelperPrelim20 : public IoctlHelper {
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
uint32_t getHwConfigIoctlVal() override;
uint32_t getAtomicAdvise(bool isNonAtomic) override;
uint32_t getPreferredLocationAdvise() override;
bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) override;
};
} // namespace NEO

View File

@ -136,4 +136,31 @@ uint32_t IoctlHelperPrelim20::getHwConfigIoctlVal() {
return PRELIM_DRM_I915_QUERY_HWCONFIG_TABLE;
}
uint32_t IoctlHelperPrelim20::getAtomicAdvise(bool isNonAtomic) {
return isNonAtomic ? PRELIM_I915_VM_ADVISE_ATOMIC_NONE : PRELIM_I915_VM_ADVISE_ATOMIC_SYSTEM;
}
uint32_t IoctlHelperPrelim20::getPreferredLocationAdvise() {
return PRELIM_I915_VM_ADVISE_PREFERRED_LOCATION;
}
bool IoctlHelperPrelim20::setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) {
prelim_drm_i915_gem_vm_advise vmAdvise{};
vmAdvise.handle = handle;
vmAdvise.attribute = attribute;
if (region != nullptr) {
vmAdvise.region = *reinterpret_cast<prelim_drm_i915_gem_memory_class_instance *>(region);
}
int ret = IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_VM_ADVISE, &vmAdvise);
if (ret != 0) {
int err = errno;
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err));
DEBUG_BREAK_IF(true);
return false;
}
return true;
}
} // namespace NEO

View File

@ -67,4 +67,16 @@ uint32_t IoctlHelperUpstream::getHwConfigIoctlVal() {
return DRM_I915_QUERY_HWCONFIG_TABLE;
}
uint32_t IoctlHelperUpstream::getAtomicAdvise(bool isNonAtomic) {
return 0;
}
uint32_t IoctlHelperUpstream::getPreferredLocationAdvise() {
return 0;
}
bool IoctlHelperUpstream::setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) {
return true;
}
} // namespace NEO