Fix for Execution model PageFaults

- adding PC with MediaStateClear and MEDIA_VFE_STATE in
EMCleanupSection

Change-Id: I0ee0e121bc2fcc09ac79cb3b601591247326482a
This commit is contained in:
Hoppe, Mateusz
2017-12-20 13:24:19 +01:00
committed by sys_ocldev
parent 03646887bf
commit a9f30a5059
12 changed files with 261 additions and 25 deletions

View File

@ -34,6 +34,8 @@
#include "runtime/command_queue/dispatch_walker_helper.h"
#include "runtime/helpers/kernel_commands.h"
#include <memory>
using namespace OCLRT;
using namespace DeviceHostQueue;
@ -163,6 +165,20 @@ class DeviceQueueSlb : public DeviceQueueHwTest {
}
};
HWTEST_F(DeviceQueueSlb, allocateSlbBufferAllocatesCorrectSize) {
std::unique_ptr<MockDeviceQueueHw<FamilyType>> mockDeviceQueueHw(new MockDeviceQueueHw<FamilyType>(pContext, device, deviceQueueProperties::minimumProperties[0]));
LinearStream *slbCS = mockDeviceQueueHw->getSlbCS();
size_t expectedSize = (mockDeviceQueueHw->getMinimumSlbSize() + mockDeviceQueueHw->getWaCommandsSize()) * 128;
expectedSize += sizeof(typename FamilyType::MI_BATCH_BUFFER_START);
expectedSize = alignUp(expectedSize, MemoryConstants::pageSize);
expectedSize += MockDeviceQueueHw<FamilyType>::getExecutionModelCleanupSectionSize();
expectedSize += (4 * MemoryConstants::pageSize);
EXPECT_LE(expectedSize, slbCS->getAvailableSpace());
}
HWTEST_F(DeviceQueueSlb, buildSlbAfterReset) {
auto mockDeviceQueueHw =
new MockDeviceQueueHw<FamilyType>(pContext, device, deviceQueueProperties::minimumProperties[0]);
@ -305,6 +321,13 @@ HWTEST_F(DeviceQueueSlb, cleanupSection) {
size_t cleanupSectionOffset = alignUp(mockDeviceQueueHw->numberOfDeviceEnqueues * commandsSize + sizeof(MI_BATCH_BUFFER_START), MemoryConstants::pageSize);
size_t cleanupSectionOffsetToParse = cleanupSectionOffset;
size_t slbUsed = slbCS->getUsed();
slbUsed = alignUp(slbUsed, MemoryConstants::pageSize);
size_t slbMax = slbCS->getMaxAvailableSpace();
// 4 pages padding expected after cleanup section
EXPECT_LE(4 * MemoryConstants::pageSize, slbMax - slbUsed);
if (mockParentKernel->getKernelInfo().patchInfo.executionEnvironment->UsesFencesForReadWriteImages) {
cleanupSectionOffsetToParse += getSizeForWADisableLSQCROPERFforOCL<FamilyType>(mockParentKernel) / 2;
@ -618,15 +641,127 @@ HWTEST_F(TheSimplestDeviceQueueFixture, resetDeviceQueueSetEarlyReturnValues) {
DebugManager.flags.SchedulerSimulationReturnInstance.set(3);
MockDevice *device = Device::create<MockDevice>(platformDevices[0]);
std::unique_ptr<MockDevice> device(Device::create<MockDevice>(platformDevices[0]));
MockContext context;
MockDeviceQueueHw<FamilyType> *mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(&context, device, deviceQueueProperties::minimumProperties[0]);
std::unique_ptr<MockDeviceQueueHw<FamilyType>> mockDeviceQueueHw(new MockDeviceQueueHw<FamilyType>(&context, device.get(), deviceQueueProperties::minimumProperties[0]));
mockDeviceQueueHw->resetDeviceQueue();
EXPECT_EQ(3u, mockDeviceQueueHw->getIgilQueue()->m_controls.m_SchedulerEarlyReturn);
EXPECT_EQ(0u, mockDeviceQueueHw->getIgilQueue()->m_controls.m_SchedulerEarlyReturnCounter);
delete mockDeviceQueueHw;
delete device;
}
HWTEST_F(TheSimplestDeviceQueueFixture, addMediaStateClearCmds) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
using MEDIA_VFE_STATE = typename FamilyType::MEDIA_VFE_STATE;
std::unique_ptr<MockDevice> device(Device::create<MockDevice>(platformDevices[0]));
MockContext context;
std::unique_ptr<MockDeviceQueueHw<FamilyType>> mockDeviceQueueHw(new MockDeviceQueueHw<FamilyType>(&context, device.get(), deviceQueueProperties::minimumProperties[0]));
HardwareParse hwParser;
auto *slbCS = mockDeviceQueueHw->getSlbCS();
mockDeviceQueueHw->addMediaStateClearCmds();
hwParser.parseCommands<FamilyType>(*slbCS, 0);
hwParser.findHardwareCommands<FamilyType>();
auto pipeControlItor = find<PIPE_CONTROL *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
EXPECT_NE(hwParser.cmdList.end(), pipeControlItor);
if (mockDeviceQueueHw->pipeControlWa) {
pipeControlItor++;
EXPECT_NE(hwParser.cmdList.end(), pipeControlItor);
}
PIPE_CONTROL *pipeControl = (PIPE_CONTROL *)*pipeControlItor;
EXPECT_TRUE(pipeControl->getGenericMediaStateClear());
auto mediaVfeStateItor = find<MEDIA_VFE_STATE *>(pipeControlItor, hwParser.cmdList.end());
EXPECT_NE(hwParser.cmdList.end(), mediaVfeStateItor);
}
HWTEST_F(TheSimplestDeviceQueueFixture, addExecutionModelCleanupSectionClearsMediaState) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
using MEDIA_VFE_STATE = typename FamilyType::MEDIA_VFE_STATE;
class MockDeviceQueueWithMediaStateClearRegistering : public MockDeviceQueueHw<FamilyType> {
public:
MockDeviceQueueWithMediaStateClearRegistering(Context *context,
Device *device,
cl_queue_properties &properties) : MockDeviceQueueHw<FamilyType>(context, device, properties) {
}
bool addMediaStateClearCmdsCalled = false;
void addMediaStateClearCmds() override {
addMediaStateClearCmdsCalled = true;
}
};
std::unique_ptr<MockDevice> device(Device::create<MockDevice>(platformDevices[0]));
MockContext context;
std::unique_ptr<MockDeviceQueueWithMediaStateClearRegistering> mockDeviceQueueHw(new MockDeviceQueueWithMediaStateClearRegistering(&context, device.get(), deviceQueueProperties::minimumProperties[0]));
std::unique_ptr<MockParentKernel> mockParentKernel(MockParentKernel::create(*device));
uint32_t taskCount = 7;
mockDeviceQueueHw->buildSlbDummyCommands();
EXPECT_FALSE(mockDeviceQueueHw->addMediaStateClearCmdsCalled);
mockDeviceQueueHw->addExecutionModelCleanUpSection(mockParentKernel.get(), nullptr, taskCount);
EXPECT_TRUE(mockDeviceQueueHw->addMediaStateClearCmdsCalled);
}
HWTEST_F(TheSimplestDeviceQueueFixture, getMediaStateClearCmdsSize) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
using MEDIA_VFE_STATE = typename FamilyType::MEDIA_VFE_STATE;
std::unique_ptr<MockDevice> device(Device::create<MockDevice>(platformDevices[0]));
MockContext context;
std::unique_ptr<MockDeviceQueueHw<FamilyType>> mockDeviceQueueHw(new MockDeviceQueueHw<FamilyType>(&context, device.get(), deviceQueueProperties::minimumProperties[0]));
size_t expectedSize = 2 * sizeof(PIPE_CONTROL) + sizeof(PIPE_CONTROL) + sizeof(MEDIA_VFE_STATE);
EXPECT_EQ(expectedSize, MockDeviceQueueHw<FamilyType>::getMediaStateClearCmdsSize());
}
HWTEST_F(TheSimplestDeviceQueueFixture, getExecutionModelCleanupSectionSize) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
using MI_MATH_ALU_INST_INLINE = typename FamilyType::MI_MATH_ALU_INST_INLINE;
using MI_LOAD_REGISTER_REG = typename FamilyType::MI_LOAD_REGISTER_REG;
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
using MI_MATH = typename FamilyType::MI_MATH;
using MI_BATCH_BUFFER_END = typename FamilyType::MI_BATCH_BUFFER_END;
std::unique_ptr<MockDevice> device(Device::create<MockDevice>(platformDevices[0]));
MockContext context;
std::unique_ptr<MockDeviceQueueHw<FamilyType>> mockDeviceQueueHw(new MockDeviceQueueHw<FamilyType>(&context, device.get(), deviceQueueProperties::minimumProperties[0]));
size_t expectedSize = sizeof(PIPE_CONTROL) +
2 * sizeof(MI_LOAD_REGISTER_REG) +
sizeof(MI_LOAD_REGISTER_IMM) +
sizeof(PIPE_CONTROL) +
sizeof(MI_MATH) +
NUM_ALU_INST_FOR_READ_MODIFY_WRITE * sizeof(MI_MATH_ALU_INST_INLINE);
expectedSize += MockDeviceQueueHw<FamilyType>::getProfilingEndCmdsSize();
expectedSize += MockDeviceQueueHw<FamilyType>::getMediaStateClearCmdsSize();
expectedSize += 4 * sizeof(PIPE_CONTROL);
expectedSize += sizeof(MI_BATCH_BUFFER_END);
EXPECT_EQ(expectedSize, MockDeviceQueueHw<FamilyType>::getExecutionModelCleanupSectionSize());
}
HWTEST_F(TheSimplestDeviceQueueFixture, getProfilingEndCmdsSize) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
using MI_STORE_REGISTER_MEM = typename FamilyType::MI_STORE_REGISTER_MEM;
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
std::unique_ptr<MockDevice> device(Device::create<MockDevice>(platformDevices[0]));
MockContext context;
std::unique_ptr<MockDeviceQueueHw<FamilyType>> mockDeviceQueueHw(new MockDeviceQueueHw<FamilyType>(&context, device.get(), deviceQueueProperties::minimumProperties[0]));
size_t expectedSize = sizeof(PIPE_CONTROL) + 2 * sizeof(MI_STORE_REGISTER_MEM) + sizeof(MI_LOAD_REGISTER_IMM);
EXPECT_EQ(expectedSize, MockDeviceQueueHw<FamilyType>::getProfilingEndCmdsSize());
}

