Propagate exec buffer error to L0 API level

This change makes that drm file is opened in nonblocking mode for prelim
kernels. In such case when calling exec buffer ioctl and get
EAGAIN (aka EWOULDBLOCK) we may return error to API level

Related-To: NEO-7144
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski 2022-08-25 15:49:58 +00:00 committed by Compute-Runtime-Automation
parent 5c48e027b9
commit 9a95f3c62d
24 changed files with 244 additions and 18 deletions

View File

@ -1116,6 +1116,9 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::handleSubmissionAndCompletionResults(
if (submitRet == NEO::SubmissionStatus::OUT_OF_MEMORY) {
completionRet = ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY;
}
if (submitRet == NEO::SubmissionStatus::OUT_OF_HOST_MEMORY) {
completionRet = ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}
}
return completionRet;

View File

@ -92,6 +92,9 @@ struct MockCommandQueueHw : public L0::CommandQueueHw<gfxCoreFamily> {
NEO::SubmissionStatus submitBatchBuffer(size_t offset, NEO::ResidencyContainer &residencyContainer, void *endingCmdPtr, bool isCooperative) override {
residencyContainerSnapshot = residencyContainer;
if (submitBatchBufferReturnValue.has_value()) {
return *submitBatchBufferReturnValue;
}
return BaseClass::submitBatchBuffer(offset, residencyContainer, endingCmdPtr, isCooperative);
}
@ -99,6 +102,7 @@ struct MockCommandQueueHw : public L0::CommandQueueHw<gfxCoreFamily> {
NEO::ResidencyContainer residencyContainerSnapshot;
ze_result_t synchronizeReturnValue{ZE_RESULT_SUCCESS};
std::optional<NEO::WaitStatus> reserveLinearStreamSizeReturnValue{};
std::optional<NEO::SubmissionStatus> submitBatchBufferReturnValue{};
};
struct Deleter {
@ -108,4 +112,4 @@ struct Deleter {
};
} // namespace ult
} // namespace L0
} // namespace L0

View File

@ -0,0 +1,12 @@
#
# Copyright (C) 2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(UNIX)
target_sources(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cmdqueue_linux_tests.cpp
)
endif()

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/common/helpers/ult_hw_config.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "shared/test/common/libult/create_command_stream.h"
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/test_macros/hw_test.h"
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdlist.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h"
#include "level_zero/core/test/unit_tests/mocks/mock_kernel.h"
namespace L0 {
namespace ult {
struct CommandQueueLinuxTests : public Test<DeviceFixture> {
void SetUp() override {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
ultHwConfig.useHwCsr = true;
ultHwConfig.forceOsAgnosticMemoryManager = false;
auto *executionEnvironment = new NEO::ExecutionEnvironment();
prepareDeviceEnvironments(*executionEnvironment);
executionEnvironment->initializeMemoryManager();
setupWithExecutionEnvironment(*executionEnvironment);
}
};
HWCMDTEST_F(IGFX_XE_HP_CORE, CommandQueueLinuxTests, givenExecBufferErrorWhenExecutingCommandListsThenOutOfHostMemoryIsReturned) {
auto drm = neoDevice->getRootDeviceEnvironment().osInterface->getDriverModel()->as<DrmMock>();
drm->execBufferResult = -1;
drm->baseErrno = false;
drm->errnoRetVal = EWOULDBLOCK;
const ze_command_queue_desc_t desc = {};
ze_result_t returnValue;
auto commandQueue = whiteboxCast(CommandQueue::create(productFamily,
device,
neoDevice->getDefaultEngine().commandStreamReceiver,
&desc,
false,
false,
returnValue));
EXPECT_EQ(ZE_RESULT_SUCCESS, returnValue);
Mock<Kernel> kernel;
kernel.immutableData.isaGraphicsAllocation.reset(neoDevice->getMemoryManager()->allocateGraphicsMemoryWithProperties(
{device->getRootDeviceIndex(), MemoryConstants::pageSize, NEO::AllocationType::KERNEL_ISA, neoDevice->getDeviceBitfield()}));
kernel.immutableData.device = device;
auto commandList = std::unique_ptr<CommandList>(whiteboxCast(CommandList::create(productFamily, device, NEO::EngineGroupType::RenderCompute, 0u, returnValue)));
EXPECT_EQ(ZE_RESULT_SUCCESS, returnValue);
ASSERT_NE(nullptr, commandList);
ze_group_count_t dispatchFunctionArguments{1, 1, 1};
CmdListKernelLaunchParams launchParams = {};
commandList->appendLaunchKernel(kernel.toHandle(), &dispatchFunctionArguments, nullptr, 0, nullptr, launchParams);
ze_command_list_handle_t cmdListHandles[1] = {commandList->toHandle()};
returnValue = commandQueue->executeCommandLists(1, cmdListHandles, nullptr, false);
EXPECT_EQ(ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY, returnValue);
commandQueue->destroy();
neoDevice->getMemoryManager()->freeGraphicsMemory(kernel.immutableData.isaGraphicsAllocation.release());
}
} // namespace ult
} // namespace L0

