diff --git a/shared/source/debug_settings/debug_variables_base.inl b/shared/source/debug_settings/debug_variables_base.inl index 8b58d878bd..e4f2bc2e03 100644 --- a/shared/source/debug_settings/debug_variables_base.inl +++ b/shared/source/debug_settings/debug_variables_base.inl @@ -223,6 +223,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, ForceStatelessMocsEncryptionBit, -1, "-1: defaul DECLARE_DEBUG_VARIABLE(int32_t, CopyHostPtrOnCpu, -1, "-1: default, 0: disable, 1:enable, In clCreateBuffer with CL_MEM_COPY_HOST_PTR, copy memory using locked ptr on cpu") DECLARE_DEBUG_VARIABLE(int32_t, ForceZeDeviceCanAccessPerReturnValue, -1, "-1: default, 0: zeDeviceCanAccessPeer always return false 1: zeDeviceCanAccessPeer always return true") DECLARE_DEBUG_VARIABLE(int32_t, AdjustThreadGroupDispatchSize, -1, "-1: default, 0: do not adjust thread group dispatch size 1: adjust thread group dispatch size (PVC)") +DECLARE_DEBUG_VARIABLE(int32_t, ForceNonblockingExecbufferCalls, -1, "-1: default, 0: make execbuffer call blocking, 1: make execbuffer call nonblocking. Supported only in prelim i915 kernels.") /*LOGGING FLAGS*/ DECLARE_DEBUG_VARIABLE(int32_t, PrintDriverDiagnostics, -1, "prints driver diagnostics messages to standard output, value corresponds to hint level") diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 7b5b38f057..45f3f897a4 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -31,8 +31,11 @@ namespace NEO { IoctlHelperPrelim20::IoctlHelperPrelim20(Drm &drmArg) : IoctlHelper(drmArg) { auto hwHelper = HwInfoConfig::get(this->drm.getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily); - if (hwHelper && hwHelper->isNonBlockingGpuSubmissionSupported()) { - handleExecBufferInNonBlockMode = true; + handleExecBufferInNonBlockMode = hwHelper && hwHelper->isNonBlockingGpuSubmissionSupported(); + if (DebugManager.flags.ForceNonblockingExecbufferCalls.get() != -1) { + handleExecBufferInNonBlockMode = DebugManager.flags.ForceNonblockingExecbufferCalls.get(); + } + if (handleExecBufferInNonBlockMode) { auto fileDescriptor = this->drm.getFileDescriptor(); SysCalls::fcntl(fileDescriptor, F_SETFL, SysCalls::fcntl(fileDescriptor, F_GETFL) | O_NONBLOCK); } diff --git a/shared/test/common/test_files/igdrcl.config b/shared/test/common/test_files/igdrcl.config index 5f07f687e9..f8a94ca572 100644 --- a/shared/test/common/test_files/igdrcl.config +++ b/shared/test/common/test_files/igdrcl.config @@ -477,4 +477,5 @@ PrintCompletionFenceUsage = 0 SetAmountOfReusableAllocations = -1 ExperimentalSmallBufferPoolAllocator = -1 ForceZeDeviceCanAccessPerReturnValue = -1 -AdjustThreadGroupDispatchSize = -1 \ No newline at end of file +AdjustThreadGroupDispatchSize = -1 +ForceNonblockingExecbufferCalls = -1 diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp index edd94b5011..64a0fdab39 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp @@ -464,4 +464,47 @@ HWTEST2_F(IoctlPrelimHelperTests, givenNonXeHpcWhenCreatingIoctlHelperThenProper EXPECT_EQ(0, SysCalls::getFileDescriptorFlagsCalled); EXPECT_EQ(0, SysCalls::setFileDescriptorFlagsCalled); -} \ No newline at end of file +} + +TEST_F(IoctlPrelimHelperTests, givenDisabledForceNonblockingExecbufferCallsFlagWhenCreatingIoctlHelperThenExecBufferIsHandledBlocking) { + DebugManagerStateRestore restorer; + + DebugManager.flags.ForceNonblockingExecbufferCalls.set(0); + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm{Drm::create(std::make_unique(0, ""), *executionEnvironment.rootDeviceEnvironments[0])}; + + VariableBackup backupGetFlags(&SysCalls::getFileDescriptorFlagsCalled, 0); + VariableBackup backupSetFlags(&SysCalls::setFileDescriptorFlagsCalled, 0); + VariableBackup backupPassedFlags(&SysCalls::passedFileDescriptorFlagsToSet, 0); + + IoctlHelperPrelim20 ioctlHelper{*drm}; + + EXPECT_EQ(0, SysCalls::getFileDescriptorFlagsCalled); + EXPECT_EQ(0, SysCalls::setFileDescriptorFlagsCalled); + + EXPECT_TRUE(ioctlHelper.checkIfIoctlReinvokeRequired(EAGAIN, DrmIoctl::GemExecbuffer2)); + EXPECT_TRUE(ioctlHelper.checkIfIoctlReinvokeRequired(EAGAIN, DrmIoctl::GemVmBind)); + EXPECT_TRUE(ioctlHelper.checkIfIoctlReinvokeRequired(EBUSY, DrmIoctl::GemExecbuffer2)); +} + +TEST_F(IoctlPrelimHelperTests, givenEnabledForceNonblockingExecbufferCallsFlagWhenCreatingIoctlHelperThenExecBufferIsHandledNonBlocking) { + DebugManagerStateRestore restorer; + + DebugManager.flags.ForceNonblockingExecbufferCalls.set(1); + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm{Drm::create(std::make_unique(0, ""), *executionEnvironment.rootDeviceEnvironments[0])}; + + VariableBackup backupGetFlags(&SysCalls::getFileDescriptorFlagsCalled, 0); + VariableBackup backupSetFlags(&SysCalls::setFileDescriptorFlagsCalled, 0); + VariableBackup 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); + + EXPECT_FALSE(ioctlHelper.checkIfIoctlReinvokeRequired(EAGAIN, DrmIoctl::GemExecbuffer2)); + EXPECT_TRUE(ioctlHelper.checkIfIoctlReinvokeRequired(EAGAIN, DrmIoctl::GemVmBind)); + EXPECT_TRUE(ioctlHelper.checkIfIoctlReinvokeRequired(EBUSY, DrmIoctl::GemExecbuffer2)); +}