Skip to content

Commit cdc7649

Browse files
Pass OsContext to memory management methods
Operate on OsContext when per context VMs are used Related-To: NEO-4957 Change-Id: Ia6bef88a80163d4ceee9f9bf59bda6b569d8929f Signed-off-by: Mateusz Hoppe <[email protected]>
1 parent e7fd522 commit cdc7649

20 files changed

+162
-69
lines changed

opencl/source/os_interface/linux/drm_command_stream.inl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ void DrmCommandStreamReceiver<GfxFamily>::exec(const BatchBuffer &batchBuffer, u
110110
int err = bb->exec(static_cast<uint32_t>(alignUp(batchBuffer.usedSize - batchBuffer.startOffset, 8)),
111111
batchBuffer.startOffset, execFlags,
112112
batchBuffer.requiresCoherency,
113+
this->osContext,
113114
vmHandleId,
114115
drmContextId,
115116
this->residency.data(), this->residency.size(),
@@ -123,7 +124,7 @@ template <typename GfxFamily>
123124
void DrmCommandStreamReceiver<GfxFamily>::processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) {
124125
for (auto &alloc : inputAllocationsForResidency) {
125126
auto drmAlloc = static_cast<DrmAllocation *>(alloc);
126-
drmAlloc->makeBOsResident(osContext->getContextId(), handleId, &this->residency, false);
127+
drmAlloc->makeBOsResident(osContext, handleId, &this->residency, false);
127128
}
128129
}
129130

opencl/test/unit_test/mocks/linux/mock_drm_allocation.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ namespace NEO {
1313

1414
class MockBufferObject : public BufferObject {
1515
public:
16+
using BufferObject::bindInfo;
1617
using BufferObject::handle;
1718

18-
MockBufferObject() : BufferObject(nullptr, 0, 0) {
19+
MockBufferObject(Drm *drm) : BufferObject(drm, 0, 0) {
1920
}
2021
};
2122

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

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66
*/
77

88
#include "shared/source/os_interface/linux/drm_buffer_object.h"
9+
#include "shared/source/os_interface/linux/drm_memory_operations_handler_default.h"
10+
#include "shared/source/os_interface/linux/os_context_linux.h"
11+
#include "shared/source/os_interface/linux/os_interface.h"
912
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
13+
#include "shared/test/unit_test/mocks/mock_device.h"
1014

15+
#include "opencl/test/unit_test/mocks/linux/mock_drm_allocation.h"
1116
#include "opencl/test/unit_test/os_interface/linux/device_command_stream_fixture.h"
17+
#include "opencl/test/unit_test/os_interface/linux/drm_mock.h"
1218
#include "test.h"
1319

1420
#include "drm/i915_drm.h"
@@ -26,8 +32,8 @@ class TestedBufferObject : public BufferObject {
2632
this->tiling_mode = mode;
2733
}
2834

29-
void fillExecObject(drm_i915_gem_exec_object2 &execObject, uint32_t vmHandleId, uint32_t drmContextId) override {
30-
BufferObject::fillExecObject(execObject, vmHandleId, drmContextId);
35+
void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override {
36+
BufferObject::fillExecObject(execObject, osContext, vmHandleId, drmContextId);
3137
execObjectPointerFilled = &execObject;
3238
}
3339

@@ -43,10 +49,13 @@ class DrmBufferObjectFixture {
4349
std::unique_ptr<DrmMockCustom> mock;
4450
TestedBufferObject *bo;
4551
drm_i915_gem_exec_object2 execObjectsStorage[256];
52+
std::unique_ptr<OsContextLinux> osContext;
4653

4754
void SetUp() {
4855
this->mock = std::make_unique<DrmMockCustom>();
4956
ASSERT_NE(nullptr, this->mock);
57+
osContext.reset(new OsContextLinux(*this->mock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false, false, false));
58+
this->mock->reset();
5059
bo = new TestedBufferObject(this->mock.get());
5160
ASSERT_NE(nullptr, bo);
5261
}
@@ -56,6 +65,9 @@ class DrmBufferObjectFixture {
5665
if (this->mock->ioctl_expected.total >= 0) {
5766
EXPECT_EQ(this->mock->ioctl_expected.total, this->mock->ioctl_cnt.total);
5867
}
68+
mock->reset();
69+
osContext.reset(nullptr);
70+
mock.reset(nullptr);
5971
}
6072
};
6173

@@ -66,7 +78,7 @@ TEST_F(DrmBufferObjectTest, exec) {
6678
mock->ioctl_res = 0;
6779

6880
drm_i915_gem_exec_object2 execObjectsStorage = {};
69-
auto ret = bo->exec(0, 0, 0, false, 0, 1, nullptr, 0u, &execObjectsStorage);
81+
auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage);
7082
EXPECT_EQ(mock->ioctl_res, ret);
7183
EXPECT_EQ(0u, mock->execBuffer.flags);
7284
}
@@ -76,7 +88,7 @@ TEST_F(DrmBufferObjectTest, exec_ioctlFailed) {
7688
mock->ioctl_res = -1;
7789
mock->errnoValue = EFAULT;
7890
drm_i915_gem_exec_object2 execObjectsStorage = {};
79-
EXPECT_EQ(EFAULT, bo->exec(0, 0, 0, false, 0, 1, nullptr, 0u, &execObjectsStorage));
91+
EXPECT_EQ(EFAULT, bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage));
8092
}
8193

8294
TEST_F(DrmBufferObjectTest, setTiling_success) {
@@ -105,7 +117,7 @@ TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedCrosses32BitBoundaryW
105117
memset(&execObject, 0, sizeof(execObject));
106118
bo->setAddress(((uint64_t)1u << 32) - 0x1000u);
107119
bo->setSize(0x1000);
108-
bo->fillExecObject(execObject, 0, 1);
120+
bo->fillExecObject(execObject, osContext.get(), 0, 1);
109121
//base address + size > size of 32bit address space
110122
EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS);
111123
}
@@ -116,7 +128,7 @@ TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedWithin32BitBoundaryWh
116128
memset(&execObject, 0, sizeof(execObject));
117129
bo->setAddress(((uint64_t)1u << 32) - 0x1000u);
118130
bo->setSize(0xFFF);
119-
bo->fillExecObject(execObject, 0, 1);
131+
bo->fillExecObject(execObject, osContext.get(), 0, 1);
120132
//base address + size < size of 32bit address space
121133
EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS);
122134
}
@@ -133,7 +145,7 @@ TEST_F(DrmBufferObjectTest, onPinIoctlFailed) {
133145

134146
bo->setAddress(reinterpret_cast<uint64_t>(buff.get()));
135147
BufferObject *boArray[1] = {boToPin.get()};
136-
auto ret = bo->pin(boArray, 1, 0, 1);
148+
auto ret = bo->pin(boArray, 1, osContext.get(), 0, 1);
137149
EXPECT_EQ(EINVAL, ret);
138150
}
139151

