mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-22 10:17:01 +08:00
refactor: make Debugger ClientConnection common for xe/i915
- Add base ClientConnection type and derived i915/xe types - Add accessor function fo retreive ClientConnection - Move getElfOffset to common linux code - Add accessor functions for getElfSize and getElfData Related-to: NEO-9669 Signed-off-by: Brandon Yates <brandon.yates@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
a05cc69a5a
commit
0fb6f4bf3f
@@ -609,4 +609,44 @@ bool DebugSessionLinux::tryAccessIsa(NEO::DeviceBitfield deviceBitfield, const z
|
||||
return isaAccess;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> DebugSessionLinux::getAllMemoryHandles() {
|
||||
std::vector<uint64_t> allVms;
|
||||
std::unique_lock<std::mutex> memLock(asyncThreadMutex);
|
||||
|
||||
auto &vmIds = getClientConnection(clientHandle)->vmIds;
|
||||
allVms.resize(vmIds.size());
|
||||
std::copy(vmIds.begin(), vmIds.end(), allVms.begin());
|
||||
return allVms;
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionLinux::getElfOffset(const zet_debug_memory_space_desc_t *desc, size_t size, const char *&elfData, uint64_t &offset) {
|
||||
auto clientConnection = getClientConnection(clientHandle);
|
||||
auto &elfMap = clientConnection->elfMap;
|
||||
auto accessVA = desc->address;
|
||||
ze_result_t status = ZE_RESULT_ERROR_UNINITIALIZED;
|
||||
elfData = nullptr;
|
||||
|
||||
if (elfMap.size() > 0) {
|
||||
uint64_t baseVa;
|
||||
uint64_t ceilVa;
|
||||
for (auto &elf : elfMap) {
|
||||
baseVa = elf.first;
|
||||
ceilVa = elf.first + clientConnection->getElfSize(elf.second);
|
||||
if (accessVA >= baseVa && accessVA < ceilVa) {
|
||||
if (accessVA + size > ceilVa) {
|
||||
status = ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
} else {
|
||||
DEBUG_BREAK_IF(clientConnection->getElfData(elf.second) == nullptr);
|
||||
elfData = clientConnection->getElfData(elf.second);
|
||||
offset = accessVA - baseVa;
|
||||
status = ZE_RESULT_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -85,8 +85,34 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
|
||||
ze_result_t readMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer) override;
|
||||
ze_result_t writeMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) override;
|
||||
struct BindInfo {
|
||||
uint64_t gpuVa = 0;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
struct ClientConnection {
|
||||
virtual ~ClientConnection() = default;
|
||||
virtual size_t getElfSize(uint64_t elfHandle) = 0;
|
||||
virtual char *getElfData(uint64_t elfHandle) = 0;
|
||||
|
||||
std::unordered_set<uint64_t> vmIds;
|
||||
|
||||
std::unordered_map<uint64_t, BindInfo> vmToModuleDebugAreaBindInfo;
|
||||
std::unordered_map<uint64_t, BindInfo> vmToContextStateSaveAreaBindInfo;
|
||||
std::unordered_map<uint64_t, BindInfo> vmToStateBaseAreaBindInfo;
|
||||
std::unordered_map<uint64_t, uint32_t> vmToTile;
|
||||
|
||||
std::unordered_map<uint64_t, uint64_t> elfMap;
|
||||
|
||||
uint64_t moduleDebugAreaGpuVa = 0;
|
||||
uint64_t contextStateSaveAreaGpuVa = 0;
|
||||
uint64_t stateBaseAreaGpuVa = 0;
|
||||
|
||||
size_t contextStateSaveAreaSize = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual std::shared_ptr<ClientConnection> getClientConnection(uint64_t clientHandle) = 0;
|
||||
|
||||
enum class ThreadControlCmd {
|
||||
interrupt,
|
||||
resume,
|
||||
@@ -104,7 +130,7 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
ze_result_t resumeImp(const std::vector<EuThread::ThreadId> &threads, uint32_t deviceIndex) override;
|
||||
ze_result_t interruptImp(uint32_t deviceIndex) override;
|
||||
|
||||
virtual ze_result_t getElfOffset(const zet_debug_memory_space_desc_t *desc, size_t size, const char *&elfData, uint64_t &offset) = 0;
|
||||
ze_result_t getElfOffset(const zet_debug_memory_space_desc_t *desc, size_t size, const char *&elfData, uint64_t &offset);
|
||||
ze_result_t readElfSpace(const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer,
|
||||
const char *&elfData, const uint64_t offset);
|
||||
virtual bool tryReadElf(const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer, ze_result_t &status);
|
||||
@@ -120,7 +146,7 @@ struct DebugSessionLinux : DebugSessionImp {
|
||||
virtual ze_result_t getISAVMHandle(uint32_t deviceIndex, const zet_debug_memory_space_desc_t *desc, size_t size, uint64_t &vmHandle) = 0;
|
||||
virtual bool getIsaInfoForAllInstances(NEO::DeviceBitfield deviceBitfield, const zet_debug_memory_space_desc_t *desc, size_t size, uint64_t vmHandles[], ze_result_t &status) = 0;
|
||||
|
||||
virtual std::vector<uint64_t> getAllMemoryHandles() = 0;
|
||||
virtual std::vector<uint64_t> getAllMemoryHandles();
|
||||
|
||||
std::unique_ptr<IoctlHandler> ioctlHandler;
|
||||
uint64_t euControlInterruptSeqno[NEO::EngineLimits::maxHandleCount];
|
||||
|
||||
@@ -307,7 +307,7 @@ void DebugSessionLinuxi915::handleEvent(prelim_drm_i915_debug_event *event) {
|
||||
|
||||
if (event->flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE) {
|
||||
DEBUG_BREAK_IF(clientHandleToConnection.find(clientEvent->handle) != clientHandleToConnection.end());
|
||||
clientHandleToConnection[clientEvent->handle].reset(new ClientConnection);
|
||||
clientHandleToConnection[clientEvent->handle].reset(new ClientConnectioni915);
|
||||
clientHandleToConnection[clientEvent->handle]->client = *clientEvent;
|
||||
}
|
||||
|
||||
@@ -1445,35 +1445,6 @@ void DebugSessionLinuxi915::printContextVms() {
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionLinuxi915::getElfOffset(const zet_debug_memory_space_desc_t *desc, size_t size, const char *&elfData, uint64_t &offset) {
|
||||
auto &elfMap = clientHandleToConnection[clientHandle]->elfMap;
|
||||
auto accessVA = desc->address;
|
||||
ze_result_t status = ZE_RESULT_ERROR_UNINITIALIZED;
|
||||
elfData = nullptr;
|
||||
|
||||
if (elfMap.size() > 0) {
|
||||
uint64_t baseVa;
|
||||
uint64_t ceilVa;
|
||||
for (auto &elf : elfMap) {
|
||||
baseVa = elf.first;
|
||||
ceilVa = elf.first + clientHandleToConnection[clientHandle]->uuidMap[elf.second].dataSize;
|
||||
if (accessVA >= baseVa && accessVA < ceilVa) {
|
||||
if (accessVA + size > ceilVa) {
|
||||
status = ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
} else {
|
||||
DEBUG_BREAK_IF(clientHandleToConnection[clientHandle]->uuidMap[elf.second].data.get() == nullptr);
|
||||
elfData = clientHandleToConnection[clientHandle]->uuidMap[elf.second].data.get();
|
||||
offset = accessVA - baseVa;
|
||||
status = ZE_RESULT_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool DebugSessionLinuxi915::ackIsaEvents(uint32_t deviceIndex, uint64_t isaVa) {
|
||||
std::lock_guard<std::mutex> lock(asyncThreadMutex);
|
||||
|
||||
|
||||
@@ -83,12 +83,6 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
|
||||
|
||||
uint64_t ptr = 0;
|
||||
};
|
||||
|
||||
struct BindInfo {
|
||||
uint64_t gpuVa = 0;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
struct IsaAllocation {
|
||||
BindInfo bindInfo;
|
||||
uint64_t elfUuidHandle;
|
||||
@@ -122,36 +116,31 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
|
||||
return memcmp(&event1, &event2, sizeof(zet_debug_event_t)) == 0;
|
||||
};
|
||||
|
||||
struct ClientConnection {
|
||||
struct ClientConnectioni915 : public ClientConnection {
|
||||
prelim_drm_i915_debug_event_client client = {};
|
||||
|
||||
size_t getElfSize(uint64_t elfHandle) override { return uuidMap[elfHandle].dataSize; };
|
||||
char *getElfData(uint64_t elfHandle) override { return uuidMap[elfHandle].data.get(); };
|
||||
|
||||
std::unordered_map<ContextHandle, ContextParams> contextsCreated;
|
||||
std::unordered_map<uint64_t, std::pair<std::string, uint32_t>> classHandleToIndex;
|
||||
std::unordered_map<uint64_t, UuidData> uuidMap;
|
||||
std::unordered_set<uint64_t> vmIds;
|
||||
|
||||
std::unordered_map<uint64_t, BindInfo> vmToModuleDebugAreaBindInfo;
|
||||
std::unordered_map<uint64_t, BindInfo> vmToContextStateSaveAreaBindInfo;
|
||||
std::unordered_map<uint64_t, BindInfo> vmToStateBaseAreaBindInfo;
|
||||
std::unordered_map<uint64_t, uint32_t> vmToTile;
|
||||
|
||||
std::unordered_map<uint64_t, std::unique_ptr<IsaAllocation>> isaMap[NEO::EngineLimits::maxHandleCount];
|
||||
std::unordered_map<uint64_t, uint64_t> elfMap;
|
||||
std::unordered_map<uint64_t, ContextHandle> lrcToContextHandle;
|
||||
|
||||
uint64_t moduleDebugAreaGpuVa = 0;
|
||||
uint64_t contextStateSaveAreaGpuVa = 0;
|
||||
uint64_t stateBaseAreaGpuVa = 0;
|
||||
|
||||
size_t contextStateSaveAreaSize = 0;
|
||||
|
||||
std::unordered_map<uint64_t, Module> uuidToModule;
|
||||
};
|
||||
|
||||
std::shared_ptr<ClientConnection> getClientConnection(uint64_t clientHandle) override {
|
||||
return clientHandleToConnection[clientHandle];
|
||||
};
|
||||
|
||||
protected:
|
||||
MOCKABLE_VIRTUAL void handleEvent(prelim_drm_i915_debug_event *event);
|
||||
bool checkAllEventsCollected();
|
||||
std::unordered_map<uint64_t, std::unique_ptr<ClientConnection>> clientHandleToConnection;
|
||||
std::unordered_map<uint64_t, std::shared_ptr<ClientConnectioni915>> clientHandleToConnection;
|
||||
|
||||
ze_result_t readEventImp(prelim_drm_i915_debug_event *drmDebugEvent);
|
||||
|
||||
void enqueueApiEvent(zet_debug_event_t &debugEvent) override {
|
||||
@@ -181,16 +170,6 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
|
||||
static void *asyncThreadFunction(void *arg);
|
||||
void startAsyncThread() override;
|
||||
|
||||
std::vector<uint64_t> getAllMemoryHandles() override {
|
||||
std::vector<uint64_t> allVms;
|
||||
std::unique_lock<std::mutex> memLock(asyncThreadMutex);
|
||||
|
||||
auto &vmIds = clientHandleToConnection[clientHandle]->vmIds;
|
||||
allVms.resize(vmIds.size());
|
||||
std::copy(vmIds.begin(), vmIds.end(), allVms.begin());
|
||||
return allVms;
|
||||
}
|
||||
|
||||
void handleEventsAsync();
|
||||
|
||||
uint64_t getVmHandleFromClientAndlrcHandle(uint64_t clientHandle, uint64_t lrcHandle);
|
||||
@@ -201,7 +180,6 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
|
||||
void handlePageFaultEvent(prelim_drm_i915_debug_event_page_fault *pf);
|
||||
virtual bool ackIsaEvents(uint32_t deviceIndex, uint64_t isaVa);
|
||||
virtual bool ackModuleEvents(uint32_t deviceIndex, uint64_t moduleUuidHandle);
|
||||
ze_result_t getElfOffset(const zet_debug_memory_space_desc_t *desc, size_t size, const char *&elfData, uint64_t &offset) override;
|
||||
|
||||
MOCKABLE_VIRTUAL void processPendingVmBindEvents();
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *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].reset(new ClientConnectionXe);
|
||||
clientHandleToConnection[clientEvent->client_handle]->client = *clientEvent;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,13 +78,12 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
|
||||
uint16_t engineClass = UINT16_MAX;
|
||||
};
|
||||
|
||||
struct BindInfo {
|
||||
uint64_t gpuVa = 0;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
uint32_t xeDebuggerVersion = 0;
|
||||
|
||||
std::shared_ptr<ClientConnection> getClientConnection(uint64_t clientHandle) override {
|
||||
return clientHandleToConnection[clientHandle];
|
||||
};
|
||||
|
||||
protected:
|
||||
int euControlIoctl(ThreadControlCmd threadCmd,
|
||||
const NEO::EngineClassInstance *classInstance,
|
||||
@@ -143,26 +142,25 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
|
||||
UNRECOVERABLE_IF(true);
|
||||
}
|
||||
|
||||
struct ClientConnection {
|
||||
struct ClientConnectionXe : public ClientConnection {
|
||||
drm_xe_eudebug_event_client client = {};
|
||||
size_t getElfSize(uint64_t elfHandle) override { return 0; };
|
||||
char *getElfData(uint64_t elfHandle) override { return nullptr; };
|
||||
|
||||
std::unordered_map<ExecQueueHandle, ExecQueueParams> execQueues;
|
||||
std::unordered_map<uint64_t, uint64_t> lrcHandleToVmHandle;
|
||||
std::unordered_map<uint64_t, BindInfo> vmToModuleDebugAreaBindInfo;
|
||||
std::unordered_set<uint64_t> vmIds;
|
||||
};
|
||||
std::unordered_map<uint64_t, std::shared_ptr<ClientConnectionXe>> clientHandleToConnection;
|
||||
|
||||
std::vector<std::unique_ptr<uint64_t[]>> pendingVmBindEvents;
|
||||
bool checkAllEventsCollected();
|
||||
MOCKABLE_VIRTUAL void handleEvent(drm_xe_eudebug_event *event);
|
||||
void readInternalEventsAsync() override;
|
||||
void pushApiEvent(zet_debug_event_t &debugEvent);
|
||||
ze_result_t getElfOffset(const zet_debug_memory_space_desc_t *desc, size_t size, const char *&elfData, uint64_t &offset) override { return ZE_RESULT_ERROR_UNKNOWN; };
|
||||
ze_result_t getISAVMHandle(uint32_t deviceIndex, const zet_debug_memory_space_desc_t *desc, size_t size, uint64_t &vmHandle) override { return ZE_RESULT_ERROR_UNKNOWN; };
|
||||
bool getIsaInfoForAllInstances(NEO::DeviceBitfield deviceBitfield, const zet_debug_memory_space_desc_t *desc, size_t size, uint64_t vmHandles[], ze_result_t &status) override { return false; };
|
||||
|
||||
std::unordered_map<uint64_t, std::unique_ptr<ClientConnection>> clientHandleToConnection;
|
||||
std::atomic<bool> detached{false};
|
||||
std::vector<uint64_t> getAllMemoryHandles() override { return {}; };
|
||||
|
||||
ze_result_t readEventImp(drm_xe_eudebug_event *drmDebugEvent);
|
||||
int ioctl(unsigned long request, void *arg);
|
||||
|
||||
@@ -199,7 +199,7 @@ struct MockDebugSessionLinuxi915 : public L0::DebugSessionLinuxi915 {
|
||||
using L0::DebugSessionLinuxi915::writeGpuMemory;
|
||||
|
||||
MockDebugSessionLinuxi915(const zet_debug_config_t &config, L0::Device *device, int debugFd, void *params) : DebugSessionLinuxi915(config, device, debugFd, params) {
|
||||
clientHandleToConnection[mockClientHandle].reset(new ClientConnection);
|
||||
clientHandleToConnection[mockClientHandle].reset(new ClientConnectioni915);
|
||||
clientHandle = mockClientHandle;
|
||||
createEuThreads();
|
||||
}
|
||||
|
||||
@@ -907,7 +907,7 @@ TEST_F(DebugApiLinuxTest, GivenCommandQueueDestroyedWhenHandlingEventThenExitEve
|
||||
|
||||
auto handler = new MockIoctlHandlerI915;
|
||||
session->ioctlHandler.reset(handler);
|
||||
session->clientHandleToConnection[10u].reset(new L0::DebugSessionLinuxi915::ClientConnection);
|
||||
session->clientHandleToConnection[10u].reset(new L0::DebugSessionLinuxi915::ClientConnectioni915);
|
||||
|
||||
session->handleEvent(&uuid.base);
|
||||
EXPECT_EQ(0u, session->apiEvents.size());
|
||||
@@ -944,7 +944,7 @@ TEST_F(DebugApiLinuxTest, GivenDestroyClientForClientNotSavedWhenHandlingEventTh
|
||||
|
||||
auto handler = new MockIoctlHandlerI915;
|
||||
session->ioctlHandler.reset(handler);
|
||||
session->clientHandleToConnection[10u].reset(new L0::DebugSessionLinuxi915::ClientConnection);
|
||||
session->clientHandleToConnection[10u].reset(new L0::DebugSessionLinuxi915::ClientConnectioni915);
|
||||
|
||||
session->handleEvent(&clientDestroy.base);
|
||||
EXPECT_EQ(0u, session->apiEvents.size());
|
||||
|
||||
@@ -127,6 +127,7 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe {
|
||||
using L0::DebugSessionImp::allThreads;
|
||||
using L0::DebugSessionImp::apiEvents;
|
||||
using L0::DebugSessionImp::stateSaveAreaHeader;
|
||||
using L0::DebugSessionLinux::getClientConnection;
|
||||
using L0::DebugSessionLinuxXe::asyncThread;
|
||||
using L0::DebugSessionLinuxXe::asyncThreadFunction;
|
||||
using L0::DebugSessionLinuxXe::checkStoppedThreadsAndGenerateEvents;
|
||||
@@ -145,7 +146,7 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe {
|
||||
using L0::DebugSessionLinuxXe::ThreadControlCmd;
|
||||
|
||||
MockDebugSessionLinuxXe(const zet_debug_config_t &config, L0::Device *device, int debugFd, void *params) : DebugSessionLinuxXe(config, device, debugFd, params) {
|
||||
clientHandleToConnection[mockClientHandle].reset(new ClientConnection);
|
||||
clientHandleToConnection[mockClientHandle].reset(new ClientConnectionXe);
|
||||
clientHandle = mockClientHandle;
|
||||
createEuThreads();
|
||||
}
|
||||
|
||||
@@ -1036,5 +1036,18 @@ TEST_F(DebugApiLinuxTestXe, GivenNoAttentionBitsWhenMultipleThreadsPassedToCheck
|
||||
EXPECT_EQ(0u, sessionMock->apiEvents.size());
|
||||
}
|
||||
|
||||
TEST_F(DebugApiLinuxTestXe, GivenNoElfDataImplementationThenGetElfDataReturnsNullptr) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
uint64_t elfHandle = 0;
|
||||
auto sessionMock = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
|
||||
ASSERT_NE(nullptr, sessionMock);
|
||||
|
||||
auto clientConnection = sessionMock->getClientConnection(MockDebugSessionLinuxXe::mockClientHandle);
|
||||
ASSERT_NE(nullptr, clientConnection);
|
||||
ASSERT_EQ(nullptr, clientConnection->getElfData(elfHandle));
|
||||
ASSERT_EQ(0u, clientConnection->getElfSize(elfHandle));
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
Reference in New Issue
Block a user