View File

@ -357,6 +357,30 @@ HWTEST2_F(CommandQueueCreate, givenLogicalStateHelperAndImmediateCmdListWhenExec
commandQueue->destroy();
}
HWTEST2_F(CommandQueueCreate, givenOutOfHostMemoryErrorFromSubmitBatchBufferWhenExecutingCommandListsThenOutOfHostMemoryIsReturned, IsAtLeastSkl) {
const ze_command_queue_desc_t desc = {};
auto commandQueue = new MockCommandQueueHw<gfxCoreFamily>(device, neoDevice->getDefaultEngine().commandStreamReceiver, &desc);
commandQueue->initialize(false, false);
commandQueue->submitBatchBufferReturnValue = NEO::SubmissionStatus::OUT_OF_HOST_MEMORY;
Mock<Kernel> kernel;
kernel.immutableData.device = device;
ze_result_t returnValue;
auto commandList = std::unique_ptr<CommandList>(whiteboxCast(CommandList::create(productFamily, device, NEO::EngineGroupType::RenderCompute, 0u, returnValue)));
ASSERT_NE(nullptr, commandList);
ze_group_count_t dispatchFunctionArguments{1, 1, 1};
CmdListKernelLaunchParams launchParams = {};
commandList->appendLaunchKernel(kernel.toHandle(), &dispatchFunctionArguments, nullptr, 0, nullptr, launchParams);
ze_command_list_handle_t cmdListHandles[1] = {commandList->toHandle()};
const auto result = commandQueue->executeCommandLists(1, cmdListHandles, nullptr, false);
EXPECT_EQ(ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY, result);
commandQueue->destroy();
}
HWTEST2_F(CommandQueueCreate, givenGpuHangInReservingLinearStreamWhenExecutingCommandListsThenDeviceLostIsReturned, IsSKL) {
const ze_command_queue_desc_t desc = {};
MockCommandQueueHw<gfxCoreFamily> commandQueue(device, neoDevice->getDefaultEngine().commandStreamReceiver, &desc);

View File

@ -14,6 +14,7 @@ enum class SubmissionStatus : uint32_t {
SUCCESS = 0,
FAILED,
OUT_OF_MEMORY,
OUT_OF_HOST_MEMORY,
UNSUPPORTED,
DEVICE_UNINITIALIZED,
};

View File

@ -20,6 +20,9 @@ SubmissionStatus DrmCommandStreamReceiver<GfxFamily>::flushInternal(const BatchB
int ret = this->exec(batchBuffer, 0u, static_cast<const OsContextLinux *>(osContext)->getDrmContextIds()[0], 0);
if (ret) {
if (ret == EWOULDBLOCK) {
return SubmissionStatus::OUT_OF_HOST_MEMORY;
}
return SubmissionStatus::FAILED;
}
return SubmissionStatus::SUCCESS;

View File

@ -39,6 +39,9 @@ SubmissionStatus DrmCommandStreamReceiver<GfxFamily>::flushInternal(const BatchB
int ret = this->exec(batchBuffer, tileIterator, drmContextIds[contextIndex], contextIndex);
if (ret) {
if (ret == EWOULDBLOCK) {
return SubmissionStatus::OUT_OF_HOST_MEMORY;
}
return SubmissionStatus::FAILED;
}

View File

@ -58,6 +58,10 @@ void Drm::queryAndSetVmBindPatIndexProgrammingSupport() {
}
int Drm::ioctl(DrmIoctl request, void *arg) {
auto shouldBreakIoctlLoopOnWouldBlock = false;
if (ioctlHelper) {
shouldBreakIoctlLoopOnWouldBlock = ioctlHelper->shouldBreakIoctlLoopOnWouldBlock(request);
}
auto requestValue = getIoctlRequestValue(request, ioctlHelper.get());
int ret;
int returnedErrno;
@ -108,6 +112,10 @@ int Drm::ioctl(DrmIoctl request, void *arg) {
}
}
if (ret == -1 && returnedErrno == EWOULDBLOCK && shouldBreakIoctlLoopOnWouldBlock) {
break;
}
} while (ret == -1 && (returnedErrno == EINTR || returnedErrno == EAGAIN || returnedErrno == EBUSY || returnedErrno == -EBUSY));
SYSTEM_LEAVE(request);
return ret;

View File

@ -369,4 +369,5 @@ std::string IoctlHelper::getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId
return "/gt/gt" + std::to_string(subDeviceId) + "/mem_RP0_freq_mhz";
}
bool IoctlHelper::shouldBreakIoctlLoopOnWouldBlock(DrmIoctl ioctlRequest) const { return false; }
} // namespace NEO

