Skip to content

Commit 07cacd4

Browse files
Add new IOCTL call to disable persistence on given context
Change-Id: Ia91c8240fe2fac40c067e91ce70867edb2263463 Signed-off-by: Kamil Kopryk <kamil.kopryk@intel.com> Related-To: NEO-4048
1 parent 6ba7614 commit 07cacd4

File tree

10 files changed

+95
-1
lines changed

10 files changed

+95
-1
lines changed

runtime/os_interface/linux/drm_neo.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,27 @@ bool Drm::setQueueSliceCount(uint64_t sliceCount) {
176176
return false;
177177
}
178178

179+
void Drm::checkNonPersistentSupport() {
180+
drm_i915_gem_context_param contextParam = {};
181+
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
182+
183+
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
184+
if (retVal == 0) {
185+
nonPersistentSupported = true;
186+
} else {
187+
nonPersistentSupported = false;
188+
}
189+
}
190+
191+
void Drm::setNonPersistent(uint32_t drmContextId) {
192+
drm_i915_gem_context_param contextParam = {};
193+
contextParam.ctx_id = drmContextId;
194+
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
195+
196+
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
197+
UNRECOVERABLE_IF(retVal != 0);
198+
}
199+
179200
uint32_t Drm::createDrmContext() {
180201
drm_i915_gem_context_create gcc = {};
181202
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &gcc);

runtime/os_interface/linux/drm_neo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@ class Drm {
6262

6363
int queryGttSize(uint64_t &gttSizeOutput);
6464
bool isPreemptionSupported() const { return preemptionSupported; }
65+
bool isNonPersistentSupported() const { return nonPersistentSupported; }
6566
MOCKABLE_VIRTUAL void checkPreemptionSupport();
6667
int getFileDescriptor() const { return fd; }
6768
uint32_t createDrmContext();
6869
void destroyDrmContext(uint32_t drmContextId);
6970
void setLowPriorityContextParam(uint32_t drmContextId);
71+
void setNonPersistent(uint32_t drmContextId);
7072
unsigned int bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, aub_stream::EngineType engineType);
7173

