mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-08 05:56:36 +08:00
feature: Implement Xe Eu debug Open and Exec Queue events
Related-To: NEO-8407 Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
e949ba7144
commit
b34e8646ac
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Intel Corporation
|
||||
* Copyright (C) 2021-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -116,4 +116,9 @@ std::unique_ptr<uint64_t[]> DebugSessionLinux::getInternalEvent() {
|
||||
return eventMemory;
|
||||
}
|
||||
|
||||
void DebugSessionLinux::closeAsyncThread() {
|
||||
asyncThread.close();
|
||||
internalEventThread.close();
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
* Copyright (C) 2023-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -20,6 +20,7 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
DebugSessionLinux(const zet_debug_config_t &config, Device *device, int fd) : DebugSessionImp(config, device), fd(fd){};
|
||||
static ze_result_t translateDebuggerOpenErrno(int error);
|
||||
bool closeFd();
|
||||
void closeAsyncThread();
|
||||
|
||||
int fd = 0;
|
||||
std::atomic<bool> internalThreadHasStarted{false};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2023 Intel Corporation
|
||||
* Copyright (C) 2022-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -322,11 +322,6 @@ void DebugSessionLinuxi915::startAsyncThread() {
|
||||
asyncThread.thread = NEO::Thread::create(asyncThreadFunction, reinterpret_cast<void *>(this));
|
||||
}
|
||||
|
||||
void DebugSessionLinuxi915::closeAsyncThread() {
|
||||
asyncThread.close();
|
||||
internalEventThread.close();
|
||||
}
|
||||
|
||||
void DebugSessionLinuxi915::handleEventsAsync() {
|
||||
auto eventMemory = getInternalEvent();
|
||||
if (eventMemory != nullptr) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2023 Intel Corporation
|
||||
* Copyright (C) 2022-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -195,7 +195,6 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
|
||||
|
||||
static void *asyncThreadFunction(void *arg);
|
||||
void startAsyncThread() override;
|
||||
void closeAsyncThread();
|
||||
|
||||
virtual std::vector<uint64_t> getAllMemoryHandles() {
|
||||
std::vector<uint64_t> allVms;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
* Copyright (C) 2023-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -30,7 +30,7 @@ DebugSessionLinuxXe::DebugSessionLinuxXe(const zet_debug_config_t &config, Devic
|
||||
};
|
||||
DebugSessionLinuxXe::~DebugSessionLinuxXe() {
|
||||
|
||||
// closeAsyncThread();
|
||||
closeAsyncThread();
|
||||
closeInternalEventsThread();
|
||||
closeFd();
|
||||
}
|
||||
@@ -83,6 +83,31 @@ ze_result_t DebugSessionLinuxXe::initialize() {
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void DebugSessionLinuxXe::handleEventsAsync() {
|
||||
auto eventMemory = getInternalEvent();
|
||||
if (eventMemory != nullptr) {
|
||||
auto debugEvent = reinterpret_cast<drm_xe_eudebug_event *>(eventMemory.get());
|
||||
handleEvent(debugEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void *DebugSessionLinuxXe::asyncThreadFunction(void *arg) {
|
||||
DebugSessionLinuxXe *self = reinterpret_cast<DebugSessionLinuxXe *>(arg);
|
||||
PRINT_DEBUGGER_INFO_LOG("Debugger async thread start\n", "");
|
||||
|
||||
while (self->asyncThread.threadActive) {
|
||||
self->handleEventsAsync();
|
||||
}
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("Debugger async thread closing\n", "");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DebugSessionLinuxXe::startAsyncThread() {
|
||||
asyncThread.thread = NEO::Thread::create(asyncThreadFunction, reinterpret_cast<void *>(this));
|
||||
}
|
||||
|
||||
void DebugSessionLinuxXe::readInternalEventsAsync() {
|
||||
|
||||
struct pollfd pollFd = {
|
||||
@@ -159,4 +184,60 @@ bool DebugSessionLinuxXe::closeConnection() {
|
||||
return closeFd();
|
||||
}
|
||||
|
||||
void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *event) {
|
||||
auto type = event->type;
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type = %u flags = %u seqno = %llu len = %lu",
|
||||
(uint16_t)event->type, (uint16_t)event->flags, (uint64_t)event->seqno, (uint32_t)event->len);
|
||||
|
||||
switch (type) {
|
||||
case DRM_XE_EUDEBUG_EVENT_OPEN: {
|
||||
auto clientEvent = reinterpret_cast<drm_xe_eudebug_event_client *>(event);
|
||||
|
||||
if (event->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
|
||||
DEBUG_BREAK_IF(clientHandleToConnection.find(clientEvent->client_handle) != clientHandleToConnection.end());
|
||||
clientHandleToConnection[clientEvent->client_handle].reset(new ClientConnection);
|
||||
clientHandleToConnection[clientEvent->client_handle]->client = *clientEvent;
|
||||
}
|
||||
|
||||
if (event->flags & DRM_XE_EUDEBUG_EVENT_DESTROY) {
|
||||
clientHandleClosed = clientEvent->client_handle;
|
||||
}
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type: DRM_XE_EUDEBUG_EVENT_OPEN flags = %u len = %lu client.handle = %llu\n",
|
||||
(uint16_t)event->flags, (uint32_t)event->len, (uint64_t)clientEvent->client_handle);
|
||||
|
||||
} break;
|
||||
|
||||
case DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE: {
|
||||
drm_xe_eudebug_event_exec_queue *execQueue = reinterpret_cast<drm_xe_eudebug_event_exec_queue *>(event);
|
||||
|
||||
if (event->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
|
||||
UNRECOVERABLE_IF(clientHandleToConnection.find(execQueue->client_handle) == clientHandleToConnection.end());
|
||||
clientHandleToConnection[execQueue->client_handle]->execQueues[execQueue->exec_queue_handle].vmHandle = execQueue->vm_handle;
|
||||
clientHandleToConnection[execQueue->client_handle]->execQueues[execQueue->exec_queue_handle].engineClass = execQueue->engine_class;
|
||||
for (uint16_t idx = 0; idx < execQueue->width; idx++) {
|
||||
clientHandleToConnection[execQueue->client_handle]->lrcHandleToVmHandle[execQueue->lrc_handle[idx]] = execQueue->vm_handle;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->flags & DRM_XE_EUDEBUG_EVENT_DESTROY) {
|
||||
for (uint16_t idx = 0; idx < execQueue->width; idx++) {
|
||||
clientHandleToConnection[execQueue->client_handle]->lrcHandleToVmHandle.erase(execQueue->lrc_handle[idx]);
|
||||
}
|
||||
clientHandleToConnection[execQueue->client_handle]->execQueues.erase(execQueue->exec_queue_handle);
|
||||
}
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type: DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE flags = %u len = %lu client_handle = %llu\
|
||||
vm_handle = %llu exec_queue_handle = %llu engine_class = %u\n",
|
||||
(uint16_t)event->flags, (uint32_t)event->len, (uint64_t)execQueue->client_handle, (uint64_t)execQueue->vm_handle,
|
||||
(uint64_t)execQueue->exec_queue_handle, (uint16_t)execQueue->engine_class);
|
||||
} break;
|
||||
|
||||
default:
|
||||
PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type: UNHANDLED %u flags = %u len = %lu\n", (uint16_t)event->type, (uint16_t)event->flags, (uint32_t)event->len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
* Copyright (C) 2023-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -42,8 +42,54 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void startAsyncThread() override {
|
||||
}
|
||||
struct IoctlHandlerXe : DebugSessionLinux::IoctlHandler {
|
||||
int ioctl(int fd, unsigned long request, void *arg) override {
|
||||
int ret = 0;
|
||||
int error = 0;
|
||||
bool shouldRetryIoctl = false;
|
||||
do {
|
||||
shouldRetryIoctl = false;
|
||||
ret = NEO::SysCalls::ioctl(fd, request, arg);
|
||||
error = errno;
|
||||
|
||||
if (ret == -1) {
|
||||
shouldRetryIoctl = (error == EINTR || error == EAGAIN || error == EBUSY);
|
||||
|
||||
if (request == DRM_XE_EUDEBUG_IOCTL_EU_CONTROL) {
|
||||
shouldRetryIoctl = (error == EINTR || error == EAGAIN);
|
||||
}
|
||||
}
|
||||
} while (shouldRetryIoctl);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
using ContextHandle = uint64_t;
|
||||
using ExecQueueHandle = uint64_t;
|
||||
|
||||
struct ContextParams {
|
||||
ContextHandle handle = 0;
|
||||
uint64_t vm = UINT64_MAX;
|
||||
std::vector<drm_xe_engine_class_instance> engines;
|
||||
};
|
||||
|
||||
struct ExecQueueParams {
|
||||
uint64_t vmHandle = 0;
|
||||
uint16_t engineClass = UINT16_MAX;
|
||||
};
|
||||
|
||||
struct BindInfo {
|
||||
uint64_t gpuVa = 0;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<IoctlHandlerXe> ioctlHandler;
|
||||
uint32_t xeDebuggerVersion = 0;
|
||||
|
||||
protected:
|
||||
void startAsyncThread() override;
|
||||
static void *asyncThreadFunction(void *arg);
|
||||
void handleEventsAsync();
|
||||
|
||||
bool readModuleDebugArea() override {
|
||||
UNRECOVERABLE_IF(true);
|
||||
@@ -100,52 +146,18 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
|
||||
UNRECOVERABLE_IF(true);
|
||||
}
|
||||
|
||||
struct IoctlHandlerXe : DebugSessionLinux::IoctlHandler {
|
||||
int ioctl(int fd, unsigned long request, void *arg) override {
|
||||
int ret = 0;
|
||||
int error = 0;
|
||||
bool shouldRetryIoctl = false;
|
||||
do {
|
||||
shouldRetryIoctl = false;
|
||||
ret = NEO::SysCalls::ioctl(fd, request, arg);
|
||||
error = errno;
|
||||
|
||||
if (ret == -1) {
|
||||
shouldRetryIoctl = (error == EINTR || error == EAGAIN || error == EBUSY);
|
||||
|
||||
if (request == DRM_XE_EUDEBUG_IOCTL_EU_CONTROL) {
|
||||
shouldRetryIoctl = (error == EINTR || error == EAGAIN);
|
||||
}
|
||||
}
|
||||
} while (shouldRetryIoctl);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
using ContextHandle = uint64_t;
|
||||
|
||||
struct ContextParams {
|
||||
ContextHandle handle = 0;
|
||||
uint64_t vm = UINT64_MAX;
|
||||
std::vector<drm_xe_engine_class_instance> engines;
|
||||
};
|
||||
|
||||
struct BindInfo {
|
||||
uint64_t gpuVa = 0;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
struct ClientConnection {
|
||||
drm_xe_eudebug_event_client client = {};
|
||||
std::unordered_map<ExecQueueHandle, ExecQueueParams> execQueues;
|
||||
std::unordered_map<uint64_t, uint64_t> lrcHandleToVmHandle;
|
||||
std::unordered_map<uint64_t, BindInfo> vmToModuleDebugAreaBindInfo;
|
||||
};
|
||||
|
||||
std::vector<std::unique_ptr<uint64_t[]>> pendingVmBindEvents;
|
||||
bool checkAllEventsCollected();
|
||||
void handleEvent(drm_xe_eudebug_event *event);
|
||||
MOCKABLE_VIRTUAL void handleEvent(drm_xe_eudebug_event *event);
|
||||
void readInternalEventsAsync() override;
|
||||
void pushApiEvent(zet_debug_event_t &debugEvent);
|
||||
std::unique_ptr<IoctlHandlerXe> ioctlHandler;
|
||||
uint32_t xeDebuggerVersion = 0;
|
||||
std::unordered_map<uint64_t, std::unique_ptr<ClientConnection>> clientHandleToConnection;
|
||||
std::atomic<bool> detached{false};
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
namespace L0 {
|
||||
namespace ult {
|
||||
using typeOfLrcHandle = std::decay<decltype(drm_xe_eudebug_event_exec_queue::lrc_handle[0])>::type;
|
||||
|
||||
struct DebugApiLinuxXeFixture : public DeviceFixture {
|
||||
void setUp() {
|
||||
@@ -97,8 +98,17 @@ struct MockIoctlHandlerXe : public L0::DebugSessionLinuxXe::IoctlHandlerXe {
|
||||
|
||||
struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe {
|
||||
using L0::DebugSessionImp::apiEvents;
|
||||
using L0::DebugSessionLinuxXe::asyncThread;
|
||||
using L0::DebugSessionLinuxXe::asyncThreadFunction;
|
||||
using L0::DebugSessionLinuxXe::clientHandleClosed;
|
||||
using L0::DebugSessionLinuxXe::clientHandleToConnection;
|
||||
using L0::DebugSessionLinuxXe::handleEvent;
|
||||
using L0::DebugSessionLinuxXe::internalEventQueue;
|
||||
using L0::DebugSessionLinuxXe::internalEventThread;
|
||||
using L0::DebugSessionLinuxXe::invalidClientHandle;
|
||||
using L0::DebugSessionLinuxXe::readEventImp;
|
||||
using L0::DebugSessionLinuxXe::readInternalEventsAsync;
|
||||
using L0::DebugSessionLinuxXe::startAsyncThread;
|
||||
|
||||
MockDebugSessionLinuxXe(const zet_debug_config_t &config, L0::Device *device, int debugFd, void *params) : DebugSessionLinuxXe(config, device, debugFd, params) {
|
||||
clientHandleToConnection[mockClientHandle].reset(new ClientConnection);
|
||||
@@ -115,9 +125,35 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe {
|
||||
}
|
||||
return DebugSessionLinuxXe::initialize();
|
||||
}
|
||||
|
||||
std::unique_ptr<uint64_t[]> getInternalEvent() override {
|
||||
getInternalEventCounter++;
|
||||
if (synchronousInternalEventRead) {
|
||||
readInternalEventsAsync();
|
||||
}
|
||||
return DebugSessionLinuxXe::getInternalEvent();
|
||||
}
|
||||
|
||||
bool synchronousInternalEventRead = false;
|
||||
std::atomic<int> getInternalEventCounter = 0;
|
||||
ze_result_t initializeRetVal = ZE_RESULT_FORCE_UINT32;
|
||||
static constexpr uint64_t mockClientHandle = 1;
|
||||
};
|
||||
|
||||
struct MockAsyncThreadDebugSessionLinuxXe : public MockDebugSessionLinuxXe {
|
||||
using MockDebugSessionLinuxXe::MockDebugSessionLinuxXe;
|
||||
static void *mockAsyncThreadFunction(void *arg) {
|
||||
DebugSessionLinuxXe::asyncThreadFunction(arg);
|
||||
reinterpret_cast<MockAsyncThreadDebugSessionLinuxXe *>(arg)->asyncThreadFinished = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void startAsyncThread() override {
|
||||
asyncThread.thread = NEO::Thread::create(mockAsyncThreadFunction, reinterpret_cast<void *>(this));
|
||||
}
|
||||
|
||||
std::atomic<bool> asyncThreadFinished{false};
|
||||
};
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
* Copyright (C) 2023-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -412,5 +412,255 @@ TEST_F(DebugApiLinuxTestXe, GivenMoreThan3EventsInQueueThenInternalEventsOnlyRea
|
||||
EXPECT_EQ(static_cast<decltype(drm_xe_eudebug_event::type)>(DRM_XE_EUDEBUG_EVENT_READ), handler->debugEventInput.type);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenEventInInternalEventQueueWhenAsyncThreadFunctionIsExecutedThenEventIsHandled) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockAsyncThreadDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, session);
|
||||
|
||||
session->clientHandleToConnection.clear();
|
||||
|
||||
uint8_t eventClientData[sizeof(drm_xe_eudebug_event_client)];
|
||||
auto client = reinterpret_cast<drm_xe_eudebug_event_client *>(&eventClientData);
|
||||
client->base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client->base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
client->base.len = sizeof(drm_xe_eudebug_event_client);
|
||||
client->client_handle = 0x123456789;
|
||||
|
||||
auto memory = std::make_unique<uint64_t[]>(sizeof(drm_xe_eudebug_event_client) / sizeof(uint64_t));
|
||||
memcpy(memory.get(), client, sizeof(drm_xe_eudebug_event_client));
|
||||
|
||||
// Clear the event queue before using it
|
||||
while (!session->internalEventQueue.empty()) {
|
||||
session->internalEventQueue.pop();
|
||||
}
|
||||
session->internalEventQueue.push(std::move(memory));
|
||||
|
||||
session->startAsyncThread();
|
||||
|
||||
while (session->getInternalEventCounter == 0)
|
||||
;
|
||||
EXPECT_TRUE(session->asyncThread.threadActive);
|
||||
EXPECT_FALSE(session->asyncThreadFinished);
|
||||
|
||||
session->closeAsyncThread();
|
||||
|
||||
EXPECT_FALSE(session->asyncThread.threadActive);
|
||||
EXPECT_TRUE(session->asyncThreadFinished);
|
||||
EXPECT_EQ(session->clientHandleToConnection.size(), 1ul);
|
||||
EXPECT_NE(session->clientHandleToConnection.find(client->client_handle), session->clientHandleToConnection.end());
|
||||
|
||||
uint64_t wrongClientHandle = 34;
|
||||
EXPECT_EQ(session->clientHandleToConnection.find(wrongClientHandle), session->clientHandleToConnection.end());
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenNoEventInInternalEventQueueWhenAsyncThreadFunctionIsExecutedThenEventsAreCheckedForAvailability) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockAsyncThreadDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, session);
|
||||
|
||||
// Clear the event queue before using it
|
||||
while (!session->internalEventQueue.empty()) {
|
||||
session->internalEventQueue.pop();
|
||||
}
|
||||
|
||||
session->startAsyncThread();
|
||||
|
||||
while (session->getInternalEventCounter == 0)
|
||||
;
|
||||
EXPECT_TRUE(session->asyncThread.threadActive);
|
||||
EXPECT_FALSE(session->asyncThreadFinished);
|
||||
|
||||
session->closeAsyncThread();
|
||||
|
||||
EXPECT_FALSE(session->asyncThread.threadActive);
|
||||
EXPECT_TRUE(session->asyncThreadFinished);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenOneEuDebugOpenEventAndOneIncorrectEventWhenHandleEventThenEventsAreHandled) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, session);
|
||||
|
||||
session->clientHandleToConnection.clear();
|
||||
drm_xe_eudebug_event_client client1;
|
||||
client1.base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client1.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
client1.client_handle = 0x123456789;
|
||||
|
||||
drm_xe_eudebug_event client2;
|
||||
client2.type = DRM_XE_EUDEBUG_EVENT_NONE;
|
||||
client2.flags = 0;
|
||||
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client1));
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client2));
|
||||
EXPECT_EQ(session->clientHandleToConnection.size(), 1ul);
|
||||
EXPECT_NE(session->clientHandleToConnection.find(client1.client_handle), session->clientHandleToConnection.end());
|
||||
|
||||
uint64_t wrongClientHandle = 34;
|
||||
EXPECT_EQ(session->clientHandleToConnection.find(wrongClientHandle), session->clientHandleToConnection.end());
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenEuDebugOpenEventWithEventCreateFlagWhenHandleEventThenNewClientConnectionIsCreated) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, session);
|
||||
|
||||
session->clientHandleToConnection.clear();
|
||||
drm_xe_eudebug_event_client client1;
|
||||
client1.base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client1.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
client1.client_handle = 0x123456789;
|
||||
|
||||
drm_xe_eudebug_event_client client2;
|
||||
client2.base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client2.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
client2.client_handle = 0x123456788;
|
||||
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client1));
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client2));
|
||||
EXPECT_EQ(session->clientHandleToConnection.size(), 2ul);
|
||||
EXPECT_NE(session->clientHandleToConnection.find(client1.client_handle), session->clientHandleToConnection.end());
|
||||
EXPECT_NE(session->clientHandleToConnection.find(client2.client_handle), session->clientHandleToConnection.end());
|
||||
|
||||
uint64_t wrongClientHandle = 34;
|
||||
EXPECT_EQ(session->clientHandleToConnection.find(wrongClientHandle), session->clientHandleToConnection.end());
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenEuDebugOpenEventWithEventDestroyFlagWhenHandleEventThenClientConnectionIsDestroyed) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, session);
|
||||
|
||||
session->clientHandleToConnection.clear();
|
||||
drm_xe_eudebug_event_client client1;
|
||||
client1.base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client1.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
client1.client_handle = 0x123456789;
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client1));
|
||||
EXPECT_EQ(session->clientHandleToConnection.size(), 1ul);
|
||||
EXPECT_NE(session->clientHandleToConnection.find(client1.client_handle), session->clientHandleToConnection.end());
|
||||
|
||||
drm_xe_eudebug_event_client client2;
|
||||
client2.base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client2.base.flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
|
||||
client2.client_handle = client1.client_handle;
|
||||
EXPECT_EQ(session->clientHandleClosed, session->invalidClientHandle);
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client2));
|
||||
EXPECT_EQ(session->clientHandleClosed, client2.client_handle);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenEuDebugExecQueueEventWithEventCreateFlagWhenHandleEventThenExecQueueIsCreated) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, session);
|
||||
|
||||
session->clientHandleToConnection.clear();
|
||||
drm_xe_eudebug_event_client client1;
|
||||
client1.base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client1.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
client1.client_handle = 0x123456789;
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client1));
|
||||
|
||||
uint64_t execQueueData[sizeof(drm_xe_eudebug_event_exec_queue) / sizeof(uint64_t) + 3 * sizeof(typeOfLrcHandle)];
|
||||
auto *lrcHandle = reinterpret_cast<typeOfLrcHandle *>(ptrOffset(execQueueData, sizeof(drm_xe_eudebug_event_exec_queue)));
|
||||
typeOfLrcHandle lrcHandleTemp[3];
|
||||
const uint64_t lrcHandle0 = 2;
|
||||
const uint64_t lrcHandle1 = 3;
|
||||
const uint64_t lrcHandle2 = 5;
|
||||
lrcHandleTemp[0] = static_cast<typeOfLrcHandle>(lrcHandle0);
|
||||
lrcHandleTemp[1] = static_cast<typeOfLrcHandle>(lrcHandle1);
|
||||
lrcHandleTemp[2] = static_cast<typeOfLrcHandle>(lrcHandle2);
|
||||
|
||||
drm_xe_eudebug_event_exec_queue *execQueue = reinterpret_cast<drm_xe_eudebug_event_exec_queue *>(&execQueueData);
|
||||
execQueue->base.type = DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE;
|
||||
execQueue->base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
execQueue->client_handle = client1.client_handle;
|
||||
execQueue->vm_handle = 0x1234;
|
||||
execQueue->exec_queue_handle = 0x100;
|
||||
execQueue->engine_class = DRM_XE_ENGINE_CLASS_COMPUTE;
|
||||
execQueue->width = 3;
|
||||
memcpy(lrcHandle, lrcHandleTemp, sizeof(lrcHandleTemp));
|
||||
session->handleEvent(&execQueue->base);
|
||||
EXPECT_NE(session->clientHandleToConnection.find(execQueue->client_handle), session->clientHandleToConnection.end());
|
||||
EXPECT_EQ(session->clientHandleToConnection[execQueue->client_handle]->execQueues[execQueue->exec_queue_handle].vmHandle,
|
||||
execQueue->vm_handle);
|
||||
EXPECT_EQ(session->clientHandleToConnection[execQueue->client_handle]->execQueues[execQueue->exec_queue_handle].engineClass,
|
||||
DRM_XE_ENGINE_CLASS_COMPUTE);
|
||||
for (uint16_t idx = 0; idx < execQueue->width; idx++) {
|
||||
EXPECT_EQ(session->clientHandleToConnection[execQueue->client_handle]->lrcHandleToVmHandle[execQueue->lrc_handle[idx]],
|
||||
execQueue->vm_handle);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenEuDebugExecQueueEventWithEventDestroyFlagWhenHandleEventThenExecQueueIsDestroyed) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, session);
|
||||
|
||||
session->clientHandleToConnection.clear();
|
||||
drm_xe_eudebug_event_client client1;
|
||||
client1.base.type = DRM_XE_EUDEBUG_EVENT_OPEN;
|
||||
client1.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
client1.client_handle = 0x123456789;
|
||||
session->handleEvent(reinterpret_cast<drm_xe_eudebug_event *>(&client1));
|
||||
|
||||
uint64_t execQueueData[sizeof(drm_xe_eudebug_event_exec_queue) / sizeof(uint64_t) + 3 * sizeof(typeOfLrcHandle)];
|
||||
auto *lrcHandle = reinterpret_cast<typeOfLrcHandle *>(ptrOffset(execQueueData, sizeof(drm_xe_eudebug_event_exec_queue)));
|
||||
typeOfLrcHandle lrcHandleTemp[3];
|
||||
const uint64_t lrcHandle0 = 2;
|
||||
const uint64_t lrcHandle1 = 3;
|
||||
const uint64_t lrcHandle2 = 5;
|
||||
lrcHandleTemp[0] = static_cast<typeOfLrcHandle>(lrcHandle0);
|
||||
lrcHandleTemp[1] = static_cast<typeOfLrcHandle>(lrcHandle1);
|
||||
lrcHandleTemp[2] = static_cast<typeOfLrcHandle>(lrcHandle2);
|
||||
|
||||
// ExecQueue create event handle
|
||||
drm_xe_eudebug_event_exec_queue *execQueue = reinterpret_cast<drm_xe_eudebug_event_exec_queue *>(&execQueueData);
|
||||
execQueue->base.type = DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE;
|
||||
execQueue->base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
|
||||
execQueue->client_handle = client1.client_handle;
|
||||
execQueue->vm_handle = 0x1234;
|
||||
execQueue->exec_queue_handle = 0x100;
|
||||
execQueue->engine_class = DRM_XE_ENGINE_CLASS_COMPUTE;
|
||||
execQueue->width = 3;
|
||||
memcpy(lrcHandle, lrcHandleTemp, sizeof(lrcHandleTemp));
|
||||
session->handleEvent(&execQueue->base);
|
||||
EXPECT_NE(session->clientHandleToConnection.find(execQueue->client_handle), session->clientHandleToConnection.end());
|
||||
EXPECT_EQ(session->clientHandleToConnection[execQueue->client_handle]->execQueues[execQueue->exec_queue_handle].vmHandle,
|
||||
execQueue->vm_handle);
|
||||
EXPECT_EQ(session->clientHandleToConnection[execQueue->client_handle]->execQueues[execQueue->exec_queue_handle].engineClass,
|
||||
DRM_XE_ENGINE_CLASS_COMPUTE);
|
||||
for (uint16_t idx = 0; idx < execQueue->width; idx++) {
|
||||
EXPECT_EQ(session->clientHandleToConnection[execQueue->client_handle]->lrcHandleToVmHandle[execQueue->lrc_handle[idx]],
|
||||
execQueue->vm_handle);
|
||||
}
|
||||
|
||||
// ExecQueue Destroy event handle
|
||||
execQueue->base.type = DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE;
|
||||
execQueue->base.flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
|
||||
execQueue->client_handle = client1.client_handle;
|
||||
execQueue->vm_handle = 0x1234;
|
||||
execQueue->exec_queue_handle = 0x100;
|
||||
execQueue->engine_class = DRM_XE_ENGINE_CLASS_COMPUTE;
|
||||
execQueue->width = 3;
|
||||
session->handleEvent(&execQueue->base);
|
||||
EXPECT_TRUE(session->clientHandleToConnection[execQueue->client_handle]->execQueues.empty());
|
||||
EXPECT_TRUE(session->clientHandleToConnection[execQueue->client_handle]->lrcHandleToVmHandle.empty());
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
Reference in New Issue
Block a user