View File

@ -136,6 +136,8 @@ class IoctlHelper {
uint32_t getFlagsForPrimeHandleToFd() const;
virtual bool shouldBreakIoctlLoopOnWouldBlock(DrmIoctl ioctlRequest) const;
protected:
Drm &drm;
};
@ -207,7 +209,7 @@ class IoctlHelperImpl : public IoctlHelperUpstream {
class IoctlHelperPrelim20 : public IoctlHelper {
public:
using IoctlHelper::IoctlHelper;
IoctlHelperPrelim20(Drm &drmArg);
bool initialize() override;
bool isSetPairAvailable() override;
@ -254,6 +256,7 @@ class IoctlHelperPrelim20 : public IoctlHelper {
int getDrmParamValue(DrmParam drmParam) const override;
std::string getDrmParamString(DrmParam param) const override;
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
bool shouldBreakIoctlLoopOnWouldBlock(DrmIoctl ioctlRequest) const override;
};
} // namespace NEO

View File

@ -12,9 +12,11 @@
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/helpers/string.h"
#include "shared/source/os_interface/linux/cache_info.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/drm_wrappers.h"
#include "shared/source/os_interface/linux/i915_prelim.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include <algorithm>
#include <cerrno>
@ -25,6 +27,11 @@
namespace NEO {
IoctlHelperPrelim20::IoctlHelperPrelim20(Drm &drmArg) : IoctlHelper(drmArg) {
auto fileDescriptor = this->drm.getFileDescriptor();
SysCalls::fcntl(fileDescriptor, F_SETFL, SysCalls::fcntl(fileDescriptor, F_GETFL) | O_NONBLOCK);
};
bool IoctlHelperPrelim20::isSetPairAvailable() {
int setPairSupported = 0;
GetParam getParam{};
@ -645,6 +652,8 @@ std::string IoctlHelperPrelim20::getIoctlString(DrmIoctl ioctlRequest) const {
}
}
bool IoctlHelperPrelim20::shouldBreakIoctlLoopOnWouldBlock(DrmIoctl ioctlRequest) const { return ioctlRequest == DrmIoctl::GemExecbuffer2; }
static_assert(sizeof(MemoryClassInstance) == sizeof(prelim_drm_i915_gem_memory_class_instance));
static_assert(offsetof(MemoryClassInstance, memoryClass) == offsetof(prelim_drm_i915_gem_memory_class_instance, memory_class));
static_assert(offsetof(MemoryClassInstance, memoryInstance) == offsetof(prelim_drm_i915_gem_memory_class_instance, memory_instance));

View File

@ -29,5 +29,7 @@ ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
void *mmap(void *addr, size_t size, int prot, int flags, int fd, off_t off);
int munmap(void *addr, size_t size);
ssize_t read(int fd, void *buf, size_t count);
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, int arg);
} // namespace SysCalls
} // namespace NEO

