fix: Do not wait infinitely for fence when context is hung

- when driver is unloaded cleanup paths wait for not completed
fences. In case a context has hung - set finite wait timeout

Resolves: NEO-7613

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2023-01-10 17:20:07 +00:00
committed by Compute-Runtime-Automation
parent af40c80162
commit 5e4604f66d
4 changed files with 58 additions and 5 deletions

View File

@@ -254,6 +254,29 @@ HWTEST_F(DrmDirectSubmissionTest, givenCompletionFenceSupportAndFenceIsNotComple
EXPECT_EQ(osContext->getDrmContextIds().size(), drm->waitUserFenceParams.size());
}
HWTEST_F(DrmDirectSubmissionTest, givenCompletionFenceSupportAndHangingContextWhenDestroyingThenWaitForUserFenceIsCalledWithSmallTimeout) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDrmCompletionFence.set(1);
auto &commandStreamReceiver = *device->getDefaultEngine().commandStreamReceiver;
auto drm = static_cast<DrmMock *>(executionEnvironment.rootDeviceEnvironments[0]->osInterface->getDriverModel()->as<Drm>());
ASSERT_TRUE(drm->completionFenceSupport());
drm->waitUserFenceParams.clear();
osContext->setHangDetected();
{
MockDrmDirectSubmission<FamilyType, RenderDispatcher<FamilyType>> directSubmission(commandStreamReceiver);
directSubmission.completionFenceValue = 10;
}
EXPECT_EQ(osContext->getDrmContextIds().size(), drm->waitUserFenceParams.size());
EXPECT_EQ(1, drm->waitUserFenceParams[0].timeout);
EXPECT_EQ(10u, drm->waitUserFenceParams[0].value);
EXPECT_EQ(Drm::ValueWidth::U64, drm->waitUserFenceParams[0].dataWidth);
}
HWTEST_F(DrmDirectSubmissionTest, givenCompletionFenceSupportAndFenceIsNotCompletedWhenWaitOnSpecificAddressesPerOsContext) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDrmCompletionFence.set(1);

View File

@@ -470,3 +470,24 @@ TEST(DrmBufferObjectTestPrelim, givenProvidedNoCtxIdWhenCallingWaitUserFenceThen
EXPECT_EQ(value, waitUserFence->value);
EXPECT_EQ(2, waitUserFence->timeout);
}
TEST(DrmTestPrelim, givenHungContextWhenCallingWaitUserFenceThenSmallTimeoutIsPassed) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
OsContextLinux osContext(drm, 0, 10u, EngineDescriptorHelper::getDefaultDescriptor());
osContext.ensureContextInitialized();
osContext.setHangDetected();
uint64_t memory = 0;
uint64_t value = 20;
drm.waitOnUserFences(osContext, reinterpret_cast<uint64_t>(&memory), value, 1, 0);
EXPECT_EQ(osContext.getDrmContextIds().size(), drm.context.waitUserFenceCalled);
const auto &waitUserFence = drm.context.receivedWaitUserFence;
ASSERT_TRUE(waitUserFence);
EXPECT_EQ(DrmPrelimHelper::getU64WaitUserFenceFlag(), waitUserFence->mask);
EXPECT_EQ(reinterpret_cast<uint64_t>(&memory), waitUserFence->addr);
EXPECT_EQ(0u, waitUserFence->flags);
EXPECT_EQ(value, waitUserFence->value);
EXPECT_EQ(1, waitUserFence->timeout);
}