feature: add support for new vm bind flags based on upstream xe kernel

support for DRM_XE_VM_BIND_FLAG_IMMEDIATE and DRM_XE_VM_BIND_FLAG_READONLY

Fixes: #717

Related-To: NEO-10958
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2024-07-25 10:47:37 +00:00
committed by Compute-Runtime-Automation
parent 27c2359f23
commit b488799e85
5 changed files with 127 additions and 22 deletions

View File

@@ -11,7 +11,6 @@ set(NEO_CORE_OS_INTERFACE_LINUX_XE
${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_xe.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_xe.h
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/ioctl_helper_xe_query_hw_ip_version.cpp
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/ioctl_helper_xe_vm_bind_flags.cpp
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/ioctl_helper_xe_perf.cpp
)

View File

@@ -11,6 +11,7 @@
#include "shared/source/execution_environment/execution_environment.h"
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/common_types.h"
#include "shared/source/helpers/constants.h"
@@ -791,13 +792,19 @@ bool IoctlHelperXe::completionFenceExtensionSupported(const bool isVmBindAvailab
}
uint64_t IoctlHelperXe::getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident, bool bindLock, bool readOnlyResource) {
uint64_t ret = 0;
uint64_t flags = 0;
xeLog(" -> IoctlHelperXe::%s %d %d %d %d %d\n", __FUNCTION__, bindCapture, bindImmediate, bindMakeResident, bindLock, readOnlyResource);
if (bindCapture) {
ret |= DRM_XE_VM_BIND_FLAG_DUMPABLE;
flags |= DRM_XE_VM_BIND_FLAG_DUMPABLE;
}
ret |= getAdditionalFlagsForVmBind(bindImmediate, readOnlyResource);
return ret;
if (bindImmediate && supportedFeatures.flags.vmBindImmediate) {
flags |= DRM_XE_VM_BIND_FLAG_IMMEDIATE;
}
if (readOnlyResource && supportedFeatures.flags.vmBindReadOnly) {
flags |= DRM_XE_VM_BIND_FLAG_READONLY;
}
return flags;
}
int IoctlHelperXe::queryDistances(std::vector<QueryItem> &queryItems, std::vector<DistanceInfo> &distanceInfos) {
@@ -1592,4 +1599,40 @@ std::string IoctlHelperXe::getIoctlString(DrmIoctl ioctlRequest) const {
return "???";
}
}
void IoctlHelperXe::querySupportedFeatures() {
struct drm_xe_vm_create vmCreate = {};
auto ret = IoctlHelper::ioctl(DrmIoctl::gemVmCreate, &vmCreate);
DEBUG_BREAK_IF(ret != 0);
auto checkVmBindFlagSupport = [&](uint32_t flag) -> bool {
uint8_t dummyData[2 * MemoryConstants::pageSize]{};
drm_xe_vm_bind bind = {};
bind.num_binds = 1;
bind.vm_id = vmCreate.vm_id;
bind.bind.range = MemoryConstants::pageSize;
bind.bind.userptr = alignUp(castToUint64(dummyData), MemoryConstants::pageSize);
bind.bind.addr = alignUp(castToUint64(dummyData), MemoryConstants::pageSize);
bind.bind.op = DRM_XE_VM_BIND_OP_MAP_USERPTR;
bind.bind.flags = flag;
bind.bind.pat_index = 1;
ret = IoctlHelper::ioctl(DrmIoctl::gemVmBind, &bind);
if (ret == 0) {
bind.bind.op = DRM_XE_VM_BIND_OP_UNMAP;
ret = IoctlHelper::ioctl(DrmIoctl::gemVmBind, &bind);
DEBUG_BREAK_IF(ret != 0);
return true;
}
return false;
};
supportedFeatures.flags.vmBindImmediate = checkVmBindFlagSupport(DRM_XE_VM_BIND_FLAG_IMMEDIATE);
supportedFeatures.flags.vmBindReadOnly = checkVmBindFlagSupport(DRM_XE_VM_BIND_FLAG_READONLY);
struct drm_xe_vm_destroy vmDestroy = {};
vmDestroy.vm_id = vmCreate.vm_id;
ret = IoctlHelper::ioctl(DrmIoctl::gemVmDestroy, &vmDestroy);
DEBUG_BREAK_IF(ret != 0);
};
} // namespace NEO

View File