View File

@ -93,5 +93,12 @@ ssize_t read(int fd, void *buf, size_t count) {
return ::read(fd, buf, count);
}
int fcntl(int fd, int cmd) {
return ::fcntl(fd, cmd);
}
int fcntl(int fd, int cmd, int arg) {
return ::fcntl(fd, cmd, arg);
}
} // namespace SysCalls
} // namespace NEO

View File

@ -193,7 +193,7 @@ int DrmMock::ioctl(DrmIoctl request, void *arg) {
for (uint32_t i = 0; i < execbuf->getBufferCount(); i++) {
this->receivedBos.push_back(execObjects[i]);
}
return 0;
return execBufferResult;
}
if (request == DrmIoctl::GemUserptr) {
ioctlCount.gemUserptr++;

View File

@ -212,6 +212,7 @@ class DrmMock : public Drm {
//DRM_IOCTL_I915_GEM_EXECBUFFER2
std::vector<MockExecBuffer> execBuffers{};
std::vector<MockExecObject> receivedBos{};
int execBufferResult = 0;
//DRM_IOCTL_I915_GEM_CREATE
uint64_t createParamsSize = 0;
uint32_t createParamsHandle = 0;

View File

@ -8,12 +8,15 @@
#pragma once
#include "shared/source/os_interface/linux/drm_buffer_object.h"
#include "shared/source/os_interface/linux/drm_memory_operations_handler_default.h"
#include "shared/source/os_interface/linux/drm_wrappers.h"
#include "shared/source/os_interface/linux/os_context_linux.h"
#include "shared/test/common/helpers/engine_descriptor_helper.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include <memory>
using namespace NEO;
class TestedBufferObject : public BufferObject {
public:
using BufferObject::handle;

View File

@ -20,6 +20,14 @@
#include <algorithm>
template <typename GfxFamily>
struct MockDrmCsr : public DrmCommandStreamReceiver<GfxFamily> {
using DrmCommandStreamReceiver<GfxFamily>::DrmCommandStreamReceiver;
using DrmCommandStreamReceiver<GfxFamily>::dispatchMode;
using DrmCommandStreamReceiver<GfxFamily>::completionFenceValuePointer;
using DrmCommandStreamReceiver<GfxFamily>::flushInternal;
};
class DrmCommandStreamTest : public ::testing::Test {
public:
template <typename GfxFamily>
@ -43,7 +51,7 @@ class DrmCommandStreamTest : public ::testing::Test {
PreemptionHelper::getDefaultPreemptionMode(*hwInfo)));
osContext->ensureContextInitialized();
csr = new DrmCommandStreamReceiver<GfxFamily>(executionEnvironment, 0, 1, gemCloseWorkerMode::gemCloseWorkerActive);
csr = new MockDrmCsr<GfxFamily>(executionEnvironment, 0, 1, gemCloseWorkerMode::gemCloseWorkerActive);
ASSERT_NE(nullptr, csr);
csr->setupContext(*osContext);

View File

@ -5,6 +5,8 @@
*
*/
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
#include "shared/source/helpers/string.h"
#include "shared/source/os_interface/linux/drm_wrappers.h"
#include "shared/source/os_interface/linux/i915.h"
@ -17,6 +19,7 @@
#include <cstdio>
#include <cstring>
#include <dlfcn.h>
#include <fcntl.h>
#include <iostream>
#include <poll.h>
#include <stdio.h>
@ -31,7 +34,6 @@ int closeFuncArgPassed = 0;
int closeFuncRetVal = 0;
int dlOpenFlags = 0;
bool dlOpenCalled = 0;
constexpr int fakeFileDescriptor = 123;
bool makeFakeDevicePath = false;
bool allowFakeDevicePath = false;
constexpr unsigned long int invalidIoctl = static_cast<unsigned long int>(-1);
@ -43,6 +45,9 @@ uint32_t mmapFuncCalled = 0u;
uint32_t munmapFuncCalled = 0u;
bool isInvalidAILTest = false;
const char *drmVersion = "i915";
int passedFileDescriptorFlagsToSet = 0;
int getFileDescriptorFlagsCalled = 0;
int setFileDescriptorFlagsCalled = 0;
int (*sysCallsOpen)(const char *pathname, int flags) = nullptr;
ssize_t (*sysCallsPread)(int fd, void *buf, size_t count, off_t offset) = nullptr;
@ -195,5 +200,21 @@ ssize_t read(int fd, void *buf, size_t count) {
return 0;
}
int fcntl(int fd, int cmd) {
if (cmd == F_GETFL) {
getFileDescriptorFlagsCalled++;
return O_RDWR;
}
return 0;
}
int fcntl(int fd, int cmd, int arg) {
if (cmd == F_SETFL) {
setFileDescriptorFlagsCalled++;
passedFileDescriptorFlagsToSet = arg;
}
return 0;
}
} // namespace SysCalls
} // namespace NEO

View File

@ -21,5 +21,9 @@ extern int (*sysCallsPoll)(struct pollfd *pollFd, unsigned long int numberOfFds,
extern ssize_t (*sysCallsRead)(int fd, void *buf, size_t count);
extern const char *drmVersion;
constexpr int fakeFileDescriptor = 123;
extern int passedFileDescriptorFlagsToSet;
extern int getFileDescriptorFlagsCalled;
extern int setFileDescriptorFlagsCalled;
} // namespace SysCalls
} // namespace NEO