@@ -144,7 +156,7 @@ TEST_F(DrmBufferObjectTest, whenPrintExecutionBufferIsSetToTrueThenMessageFoundI
144156
drm_i915_gem_exec_object2 execObjectsStorage = {};
145157

146158
testing::internal::CaptureStdout();
147-
auto ret = bo->exec(0, 0, 0, false, 0, 1, nullptr, 0u, &execObjectsStorage);
159+
auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage);
148160
EXPECT_EQ(0, ret);
149161

150162
std::string output = testing::internal::GetCapturedStdout();
@@ -170,7 +182,7 @@ TEST(DrmBufferObjectSimpleTest, givenInvalidBoWhenPinIsCalledThenErrorIsReturned
170182
mock->errnoValue = EFAULT;
171183

172184
BufferObject *boArray[1] = {boToPin.get()};
173-
auto ret = bo->pin(boArray, 1, 0, 1);
185+
auto ret = bo->pin(boArray, 1, nullptr, 0, 1);
174186
EXPECT_EQ(EFAULT, ret);
175187
}
176188

@@ -185,6 +197,8 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenPinnedThenAllBosArePinned) {
185197
std::unique_ptr<uint32_t[]> buff(new uint32_t[256]);
186198
std::unique_ptr<DrmMockCustom> mock(new DrmMockCustom);
187199
ASSERT_NE(nullptr, mock.get());
200+
OsContextLinux osContext(*mock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false, false, false);
201+
188202
std::unique_ptr<TestedBufferObject> bo(new TestedBufferObject(mock.get()));
189203
ASSERT_NE(nullptr, bo.get());
190204
mock->ioctl_res = 0;
@@ -200,7 +214,7 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenPinnedThenAllBosArePinned) {
200214
BufferObject *array[3] = {boToPin.get(), boToPin2.get(), boToPin3.get()};
201215

202216
bo->setAddress(reinterpret_cast<uint64_t>(buff.get()));
203-
auto ret = bo->pin(array, 3, 0, 1);
217+
auto ret = bo->pin(array, 3, &osContext, 0, 1);
204218
EXPECT_EQ(mock->ioctl_res, ret);
205219

206220
EXPECT_LT(0u, mock->execBuffer.batch_len);
@@ -224,3 +238,51 @@ TEST_F(DrmBufferObjectTest, givenDeleterWhenBufferObjectIsCreatedAndDeletedThenC
224238
mock->ioctl_cnt.reset();
225239
mock->ioctl_expected.reset();
226240
}
241+
242+
TEST(DrmBufferObject, givenPerContextVmRequiredWhenBoCreatedThenBindInfoIsInitializedToOsContextCount) {
243+
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
244+
device->getRootDeviceEnvironment().executionEnvironment.setPerContextMemorySpace();
245+
246+
DrmMock drm(*(device->getExecutionEnvironment()->rootDeviceEnvironments[0].get()));
247+
EXPECT_TRUE(drm.isPerContextVMRequired());
248+
MockBufferObject bo(&drm);
249+
250+
auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount();
251+
EXPECT_EQ(osContextCount, bo.bindInfo.size());
252+
253+
for (auto &iter : bo.bindInfo) {
254+
for (uint32_t i = 0; i < EngineLimits::maxHandleCount; i++) {
255+
EXPECT_FALSE(iter[i]);
256+
}
257+
}
258+
}
259+
260+
TEST(DrmBufferObject, givenPerContextVmRequiredWhenBoBoundAndUnboundThenCorrectBindInfoIsUpdated) {
261+
auto executionEnvironment = new ExecutionEnvironment;
262+
executionEnvironment->setPerContextMemorySpace();
263+
executionEnvironment->prepareRootDeviceEnvironments(1);
264+
executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(defaultHwInfo.get());
265+
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
266+
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create();
267+
268+
DrmMockNonFailing *drm = new DrmMockNonFailing(*executionEnvironment->rootDeviceEnvironments[0]);
269+
EXPECT_TRUE(drm->isPerContextVMRequired());
270+
271+
executionEnvironment->rootDeviceEnvironments[0]->osInterface->get()->setDrm(drm);
272+
273+
std::unique_ptr<Device> device(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0));
274+
275+
MockBufferObject bo(drm);
276+
277+
auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount();
278+
EXPECT_EQ(osContextCount, bo.bindInfo.size());
279+
280+
auto contextId = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount() / 2;
281+
auto osContext = device->getExecutionEnvironment()->memoryManager->getRegisteredEngines()[contextId].osContext;
282+
283+
bo.bind(osContext, 0);
284+
EXPECT_TRUE(bo.bindInfo[contextId][0]);
285+
286+
bo.unbind(osContext, 0);
287+
EXPECT_FALSE(bo.bindInfo[contextId][0]);
288+
}

opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ class DrmCommandStreamEnhancedTemplate : public ::testing::Test {
127127
}
128128

129129
template <typename GfxFamily>
130-
void makeResidentBufferObjects(DrmAllocation *drmAllocation) {
131-
drmAllocation->bindBOs(0u, &static_cast<TestedDrmCommandStreamReceiver<GfxFamily> *>(csr)->residency, false);
130+
void makeResidentBufferObjects(OsContext *osContext, DrmAllocation *drmAllocation) {
131+
drmAllocation->bindBOs(osContext, 0u, &static_cast<TestedDrmCommandStreamReceiver<GfxFamily> *>(csr)->residency, false);
132132
}
133133

134134
template <typename GfxFamily>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenAllocationWithSingleBuffer
14861486
auto allocation = new DrmAllocation(0, GraphicsAllocation::AllocationType::UNKNOWN, bos, nullptr, 0u, size, MemoryPool::LocalMemory);
14871487
EXPECT_EQ(bo, allocation->getBO());
14881488

1489-
makeResidentBufferObjects<FamilyType>(allocation);
1489+
makeResidentBufferObjects<FamilyType>(&csr->getOsContext(), allocation);
14901490
EXPECT_TRUE(isResident<FamilyType>(bo));
14911491

14921492
mm->freeGraphicsMemory(allocation);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2984,7 +2984,7 @@ TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenDisabledForcePinAndEna
29842984
PinBufferObject(Drm *drm) : BufferObject(drm, 1, 0) {
29852985
}
29862986

2987-
int pin(BufferObject *const boToPin[], size_t numberOfBos, uint32_t vmHandleId, uint32_t drmContextId) override {
2987+
int pin(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override {
29882988
for (size_t i = 0; i < numberOfBos; i++) {
29892989
pinnedBoArray[i] = boToPin[i];
29902990
}

opencl/test/unit_test/os_interface/linux/drm_mock.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,9 @@ class DrmMock : public Drm {
140140

141141
virtual int handleRemainingRequests(unsigned long request, void *arg) { return -1; }
142142
};
143+
144+
class DrmMockNonFailing : public DrmMock {
145+
public:
146+
using DrmMock::DrmMock;
147+
int handleRemainingRequests(unsigned long request, void *arg) override { return 0; }
148+
};

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "shared/source/debug_settings/debug_settings_manager.h"
99

1010
#include "opencl/test/unit_test/mocks/linux/mock_drm_allocation.h"
11+
#include "opencl/test/unit_test/os_interface/linux/drm_mock.h"
1112
#include "opencl/test/unit_test/utilities/file_logger_tests.h"
1213
#include "test.h"
1314

@@ -22,10 +23,10 @@ TEST(FileLogger, GivenLogAllocationMemoryPoolFlagThenLogsCorrectInfo) {
2223
// Log file not created
2324
bool logFileCreated = fileExists(fileLogger.getLogFileName());
2425
EXPECT_FALSE(logFileCreated);
25-
26+
DrmMock drm{};
2627
MockDrmAllocation allocation(GraphicsAllocation::AllocationType::BUFFER, MemoryPool::System64KBPages);
2728

28-
MockBufferObject bo;
29+
MockBufferObject bo(&drm);
2930
bo.handle = 4;
3031

3132
allocation.bufferObjects[0] = &bo;

shared/source/direct_submission/linux/drm_direct_submission.inl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ bool DrmDirectSubmission<GfxFamily, Dispatcher>::submit(uint64_t gpuAddress, siz
6161
0,
6262
execFlags,
6363
false,
64+
&this->osContext,
6465
drmIterator,
6566
drmContextIds[drmIterator],
6667
nullptr,

shared/source/os_interface/linux/drm_allocation.cpp

Lines changed: 9 additions & 8 deletions
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/os_context.h"
1314

1415
#include <sstream>
1516

@@ -28,20 +29,20 @@ uint64_t DrmAllocation::peekInternalHandle(MemoryManager *memoryManager) {
2829
return static_cast<uint64_t>((static_cast<DrmMemoryManager *>(memoryManager))->obtainFdFromHandle(getBO()->peekHandle(), this->rootDeviceIndex));
2930
}
3031

31-
void DrmAllocation::makeBOsResident(uint32_t osContextId, uint32_t vmHandleId, std::vector<BufferObject *> *bufferObjects, bool bind) {
32+
void DrmAllocation::makeBOsResident(OsContext *osContext, uint32_t vmHandleId, std::vector<BufferObject *> *bufferObjects, bool bind) {
3233
if (this->fragmentsStorage.fragmentCount) {
3334
for (unsigned int f = 0; f < this->fragmentsStorage.fragmentCount; f++) {
34-
if (!this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContextId]) {
35-
bindBO(this->fragmentsStorage.fragmentStorageData[f].osHandleStorage->bo, vmHandleId, bufferObjects, bind);
36-
this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContextId] = true;
35+
if (!this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContext->getContextId()]) {
36+
bindBO(this->fragmentsStorage.fragmentStorageData[f].osHandleStorage->bo, osContext, vmHandleId, bufferObjects, bind);
37+
this->fragmentsStorage.fragmentStorageData[f].residency->resident[osContext->getContextId()] = true;
3738
}
3839
}
3940
} else {
40-
bindBOs(vmHandleId, bufferObjects, bind);
41+
bindBOs(osContext, vmHandleId, bufferObjects, bind);
4142
}
4243
}
4344

44-
void DrmAllocation::bindBO(BufferObject *bo, uint32_t vmHandleId, std::vector<BufferObject *> *bufferObjects, bool bind) {
45+
void DrmAllocation::bindBO(BufferObject *bo, OsContext *osContext, uint32_t vmHandleId, std::vector<BufferObject *> *bufferObjects, bool bind) {
4546
if (bo) {
4647
if (bufferObjects) {
4748
if (bo->peekIsReusableAllocation()) {
@@ -56,9 +57,9 @@ void DrmAllocation::bindBO(BufferObject *bo, uint32_t vmHandleId, std::vector<Bu
5657

5758
} else {
5859
if (bind) {
59-
bo->bind(vmHandleId);
60+
bo->bind(osContext, vmHandleId);
6061
} else {
61-
bo->unbind(vmHandleId);
62+
bo->unbind(osContext, vmHandleId);
6263
}
6364
}
6465
}

0 commit comments

Comments
 (0)