7274
void setGtType(GTTYPE eGtType) { this->eGtType = eGtType; }
@@ -78,6 +80,7 @@ class Drm {
7880
bool queryEngineInfo();
7981
bool queryMemoryInfo();
8082
int setupHardwareInfo(DeviceDescriptor *, bool);
83+
void checkNonPersistentSupport();
8184

8285
MemoryInfo *getMemoryInfo() const {
8386
return memoryInfo.get();
@@ -91,6 +94,7 @@ class Drm {
9194
bool sliceCountChangeSupported = false;
9295
drm_i915_gem_context_param_sseu sseu{};
9396
bool preemptionSupported = false;
97+
bool nonPersistentSupported = false;
9498
int fd;
9599
int deviceId = 0;
96100
int revisionId = 0;

runtime/os_interface/linux/hw_info_config.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou
161161
outHwInfo->capabilityTable.ftrRenderCompressedBuffers = false;
162162
outHwInfo->capabilityTable.ftrRenderCompressedImages = false;
163163
drm->checkQueueSliceSupport();
164+
drm->checkNonPersistentSupport();
164165
drm->checkPreemptionSupport();
165166
bool preemption = drm->isPreemptionSupported();
166167
PreemptionHelper::adjustDefaultPreemptionMode(outHwInfo->capabilityTable,

runtime/os_interface/linux/os_context_linux.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ OsContextLinux::OsContextLinux(Drm &drm, uint32_t contextId, DeviceBitfield devi
2727
for (auto deviceIndex = 0u; deviceIndex < deviceBitfield.size(); deviceIndex++) {
2828
if (deviceBitfield.test(deviceIndex)) {
2929
auto drmContextId = drm.createDrmContext();
30+
if (drm.isNonPersistentSupported()) {
31+
drm.setNonPersistent(drmContextId);
32+
}
3033
if (drm.isPreemptionSupported() && lowPriority) {
3134
drm.setLowPriorityContextParam(drmContextId);
3235
}

third_party/uapi/drm/i915_drm.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,21 @@ struct drm_i915_gem_context_param {
15671567
* i915_context_engines_bond (I915_CONTEXT_ENGINES_EXT_BOND)
15681568
*/
15691569
#define I915_CONTEXT_PARAM_ENGINES 0xa
1570+
1571+
/*
1572+
* I915_CONTEXT_PARAM_PERSISTENCE:
1573+
*
1574+
* Allow the context and active rendering to survive the process until
1575+
* completion. Persistence allows fire-and-forget clients to queue up a
1576+
* bunch of work, hand the output over to a display server and then quit.
1577+
* If the context is marked as not persistent, upon closing (either via
1578+
* an explicit DRM_I915_GEM_CONTEXT_DESTROY or implicitly from file closure
1579+
* or process termination), the context and any outstanding requests will be
1580+
* cancelled (and exported fences for cancelled requests marked as -EIO).
1581+
*
1582+
* By default, new contexts allow persistence.
1583+
*/
1584+
#define I915_CONTEXT_PARAM_PERSISTENCE 0xb
15701585
/* Must be kept compact -- no holes and well documented */
15711586

15721587
__u64 value;

unit_tests/os_interface/linux/device_command_stream_fixture.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ class DrmMockCustom : public Drm {
274274
*getParam->value = getParamRetValue;
275275
} break;
276276

277+
case DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM: {
278+
} break;
279+
277280
case DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM: {
278281
ioctl_cnt.contextGetParam++;
279282
auto getContextParam = (drm_i915_gem_context_param *)arg;

unit_tests/os_interface/linux/drm_mock.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ int DrmMock::ioctl(unsigned long request, void *arg) {
8585
}
8686
return this->StoredRetValForSetSSEU;
8787
}
88+
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PERSISTENCE) {
89+
return this->StoredRetValForPersistant;
90+
}
8891
}
8992

9093
if ((request == DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM) && (arg != nullptr)) {
@@ -100,6 +103,9 @@ int DrmMock::ioctl(unsigned long request, void *arg) {
100103
}
101104
return this->StoredRetValForGetSSEU;
102105
}
106+
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PERSISTENCE) {
107+
return this->StoredRetValForPersistant;
108+
}
103109
}
104110

105111
if (request == DRM_IOCTL_I915_GEM_EXECBUFFER2) {

unit_tests/os_interface/linux/drm_mock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class DrmMock : public Drm {
2525
using Drm::engineInfo;
2626
using Drm::getQueueSliceCount;
2727
using Drm::memoryInfo;
28+
using Drm::nonPersistentSupported;
2829
using Drm::preemptionSupported;
2930
using Drm::query;
3031
using Drm::sliceCountChangeSupported;
@@ -96,6 +97,7 @@ class DrmMock : public Drm {
9697
int StoredRetValForDeviceRevID = 0;
9798
int StoredRetValForPooledEU = 0;
9899
int StoredRetValForMinEUinPool = 0;
100+
int StoredRetValForPersistant = 0;
99101
int StoredPreemptionSupport =
100102
I915_SCHEDULER_CAP_ENABLED |
101103
I915_SCHEDULER_CAP_PRIORITY |

unit_tests/os_interface/linux/drm_tests.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ TEST(DrmTest, GivenDrmWhenAskedForContextThatFailsThenFalseIsReturned) {
173173

174174
TEST(DrmTest, givenDrmWhenOsContextIsCreatedThenCreateAndDestroyNewDrmOsContext) {
175175
DrmMock drmMock;
176-
177176
uint32_t drmContextId1 = 123;
178177
uint32_t drmContextId2 = 456;
179178

@@ -199,6 +198,30 @@ TEST(DrmTest, givenDrmWhenOsContextIsCreatedThenCreateAndDestroyNewDrmOsContext)
199198
EXPECT_EQ(0u, drmMock.receivedContextParamRequestCount);
200199
}
201200

201+
TEST(DrmTest, givenDrmAndNegativeCheckNonPersistentSupportWhenOsContextIsCreatedThenReceivedContextParamRequestCountReturnsCorrectValue) {
202+
203+
DrmMock drmMock;
204+
uint32_t drmContextId1 = 123;
205+
drmMock.StoredCtxId = drmContextId1;
206+
auto expectedCount = 0u;
207+
208+
{
209+
drmMock.StoredRetValForPersistant = -1;
210+
drmMock.checkNonPersistentSupport();
211+
++expectedCount;
212+
OsContextLinux osContext(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
213+
EXPECT_EQ(expectedCount, drmMock.receivedContextParamRequestCount);
214+
}
215+
{
216+
drmMock.StoredRetValForPersistant = 0;
217+
drmMock.checkNonPersistentSupport();
218+
++expectedCount;
219+
OsContextLinux osContext(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
220+
++expectedCount;
221+
EXPECT_EQ(expectedCount, drmMock.receivedContextParamRequestCount);
222+
}
223+
}
224+
202225
TEST(DrmTest, givenDrmPreemptionEnabledAndLowPriorityEngineWhenCreatingOsContextThenCallSetContextPriorityIoctl) {
203226
DrmMock drmMock;
204227
drmMock.StoredCtxId = 123;
@@ -332,6 +355,16 @@ TEST(DrmTest, givenPlatformWhereGetSseuRetFailureWhenCallSetQueueSliceCountThenS
332355
EXPECT_NE(drm->getSliceMask(newSliceCount), drm->storedParamSseu);
333356
}
334357

358+
TEST(DrmTest, whenCheckNonPeristentSupportIsCalledThenIsNonPersistentSupportedReturnsCorrectValues) {
359+
std::unique_ptr<DrmMock> drm = std::make_unique<DrmMock>();
360+
drm->StoredRetValForPersistant = -1;
361+
drm->checkNonPersistentSupport();
362+
EXPECT_FALSE(drm->isNonPersistentSupported());
363+
drm->StoredRetValForPersistant = 0;
364+
drm->checkNonPersistentSupport();
365+
EXPECT_TRUE(drm->isNonPersistentSupported());
366+
}
367+
335368
TEST(DrmTest, givenPlatformWhereSetSseuRetFailureWhenCallSetQueueSliceCountThenReturnFalse) {
336369
uint64_t newSliceCount = 1;
337370
std::unique_ptr<DrmMock> drm = std::make_unique<DrmMock>();

unit_tests/os_interface/linux/hw_info_config_linux_tests.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ TEST_F(HwInfoConfigTestLinuxDummy, dummyNegativeUnknownDeviceId) {
263263
EXPECT_EQ(-1, ret);
264264
}
265265

266+
TEST_F(HwInfoConfigTestLinuxDummy, whenConfigureHwInfoIsCalledThenIsNonPersistentSupportedReturnsTrue) {
267+
int ret = hwConfig.configureHwInfo(&pInHwInfo, &outHwInfo, osInterface);
268+
EXPECT_EQ(0, ret);
269+
EXPECT_TRUE(drm->isNonPersistentSupported());
270+
}
271+
266272
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledMidThreadOn) {
267273
pInHwInfo.capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
268274
drm->StoredPreemptionSupport =

0 commit comments

Comments
 (0)