View File

@ -6,7 +6,9 @@
*/
#include "shared/source/helpers/api_specific_config.h"
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/mocks/mock_graphics_allocation.h"
#include "shared/test/common/os_interface/linux/drm_buffer_object_fixture.h"
#include "shared/test/common/os_interface/linux/drm_command_stream_fixture.h"
#include "shared/test/common/test_macros/hw_test.h"
@ -15,13 +17,6 @@ extern ApiSpecificConfig::ApiType apiTypeForUlts;
} //namespace NEO
using namespace NEO;
template <typename GfxFamily>
struct MockDrmCsr : public DrmCommandStreamReceiver<GfxFamily> {
using DrmCommandStreamReceiver<GfxFamily>::DrmCommandStreamReceiver;
using DrmCommandStreamReceiver<GfxFamily>::dispatchMode;
using DrmCommandStreamReceiver<GfxFamily>::completionFenceValuePointer;
};
HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenL0ApiConfigWhenCreatingDrmCsrThenEnableImmediateDispatch) {
VariableBackup<ApiSpecificConfig::ApiType> backup(&apiTypeForUlts, ApiSpecificConfig::L0);
MockDrmCsr<FamilyType> csr(executionEnvironment, 0, 1, gemCloseWorkerMode::gemCloseWorkerInactive);
@ -75,3 +70,20 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenNoTagAddressWhenGettingCompletionA
EXPECT_EQ(nullptr, csr->getTagAddress());
EXPECT_EQ(0u, csr->getCompletionAddress());
}
HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenExecBufferErrorWhenFlushInternalThenProperErrorIsReturned) {
mock->execBufferResult = -1;
mock->baseErrno = false;
mock->errnoRetVal = EWOULDBLOCK;
TestedBufferObject bo(mock, 128);
MockDrmAllocation cmdBuffer(AllocationType::COMMAND_BUFFER, MemoryPool::System4KBPages);
cmdBuffer.bufferObjects[0] = &bo;
uint8_t buff[128]{};
LinearStream cs(&cmdBuffer, buff, 128);
BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false};
auto ret = static_cast<MockDrmCsr<FamilyType> *>(csr)->flushInternal(batchBuffer, csr->getResidencyAllocations());
EXPECT_EQ(SubmissionStatus::OUT_OF_HOST_MEMORY, ret);
}

