mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
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:

committed by
Compute-Runtime-Automation

parent
ee18008750
commit
242b08d72b
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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(), ®ion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
enabledMemAdviseFlags = flags;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user