@@ -219,7 +219,6 @@ class IoctlHelperXe : public IoctlHelper {
static_assert(sizeof(SupportedFeatures::flags) == sizeof(SupportedFeatures::allFlags), "");
void querySupportedFeatures();
uint64_t getAdditionalFlagsForVmBind(bool bindImmediate, bool readOnlyResource);
};
template <typename... XeLogArgs>

View File

@@ -1,16 +0,0 @@
/*
* Copyright (C) 2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h"
namespace NEO {
void IoctlHelperXe::querySupportedFeatures(){};
uint64_t IoctlHelperXe::getAdditionalFlagsForVmBind(bool bindImmediate, bool readOnlyResource) {
return 0;
}
} // namespace NEO

View File

@@ -2178,3 +2178,83 @@ TEST(IoctlHelperXeTest, whenCheckingGpuHangThenBanPropertyIsQueried) {
EXPECT_TRUE(drm->checkResetStatus(osContext));
EXPECT_TRUE(osContext.isHangDetected());
}
TEST(IoctlHelperXeVmBindTest, givenImmediateAndReadOnlyBindFlagsSupportedWhenGettingFlagsForVmBindThenCorrectFlagsAreReturned) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]);
auto xeIoctlHelper = static_cast<MockIoctlHelperXe *>(drm->getIoctlHelper());
xeIoctlHelper->initialize();
for (const auto &bindImmediateSupport : ::testing::Bool()) {
for (const auto &bindReadOnlySupport : ::testing::Bool()) {
xeIoctlHelper->supportedFeatures.flags.vmBindImmediate = bindImmediateSupport;
xeIoctlHelper->supportedFeatures.flags.vmBindReadOnly = bindReadOnlySupport;
uint64_t expectedFlags = DRM_XE_VM_BIND_FLAG_DUMPABLE;
if (bindImmediateSupport) {
expectedFlags |= DRM_XE_VM_BIND_FLAG_IMMEDIATE;
}
if (bindReadOnlySupport) {
expectedFlags |= DRM_XE_VM_BIND_FLAG_READONLY;
}
auto bindFlags = xeIoctlHelper->getFlagsForVmBind(true, true, false, false, true);
EXPECT_EQ(expectedFlags, bindFlags);
}
}
}
struct DrmMockXeVmBind : public DrmMockXe {
static auto create(RootDeviceEnvironment &rootDeviceEnvironment) {
auto drm = std::unique_ptr<DrmMockXeVmBind>(new DrmMockXeVmBind{rootDeviceEnvironment});
drm->initInstance();
return drm;
}
int ioctl(DrmIoctl request, void *arg) override {
switch (request) {
case DrmIoctl::gemVmBind: {
auto vmBindInput = static_cast<drm_xe_vm_bind *>(arg);
if ((vmBindInput->bind.flags & DRM_XE_VM_BIND_FLAG_IMMEDIATE) == DRM_XE_VM_BIND_FLAG_IMMEDIATE && !supportsBindImmediate) {
return -EINVAL;
}
if ((vmBindInput->bind.flags & DRM_XE_VM_BIND_FLAG_READONLY) == DRM_XE_VM_BIND_FLAG_READONLY && !supportsBindReadOnly) {
return -EINVAL;
}
return 0;
} break;
default:
return DrmMockXe::ioctl(request, arg);
}
};
bool supportsBindImmediate = true;
bool supportsBindReadOnly = true;
protected:
// Don't call directly, use the create() function
DrmMockXeVmBind(RootDeviceEnvironment &rootDeviceEnvironment) : DrmMockXe(rootDeviceEnvironment) {}
};
TEST(IoctlHelperXeVmBindTest, whenInitializeIoctlHelperThenQueryBindFlagsSupport) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = DrmMockXeVmBind::create(*executionEnvironment->rootDeviceEnvironments[0]);
for (const auto &bindImmediateSupport : ::testing::Bool()) {
for (const auto &bindReadOnlySupport : ::testing::Bool()) {
drm->supportsBindImmediate = bindImmediateSupport;
drm->supportsBindReadOnly = bindReadOnlySupport;
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(*drm);
xeIoctlHelper->initialize();
EXPECT_EQ(xeIoctlHelper->supportedFeatures.flags.vmBindImmediate, bindImmediateSupport);
EXPECT_EQ(xeIoctlHelper->supportedFeatures.flags.vmBindReadOnly, bindReadOnlySupport);
}
}
}