Skip to content

Commit 242b08d

Browse files
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 <[email protected]>
1 parent ee18008 commit 242b08d

File tree

7 files changed

+174
-11
lines changed

7 files changed

+174
-11
lines changed

opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp

+63
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "shared/test/common/helpers/debug_manager_state_restore.h"
1111
#include "shared/test/common/helpers/default_hw_info.h"
1212
#include "shared/test/common/libult/linux/drm_mock.h"
13+
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
1314
#include "shared/test/common/test_macros/test.h"
1415

1516
using namespace NEO;
@@ -194,3 +195,65 @@ TEST(IoctlHelperTestsPrelim, givenPrelimsWhenGetHwConfigIoctlValThenCorrectValue
194195
uint32_t ioctlVal = (1 << 16) | 6;
195196
EXPECT_EQ(ioctlVal, IoctlHelper::get(drm.get())->getHwConfigIoctlVal());
196197
}
198+
199+
TEST(IoctlHelperTestsPrelim, givenDrmAllocationWhenSetMemAdviseFailsThenDontUpdateMemAdviceFlags) {
200+
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
201+
executionEnvironment->prepareRootDeviceEnvironments(1);
202+
203+
DrmPrelimMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
204+
drm.ioctlRetVal = -1;
205+
206+
MockBufferObject bo(&drm, 0, 0, 1);
207+
MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::LocalMemory);
208+
allocation.bufferObjects[0] = &bo;
209+
210+
MemAdviseFlags memAdviseFlags{};
211+
memAdviseFlags.non_atomic = 1;
212+
213+
allocation.setMemAdvise(&drm, memAdviseFlags);
214+
215+
EXPECT_EQ(1u, drm.ioctlCallsCount);
216+
EXPECT_NE(memAdviseFlags.memadvise_flags, allocation.enabledMemAdviseFlags.memadvise_flags);
217+
}
218+
219+
TEST(IoctlHelperTestsPrelim, givenDrmAllocationWhenSetMemAdviseWithNonAtomicIsCalledThenUpdateTheCorrespondingVmAdviceForBufferObject) {
220+
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
221+
executionEnvironment->prepareRootDeviceEnvironments(1);
222+
223+
DrmPrelimMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
224+
225+
MockBufferObject bo(&drm, 0, 0, 1);
226+
MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::LocalMemory);
227+
allocation.bufferObjects[0] = &bo;
228+
229+
MemAdviseFlags memAdviseFlags{};
230+
231+
for (auto nonAtomic : {true, false}) {
232+
memAdviseFlags.non_atomic = nonAtomic;
233+
234+
EXPECT_TRUE(allocation.setMemAdvise(&drm, memAdviseFlags));
235+
EXPECT_EQ(memAdviseFlags.memadvise_flags, allocation.enabledMemAdviseFlags.memadvise_flags);
236+
}
237+
EXPECT_EQ(2u, drm.ioctlCallsCount);
238+
}
239+
240+
TEST(IoctlHelperTestsPrelim, givenDrmAllocationWhenSetMemAdviseWithDevicePreferredLocationIsCalledThenUpdateTheCorrespondingVmAdviceForBufferObject) {
241+
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
242+
executionEnvironment->prepareRootDeviceEnvironments(1);
243+
244+
DrmPrelimMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
245+
246+
MockBufferObject bo(&drm, 0, 0, 1);
247+
MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::LocalMemory);
248+
allocation.bufferObjects[0] = &bo;
249+
250+
MemAdviseFlags memAdviseFlags{};
251+
252+
for (auto devicePreferredLocation : {true, false}) {
253+
memAdviseFlags.device_preferred_location = devicePreferredLocation;
254+
255+
EXPECT_TRUE(allocation.setMemAdvise(&drm, memAdviseFlags));
256+
EXPECT_EQ(memAdviseFlags.memadvise_flags, allocation.enabledMemAdviseFlags.memadvise_flags);
257+
}
258+
EXPECT_EQ(2u, drm.ioctlCallsCount);
259+
}

opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,23 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenClosAllocWaysThenReturnZeroWays)
9191

9292
EXPECT_EQ(0, cacheRegion);
9393
}
94+
95+
TEST(IoctlHelperTestsUpstream, givenUpstreamWhenGetAdviseThenReturnCorrectValue) {
96+
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
97+
executionEnvironment->prepareRootDeviceEnvironments(1);
98+
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
99+
100+
auto ioctlHelper = IoctlHelper::get(drm.get());
101+
EXPECT_EQ(0u, ioctlHelper->getAtomicAdvise(false));
102+
EXPECT_EQ(0u, ioctlHelper->getAtomicAdvise(true));
103+
EXPECT_EQ(0u, ioctlHelper->getPreferredLocationAdvise());
104+
}
105+
106+
TEST(IoctlHelperTestsUpstream, givenUpstreamWhenSetVmBoAdviseThenReturnTrue) {
107+
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
108+
executionEnvironment->prepareRootDeviceEnvironments(1);
109+
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
110+
111+
auto ioctlHelper = IoctlHelper::get(drm.get());
112+
EXPECT_TRUE(ioctlHelper->setVmBoAdvise(drm.get(), 0, 0, nullptr));
113+
}

shared/source/os_interface/linux/drm_allocation.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "shared/source/memory_manager/residency.h"
1111
#include "shared/source/os_interface/linux/drm_buffer_object.h"
1212
#include "shared/source/os_interface/linux/drm_memory_manager.h"
13+
#include "shared/source/os_interface/linux/ioctl_helper.h"
1314
#include "shared/source/os_interface/os_context.h"
1415

1516
#include <sstream>
@@ -167,4 +168,46 @@ void DrmAllocation::markForCapture() {
167168
}
168169
}
169170
}
171+
172+
bool DrmAllocation::setMemAdvise(Drm *drm, MemAdviseFlags flags) {
173+
bool success = true;
174+
175+
if (flags.cached_memory != enabledMemAdviseFlags.cached_memory) {
176+
CachePolicy memType = flags.cached_memory ? CachePolicy::WriteBack : CachePolicy::Uncached;
177+
setCachePolicy(memType);
178+
}
179+
180+
auto ioctlHelper = IoctlHelper::get(drm);
181+
if (flags.non_atomic != enabledMemAdviseFlags.non_atomic) {
182+
for (auto bo : bufferObjects) {
183+
if (bo != nullptr) {
184+
success &= ioctlHelper->setVmBoAdvise(drm, bo->peekHandle(), ioctlHelper->getAtomicAdvise(flags.non_atomic), nullptr);
185+
}
186+
}
187+
}
188+
189+
if (flags.device_preferred_location != enabledMemAdviseFlags.device_preferred_location) {
190+
drm_i915_gem_memory_class_instance region{};
191+
for (auto handleId = 0u; handleId < EngineLimits::maxHandleCount; handleId++) {
192+
auto bo = bufferObjects[handleId];
193+
if (bo != nullptr) {
194+
if (flags.device_preferred_location) {
195+
region.memory_class = I915_MEMORY_CLASS_DEVICE;
196+
region.memory_instance = handleId;
197+
} else {
198+
region.memory_class = -1;
199+
region.memory_instance = 0;
200+
}
201+
success &= ioctlHelper->setVmBoAdvise(drm, bo->peekHandle(), ioctlHelper->getPreferredLocationAdvise(), &region);
202+
}
203+
}
204+
}
205+
206+
if (success) {
207+
enabledMemAdviseFlags = flags;
208+
}
209+
210+
return success;
211+
}
212+
170213
} // namespace NEO

shared/source/os_interface/linux/drm_allocation_extended.cpp

-11
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,6 @@ bool DrmAllocation::setCacheRegion(Drm *drm, CacheRegion regionIndex) {
3131
return setCacheAdvice(drm, 0, regionIndex);
3232
}
3333

