mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-05 09:09:04 +08:00
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:
committed by
Compute-Runtime-Automation
parent
5c48e027b9
commit
9a95f3c62d
@@ -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++;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user