mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-20 17:00:59 +08:00
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
This commit is contained in:
@@ -176,6 +176,27 @@ bool Drm::setQueueSliceCount(uint64_t sliceCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Drm::checkNonPersistentSupport() {
|
||||
drm_i915_gem_context_param contextParam = {};
|
||||
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
|
||||
|
||||
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
|
||||
if (retVal == 0) {
|
||||
nonPersistentSupported = true;
|
||||
} else {
|
||||
nonPersistentSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Drm::setNonPersistent(uint32_t drmContextId) {
|
||||
drm_i915_gem_context_param contextParam = {};
|
||||
contextParam.ctx_id = drmContextId;
|
||||
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
|
||||
|
||||
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
||||
UNRECOVERABLE_IF(retVal != 0);
|
||||
}
|
||||
|
||||
uint32_t Drm::createDrmContext() {
|
||||
drm_i915_gem_context_create gcc = {};
|
||||
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &gcc);
|
||||
|
||||
@@ -62,11 +62,13 @@ class Drm {
|
||||
|
||||
int queryGttSize(uint64_t >tSizeOutput);
|
||||
bool isPreemptionSupported() const { return preemptionSupported; }
|
||||
bool isNonPersistentSupported() const { return nonPersistentSupported; }
|
||||
MOCKABLE_VIRTUAL void checkPreemptionSupport();
|
||||
int getFileDescriptor() const { return fd; }
|
||||
uint32_t createDrmContext();
|
||||
void destroyDrmContext(uint32_t drmContextId);
|
||||
void setLowPriorityContextParam(uint32_t drmContextId);
|
||||
void setNonPersistent(uint32_t drmContextId);
|
||||
unsigned int bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, aub_stream::EngineType engineType);
|
||||
|
||||
void setGtType(GTTYPE eGtType) { this->eGtType = eGtType; }
|
||||
@@ -78,6 +80,7 @@ class Drm {
|
||||
bool queryEngineInfo();
|
||||
bool queryMemoryInfo();
|
||||
int setupHardwareInfo(DeviceDescriptor *, bool);
|
||||
void checkNonPersistentSupport();
|
||||
|
||||
MemoryInfo *getMemoryInfo() const {
|
||||
return memoryInfo.get();
|
||||
@@ -91,6 +94,7 @@ class Drm {
|
||||
bool sliceCountChangeSupported = false;
|
||||
drm_i915_gem_context_param_sseu sseu{};
|
||||
bool preemptionSupported = false;
|
||||
bool nonPersistentSupported = false;
|
||||
int fd;
|
||||
int deviceId = 0;
|
||||
int revisionId = 0;
|
||||
|
||||
@@ -161,6 +161,7 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou
|
||||
outHwInfo->capabilityTable.ftrRenderCompressedBuffers = false;
|
||||
outHwInfo->capabilityTable.ftrRenderCompressedImages = false;
|
||||
drm->checkQueueSliceSupport();
|
||||
drm->checkNonPersistentSupport();
|
||||
drm->checkPreemptionSupport();
|
||||
bool preemption = drm->isPreemptionSupported();
|
||||
PreemptionHelper::adjustDefaultPreemptionMode(outHwInfo->capabilityTable,
|
||||
|
||||
@@ -27,6 +27,9 @@ OsContextLinux::OsContextLinux(Drm &drm, uint32_t contextId, DeviceBitfield devi
|
||||
for (auto deviceIndex = 0u; deviceIndex < deviceBitfield.size(); deviceIndex++) {
|
||||
if (deviceBitfield.test(deviceIndex)) {
|
||||
auto drmContextId = drm.createDrmContext();
|
||||
if (drm.isNonPersistentSupported()) {
|
||||
drm.setNonPersistent(drmContextId);
|
||||
}
|
||||
if (drm.isPreemptionSupported() && lowPriority) {
|
||||
drm.setLowPriorityContextParam(drmContextId);
|
||||
}
|
||||
|
||||
15
third_party/uapi/drm/i915_drm.h
vendored
15
third_party/uapi/drm/i915_drm.h
vendored
@@ -1567,6 +1567,21 @@ struct drm_i915_gem_context_param {
|
||||
* i915_context_engines_bond (I915_CONTEXT_ENGINES_EXT_BOND)
|
||||
*/
|
||||
#define I915_CONTEXT_PARAM_ENGINES 0xa
|
||||
|
||||
/*
|
||||
* I915_CONTEXT_PARAM_PERSISTENCE:
|
||||
*
|
||||
* Allow the context and active rendering to survive the process until
|
||||
* completion. Persistence allows fire-and-forget clients to queue up a
|
||||
* bunch of work, hand the output over to a display server and then quit.
|
||||
* If the context is marked as not persistent, upon closing (either via
|
||||
* an explicit DRM_I915_GEM_CONTEXT_DESTROY or implicitly from file closure
|
||||
* or process termination), the context and any outstanding requests will be
|
||||
* cancelled (and exported fences for cancelled requests marked as -EIO).
|
||||
*
|
||||
* By default, new contexts allow persistence.
|
||||
*/
|
||||
#define I915_CONTEXT_PARAM_PERSISTENCE 0xb
|
||||
/* Must be kept compact -- no holes and well documented */
|
||||
|
||||
__u64 value;
|
||||
|
||||
@@ -274,6 +274,9 @@ class DrmMockCustom : public Drm {
|
||||
*getParam->value = getParamRetValue;
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM: {
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM: {
|
||||
ioctl_cnt.contextGetParam++;
|
||||
auto getContextParam = (drm_i915_gem_context_param *)arg;
|
||||
|
||||
@@ -85,6 +85,9 @@ int DrmMock::ioctl(unsigned long request, void *arg) {
|
||||
}
|
||||
return this->StoredRetValForSetSSEU;
|
||||
}
|
||||
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PERSISTENCE) {
|
||||
return this->StoredRetValForPersistant;
|
||||
}
|
||||
}
|
||||
|
||||
if ((request == DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM) && (arg != nullptr)) {
|
||||
@@ -100,6 +103,9 @@ int DrmMock::ioctl(unsigned long request, void *arg) {
|
||||
}
|
||||
return this->StoredRetValForGetSSEU;
|
||||
}
|
||||
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PERSISTENCE) {
|
||||
return this->StoredRetValForPersistant;
|
||||
}
|
||||
}
|
||||
|
||||
if (request == DRM_IOCTL_I915_GEM_EXECBUFFER2) {
|
||||
|
||||
@@ -25,6 +25,7 @@ class DrmMock : public Drm {
|
||||
using Drm::engineInfo;
|
||||
using Drm::getQueueSliceCount;
|
||||
using Drm::memoryInfo;
|
||||
using Drm::nonPersistentSupported;
|
||||
using Drm::preemptionSupported;
|
||||
using Drm::query;
|
||||
using Drm::sliceCountChangeSupported;
|
||||
@@ -96,6 +97,7 @@ class DrmMock : public Drm {
|
||||
int StoredRetValForDeviceRevID = 0;
|
||||
int StoredRetValForPooledEU = 0;
|
||||
int StoredRetValForMinEUinPool = 0;
|
||||
int StoredRetValForPersistant = 0;
|
||||
int StoredPreemptionSupport =
|
||||
I915_SCHEDULER_CAP_ENABLED |
|
||||
I915_SCHEDULER_CAP_PRIORITY |
|
||||
|
||||
@@ -173,7 +173,6 @@ TEST(DrmTest, GivenDrmWhenAskedForContextThatFailsThenFalseIsReturned) {
|
||||
|
||||
TEST(DrmTest, givenDrmWhenOsContextIsCreatedThenCreateAndDestroyNewDrmOsContext) {
|
||||
DrmMock drmMock;
|
||||
|
||||
uint32_t drmContextId1 = 123;
|
||||
uint32_t drmContextId2 = 456;
|
||||
|
||||
@@ -199,6 +198,30 @@ TEST(DrmTest, givenDrmWhenOsContextIsCreatedThenCreateAndDestroyNewDrmOsContext)
|
||||
EXPECT_EQ(0u, drmMock.receivedContextParamRequestCount);
|
||||
}
|
||||
|
||||
TEST(DrmTest, givenDrmAndNegativeCheckNonPersistentSupportWhenOsContextIsCreatedThenReceivedContextParamRequestCountReturnsCorrectValue) {
|
||||
|
||||
DrmMock drmMock;
|
||||
uint32_t drmContextId1 = 123;
|
||||
drmMock.StoredCtxId = drmContextId1;
|
||||
auto expectedCount = 0u;
|
||||
|
||||
{
|
||||
drmMock.StoredRetValForPersistant = -1;
|
||||
drmMock.checkNonPersistentSupport();
|
||||
++expectedCount;
|
||||
OsContextLinux osContext(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
|
||||
EXPECT_EQ(expectedCount, drmMock.receivedContextParamRequestCount);
|
||||
}
|
||||
{
|
||||
drmMock.StoredRetValForPersistant = 0;
|
||||
drmMock.checkNonPersistentSupport();
|
||||
++expectedCount;
|
||||
OsContextLinux osContext(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
|
||||
++expectedCount;
|
||||
EXPECT_EQ(expectedCount, drmMock.receivedContextParamRequestCount);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DrmTest, givenDrmPreemptionEnabledAndLowPriorityEngineWhenCreatingOsContextThenCallSetContextPriorityIoctl) {
|
||||
DrmMock drmMock;
|
||||
drmMock.StoredCtxId = 123;
|
||||
@@ -332,6 +355,16 @@ TEST(DrmTest, givenPlatformWhereGetSseuRetFailureWhenCallSetQueueSliceCountThenS
|
||||
EXPECT_NE(drm->getSliceMask(newSliceCount), drm->storedParamSseu);
|
||||
}
|
||||
|
||||
TEST(DrmTest, whenCheckNonPeristentSupportIsCalledThenIsNonPersistentSupportedReturnsCorrectValues) {
|
||||
std::unique_ptr<DrmMock> drm = std::make_unique<DrmMock>();
|
||||
drm->StoredRetValForPersistant = -1;
|
||||
drm->checkNonPersistentSupport();
|
||||
EXPECT_FALSE(drm->isNonPersistentSupported());
|
||||
drm->StoredRetValForPersistant = 0;
|
||||
drm->checkNonPersistentSupport();
|
||||
EXPECT_TRUE(drm->isNonPersistentSupported());
|
||||
}
|
||||
|
||||
TEST(DrmTest, givenPlatformWhereSetSseuRetFailureWhenCallSetQueueSliceCountThenReturnFalse) {
|
||||
uint64_t newSliceCount = 1;
|
||||
std::unique_ptr<DrmMock> drm = std::make_unique<DrmMock>();
|
||||
|
||||
@@ -263,6 +263,12 @@ TEST_F(HwInfoConfigTestLinuxDummy, dummyNegativeUnknownDeviceId) {
|
||||
EXPECT_EQ(-1, ret);
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, whenConfigureHwInfoIsCalledThenIsNonPersistentSupportedReturnsTrue) {
|
||||
int ret = hwConfig.configureHwInfo(&pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_TRUE(drm->isNonPersistentSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledMidThreadOn) {
|
||||
pInHwInfo.capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
|
||||
drm->StoredPreemptionSupport =
|
||||
|
||||
Reference in New Issue
Block a user