34-
bool DrmAllocation::setMemAdvise(Drm *drm, MemAdviseFlags flags) {
35-
if (flags.cached_memory != enabledMemAdviseFlags.cached_memory) {
36-
CachePolicy memType = flags.cached_memory ? CachePolicy::WriteBack : CachePolicy::Uncached;
37-
setCachePolicy(memType);
38-
}
39-
40-
enabledMemAdviseFlags = flags;
41-
42-
return true;
43-
}
44-
4534
bool DrmAllocation::shouldAllocationPageFault(const Drm *drm) {
4635
return false;
4736
}

shared/source/os_interface/linux/ioctl_helper.h

+9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class IoctlHelper {
3333
virtual int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
3434
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) = 0;
3535
virtual uint32_t getHwConfigIoctlVal() = 0;
36+
virtual uint32_t getAtomicAdvise(bool isNonAtomic) = 0;
37+
virtual uint32_t getPreferredLocationAdvise() = 0;
38+
virtual bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) = 0;
3639
};
3740

3841
class IoctlHelperUpstream : public IoctlHelper {
@@ -45,6 +48,9 @@ class IoctlHelperUpstream : public IoctlHelper {
4548
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
4649
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
4750
uint32_t getHwConfigIoctlVal() override;
51+
uint32_t getAtomicAdvise(bool isNonAtomic) override;
52+
uint32_t getPreferredLocationAdvise() override;
53+
bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) override;
4854
};
4955

5056
template <PRODUCT_FAMILY gfxProduct>
@@ -68,6 +74,9 @@ class IoctlHelperPrelim20 : public IoctlHelper {
6874
int waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
6975
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) override;
7076
uint32_t getHwConfigIoctlVal() override;
77+
uint32_t getAtomicAdvise(bool isNonAtomic) override;
78+
uint32_t getPreferredLocationAdvise() override;
79+
bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) override;
7180
};
7281

7382
} // namespace NEO

shared/source/os_interface/linux/ioctl_helper_prelim.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,31 @@ uint32_t IoctlHelperPrelim20::getHwConfigIoctlVal() {
136136
return PRELIM_DRM_I915_QUERY_HWCONFIG_TABLE;
137137
}
138138

139+
uint32_t IoctlHelperPrelim20::getAtomicAdvise(bool isNonAtomic) {
140+
return isNonAtomic ? PRELIM_I915_VM_ADVISE_ATOMIC_NONE : PRELIM_I915_VM_ADVISE_ATOMIC_SYSTEM;
141+
}
142+
143+
uint32_t IoctlHelperPrelim20::getPreferredLocationAdvise() {
144+
return PRELIM_I915_VM_ADVISE_PREFERRED_LOCATION;
145+
}
146+
147+
bool IoctlHelperPrelim20::setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) {
148+
prelim_drm_i915_gem_vm_advise vmAdvise{};
149+
150+
vmAdvise.handle = handle;
151+
vmAdvise.attribute = attribute;
152+
if (region != nullptr) {
153+
vmAdvise.region = *reinterpret_cast<prelim_drm_i915_gem_memory_class_instance *>(region);
154+
}
155+
156+
int ret = IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_VM_ADVISE, &vmAdvise);
157+
if (ret != 0) {
158+
int err = errno;
159+
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));
160+
DEBUG_BREAK_IF(true);
161+
return false;
162+
}
163+
return true;
164+
}
165+
139166
} // namespace NEO

shared/source/os_interface/linux/ioctl_helper_upstream.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,16 @@ uint32_t IoctlHelperUpstream::getHwConfigIoctlVal() {
6767
return DRM_I915_QUERY_HWCONFIG_TABLE;
6868
}
6969

70+
uint32_t IoctlHelperUpstream::getAtomicAdvise(bool isNonAtomic) {
71+
return 0;
72+
}
73+
74+
uint32_t IoctlHelperUpstream::getPreferredLocationAdvise() {
75+
return 0;
76+
}
77+
78+
bool IoctlHelperUpstream::setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) {
79+
return true;
80+
}
81+
7082
} // namespace NEO

0 commit comments

Comments
 (0)