mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 21:18:24 +08:00
Simplify preemption control on Linux
Change-Id: Ie0896cc8950f7fbb271b710b8bb221eb41ba0445 Signed-off-by: Dunajski, Bartosz <bartosz.dunajski@intel.com>
This commit is contained in:
committed by
sys_ocldev
parent
9e53740130
commit
f5508ed2d7
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -1,5 +1,5 @@
|
||||
#!groovy
|
||||
dependenciesRevision='0069cbdd1559b47c9de98ca934b334b12fa59703-1174'
|
||||
strategy='EQUAL'
|
||||
allowedCD=274
|
||||
allowedCD=273
|
||||
allowedF=4
|
||||
|
||||
@@ -28,8 +28,9 @@ const DeviceDescriptor deviceDescriptorTable[] = {
|
||||
static std::array<Drm *, 1> drms = {{nullptr}};
|
||||
|
||||
Drm::~Drm() {
|
||||
if (lowPriorityContextId)
|
||||
contextDestroy();
|
||||
if (lowPriorityContextId != 0) {
|
||||
destroyLowPriorityContext();
|
||||
}
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
@@ -129,49 +129,34 @@ bool Drm::is48BitAddressRangeSupported() {
|
||||
return (ret == 0) && (value == 3);
|
||||
}
|
||||
|
||||
bool Drm::hasPreemption() {
|
||||
void Drm::checkPreemptionSupport() {
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
int value = 0;
|
||||
auto ret = getParam(I915_PARAM_HAS_PREEMPTION, &value);
|
||||
if (ret == 0 && value == 1) {
|
||||
return contextCreate() && setLowPriority();
|
||||
}
|
||||
preemptionSupported = (ret == 0 && value == 1);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Drm::setLowPriority() {
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
struct drm_i915_gem_context_param gcp = {};
|
||||
void Drm::createLowPriorityContext() {
|
||||
drm_i915_gem_context_create gcc = {};
|
||||
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &gcc);
|
||||
UNRECOVERABLE_IF(retVal != 0);
|
||||
lowPriorityContextId = gcc.ctx_id;
|
||||
|
||||
drm_i915_gem_context_param gcp = {};
|
||||
gcp.ctx_id = lowPriorityContextId;
|
||||
gcp.param = I915_CONTEXT_PARAM_PRIORITY;
|
||||
gcp.value = -1023;
|
||||
|
||||
int ret = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &gcp);
|
||||
if (ret == 0) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &gcp);
|
||||
UNRECOVERABLE_IF(retVal != 0);
|
||||
}
|
||||
|
||||
bool Drm::contextCreate() {
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
drm_i915_gem_context_create gcc = {};
|
||||
if (ioctl(DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &gcc) == 0) {
|
||||
lowPriorityContextId = gcc.ctx_id;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void Drm::contextDestroy() {
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
void Drm::destroyLowPriorityContext() {
|
||||
drm_i915_gem_context_destroy destroy = {};
|
||||
destroy.ctx_id = lowPriorityContextId;
|
||||
ioctl(DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy);
|
||||
#endif
|
||||
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy);
|
||||
UNRECOVERABLE_IF(retVal != 0);
|
||||
}
|
||||
|
||||
int Drm::getEuTotal(int &euTotal) {
|
||||
|
||||
@@ -54,11 +54,11 @@ class Drm {
|
||||
int getMinEuInPool(int &minEUinPool);
|
||||
|
||||
bool is48BitAddressRangeSupported();
|
||||
MOCKABLE_VIRTUAL bool hasPreemption();
|
||||
bool setLowPriority();
|
||||
bool isPreemptionSupported() const { return preemptionSupported; }
|
||||
MOCKABLE_VIRTUAL void checkPreemptionSupport();
|
||||
int getFileDescriptor() const { return fd; }
|
||||
bool contextCreate();
|
||||
void contextDestroy();
|
||||
void createLowPriorityContext();
|
||||
void destroyLowPriorityContext();
|
||||
|
||||
void setGtType(GTTYPE eGtType) { this->eGtType = eGtType; }
|
||||
GTTYPE getGtType() const { return this->eGtType; }
|
||||
@@ -68,6 +68,7 @@ class Drm {
|
||||
|
||||
protected:
|
||||
bool useSimplifiedMocsTable = false;
|
||||
bool preemptionSupported = false;
|
||||
int fd;
|
||||
int deviceId;
|
||||
int revisionId;
|
||||
|
||||
@@ -160,7 +160,11 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou
|
||||
outHwInfo->capabilityTable.ftrRenderCompressedBuffers = false;
|
||||
outHwInfo->capabilityTable.ftrRenderCompressedImages = false;
|
||||
|
||||
bool preemption = drm->hasPreemption();
|
||||
drm->checkPreemptionSupport();
|
||||
bool preemption = drm->isPreemptionSupported();
|
||||
if (preemption) {
|
||||
drm->createLowPriorityContext();
|
||||
}
|
||||
preemption = hwHelper.setupPreemptionRegisters(outHwInfo, preemption);
|
||||
PreemptionHelper::adjustDefaultPreemptionMode(outHwInfo->capabilityTable,
|
||||
static_cast<bool>(outHwInfo->pSkuTable->ftrGpGpuMidThreadLevelPreempt) && preemption,
|
||||
|
||||
@@ -16,11 +16,7 @@ GEN10TEST_F(DeviceFactoryLinuxTestCnl, queryWhitelistedPreemptionRegister) {
|
||||
|
||||
bool success = DeviceFactory::getDevices(&hwInfo, numDevices, executionEnvironment);
|
||||
EXPECT_TRUE(success);
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
EXPECT_TRUE(hwInfo->capabilityTable.whitelistedRegisters.csChicken1_0x2580);
|
||||
#else
|
||||
EXPECT_FALSE(hwInfo->capabilityTable.whitelistedRegisters.csChicken1_0x2580);
|
||||
#endif
|
||||
|
||||
DeviceFactory::releaseDevices();
|
||||
}
|
||||
|
||||
@@ -16,11 +16,7 @@ GEN9TEST_F(DeviceFactoryLinuxTestSkl, queryWhitelistedPreemptionRegister) {
|
||||
|
||||
bool success = DeviceFactory::getDevices(&hwInfo, numDevices, executionEnvironment);
|
||||
EXPECT_TRUE(success);
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
EXPECT_TRUE(hwInfo->capabilityTable.whitelistedRegisters.csChicken1_0x2580);
|
||||
#else
|
||||
EXPECT_FALSE(hwInfo->capabilityTable.whitelistedRegisters.csChicken1_0x2580);
|
||||
#endif
|
||||
|
||||
DeviceFactory::releaseDevices();
|
||||
}
|
||||
|
||||
@@ -264,25 +264,26 @@ TEST_F(DrmTests, givenKernelSupportingTurboPatchWhenDeviceIsCreatedThenSimplifie
|
||||
EXPECT_FALSE(drm->getSimplifiedMocsTableUsage());
|
||||
}
|
||||
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
TEST_F(DrmTests, checkPreemption) {
|
||||
auto drm = DrmWrap::createDrm(0);
|
||||
EXPECT_NE(drm, nullptr);
|
||||
bool ret = drm->hasPreemption();
|
||||
EXPECT_EQ(ret, true);
|
||||
drm->checkPreemptionSupport();
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
#else
|
||||
EXPECT_FALSE(drm->isPreemptionSupported());
|
||||
#endif
|
||||
DrmWrap::closeDevice(0);
|
||||
|
||||
drm = DrmWrap::get(0);
|
||||
EXPECT_EQ(drm, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_F(DrmTests, failOnContextCreate) {
|
||||
auto drm = DrmWrap::createDrm(0);
|
||||
EXPECT_NE(drm, nullptr);
|
||||
failOnContextCreate = -1;
|
||||
bool ret = drm->hasPreemption();
|
||||
EXPECT_EQ(ret, false);
|
||||
EXPECT_THROW(drm->createLowPriorityContext(), std::exception);
|
||||
EXPECT_FALSE(drm->isPreemptionSupported());
|
||||
failOnContextCreate = 0;
|
||||
DrmWrap::closeDevice(0);
|
||||
|
||||
@@ -294,8 +295,8 @@ TEST_F(DrmTests, failOnSetPriority) {
|
||||
auto drm = DrmWrap::createDrm(0);
|
||||
EXPECT_NE(drm, nullptr);
|
||||
failOnSetPriority = -1;
|
||||
bool ret = drm->hasPreemption();
|
||||
EXPECT_EQ(ret, false);
|
||||
EXPECT_THROW(drm->createLowPriorityContext(), std::exception);
|
||||
EXPECT_FALSE(drm->isPreemptionSupported());
|
||||
failOnSetPriority = 0;
|
||||
DrmWrap::closeDevice(0);
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
using namespace OCLRT;
|
||||
|
||||
#if !defined(I915_PARAM_HAS_PREEMPTION)
|
||||
#define I915_PARAM_HAS_PREEMPTION 0x806
|
||||
#endif
|
||||
|
||||
static const int mockFd = 33;
|
||||
// Mock DRM class that responds to DRM_IOCTL_I915_GETPARAMs
|
||||
class DrmMock : public Drm {
|
||||
@@ -32,7 +36,7 @@ class DrmMock : public Drm {
|
||||
sysFsDefaultGpuPath = sysFsDefaultGpuPathToRestore;
|
||||
}
|
||||
}
|
||||
virtual inline int ioctl(unsigned long request, void *arg) {
|
||||
int ioctl(unsigned long request, void *arg) override {
|
||||
if ((request == DRM_IOCTL_I915_GETPARAM) && (arg != nullptr)) {
|
||||
drm_i915_getparam_t *gp = (drm_i915_getparam_t *)arg;
|
||||
if (false
|
||||
@@ -194,20 +198,8 @@ class DrmMock : public Drm {
|
||||
void setDeviceID(int deviceId) { this->deviceId = deviceId; }
|
||||
void setDeviceRevID(int revisionId) { this->revisionId = revisionId; }
|
||||
|
||||
bool hasPreemption() {
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
drm_i915_getparam_t gp;
|
||||
int value = 0;
|
||||
gp.value = &value;
|
||||
gp.param = I915_PARAM_HAS_PREEMPTION;
|
||||
int ret = ioctl(DRM_IOCTL_I915_GETPARAM, &gp);
|
||||
if (ret == 0 && *gp.value == 1) {
|
||||
return contextCreate() && setLowPriority();
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return this->StoredMockPreemptionSupport == 1 ? true : false;
|
||||
#endif
|
||||
void checkPreemptionSupport() override {
|
||||
preemptionSupported = StoredPreemptionSupport;
|
||||
}
|
||||
|
||||
int StoredEUVal = -1;
|
||||
@@ -224,8 +216,7 @@ class DrmMock : public Drm {
|
||||
int StoredRetValForPooledEU = 0;
|
||||
int StoredRetValForMinEUinPool = 0;
|
||||
int StoredPPGTT = 3;
|
||||
int StoredPreemptionSupport = 1;
|
||||
int StoredMockPreemptionSupport = 0;
|
||||
int StoredPreemptionSupport = 0;
|
||||
int StoredExecSoftPin = 0;
|
||||
uint32_t StoredCtxId = 1;
|
||||
|
||||
|
||||
@@ -125,13 +125,15 @@ TEST(DrmTest, GivenDrmWhenAskedFor48BitAddressCorrectValueReturned) {
|
||||
delete pDrm;
|
||||
}
|
||||
|
||||
#if defined(I915_PARAM_HAS_PREEMPTION)
|
||||
TEST(DrmTest, GivenDrmWhenAskedForPreemptionCorrectValueReturned) {
|
||||
DrmMock *pDrm = new DrmMock;
|
||||
pDrm->StoredPreemptionSupport = 1;
|
||||
EXPECT_TRUE(pDrm->hasPreemption());
|
||||
pDrm->checkPreemptionSupport();
|
||||
EXPECT_TRUE(pDrm->isPreemptionSupported());
|
||||
|
||||
pDrm->StoredPreemptionSupport = 0;
|
||||
EXPECT_FALSE(pDrm->hasPreemption());
|
||||
pDrm->checkPreemptionSupport();
|
||||
EXPECT_FALSE(pDrm->isPreemptionSupported());
|
||||
delete pDrm;
|
||||
}
|
||||
|
||||
@@ -140,7 +142,7 @@ TEST(DrmTest, GivenDrmWhenAskedForContextThatPassedThenValidContextIdsReturned)
|
||||
EXPECT_EQ(0u, pDrm->lowPriorityContextId);
|
||||
pDrm->StoredRetVal = 0;
|
||||
pDrm->StoredCtxId = 2;
|
||||
EXPECT_TRUE(pDrm->contextCreate());
|
||||
pDrm->createLowPriorityContext();
|
||||
EXPECT_EQ(2u, pDrm->lowPriorityContextId);
|
||||
pDrm->StoredRetVal = 0;
|
||||
pDrm->StoredCtxId = 1;
|
||||
@@ -150,36 +152,17 @@ TEST(DrmTest, GivenDrmWhenAskedForContextThatPassedThenValidContextIdsReturned)
|
||||
TEST(DrmTest, GivenDrmWhenAskedForContextThatFailsThenFalseIsReturned) {
|
||||
DrmMock *pDrm = new DrmMock;
|
||||
pDrm->StoredRetVal = -1;
|
||||
EXPECT_FALSE(pDrm->contextCreate());
|
||||
EXPECT_THROW(pDrm->createLowPriorityContext(), std::exception);
|
||||
pDrm->StoredRetVal = 0;
|
||||
delete pDrm;
|
||||
}
|
||||
|
||||
TEST(DrmTest, GivenDrmWhenAskedForContextWithLowPriorityThatFailsThenFalseIsReturned) {
|
||||
DrmMock *pDrm = new DrmMock;
|
||||
EXPECT_TRUE(pDrm->contextCreate());
|
||||
pDrm->StoredRetVal = -1;
|
||||
EXPECT_FALSE(pDrm->setLowPriority());
|
||||
pDrm->StoredRetVal = 0;
|
||||
delete pDrm;
|
||||
}
|
||||
#else
|
||||
TEST(DrmTest, GivenDrmWhenAskedForContextWithLowPriorityThenFalseIsReturned) {
|
||||
DrmMock drmMock;
|
||||
EXPECT_FALSE(drmMock.contextCreate());
|
||||
}
|
||||
|
||||
TEST(DrmTest, GivenDrmWhenContextDestroyIsCalledThenThereAreNoLeaksOrCrashes) {
|
||||
DrmMock drmMock;
|
||||
drmMock.contextDestroy();
|
||||
drmMock.createLowPriorityContext();
|
||||
drmMock.destroyLowPriorityContext();
|
||||
}
|
||||
|
||||
TEST(DrmTest, GivenDrmWhenSetContextPriorityIsCalledThenFalseIsReturned) {
|
||||
DrmMock drmMock;
|
||||
EXPECT_FALSE(drmMock.setLowPriority());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(DrmTest, getExecSoftPin) {
|
||||
DrmMock *pDrm = new DrmMock;
|
||||
int execSoftPin = 0;
|
||||
|
||||
@@ -249,81 +249,81 @@ TEST_F(HwInfoConfigTestLinuxDummy, dummyNegativeUnknownDeviceId) {
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledMidThreadOn) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
|
||||
drm->StoredPreemptionSupport = 1;
|
||||
drm->StoredMockPreemptionSupport = 1;
|
||||
drm->StoredDeviceID = hwConfigTestMidThreadBit;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::MidThread, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledThreadGroupOn) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
|
||||
drm->StoredPreemptionSupport = 1;
|
||||
drm->StoredMockPreemptionSupport = 1;
|
||||
drm->StoredDeviceID = hwConfigTestThreadGroupBit;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::ThreadGroup, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledMidBatchOn) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
|
||||
drm->StoredPreemptionSupport = 1;
|
||||
drm->StoredMockPreemptionSupport = 1;
|
||||
drm->StoredDeviceID = hwConfigTestMidBatchBit;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::MidBatch, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledNoPreemption) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
|
||||
drm->StoredPreemptionSupport = 1;
|
||||
drm->StoredMockPreemptionSupport = 1;
|
||||
drm->StoredDeviceID = 1;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::Disabled, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmDisabledAllPreemption) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
|
||||
drm->StoredPreemptionSupport = 0;
|
||||
drm->StoredMockPreemptionSupport = 0;
|
||||
drm->StoredDeviceID = hwConfigTestMidThreadBit | hwConfigTestThreadGroupBit | hwConfigTestMidBatchBit;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::Disabled, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_FALSE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledAllPreemptionDriverThreadGroup) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::ThreadGroup;
|
||||
drm->StoredPreemptionSupport = 1;
|
||||
drm->StoredMockPreemptionSupport = 1;
|
||||
drm->StoredDeviceID = hwConfigTestMidThreadBit | hwConfigTestThreadGroupBit | hwConfigTestMidBatchBit;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::ThreadGroup, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledAllPreemptionDriverMidBatch) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::MidBatch;
|
||||
drm->StoredPreemptionSupport = 1;
|
||||
drm->StoredMockPreemptionSupport = 1;
|
||||
drm->StoredDeviceID = hwConfigTestMidThreadBit | hwConfigTestThreadGroupBit | hwConfigTestMidBatchBit;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::MidBatch, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledAllPreemptionDriverDisabled) {
|
||||
pInHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled;
|
||||
drm->StoredPreemptionSupport = 1;
|
||||
drm->StoredMockPreemptionSupport = 1;
|
||||
drm->StoredDeviceID = hwConfigTestMidThreadBit | hwConfigTestThreadGroupBit | hwConfigTestMidBatchBit;
|
||||
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(PreemptionMode::Disabled, outHwInfo.capabilityTable.defaultPreemptionMode);
|
||||
EXPECT_TRUE(drm->isPreemptionSupported());
|
||||
}
|
||||
|
||||
TEST_F(HwInfoConfigTestLinuxDummy, givenPlatformEnabledFtrCompressionWhenInitializingThenForceDisable) {
|
||||
|
||||
Reference in New Issue
Block a user