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/debug_manager_state_restore.h"
|
||||||
#include "shared/test/common/helpers/default_hw_info.h"
|
#include "shared/test/common/helpers/default_hw_info.h"
|
||||||
#include "shared/test/common/libult/linux/drm_mock.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"
|
#include "shared/test/common/test_macros/test.h"
|
||||||
|
|
||||||
using namespace NEO;
|
using namespace NEO;
|
||||||
@ -194,3 +195,65 @@ TEST(IoctlHelperTestsPrelim, givenPrelimsWhenGetHwConfigIoctlValThenCorrectValue
|
|||||||
uint32_t ioctlVal = (1 << 16) | 6;
|
uint32_t ioctlVal = (1 << 16) | 6;
|
||||||
EXPECT_EQ(ioctlVal, IoctlHelper::get(drm.get())->getHwConfigIoctlVal());
|
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);
|
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/memory_manager/residency.h"
|
||||||
#include "shared/source/os_interface/linux/drm_buffer_object.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/drm_memory_manager.h"
|
||||||
|
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
||||||
#include "shared/source/os_interface/os_context.h"
|
#include "shared/source/os_interface/os_context.h"
|
||||||
|
|
||||||
#include <sstream>
|
#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
|
} // namespace NEO
|
||||||
|
@ -31,17 +31,6 @@ bool DrmAllocation::setCacheRegion(Drm *drm, CacheRegion regionIndex) {
|
|||||||
return setCacheAdvice(drm, 0, 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) {
|
bool DrmAllocation::shouldAllocationPageFault(const Drm *drm) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,9 @@ class IoctlHelper {
|
|||||||
virtual int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
|
virtual int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
|
||||||
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) = 0;
|
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) = 0;
|
||||||
virtual uint32_t getHwConfigIoctlVal() = 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 {
|
class IoctlHelperUpstream : public IoctlHelper {
|
||||||
@ -45,6 +48,9 @@ class IoctlHelperUpstream : public IoctlHelper {
|
|||||||
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
|
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
|
||||||
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
|
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
|
||||||
uint32_t getHwConfigIoctlVal() 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>
|
template <PRODUCT_FAMILY gfxProduct>
|
||||||
@ -68,6 +74,9 @@ class IoctlHelperPrelim20 : public IoctlHelper {
|
|||||||
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
|
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
|
||||||
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
|
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
|
||||||
uint32_t getHwConfigIoctlVal() 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
|
} // namespace NEO
|
||||||
|
@ -136,4 +136,31 @@ uint32_t IoctlHelperPrelim20::getHwConfigIoctlVal() {
|
|||||||
return PRELIM_DRM_I915_QUERY_HWCONFIG_TABLE;
|
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
|
} // namespace NEO
|
||||||
|
@ -67,4 +67,16 @@ uint32_t IoctlHelperUpstream::getHwConfigIoctlVal() {
|
|||||||
return DRM_I915_QUERY_HWCONFIG_TABLE;
|
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
|
} // namespace NEO
|
||||||
|
Reference in New Issue
Block a user