mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 21:18:24 +08:00
fix(debugger): use per-context fences for vm_bind operations
- vm_bind with user fence updates fence value independently for every VM hence with per-context VMs, every context needs its unique fence address. This prevents 2 contexts from updating value possibly writing lower value than the one that was already stored Resolves: NEO-8004 Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
af4fd337c5
commit
7d82b690e4
@@ -1399,8 +1399,19 @@ int changeBufferObjectBinding(Drm *drm, OsContext *osContext, uint32_t vmHandleI
|
||||
|
||||
if (!drm->hasPageFaultSupport() || bo->isExplicitResidencyRequired()) {
|
||||
auto nextExtension = vmBind.extensions;
|
||||
auto address = castToUint64(drm->getFenceAddr(vmHandleId));
|
||||
auto value = drm->getNextFenceVal(vmHandleId);
|
||||
|
||||
uint64_t address = 0;
|
||||
uint64_t value = 0;
|
||||
|
||||
if (drm->isPerContextVMRequired()) {
|
||||
auto osContextLinux = static_cast<OsContextLinux *>(osContext);
|
||||
address = castToUint64(osContextLinux->getFenceAddr(vmHandleId));
|
||||
value = osContextLinux->getNextFenceVal(vmHandleId);
|
||||
} else {
|
||||
address = castToUint64(drm->getFenceAddr(vmHandleId));
|
||||
value = drm->getNextFenceVal(vmHandleId);
|
||||
}
|
||||
|
||||
incrementFenceValue = true;
|
||||
ioctlHelper->fillVmBindExtUserFence(vmBindExtUserFence, address, value, nextExtension);
|
||||
vmBind.extensions = castToUint64(vmBindExtUserFence);
|
||||
@@ -1422,7 +1433,12 @@ int changeBufferObjectBinding(Drm *drm, OsContext *osContext, uint32_t vmHandleI
|
||||
}
|
||||
}
|
||||
if (incrementFenceValue) {
|
||||
drm->incFenceVal(vmHandleId);
|
||||
if (drm->isPerContextVMRequired()) {
|
||||
auto osContextLinux = static_cast<OsContextLinux *>(osContext);
|
||||
osContextLinux->incFenceVal(vmHandleId);
|
||||
} else {
|
||||
drm->incFenceVal(vmHandleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/helpers/engine_node_helper.h"
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
#include "shared/source/helpers/ptr_math.h"
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
||||
#include "shared/source/os_interface/os_context.h"
|
||||
@@ -30,7 +31,10 @@ OsContext *OsContextLinux::create(OSInterface *osInterface, uint32_t rootDeviceI
|
||||
|
||||
OsContextLinux::OsContextLinux(Drm &drm, uint32_t rootDeviceIndex, uint32_t contextId, const EngineDescriptor &engineDescriptor)
|
||||
: OsContext(rootDeviceIndex, contextId, engineDescriptor),
|
||||
drm(drm) {}
|
||||
drm(drm) {
|
||||
pagingFence.fill(0u);
|
||||
fenceVal.fill(0u);
|
||||
}
|
||||
|
||||
bool OsContextLinux::initializeContext() {
|
||||
auto hwInfo = drm.getRootDeviceEnvironment().getHardwareInfo();
|
||||
@@ -88,11 +92,28 @@ Drm &OsContextLinux::getDrm() const {
|
||||
void OsContextLinux::waitForPagingFence() {
|
||||
for (auto drmIterator = 0u; drmIterator < this->deviceBitfield.size(); drmIterator++) {
|
||||
if (this->deviceBitfield.test(drmIterator)) {
|
||||
drm.waitForBind(drmIterator);
|
||||
this->waitForBind(drmIterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OsContextLinux::waitForBind(uint32_t drmIterator) {
|
||||
if (drm.isPerContextVMRequired()) {
|
||||
if (pagingFence[drmIterator] >= fenceVal[drmIterator]) {
|
||||
return;
|
||||
}
|
||||
auto lock = drm.lockBindFenceMutex();
|
||||
auto fenceAddress = castToUint64(&this->pagingFence[drmIterator]);
|
||||
auto fenceValue = this->fenceVal[drmIterator];
|
||||
lock.unlock();
|
||||
|
||||
drm.waitUserFence(0u, fenceAddress, fenceValue, Drm::ValueWidth::U64, -1, drm.getIoctlHelper()->getWaitUserFenceSoftFlag());
|
||||
|
||||
} else {
|
||||
drm.waitForBind(drmIterator);
|
||||
}
|
||||
}
|
||||
|
||||
void OsContextLinux::reInitializeContext() {}
|
||||
|
||||
uint64_t OsContextLinux::getOfflineDumpContextId(uint32_t deviceIndex) const {
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "shared/source/helpers/mt_helpers.h"
|
||||
#include "shared/source/memory_manager/definitions/engine_limits.h"
|
||||
#include "shared/source/os_interface/os_context.h"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
@@ -52,6 +54,11 @@ class OsContextLinux : public OsContext {
|
||||
|
||||
uint64_t getOfflineDumpContextId(uint32_t deviceIndex) const override;
|
||||
|
||||
uint64_t getNextFenceVal(uint32_t deviceIndex) { return fenceVal[deviceIndex] + 1; }
|
||||
void incFenceVal(uint32_t deviceIndex) { fenceVal[deviceIndex]++; }
|
||||
uint64_t *getFenceAddr(uint32_t deviceIndex) { return &pagingFence[deviceIndex]; }
|
||||
void waitForBind(uint32_t drmIterator);
|
||||
|
||||
protected:
|
||||
bool initializeContext() override;
|
||||
|
||||
@@ -60,6 +67,10 @@ class OsContextLinux : public OsContext {
|
||||
unsigned int engineFlag = 0;
|
||||
std::vector<uint32_t> drmContextIds;
|
||||
std::vector<uint32_t> drmVmIds;
|
||||
|
||||
std::array<uint64_t, EngineLimits::maxHandleCount> pagingFence;
|
||||
std::array<uint64_t, EngineLimits::maxHandleCount> fenceVal;
|
||||
|
||||
Drm &drm;
|
||||
bool contextHangDetected = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user