View File

@ -884,12 +884,6 @@ HWTEST_TEMPLATED_F(DrmCommandStreamBlitterDirectSubmissionTest, givenEnabledDire
EXPECT_EQ(nullptr, static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->directSubmission.get());
}
template <typename GfxFamily>
struct MockDrmCsr : public DrmCommandStreamReceiver<GfxFamily> {
using DrmCommandStreamReceiver<GfxFamily>::DrmCommandStreamReceiver;
using DrmCommandStreamReceiver<GfxFamily>::dispatchMode;
};
HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenDrmCommandStreamReceiverWhenCreatePageTableManagerIsCalledThenCreatePageTableManager) {
executionEnvironment.prepareRootDeviceEnvironments(2);
executionEnvironment.rootDeviceEnvironments[1]->setHwInfo(defaultHwInfo.get());

View File

@ -10,7 +10,9 @@
#include "shared/source/os_interface/linux/i915_prelim.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
#include "shared/test/common/test_macros/test.h"
using namespace NEO;
@ -348,3 +350,22 @@ TEST_F(IoctlPrelimHelperTests, givenPrelimWhenGettingEuStallPropertiesThenCorrec
TEST_F(IoctlPrelimHelperTests, givenPrelimWhenGettingEuStallFdParameterThenCorrectIoctlValueIsReturned) {
EXPECT_EQ(static_cast<uint32_t>(PRELIM_I915_PERF_FLAG_FD_EU_STALL), ioctlHelper.getEuStallFdParameter());
}
TEST_F(IoctlPrelimHelperTests, whenCallingIoctlWithGemExecbufferThenShouldBreakOnWouldBlock) {
EXPECT_TRUE(ioctlHelper.shouldBreakIoctlLoopOnWouldBlock(DrmIoctl::GemExecbuffer2));
EXPECT_FALSE(ioctlHelper.shouldBreakIoctlLoopOnWouldBlock(DrmIoctl::GemVmBind));
}
TEST(IoctlPrelimHelperTest, whenCreatingIoctlHelperThenProperFlagsAreSetToFileDescriptor) {
MockExecutionEnvironment executionEnvironment{};
std::unique_ptr<Drm> drm{Drm::create(std::make_unique<HwDeviceIdDrm>(0, ""), *executionEnvironment.rootDeviceEnvironments[0])};
VariableBackup<decltype(SysCalls::getFileDescriptorFlagsCalled)> backupGetFlags(&SysCalls::getFileDescriptorFlagsCalled, 0);
VariableBackup<decltype(SysCalls::setFileDescriptorFlagsCalled)> backupSetFlags(&SysCalls::setFileDescriptorFlagsCalled, 0);
VariableBackup<decltype(SysCalls::passedFileDescriptorFlagsToSet)> backupPassedFlags(&SysCalls::passedFileDescriptorFlagsToSet, 0);
IoctlHelperPrelim20 ioctlHelper{*drm};
EXPECT_EQ(1, SysCalls::getFileDescriptorFlagsCalled);
EXPECT_EQ(1, SysCalls::setFileDescriptorFlagsCalled);
EXPECT_EQ((O_RDWR | O_NONBLOCK), SysCalls::passedFileDescriptorFlagsToSet);
}

View File

@ -477,3 +477,11 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenInitializingThenTrueIsReturned)
IoctlHelperUpstream ioctlHelper{*drm};
EXPECT_EQ(true, ioctlHelper.initialize());
}
TEST(IoctlHelperUpstreamTest, whenCallingIoctlWithGemExecbufferThenShouldNotBreakOnWouldBlock) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
IoctlHelperUpstream ioctlHelper{*drm};
EXPECT_FALSE(ioctlHelper.shouldBreakIoctlLoopOnWouldBlock(DrmIoctl::GemExecbuffer2));
EXPECT_FALSE(ioctlHelper.shouldBreakIoctlLoopOnWouldBlock(DrmIoctl::GemVmBind));
}