View File

@ -506,3 +506,19 @@ HWTEST_F(ParentKernelEnqueueFixture, givenCsrInBatchingModeWhenExecutionModelKer
EXPECT_EQ(1, mockCsr->flushCalledCount);
}
}
HWTEST_F(ParentKernelEnqueueFixture, ParentKernelEnqueueMarksCSRMediaVFEStateDirty) {
if (pDevice->getSupportedClVersion() >= 20) {
size_t offset[3] = {0, 0, 0};
size_t gws[3] = {1, 1, 1};
int32_t execStamp;
auto mockCsr = new MockCsr<FamilyType>(execStamp);
pDevice->resetCommandStreamReceiver(mockCsr);
mockCsr->overrideMediaVFEStateDirty(false);
pCmdQ->enqueueKernel(parentKernel, 1, offset, gws, gws, 0, nullptr, nullptr);
EXPECT_TRUE(mockCsr->peekMediaVfeStateDirty());
}
}

View File

@ -39,9 +39,11 @@ GEN8TEST_F(Gen8DeviceQueueSlb, expectedAllocationSize) {
sizeof(typename FamilyType::MI_LOAD_REGISTER_IMM) +
sizeof(typename FamilyType::MI_LOAD_REGISTER_IMM);
expectedSize *= 128; //num of enqueues
expectedSize += sizeof(typename FamilyType::MI_BATCH_BUFFER_START) + (4 * MemoryConstants::pageSize);
expectedSize += sizeof(typename FamilyType::MI_BATCH_BUFFER_START);
expectedSize = alignUp(expectedSize, MemoryConstants::pageSize);
expectedSize += MockDeviceQueueHw<FamilyType>::getExecutionModelCleanupSectionSize();
expectedSize += (4 * MemoryConstants::pageSize);
expectedSize = alignUp(expectedSize, MemoryConstants::pageSize);
ASSERT_NE(deviceQueue->getSlbBuffer(), nullptr);
EXPECT_EQ(deviceQueue->getSlbBuffer()->getUnderlyingBufferSize(), expectedSize);

View File

@ -42,7 +42,10 @@ GEN9TEST_F(Gen9DeviceQueueSlb, expectedAllocationSize) {
sizeof(typename FamilyType::PIPE_CONTROL) +
sizeof(typename FamilyType::PIPE_CONTROL);
expectedSize *= 128; //num of enqueues
expectedSize += sizeof(typename FamilyType::MI_BATCH_BUFFER_START) + (4 * MemoryConstants::pageSize);
expectedSize += sizeof(typename FamilyType::MI_BATCH_BUFFER_START);
expectedSize = alignUp(expectedSize, MemoryConstants::pageSize);
expectedSize += MockDeviceQueueHw<FamilyType>::getExecutionModelCleanupSectionSize();
expectedSize += (4 * MemoryConstants::pageSize);
expectedSize = alignUp(expectedSize, MemoryConstants::pageSize);
ASSERT_NE(deviceQueue->getSlbBuffer(), nullptr);

View File

@ -96,6 +96,7 @@ template <typename GfxFamily>
class MockCsr : public MockCsrBase<GfxFamily> {
public:
using BaseClass = MockCsrBase<GfxFamily>;
using CommandStreamReceiver::mediaVfeStateDirty;
MockCsr() = delete;
MockCsr(const HardwareInfo &hwInfoIn) = delete;
@ -132,6 +133,8 @@ class MockCsr : public MockCsrBase<GfxFamily> {
dispatchFlags);
}
bool peekMediaVfeStateDirty() const { return mediaVfeStateDirty; }
bool slmUsedInLastFlushTask = false;
uint32_t lastTaskLevelToFlushTask = 0;
};

View File

@ -51,6 +51,10 @@ class MockDeviceQueueHw : public DeviceQueueHw<GfxFamily> {
using BaseClass::getSlbCS;
using BaseClass::getWaCommandsSize;
using BaseClass::offsetDsh;
using BaseClass::addMediaStateClearCmds;
using BaseClass::getMediaStateClearCmdsSize;
using BaseClass::getProfilingEndCmdsSize;
using BaseClass::getExecutionModelCleanupSectionSize;
bool arbCheckWa;
bool miAtomicWa;