feature: Register resources for Xe at vm creation (1/x)
Add interfaces to IoctlHelperXe for registering resources. Introduce new debug key EnableXeResourceRegistration to attach resources to vm_create ioctl. Related-to: NEO-9161 Signed-off-by: Brandon Yatse <brandon.yates@intel.com>
This commit is contained in:
parent
0aee72f1fc
commit
d3baab00db
|
@ -8,11 +8,10 @@
|
|||
#include "level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h"
|
||||
|
||||
#include "shared/test/common/helpers/variable_backup.h"
|
||||
#include "shared/test/common/mocks/linux/debug_mock_drm_xe.h"
|
||||
#include "shared/test/common/mocks/mock_device.h"
|
||||
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
|
||||
|
||||
#include "level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_mock_drm_xe.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace ult {
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "shared/test/common/helpers/gtest_helpers.h"
|
||||
#include "shared/test/common/libult/linux/drm_mock_helper.h"
|
||||
#include "shared/test/common/libult/linux/drm_query_mock.h"
|
||||
#include "shared/test/common/mocks/linux/debug_mock_drm_xe.h"
|
||||
#include "shared/test/common/mocks/mock_sip.h"
|
||||
#include "shared/test/common/mocks/ult_device_factory.h"
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
|
@ -20,7 +21,6 @@
|
|||
#include "level_zero/core/test/unit_tests/mocks/mock_built_ins.h"
|
||||
#include "level_zero/tools/source/debug/linux/xe/debug_session.h"
|
||||
#include "level_zero/tools/test/unit_tests/sources/debug/debug_session_common.h"
|
||||
#include "level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_mock_drm_xe.h"
|
||||
|
||||
#include "common/StateSaveAreaHeader.h"
|
||||
#include "uapi-eudebug/drm/xe_drm.h"
|
||||
|
|
|
@ -21,6 +21,7 @@ enum class DrmResourceClass : uint32_t {
|
|||
sbaTrackingBuffer,
|
||||
contextID,
|
||||
l0ZebinModule,
|
||||
cookie,
|
||||
maxSize
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h"
|
||||
|
||||
#include "shared/source/command_stream/csr_definitions.h"
|
||||
#include "shared/source/debugger/debugger.h"
|
||||
#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/basic_math.h"
|
||||
|
@ -1076,7 +1078,15 @@ int IoctlHelperXe::ioctl(DrmIoctl request, void *arg) {
|
|||
if (drm.hasPageFaultSupport()) {
|
||||
args.flags |= DRM_XE_VM_CREATE_FLAG_FAULT_MODE;
|
||||
}
|
||||
|
||||
if (drm.getRootDeviceEnvironment().executionEnvironment.getDebuggingMode() != DebuggingMode::disabled) {
|
||||
args.extensions = reinterpret_cast<unsigned long long>(allocateDebugMetadata());
|
||||
}
|
||||
ret = IoctlHelper::ioctl(request, &args);
|
||||
if (drm.getRootDeviceEnvironment().executionEnvironment.getDebuggingMode() != DebuggingMode::disabled) {
|
||||
args.extensions = reinterpret_cast<unsigned long long>(freeDebugMetadata(reinterpret_cast<void *>(args.extensions)));
|
||||
}
|
||||
|
||||
d->vmId = ret ? 0 : args.vm_id;
|
||||
d->flags = ret ? 0 : args.flags;
|
||||
xeVmId = d->vmId;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/os_interface/linux/drm_debug.h"
|
||||
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
||||
|
||||
#include <bitset>
|
||||
|
@ -124,6 +125,8 @@ class IoctlHelperXe : public IoctlHelper {
|
|||
void logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger) override;
|
||||
bool setDomainCpu(uint32_t handle, bool writeEnable) override;
|
||||
uint16_t getCpuCachingMode();
|
||||
void addDebugMetadata(DrmResourceClass type, uint64_t *offset, uint64_t size);
|
||||
void addDebugMetadataCookie(uint64_t cookie);
|
||||
|
||||
protected:
|
||||
const char *xeGetClassName(int className);
|
||||
|
@ -137,6 +140,8 @@ class IoctlHelperXe : public IoctlHelper {
|
|||
int xeVmBind(const VmBindParams &vmBindParams, bool bindOp);
|
||||
void xeShowBindTable();
|
||||
void updateBindInfo(uint32_t handle, uint64_t userPtr, uint64_t size);
|
||||
void *allocateDebugMetadata();
|
||||
void *freeDebugMetadata(void *metadata);
|
||||
|
||||
struct UserFenceExtension {
|
||||
static constexpr uint32_t tagValue = 0x123987;
|
||||
|
@ -164,6 +169,14 @@ class IoctlHelperXe : public IoctlHelper {
|
|||
|
||||
drm_xe_engine_class_instance *defaultEngine = nullptr;
|
||||
|
||||
struct DebugMetadata {
|
||||
DrmResourceClass type;
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
bool isCookie;
|
||||
};
|
||||
std::vector<DebugMetadata> debugMetadata;
|
||||
|
||||
private:
|
||||
template <typename... XeLogArgs>
|
||||
void xeLog(XeLogArgs &&...args) const;
|
||||
|
|
|
@ -26,4 +26,82 @@ unsigned int IoctlHelperXe::getIoctlRequestValueDebugger(DrmIoctl ioctlRequest)
|
|||
}
|
||||
}
|
||||
|
||||
void *IoctlHelperXe::allocateDebugMetadata() {
|
||||
drm_xe_ext_vm_set_debug_metadata *prev = nullptr;
|
||||
drm_xe_ext_vm_set_debug_metadata *xeMetadataRoot = nullptr;
|
||||
|
||||
for (auto metadata : debugMetadata) {
|
||||
auto *xeMetadata = new drm_xe_ext_vm_set_debug_metadata();
|
||||
if (!xeMetadataRoot) {
|
||||
xeMetadataRoot = xeMetadata;
|
||||
}
|
||||
xeMetadata->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
xeMetadata->offset = metadata.offset;
|
||||
xeMetadata->len = metadata.size;
|
||||
if (metadata.isCookie) {
|
||||
xeMetadata->type = DRM_XE_VM_DEBUG_METADATA_COOKIE;
|
||||
} else {
|
||||
|
||||
switch (metadata.type) {
|
||||
case DrmResourceClass::contextSaveArea:
|
||||
xeMetadata->type = DRM_XE_VM_DEBUG_METADATA_SIP_AREA;
|
||||
break;
|
||||
case DrmResourceClass::sbaTrackingBuffer:
|
||||
xeMetadata->type = DRM_XE_VM_DEBUG_METADATA_SBA_AREA;
|
||||
break;
|
||||
case DrmResourceClass::moduleHeapDebugArea:
|
||||
xeMetadata->type = DRM_XE_VM_DEBUG_METADATA_MODULE_AREA;
|
||||
break;
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
}
|
||||
}
|
||||
PRINT_DEBUGGER_INFO_LOG("drm_xe_ext_vm_set_debug_metadata: type = %ul, offset = %ul, len = %ul\n", xeMetadata->type, xeMetadata->offset, xeMetadata->len);
|
||||
if (prev) {
|
||||
prev->base.next_extension = reinterpret_cast<unsigned long long>(xeMetadata);
|
||||
}
|
||||
prev = xeMetadata;
|
||||
}
|
||||
return xeMetadataRoot;
|
||||
}
|
||||
|
||||
void *IoctlHelperXe::freeDebugMetadata(void *metadata) {
|
||||
xe_user_extension *ext = static_cast<xe_user_extension *>(metadata);
|
||||
xe_user_extension *prev = nullptr;
|
||||
xe_user_extension *newRoot = nullptr;
|
||||
while (ext) {
|
||||
xe_user_extension *temp = reinterpret_cast<xe_user_extension *>(ext->next_extension);
|
||||
if (ext->name == DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA) {
|
||||
if (prev) {
|
||||
prev->next_extension = ext->next_extension;
|
||||
}
|
||||
delete ext;
|
||||
} else {
|
||||
if (!newRoot) {
|
||||
newRoot = ext;
|
||||
}
|
||||
prev = ext;
|
||||
}
|
||||
ext = temp;
|
||||
}
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
void IoctlHelperXe::addDebugMetadataCookie(uint64_t cookie) {
|
||||
|
||||
DebugMetadata metadata = {DrmResourceClass::cookie, cookie, 0, true};
|
||||
debugMetadata.push_back(metadata);
|
||||
return;
|
||||
}
|
||||
|
||||
void IoctlHelperXe::addDebugMetadata(DrmResourceClass type, uint64_t *offset, uint64_t size) {
|
||||
|
||||
if (type != DrmResourceClass::moduleHeapDebugArea && type != DrmResourceClass::contextSaveArea && type != DrmResourceClass::sbaTrackingBuffer) {
|
||||
return;
|
||||
}
|
||||
DebugMetadata metadata = {type, reinterpret_cast<unsigned long long>(offset), size, false};
|
||||
debugMetadata.push_back(metadata);
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
|
@ -112,6 +112,7 @@ else()
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_wrappers.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_ioctl_helper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_os_time_linux.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/debug_mock_drm_xe.h
|
||||
)
|
||||
endif()
|
||||
if(WIN32 OR NOT DISABLE_WDDM_LINUX)
|
||||
|
|
|
@ -28,6 +28,12 @@
|
|||
|
||||
using namespace NEO;
|
||||
|
||||
struct MockIoctlHelperXeDebug : IoctlHelperXe {
|
||||
using IoctlHelperXe::debugMetadata;
|
||||
using IoctlHelperXe::freeDebugMetadata;
|
||||
using IoctlHelperXe::IoctlHelperXe;
|
||||
};
|
||||
|
||||
inline constexpr int testValueVmId = 0x5764;
|
||||
inline constexpr int testValueMapOff = 0x7788;
|
||||
inline constexpr int testValuePrime = 0x4321;
|
||||
|
@ -53,7 +59,15 @@ class DrmMockXeDebug : public DrmMockCustom {
|
|||
return setIoctlAnswer;
|
||||
}
|
||||
switch (request) {
|
||||
|
||||
case DrmIoctl::gemVmCreate: {
|
||||
struct drm_xe_vm_create *v = static_cast<struct drm_xe_vm_create *>(arg);
|
||||
drm_xe_ext_vm_set_debug_metadata *metadata = reinterpret_cast<drm_xe_ext_vm_set_debug_metadata *>(v->extensions);
|
||||
while (metadata) {
|
||||
vmCreateMetadata.push_back(*metadata);
|
||||
metadata = reinterpret_cast<drm_xe_ext_vm_set_debug_metadata *>(metadata->base.next_extension);
|
||||
}
|
||||
ret = 0;
|
||||
} break;
|
||||
case DrmIoctl::debuggerOpen: {
|
||||
auto debuggerOpen = reinterpret_cast<drm_xe_eudebug_connect *>(arg);
|
||||
|
||||
|
@ -107,6 +121,7 @@ class DrmMockXeDebug : public DrmMockCustom {
|
|||
int gemVmBindReturn = 0;
|
||||
|
||||
alignas(64) std::vector<uint8_t> queryTopology;
|
||||
std::vector<drm_xe_ext_vm_set_debug_metadata> vmCreateMetadata;
|
||||
|
||||
// Debugger ioctls
|
||||
int debuggerOpenRetval = 10; // debugFd
|
|
@ -9,6 +9,7 @@
|
|||
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
||||
#include "shared/test/common/helpers/default_hw_info.h"
|
||||
#include "shared/test/common/libult/linux/drm_mock.h"
|
||||
#include "shared/test/common/mocks/linux/debug_mock_drm_xe.h"
|
||||
#include "shared/test/common/mocks/linux/mock_os_time_linux.h"
|
||||
#include "shared/test/common/mocks/mock_execution_environment.h"
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
|
@ -32,4 +33,117 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingGetIoctForDebuggerThenCorre
|
|||
verifyIoctlString(DrmIoctl::debuggerOpen, "DRM_IOCTL_XE_EUDEBUG_CONNECT");
|
||||
|
||||
verifyIoctlRequestValue(DRM_IOCTL_XE_EUDEBUG_CONNECT, DrmIoctl::debuggerOpen);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingaddDebugMetadataThenDataIsAdded) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
DrmMockXeDebug drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXeDebug>(drm);
|
||||
uint64_t temp = 0;
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::moduleHeapDebugArea, &temp, 8000u);
|
||||
ASSERT_EQ(1u, xeIoctlHelper->debugMetadata.size());
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::contextSaveArea, &temp, 8000u);
|
||||
ASSERT_EQ(2u, xeIoctlHelper->debugMetadata.size());
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::sbaTrackingBuffer, &temp, 8000u);
|
||||
ASSERT_EQ(3u, xeIoctlHelper->debugMetadata.size());
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::isa, &temp, 8000u); // ISA should be ignored
|
||||
ASSERT_EQ(3u, xeIoctlHelper->debugMetadata.size());
|
||||
}
|
||||
|
||||
TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingVmCreateThenDebugMetadadaIsAttached) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
executionEnvironment->setDebuggingMode(DebuggingMode::offline);
|
||||
DrmMockXeDebug drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXeDebug>(drm);
|
||||
uint64_t temp = 0;
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::moduleHeapDebugArea, &temp, 8000u);
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::contextSaveArea, &temp, 8000u);
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::sbaTrackingBuffer, &temp, 8000u);
|
||||
xeIoctlHelper->addDebugMetadata(DrmResourceClass::isa, &temp, 8000u); // ISA should be ignored
|
||||
xeIoctlHelper->addDebugMetadataCookie(123u);
|
||||
|
||||
GemVmControl test = {};
|
||||
xeIoctlHelper->ioctl(DrmIoctl::gemVmCreate, &test);
|
||||
|
||||
ASSERT_EQ(4u, drm.vmCreateMetadata.size());
|
||||
ASSERT_EQ(drm.vmCreateMetadata[0].type, static_cast<unsigned long long>(DRM_XE_VM_DEBUG_METADATA_MODULE_AREA));
|
||||
ASSERT_EQ(drm.vmCreateMetadata[0].offset, reinterpret_cast<unsigned long long>(&temp));
|
||||
ASSERT_EQ(drm.vmCreateMetadata[0].len, 8000ul);
|
||||
|
||||
ASSERT_EQ(drm.vmCreateMetadata[1].type, static_cast<unsigned long long>(DRM_XE_VM_DEBUG_METADATA_SIP_AREA));
|
||||
ASSERT_EQ(drm.vmCreateMetadata[1].offset, reinterpret_cast<unsigned long long>(&temp));
|
||||
ASSERT_EQ(drm.vmCreateMetadata[1].len, 8000ul);
|
||||
|
||||
ASSERT_EQ(drm.vmCreateMetadata[2].type, static_cast<unsigned long long>(DRM_XE_VM_DEBUG_METADATA_SBA_AREA));
|
||||
ASSERT_EQ(drm.vmCreateMetadata[2].offset, reinterpret_cast<unsigned long long>(&temp));
|
||||
ASSERT_EQ(drm.vmCreateMetadata[2].len, 8000ul);
|
||||
|
||||
ASSERT_EQ(drm.vmCreateMetadata[3].type, static_cast<unsigned long long>(DRM_XE_VM_DEBUG_METADATA_COOKIE));
|
||||
ASSERT_EQ(drm.vmCreateMetadata[3].offset, 123ul);
|
||||
ASSERT_EQ(drm.vmCreateMetadata[3].len, 0ul);
|
||||
ASSERT_EQ(drm.vmCreateMetadata[3].base.next_extension, 0ul);
|
||||
}
|
||||
|
||||
TEST(IoctlHelperXeTest, givenFreeDebugMetadataWhenVmCreateHasMultipleExtTypesThenOnlyDebugMetadataIsDeleted) {
|
||||
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
executionEnvironment->setDebuggingMode(DebuggingMode::offline);
|
||||
DrmMockXeDebug drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXeDebug>(drm);
|
||||
|
||||
drm_xe_ext_vm_set_debug_metadata *node1 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
drm_xe_ext_vm_set_debug_metadata *node2 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
drm_xe_ext_vm_set_debug_metadata *node3 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node1->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
node2->base.name = 0x1234ul;
|
||||
node3->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
node1->base.next_extension = reinterpret_cast<unsigned long long>(node2);
|
||||
node2->base.next_extension = reinterpret_cast<unsigned long long>(node3);
|
||||
|
||||
drm_xe_ext_vm_set_debug_metadata *newRoot = static_cast<drm_xe_ext_vm_set_debug_metadata *>(xeIoctlHelper->freeDebugMetadata(node1));
|
||||
ASSERT_EQ(newRoot, node2);
|
||||
ASSERT_EQ(newRoot->base.next_extension, 0ul);
|
||||
delete node2;
|
||||
|
||||
node1 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node2 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node3 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node1->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
node2->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
node3->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
node1->base.next_extension = reinterpret_cast<unsigned long long>(node2);
|
||||
node2->base.next_extension = reinterpret_cast<unsigned long long>(node3);
|
||||
|
||||
newRoot = static_cast<drm_xe_ext_vm_set_debug_metadata *>(xeIoctlHelper->freeDebugMetadata(node1));
|
||||
ASSERT_EQ(newRoot, nullptr);
|
||||
|
||||
node1 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node2 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node3 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node1->base.name = 0x1234;
|
||||
node2->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
node3->base.name = DRM_XE_VM_EXTENSION_SET_DEBUG_METADATA;
|
||||
node1->base.next_extension = reinterpret_cast<unsigned long long>(node2);
|
||||
node2->base.next_extension = reinterpret_cast<unsigned long long>(node3);
|
||||
|
||||
newRoot = static_cast<drm_xe_ext_vm_set_debug_metadata *>(xeIoctlHelper->freeDebugMetadata(node1));
|
||||
ASSERT_EQ(newRoot, node1);
|
||||
ASSERT_EQ(newRoot->base.next_extension, 0ul);
|
||||
delete node1;
|
||||
|
||||
node1 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node2 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node3 = new drm_xe_ext_vm_set_debug_metadata();
|
||||
node1->base.name = 0x1234;
|
||||
node2->base.name = 0x1234;
|
||||
node3->base.name = 0x1234;
|
||||
node1->base.next_extension = reinterpret_cast<unsigned long long>(node2);
|
||||
node2->base.next_extension = reinterpret_cast<unsigned long long>(node3);
|
||||
|
||||
newRoot = static_cast<drm_xe_ext_vm_set_debug_metadata *>(xeIoctlHelper->freeDebugMetadata(node1));
|
||||
ASSERT_EQ(newRoot, node1);
|
||||
ASSERT_EQ(newRoot->base.next_extension, reinterpret_cast<unsigned long long>(node2));
|
||||
delete node1;
|
||||
delete node2;
|
||||
delete node3;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ using namespace NEO;
|
|||
|
||||
struct MockIoctlHelperXe : IoctlHelperXe {
|
||||
using IoctlHelperXe::bindInfo;
|
||||
using IoctlHelperXe::debugMetadata;
|
||||
using IoctlHelperXe::defaultEngine;
|
||||
using IoctlHelperXe::getFdFromVmExport;
|
||||
using IoctlHelperXe::IoctlHelperXe;
|
||||
|
|
Loading…
Reference in New Issue