Increment fenceValue only after successful bind operation

Related-To: NEO-7835

Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
This commit is contained in:
Maciej Plewka
2023-04-17 13:56:47 +00:00
committed by Compute-Runtime-Automation
parent c66546df73
commit bab299ee78
5 changed files with 164 additions and 7 deletions

View File

@@ -1457,7 +1457,7 @@ int changeBufferObjectBinding(Drm *drm, OsContext *osContext, uint32_t vmHandleI
std::unique_lock<std::mutex> lock;
VmBindExtUserFenceT vmBindExtUserFence{};
bool incrementFenceValue = false;
if (ioctlHelper->isWaitBeforeBindRequired(bind)) {
if (drm->useVMBindImmediate()) {
lock = drm->lockBindFenceMutex();
@@ -1466,7 +1466,7 @@ int changeBufferObjectBinding(Drm *drm, OsContext *osContext, uint32_t vmHandleI
auto nextExtension = vmBind.extensions;
auto address = castToUint64(drm->getFenceAddr(vmHandleId));
auto value = drm->getNextFenceVal(vmHandleId);
incrementFenceValue = true;
ioctlHelper->fillVmBindExtUserFence(vmBindExtUserFence, address, value, nextExtension);
vmBind.extensions = castToUint64(vmBindExtUserFence);
}
@@ -1474,20 +1474,21 @@ int changeBufferObjectBinding(Drm *drm, OsContext *osContext, uint32_t vmHandleI
}
if (bind) {
ret = ioctlHelper->vmBind(vmBind);
if (ret) {
break;
}
drm->setNewResourceBoundToVM(bo, vmHandleId);
} else {
vmBind.handle = 0u;
ret = ioctlHelper->vmUnbind(vmBind);
if (ret) {
break;
}
}
if (incrementFenceValue) {
drm->incFenceVal(vmHandleId);
}
}
return ret;

View File

@@ -162,7 +162,7 @@ class Drm : public DriverModel {
MOCKABLE_VIRTUAL bool isSetPairAvailable();
MOCKABLE_VIRTUAL bool getSetPairAvailable() { return setPairAvailable; }
bool useVMBindImmediate() const;
MOCKABLE_VIRTUAL bool useVMBindImmediate() const;
MOCKABLE_VIRTUAL bool isVmBindAvailable();
MOCKABLE_VIRTUAL bool registerResourceClasses();
@@ -215,7 +215,8 @@ class Drm : public DriverModel {
}
void waitForBind(uint32_t vmHandleId);
uint64_t getNextFenceVal(uint32_t vmHandleId) { return ++fenceVal[vmHandleId]; }
uint64_t getNextFenceVal(uint32_t vmHandleId) { return fenceVal[vmHandleId] + 1; }
void incFenceVal(uint32_t vmHandleId) { fenceVal[vmHandleId]++; }
uint64_t *getFenceAddr(uint32_t vmHandleId) { return &pagingFence[vmHandleId]; }
int waitHandle(uint32_t waitHandle, int64_t timeout);

View File

@@ -17,6 +17,7 @@
#include <fstream>
#include <limits.h>
#include <map>
#include <optional>
#include <vector>
using namespace NEO;
@@ -150,6 +151,12 @@ class DrmMock : public Drm {
uint32_t getBaseIoctlCalls() {
return static_cast<uint32_t>(virtualMemoryIds.size());
}
bool useVMBindImmediate() const override {
if (isVMBindImmediateSupported.has_value())
return *isVMBindImmediateSupported;
else
return Drm::useVMBindImmediate();
}
static const int mockFd = 33;
@@ -193,6 +200,7 @@ class DrmMock : public Drm {
bool capturedCooperativeContextRequest = false;
bool incrementVmId = false;
std::optional<bool> isVMBindImmediateSupported{};
uint32_t passedContextDebugId = std::numeric_limits<uint32_t>::max();
std::vector<ResetStats> resetStatsToReturn{};

View File

@@ -8,6 +8,8 @@
#pragma once
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include <optional>
namespace NEO {
class MockIoctlHelper : public IoctlHelperPrelim20 {
@@ -20,8 +22,28 @@ class MockIoctlHelper : public IoctlHelperPrelim20 {
int getDrmParamValue(DrmParam drmParam) const override {
return drmParamValue;
}
int vmBind(const VmBindParams &vmBindParams) override {
if (failBind.has_value())
return *failBind ? -1 : 0;
else
return IoctlHelperPrelim20::vmBind(vmBindParams);
}
int vmUnbind(const VmBindParams &vmBindParams) override {
if (failBind.has_value())
return *failBind ? -1 : 0;
else
return IoctlHelperPrelim20::vmUnbind(vmBindParams);
}
bool isWaitBeforeBindRequired(bool bind) const override {
if (waitBeforeBindRequired.has_value())
return *waitBeforeBindRequired;
else
return IoctlHelperPrelim20::isWaitBeforeBindRequired(bind);
}
unsigned int ioctlRequestValue = 1234u;
int drmParamValue = 1234;
std::optional<bool> failBind{};
std::optional<bool> waitBeforeBindRequired{};
};
} // namespace NEO

View File

@@ -12,6 +12,7 @@
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/mocks/linux/mock_drm_wrappers.h"
#include "shared/test/common/mocks/linux/mock_ioctl_helper.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_gmm_helper.h"
@@ -566,6 +567,130 @@ TEST(DrmBufferObject, givenPrintBOBindingResultWhenBOBindAndUnbindFailsThenPrint
EXPECT_TRUE(hasSubstr(unbindOutput, expected.str())) << unbindOutput;
}
TEST(DrmBufferObject, givenDrmWhenBindOperationFailsThenFenceValueNotGrow) {
auto executionEnvironment = new ExecutionEnvironment;
executionEnvironment->setDebuggingMode(NEO::DebuggingMode::Online);
executionEnvironment->prepareRootDeviceEnvironments(1);
executionEnvironment->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(defaultHwInfo.get());
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
auto drm = new DrmMock(*executionEnvironment->rootDeviceEnvironments[0]);
drm->requirePerContextVM = false;
drm->isVMBindImmediateSupported = true;
auto ioctlHelper = std::make_unique<MockIoctlHelper>(*drm);
ioctlHelper->failBind = true;
ioctlHelper->waitBeforeBindRequired = true;
drm->ioctlHelper.reset(ioctlHelper.release());
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, 0u);
uint64_t initFenceValue = 10u;
drm->fenceVal[0] = initFenceValue;
std::unique_ptr<Device> device(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0));
auto contextId = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount() / 2;
auto osContext = device->getExecutionEnvironment()->memoryManager->getRegisteredEngines()[contextId].osContext;
auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount();
MockBufferObject bo(drm, 3, 0, 0, osContextCount);
drm->bindBufferObject(osContext, 0, &bo);
EXPECT_EQ(drm->fenceVal[0], initFenceValue);
}
TEST(DrmBufferObject, givenDrmWhenBindOperationSucceedsThenFenceValueGrow) {
auto executionEnvironment = new ExecutionEnvironment;
executionEnvironment->setDebuggingMode(NEO::DebuggingMode::Online);
executionEnvironment->prepareRootDeviceEnvironments(1);
executionEnvironment->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(defaultHwInfo.get());
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
auto drm = new DrmMock(*executionEnvironment->rootDeviceEnvironments[0]);
drm->requirePerContextVM = false;
drm->isVMBindImmediateSupported = true;
auto ioctlHelper = std::make_unique<MockIoctlHelper>(*drm);
ioctlHelper->failBind = false;
ioctlHelper->waitBeforeBindRequired = true;
drm->ioctlHelper.reset(ioctlHelper.release());
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, 0u);
uint64_t initFenceValue = 10u;
drm->fenceVal[0] = initFenceValue;
std::unique_ptr<Device> device(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0));
auto contextId = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount() / 2;
auto osContext = device->getExecutionEnvironment()->memoryManager->getRegisteredEngines()[contextId].osContext;
auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount();
MockBufferObject bo(drm, 3, 0, 0, osContextCount);
drm->bindBufferObject(osContext, 0, &bo);
EXPECT_EQ(drm->fenceVal[0], initFenceValue + 1);
}
TEST(DrmBufferObject, givenDrmWhenUnBindOperationFailsThenFenceValueNotGrow) {
auto executionEnvironment = new ExecutionEnvironment;
executionEnvironment->setDebuggingMode(NEO::DebuggingMode::Online);
executionEnvironment->prepareRootDeviceEnvironments(1);
executionEnvironment->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(defaultHwInfo.get());
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
auto drm = new DrmMock(*executionEnvironment->rootDeviceEnvironments[0]);
drm->requirePerContextVM = false;
drm->isVMBindImmediateSupported = true;
auto ioctlHelper = std::make_unique<MockIoctlHelper>(*drm);
ioctlHelper->failBind = true;
ioctlHelper->waitBeforeBindRequired = true;
drm->ioctlHelper.reset(ioctlHelper.release());
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, 0u);
uint64_t initFenceValue = 10u;
drm->fenceVal[0] = initFenceValue;
std::unique_ptr<Device> device(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0));
auto contextId = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount() / 2;
auto osContext = device->getExecutionEnvironment()->memoryManager->getRegisteredEngines()[contextId].osContext;
auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount();
MockBufferObject bo(drm, 3, 0, 0, osContextCount);
drm->unbindBufferObject(osContext, 0, &bo);
EXPECT_EQ(drm->fenceVal[0], initFenceValue);
}
TEST(DrmBufferObject, givenDrmWhenUnBindOperationSucceedsThenFenceValueGrow) {
auto executionEnvironment = new ExecutionEnvironment;
executionEnvironment->setDebuggingMode(NEO::DebuggingMode::Online);
executionEnvironment->prepareRootDeviceEnvironments(1);
executionEnvironment->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(defaultHwInfo.get());
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
auto drm = new DrmMock(*executionEnvironment->rootDeviceEnvironments[0]);
drm->requirePerContextVM = false;
drm->isVMBindImmediateSupported = true;
auto ioctlHelper = std::make_unique<MockIoctlHelper>(*drm);
ioctlHelper->failBind = false;
ioctlHelper->waitBeforeBindRequired = true;
drm->ioctlHelper.reset(ioctlHelper.release());
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, 0u);
uint64_t initFenceValue = 10u;
drm->fenceVal[0] = initFenceValue;
std::unique_ptr<Device> device(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0));
auto contextId = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount() / 2;
auto osContext = device->getExecutionEnvironment()->memoryManager->getRegisteredEngines()[contextId].osContext;
auto osContextCount = device->getExecutionEnvironment()->memoryManager->getRegisteredEnginesCount();
MockBufferObject bo(drm, 3, 0, 0, osContextCount);
drm->unbindBufferObject(osContext, 0, &bo);
EXPECT_EQ(drm->fenceVal[0], initFenceValue + 1);
}
TEST(DrmBufferObject, whenBindExtHandleAddedThenItIsStored) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockResources drm(*executionEnvironment->rootDeviceEnvironments[0]);