I915_EXEC_DATA_PORT_COHERENT support

- new mechanism to switch coherency at exec level

Change-Id: I3e9cca2141822828be7d44e858e8fe2c258efbfa
This commit is contained in:
Dunajski, Bartosz 2018-03-09 13:03:48 +01:00 committed by sys_ocldev
parent 26b0b9a873
commit 933312e098
8 changed files with 105 additions and 4 deletions

View File

@ -132,7 +132,7 @@ bool BufferObject::setTiling(uint32_t mode, uint32_t stride) {
void BufferObject::fillExecObject(drm_i915_gem_exec_object2 &execObject) {
execObject.handle = this->handle;
execObject.relocation_count = 0; //No relocations, we are SoftPinning
execObject.relocation_count = 0; //No relocations, we are SoftPinning
execObject.relocs_ptr = 0ul;
execObject.alignment = 0;
execObject.offset = this->isSoftpin ? this->offset64 : 0;
@ -167,7 +167,9 @@ int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bo
execbuf.flags = flags;
if (drm->peekCoherencyDisablePatchActive() && !requiresCoherency) {
execbuf.flags = execbuf.flags | I915_PRIVATE_EXEC_FORCE_NON_COHERENT;
execbuf.flags |= (uint64_t)I915_PRIVATE_EXEC_FORCE_NON_COHERENT;
} else if (drm->peekDataPortCoherencyPatchActive() && requiresCoherency) {
execbuf.flags |= (uint64_t)I915_EXEC_DATA_PORT_COHERENT;
}
if (lowPriority) {
execbuf.rsvd1 = this->drm->lowPriorityContextId & I915_EXEC_CONTEXT_ID_MASK;

View File

@ -124,6 +124,12 @@ void Drm::obtainCoherencyDisablePatchActive() {
coherencyDisablePatchActive = (ret == 0) && (value != 0);
}
void Drm::obtainDataPortCoherencyPatchActive() {
int value = 0;
auto ret = getParamIoctl(I915_PARAM_HAS_EXEC_DATA_PORT_COHERENCY, &value);
dataPortCoherencyPatchActive = (ret == 0) && (value != 0);
}
std::string Drm::getSysFsPciPath(int deviceID) {
std::string nullPath;
std::string sysFsPciDirectory = Os::sysFsPciPath;

View File

@ -39,6 +39,9 @@ namespace OCLRT {
#define I915_CONTEXT_PRIVATE_PARAM_BOOST 0x80000000
#define I915_EXEC_DATA_PORT_COHERENT (1 << 20)
#define I915_PARAM_HAS_EXEC_DATA_PORT_COHERENCY 52
class DeviceFactory;
struct HardwareInfo;
@ -74,8 +77,10 @@ class Drm {
bool is48BitAddressRangeSupported();
MOCKABLE_VIRTUAL bool hasPreemption();
bool setLowPriority();
bool peekCoherencyDisablePatchActive() { return coherencyDisablePatchActive; }
bool peekCoherencyDisablePatchActive() const { return coherencyDisablePatchActive; }
bool peekDataPortCoherencyPatchActive() const { return dataPortCoherencyPatchActive; }
virtual void obtainCoherencyDisablePatchActive();
MOCKABLE_VIRTUAL void obtainDataPortCoherencyPatchActive();
int getFileDescriptor() const { return fd; }
bool contextCreate();
void contextDestroy();
@ -90,6 +95,7 @@ class Drm {
int revisionId;
GTTYPE eGtType;
bool coherencyDisablePatchActive = false;
bool dataPortCoherencyPatchActive = false;
Drm(int fd) : lowPriorityContextId(0), fd(fd), deviceId(0), revisionId(0), eGtType(GTTYPE_UNDEFINED) {}
virtual ~Drm();

View File

@ -131,6 +131,7 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou
pSysInfo->SubSliceCount = static_cast<uint32_t>(subSliceCount);
drm->obtainCoherencyDisablePatchActive();
drm->obtainDataPortCoherencyPatchActive();
pSkuTable->ftrSVM = drm->is48BitAddressRangeSupported();
int maxGpuFreq = 0;

View File

@ -81,6 +81,7 @@ class DrmMockCustom : public Drm {
IoctlResExt(int32_t no, int32_t res) : no(no), res(res) {}
};
void overideCoherencyPatchActive(bool newCoherencyPatchActiveValue) { coherencyDisablePatchActive = newCoherencyPatchActiveValue; }
void overideDataPortCoherencyPatchActive(bool newValue) { dataPortCoherencyPatchActive = newValue; }
class Ioctls {
public:

View File

@ -110,6 +110,36 @@ TEST_F(DrmBufferObjectTest, givenDrmWithCoherencyPatchActiveWhenExecIsCalledWith
EXPECT_EQ(expectedFlag, currentFlag);
}
TEST_F(DrmBufferObjectTest, givenDrmWithDataPortCoherencyPatchActiveWhenExecWithCoherencyRequestCalledThenSetExecFlag) {
mock->ioctl_expected.total = 1;
mock->ioctl_res = 0;
mock->overideDataPortCoherencyPatchActive(true);
auto ret = bo->exec(0, 0, 0, true);
EXPECT_EQ(mock->ioctl_res, ret);
EXPECT_NE(0u, mock->execBuffer.flags & I915_EXEC_DATA_PORT_COHERENT);
}
TEST_F(DrmBufferObjectTest, givenDrmWithoutDataPortCoherencyPatchActiveWhenExecWithCoherencyRequestCalledThenDontSetExecFlag) {
mock->ioctl_expected.total = 1;
mock->ioctl_res = 0;
mock->overideDataPortCoherencyPatchActive(false);
auto ret = bo->exec(0, 0, 0, true);
EXPECT_EQ(mock->ioctl_res, ret);
EXPECT_EQ(0u, mock->execBuffer.flags & I915_EXEC_DATA_PORT_COHERENT);
}
TEST_F(DrmBufferObjectTest, givenDrmWithDataPortCoherencyPatchActiveWhenExecWithoutCoherencyRequestCalledThenDontSetExecFlag) {
mock->ioctl_expected.total = 1;
mock->ioctl_res = 0;
mock->overideDataPortCoherencyPatchActive(true);
auto ret = bo->exec(0, 0, 0, false);
EXPECT_EQ(mock->ioctl_res, ret);
EXPECT_EQ(0u, mock->execBuffer.flags & I915_EXEC_DATA_PORT_COHERENT);
}
TEST_F(DrmBufferObjectTest, exec_ioctlFailed) {
mock->ioctl_expected.total = 1;
mock->ioctl_res = -1;

View File

@ -26,6 +26,7 @@
#include "unit_tests/os_interface/linux/drm_mock.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "runtime/os_interface/os_interface.h"
#include <fstream>
@ -180,6 +181,50 @@ TEST(DrmTest, GivenMockDrmWhenAskedFor48BitAddressCorrectValueReturned) {
delete pDrm;
}
ACTION_P2(saveGetParamData, saveParamPtr, forceReturnValuePtr) {
auto getParamArg = static_cast<drm_i915_getparam_t *>(arg1);
*saveParamPtr = getParamArg->param;
*getParamArg->value = forceReturnValuePtr;
}
struct DrmDataPortCoherencyTests : public ::testing::Test {
struct MyMockDrm : public Drm2 {
MyMockDrm() : Drm2(){};
MOCK_METHOD2(ioctl, int(unsigned long request, void *arg));
} drm;
void setupExpectCall(int expectedRetVal, int expectedGetParamValue) {
using namespace ::testing;
auto saveAndReturnAction = DoAll(saveGetParamData(&receivedGetParamType, expectedGetParamValue),
Return(expectedRetVal));
EXPECT_CALL(drm, ioctl(DRM_IOCTL_I915_GETPARAM, _)).Times(1).WillOnce(saveAndReturnAction);
}
int receivedGetParamType = 0;
};
TEST_F(DrmDataPortCoherencyTests, givenDisabledPatchWhenAskedToObtainDataPortCoherencyPatchThenReturnFlase) {
setupExpectCall(1, 0); // return error == 1, dont care about assigned feature value
drm.obtainDataPortCoherencyPatchActive();
EXPECT_EQ(receivedGetParamType, I915_PARAM_HAS_EXEC_DATA_PORT_COHERENCY);
EXPECT_FALSE(drm.peekDataPortCoherencyPatchActive());
}
TEST_F(DrmDataPortCoherencyTests, givenEnabledPatchAndDisabledFeatureWhenAskedToObtainDataPortCoherencyPatchThenReturnFlase) {
setupExpectCall(0, 0); // return success(0), set disabled feature (0)
drm.obtainDataPortCoherencyPatchActive();
EXPECT_EQ(receivedGetParamType, I915_PARAM_HAS_EXEC_DATA_PORT_COHERENCY);
EXPECT_FALSE(drm.peekDataPortCoherencyPatchActive());
}
TEST_F(DrmDataPortCoherencyTests, givenEnabledPatchAndEnabledFeatureWhenAskedToObtainDataPortCoherencyPatchThenReturnTrue) {
setupExpectCall(0, 1); // return success(0), set enabled feature (1)
drm.obtainDataPortCoherencyPatchActive();
EXPECT_EQ(receivedGetParamType, I915_PARAM_HAS_EXEC_DATA_PORT_COHERENCY);
EXPECT_TRUE(drm.peekDataPortCoherencyPatchActive());
}
#if defined(I915_PARAM_HAS_PREEMPTION)
TEST(DrmTest, GivenMockDrmWhenAskedForPreemptionCorrectValueReturned) {
Drm2 *pDrm = new Drm2;

View File

@ -358,4 +358,14 @@ TEST_F(HwInfoConfigTestLinuxDummy, givenPointerToHwInfoWhenConfigureHwInfoCalled
int ret = hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
EXPECT_EQ(0, ret);
EXPECT_EQ(outHwInfo.pSysInfo->CsrSizeInMb * MemoryConstants::megaByte, outHwInfo.capabilityTable.requiredPreemptionSurfaceSize);
}
}
TEST_F(HwInfoConfigTestLinuxDummy, whenAskedToConfigureHwInfoThenObtainDataPortCoherencyPatchStatus) {
struct MyDrm : public Drm2 {
void obtainDataPortCoherencyPatchActive() override { obtainDataPortCoherencyPatchActiveCalled = true; }
bool obtainDataPortCoherencyPatchActiveCalled = false;
} myDrm;
osInterface->get()->setDrm(&myDrm);
hwConfig.configureHwInfo(pInHwInfo, &outHwInfo, osInterface);
EXPECT_TRUE(myDrm.obtainDataPortCoherencyPatchActiveCalled);
}