2022-05-09 15:52:12 +00:00
/*
2024-01-18 18:39:41 +00:00
* Copyright ( C ) 2022 - 2024 Intel Corporation
2022-05-09 15:52:12 +00:00
*
* SPDX - License - Identifier : MIT
*
*/
# include "level_zero/tools/source/debug/linux/prelim/debug_session.h"
2022-08-05 12:46:52 +00:00
# include "shared/source/built_ins/sip.h"
2022-05-09 15:52:12 +00:00
# include "shared/source/debug_settings/debug_settings_manager.h"
2022-07-24 04:21:16 +00:00
# include "shared/source/gmm_helper/gmm_helper.h"
2023-01-02 09:56:45 +00:00
# include "shared/source/helpers/aligned_memory.h"
2022-05-09 15:52:12 +00:00
# include "shared/source/helpers/array_count.h"
2023-02-07 12:53:53 +00:00
# include "shared/source/helpers/hw_info.h"
2023-03-14 17:38:46 +00:00
# include "shared/source/helpers/sleep.h"
2022-05-09 15:52:12 +00:00
# include "shared/source/helpers/string.h"
# include "shared/source/memory_manager/memory_manager.h"
# include "shared/source/os_interface/linux/drm_debug.h"
# include "shared/source/os_interface/linux/ioctl_helper.h"
# include "shared/source/os_interface/os_interface.h"
# include "shared/source/os_interface/os_thread.h"
# include "level_zero/core/source/device/device.h"
# include "level_zero/core/source/device/device_imp.h"
2023-02-02 03:54:41 +00:00
# include "level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h"
2022-05-09 15:52:12 +00:00
# include "level_zero/include/zet_intel_gpu_debug.h"
2023-10-19 20:35:35 +00:00
# include "level_zero/tools/source/debug/linux/debug_session_factory.h"
2023-10-23 23:35:40 +00:00
# include "level_zero/tools/source/debug/linux/drm_helper.h"
2022-05-09 15:52:12 +00:00
# include <level_zero/ze_api.h>
# include "common/StateSaveAreaHeader.h"
# include <algorithm>
# include <fcntl.h>
namespace L0 {
2023-10-19 20:35:35 +00:00
static DebugSessionLinuxPopulateFactory < DEBUG_SESSION_LINUX_TYPE_I915 , DebugSessionLinuxi915 >
populatei915Debugger ;
2022-11-14 15:52:05 +00:00
DebugSession * createDebugSessionHelper ( const zet_debug_config_t & config , Device * device , int debugFd , void * params ) ;
2022-05-09 15:52:12 +00:00
2023-12-05 21:03:49 +00:00
DebugSessionLinuxi915 : : DebugSessionLinuxi915 ( const zet_debug_config_t & config , Device * device , int debugFd , void * params ) : DebugSessionLinux ( config , device , debugFd ) {
ioctlHandler . reset ( new IoctlHandleri915 ) ;
2022-05-09 15:52:12 +00:00
2022-11-14 15:52:05 +00:00
if ( params ) {
this - > i915DebuggerVersion = reinterpret_cast < prelim_drm_i915_debugger_open_param * > ( params ) - > version ;
}
if ( this - > i915DebuggerVersion > = 3 ) {
this - > blockOnFenceMode = true ;
}
2022-05-09 15:52:12 +00:00
for ( size_t i = 0 ; i < arrayCount ( euControlInterruptSeqno ) ; i + + ) {
euControlInterruptSeqno [ i ] = invalidHandle ;
}
} ;
2023-10-06 01:16:32 +00:00
DebugSessionLinuxi915 : : ~ DebugSessionLinuxi915 ( ) {
2022-05-09 15:52:12 +00:00
closeAsyncThread ( ) ;
2022-06-02 09:09:31 +00:00
closeInternalEventsThread ( ) ;
2022-07-29 11:26:12 +00:00
for ( auto & session : tileSessions ) {
delete session . first ;
}
tileSessions . resize ( 0 ) ;
2022-08-24 12:03:47 +00:00
closeFd ( ) ;
2022-05-09 15:52:12 +00:00
}
2023-10-19 20:35:35 +00:00
DebugSession * DebugSessionLinuxi915 : : createLinuxSession ( const zet_debug_config_t & config , Device * device , ze_result_t & result , bool isRootAttach ) {
struct prelim_drm_i915_debugger_open_param open = { } ;
open . pid = config . pid ;
open . events = 0 ;
open . version = 0 ;
2023-12-12 08:48:32 +00:00
auto debugFd = DrmHelper : : ioctl ( device , NEO : : DrmIoctl : : debuggerOpen , & open ) ;
2023-10-19 20:35:35 +00:00
if ( debugFd > = 0 ) {
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_DRM_IOCTL_I915_DEBUGGER_OPEN: open.pid: %d, open.events: %d, debugFd: %d \n " ,
open . pid , open . events , debugFd ) ;
return createDebugSessionHelper ( config , device , debugFd , & open ) ;
2022-05-09 15:52:12 +00:00
} else {
2023-10-19 20:35:35 +00:00
auto reason = DrmHelper : : getErrno ( device ) ;
PRINT_DEBUGGER_ERROR_LOG ( " PRELIM_DRM_IOCTL_I915_DEBUGGER_OPEN failed: open.pid: %d, open.events: %d, retCode: %d, errno: %d \n " ,
open . pid , open . events , debugFd , reason ) ;
2023-10-23 23:35:40 +00:00
result = translateDebuggerOpenErrno ( reason ) ;
2022-05-09 15:52:12 +00:00
}
return nullptr ;
}
2023-10-06 01:16:32 +00:00
int DebugSessionLinuxi915 : : ioctl ( unsigned long request , void * arg ) {
2022-05-09 15:52:12 +00:00
return ioctlHandler - > ioctl ( fd , request , arg ) ;
}
2024-02-06 22:01:29 +00:00
int DebugSessionLinuxi915 : : openVmFd ( uint64_t vmHandle , bool readOnly ) {
uint64_t flags = static_cast < decltype ( prelim_drm_i915_debug_vm_open : : flags ) > ( readOnly ? PRELIM_I915_DEBUG_VM_OPEN_READ_ONLY : PRELIM_I915_DEBUG_VM_OPEN_READ_WRITE ) ;
2022-05-09 15:52:12 +00:00
prelim_drm_i915_debug_vm_open vmOpen = {
. client_handle = static_cast < decltype ( prelim_drm_i915_debug_vm_open : : client_handle ) > ( clientHandle ) ,
. handle = static_cast < decltype ( prelim_drm_i915_debug_vm_open : : handle ) > ( vmHandle ) ,
2024-02-06 22:01:29 +00:00
. flags = flags } ;
2022-05-09 15:52:12 +00:00
2024-02-06 22:01:29 +00:00
return ioctl ( PRELIM_I915_DEBUG_IOCTL_VM_OPEN , & vmOpen ) ;
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
ze_result_t DebugSessionLinuxi915 : : initialize ( ) {
2022-05-09 15:52:12 +00:00
struct pollfd pollFd = {
. fd = this - > fd ,
. events = POLLIN ,
. revents = 0 ,
} ;
auto numberOfFds = ioctlHandler - > poll ( & pollFd , 1 , 1000 ) ;
PRINT_DEBUGGER_INFO_LOG ( " initialization poll() retCode: %d \n " , numberOfFds ) ;
if ( numberOfFds < = 0 ) {
return ZE_RESULT_NOT_READY ;
}
2022-09-23 14:56:32 +00:00
bool isRootDevice = ! connectedDevice - > getNEODevice ( ) - > isSubDevice ( ) ;
if ( isRootDevice & & ! tileAttachEnabled ) {
createEuThreads ( ) ;
}
2022-08-16 18:21:08 +00:00
createTileSessionsIfEnabled ( ) ;
2022-06-02 09:09:31 +00:00
startInternalEventsThread ( ) ;
2022-05-09 15:52:12 +00:00
bool allEventsCollected = false ;
2022-10-18 11:49:16 +00:00
bool eventAvailable = true ;
float timeDelta = 0 ;
float timeStart = clock ( ) ;
2022-05-09 15:52:12 +00:00
do {
2022-10-18 11:49:16 +00:00
if ( internalThreadHasStarted ) {
auto eventMemory = getInternalEvent ( ) ;
auto debugEvent = reinterpret_cast < prelim_drm_i915_debug_event * > ( eventMemory . get ( ) ) ;
if ( eventMemory ! = nullptr ) {
handleEvent ( debugEvent ) ;
if ( debugEvent - > type ! = PRELIM_DRM_I915_DEBUG_EVENT_VM_BIND & & pendingVmBindEvents . size ( ) > 0 ) {
processPendingVmBindEvents ( ) ;
}
eventAvailable = true ;
} else {
eventAvailable = false ;
2022-09-29 16:07:22 +00:00
}
2022-10-18 11:49:16 +00:00
allEventsCollected = checkAllEventsCollected ( ) ;
2022-06-02 09:09:31 +00:00
} else {
2022-10-18 11:49:16 +00:00
timeDelta = float ( clock ( ) - timeStart ) / CLOCKS_PER_SEC ;
2022-06-02 09:09:31 +00:00
}
2023-01-16 17:47:59 +00:00
} while ( ( eventAvailable & & ! allEventsCollected ) & & timeDelta < getThreadStartLimitTime ( ) ) ;
2022-05-09 15:52:12 +00:00
2022-10-18 11:49:16 +00:00
internalThreadHasStarted = false ;
2022-05-09 15:52:12 +00:00
if ( clientHandleClosed = = clientHandle & & clientHandle ! = invalidClientHandle ) {
return ZE_RESULT_ERROR_DEVICE_LOST ;
}
if ( allEventsCollected ) {
if ( ! readModuleDebugArea ( ) ) {
return ZE_RESULT_ERROR_UNKNOWN ;
}
return ZE_RESULT_SUCCESS ;
}
return ZE_RESULT_NOT_READY ;
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : createTileSessionsIfEnabled ( ) {
2022-08-16 18:21:08 +00:00
auto numTiles = connectedDevice - > getNEODevice ( ) - > getNumSubDevices ( ) ;
if ( numTiles > 0 & & tileAttachEnabled ) {
tileSessions . resize ( numTiles ) ;
for ( uint32_t i = 0 ; i < numTiles ; i + + ) {
auto subDevice = connectedDevice - > getNEODevice ( ) - > getSubDevice ( i ) - > getSpecializedDevice < Device > ( ) ;
2022-08-19 15:11:22 +00:00
tileSessions [ i ] = std : : pair < DebugSessionImp * , bool > { createTileSession ( config , subDevice , this ) , false } ;
2022-08-16 18:21:08 +00:00
}
tileSessionsEnabled = true ;
}
}
2023-10-06 01:16:32 +00:00
TileDebugSessionLinuxi915 * DebugSessionLinuxi915 : : createTileSession ( const zet_debug_config_t & config , Device * device , DebugSessionImp * rootDebugSession ) {
auto tileSession = new TileDebugSessionLinuxi915 ( config , device , rootDebugSession ) ;
2022-09-23 14:56:32 +00:00
tileSession - > initialize ( ) ;
return tileSession ;
2022-08-16 18:21:08 +00:00
}
2023-10-06 01:16:32 +00:00
void * DebugSessionLinuxi915 : : asyncThreadFunction ( void * arg ) {
DebugSessionLinuxi915 * self = reinterpret_cast < DebugSessionLinuxi915 * > ( arg ) ;
2022-05-09 15:52:12 +00:00
PRINT_DEBUGGER_INFO_LOG ( " Debugger async thread start \n " , " " ) ;
2022-05-30 14:24:47 +00:00
while ( self - > asyncThread . threadActive ) {
2022-06-02 09:09:31 +00:00
self - > handleEventsAsync ( ) ;
2022-05-09 15:52:12 +00:00
2022-08-19 15:11:22 +00:00
if ( self - > tileSessionsEnabled ) {
for ( size_t tileIndex = 0 ; tileIndex < self - > tileSessions . size ( ) ; tileIndex + + ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( self - > tileSessions [ tileIndex ] . first ) - > generateEventsAndResumeStoppedThreads ( ) ;
static_cast < TileDebugSessionLinuxi915 * > ( self - > tileSessions [ tileIndex ] . first ) - > sendInterrupts ( ) ;
2022-08-19 15:11:22 +00:00
}
} else {
self - > generateEventsAndResumeStoppedThreads ( ) ;
2023-04-03 16:45:59 +00:00
self - > sendInterrupts ( ) ;
2022-08-19 15:11:22 +00:00
}
2022-05-09 15:52:12 +00:00
}
PRINT_DEBUGGER_INFO_LOG ( " Debugger async thread closing \n " , " " ) ;
return nullptr ;
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : startAsyncThread ( ) {
2022-05-30 14:24:47 +00:00
asyncThread . thread = NEO : : Thread : : create ( asyncThreadFunction , reinterpret_cast < void * > ( this ) ) ;
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : handleEventsAsync ( ) {
2022-06-02 09:09:31 +00:00
auto eventMemory = getInternalEvent ( ) ;
if ( eventMemory ! = nullptr ) {
2022-09-29 16:07:22 +00:00
auto debugEvent = reinterpret_cast < prelim_drm_i915_debug_event * > ( eventMemory . get ( ) ) ;
handleEvent ( debugEvent ) ;
if ( debugEvent - > type ! = PRELIM_DRM_I915_DEBUG_EVENT_VM_BIND & & pendingVmBindEvents . size ( ) > 0 ) {
processPendingVmBindEvents ( ) ;
}
2022-06-02 09:09:31 +00:00
}
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : readInternalEventsAsync ( ) {
2022-06-02 09:09:31 +00:00
2022-05-09 15:52:12 +00:00
struct pollfd pollFd = {
. fd = fd ,
. events = POLLIN ,
. revents = 0 ,
} ;
int pollTimeout = 1000 ;
auto numberOfFds = ioctlHandler - > poll ( & pollFd , 1 , pollTimeout ) ;
PRINT_DEBUGGER_INFO_LOG ( " Debugger async thread readEvent poll() retCode: %d \n " , numberOfFds ) ;
2022-06-02 09:09:31 +00:00
if ( ! detached & & numberOfFds < 0 & & errno = = EINVAL ) {
2022-05-09 15:52:12 +00:00
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_DETACHED ;
debugEvent . info . detached . reason = ZET_DEBUG_DETACH_REASON_INVALID ;
PRINT_DEBUGGER_INFO_LOG ( " Debugger detached \n " , " " ) ;
2022-08-16 18:21:08 +00:00
if ( tileSessionsEnabled ) {
auto numTiles = connectedDevice - > getNEODevice ( ) - > getNumSubDevices ( ) ;
for ( uint32_t tileIndex = 0 ; tileIndex < numTiles ; tileIndex + + ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > pushApiEvent ( debugEvent ) ;
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > detached = true ;
2022-08-16 18:21:08 +00:00
}
} else {
2022-11-14 15:52:05 +00:00
pushApiEvent ( debugEvent ) ;
2022-08-16 18:21:08 +00:00
}
2022-05-09 15:52:12 +00:00
detached = true ;
} else if ( numberOfFds > 0 ) {
ze_result_t result = ZE_RESULT_SUCCESS ;
int maxLoopCount = 3 ;
do {
2022-06-02 09:09:31 +00:00
uint8_t maxEventBuffer [ sizeof ( prelim_drm_i915_debug_event ) + maxEventSize ] ;
auto event = reinterpret_cast < prelim_drm_i915_debug_event * > ( maxEventBuffer ) ;
event - > size = maxEventSize ;
2022-05-09 15:52:12 +00:00
event - > type = PRELIM_DRM_I915_DEBUG_EVENT_READ ;
event - > flags = 0 ;
result = readEventImp ( event ) ;
maxLoopCount - - ;
2022-06-02 09:09:31 +00:00
if ( result = = ZE_RESULT_SUCCESS ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( internalEventThreadMutex ) ;
2022-06-02 09:09:31 +00:00
auto memory = std : : make_unique < uint64_t [ ] > ( maxEventSize / sizeof ( uint64_t ) ) ;
memcpy ( memory . get ( ) , event , maxEventSize ) ;
internalEventQueue . push ( std : : move ( memory ) ) ;
internalEventCondition . notify_one ( ) ;
}
2022-05-09 15:52:12 +00:00
} while ( result = = ZE_RESULT_SUCCESS & & maxLoopCount > 0 ) ;
}
}
2023-10-06 01:16:32 +00:00
bool DebugSessionLinuxi915 : : closeConnection ( ) {
2022-05-09 15:52:12 +00:00
closeAsyncThread ( ) ;
2022-08-24 12:03:47 +00:00
closeInternalEventsThread ( ) ;
2023-05-09 15:20:35 +00:00
if ( clientHandle ! = invalidClientHandle ) {
auto numTiles = std : : max ( 1u , connectedDevice - > getNEODevice ( ) - > getNumSubDevices ( ) ) ;
for ( uint32_t i = 0 ; i < numTiles ; i + + ) {
for ( const auto & eventToAck : eventsToAck ) {
auto moduleUUID = eventToAck . second ;
ackModuleEvents ( i , moduleUUID ) ;
}
cleanRootSessionAfterDetach ( i ) ;
}
}
2022-08-24 12:03:47 +00:00
return closeFd ( ) ;
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : handleEvent ( prelim_drm_i915_debug_event * event ) {
2022-05-09 15:52:12 +00:00
auto type = event - > type ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type = %lu flags = %d seqno = %llu size = %llu " ,
( uint32_t ) event - > type , ( int ) event - > flags , ( uint64_t ) event - > seqno , ( uint64_t ) event - > size ) ;
switch ( type ) {
case PRELIM_DRM_I915_DEBUG_EVENT_CLIENT : {
auto clientEvent = reinterpret_cast < prelim_drm_i915_debug_event_client * > ( event ) ;
if ( event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE ) {
DEBUG_BREAK_IF ( clientHandleToConnection . find ( clientEvent - > handle ) ! = clientHandleToConnection . end ( ) ) ;
2024-02-13 21:49:56 +00:00
clientHandleToConnection [ clientEvent - > handle ] . reset ( new ClientConnectioni915 ) ;
2022-05-09 15:52:12 +00:00
clientHandleToConnection [ clientEvent - > handle ] - > client = * clientEvent ;
}
if ( event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_DESTROY ) {
clientHandleClosed = clientEvent - > handle ;
}
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_CLIENT flags = %d size = %llu client.handle = %llu \n " ,
( int ) event - > flags , ( uint64_t ) event - > size , ( uint64_t ) clientEvent - > handle ) ;
} break ;
case PRELIM_DRM_I915_DEBUG_EVENT_CONTEXT : {
prelim_drm_i915_debug_event_context * context = reinterpret_cast < prelim_drm_i915_debug_event_context * > ( event ) ;
if ( event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE ) {
UNRECOVERABLE_IF ( clientHandleToConnection . find ( context - > client_handle ) = = clientHandleToConnection . end ( ) ) ;
clientHandleToConnection [ context - > client_handle ] - > contextsCreated [ context - > handle ] . handle = context - > handle ;
}
if ( event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_DESTROY ) {
clientHandleToConnection [ context - > client_handle ] - > contextsCreated . erase ( context - > handle ) ;
}
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_CONTEXT flags = %d size = %llu client_handle = %llu handle = %llu \n " ,
( int ) event - > flags , ( uint64_t ) event - > size , ( uint64_t ) context - > client_handle , ( uint64_t ) context - > handle ) ;
} break ;
case PRELIM_DRM_I915_DEBUG_EVENT_UUID : {
prelim_drm_i915_debug_event_uuid * uuid = reinterpret_cast < prelim_drm_i915_debug_event_uuid * > ( event ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_UUID flags = %d size = %llu client_handle = %llu handle = %llu class_handle = %llu payload_size = %llu \n " ,
( int ) event - > flags , ( uint64_t ) event - > size , ( uint64_t ) uuid - > client_handle , ( uint64_t ) uuid - > handle , ( uint64_t ) uuid - > class_handle , ( uint64_t ) uuid - > payload_size ) ;
bool destroy = event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_DESTROY ;
bool create = event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE ;
2023-12-19 10:42:58 +00:00
if ( destroy & & clientHandleToConnection [ uuid - > client_handle ] - > uuidMap [ uuid - > handle ] . classIndex = = NEO : : DrmResourceClass : : l0ZebinModule ) {
2022-08-08 12:15:29 +00:00
DEBUG_BREAK_IF ( clientHandleToConnection [ uuid - > client_handle ] - > uuidToModule [ uuid - > handle ] . segmentVmBindCounter [ 0 ] ! = 0 | |
clientHandleToConnection [ uuid - > client_handle ] - > uuidToModule [ uuid - > handle ] . loadAddresses [ 0 ] . size ( ) > 0 ) ;
2022-05-09 15:52:12 +00:00
clientHandleToConnection [ uuid - > client_handle ] - > uuidToModule . erase ( uuid - > handle ) ;
}
2022-07-22 12:07:36 +00:00
if ( destroy & & ( clientHandle = = uuid - > client_handle ) ) {
for ( const auto & uuidToDevice : uuidL0CommandQueueHandleToDevice ) {
if ( uuidToDevice . first = = uuid - > handle ) {
2022-08-16 18:21:08 +00:00
auto deviceIndex = uuidToDevice . second ;
2022-07-22 12:07:36 +00:00
uuidL0CommandQueueHandleToDevice . erase ( uuidToDevice . first ) ;
2022-08-16 18:21:08 +00:00
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_PROCESS_EXIT ;
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
auto tileSession = reinterpret_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ deviceIndex ] . first ) ;
2022-11-14 15:52:05 +00:00
tileSession - > processExit ( ) ;
tileSession - > pushApiEvent ( debugEvent ) ;
2022-08-16 18:21:08 +00:00
} else if ( uuidL0CommandQueueHandleToDevice . size ( ) = = 0 ) {
2022-11-14 15:52:05 +00:00
pushApiEvent ( debugEvent ) ;
2022-07-22 12:07:36 +00:00
}
2022-08-16 18:21:08 +00:00
2022-07-22 12:07:36 +00:00
break ;
}
}
2022-05-09 15:52:12 +00:00
break ;
}
if ( create ) {
const auto & connection = clientHandleToConnection [ uuid - > client_handle ] ;
if ( uuid - > payload_size ) {
prelim_drm_i915_debug_read_uuid readUuid = { } ;
auto payload = std : : make_unique < char [ ] > ( uuid - > payload_size ) ;
readUuid . client_handle = uuid - > client_handle ;
readUuid . handle = static_cast < decltype ( readUuid . handle ) > ( uuid - > handle ) ;
readUuid . payload_ptr = reinterpret_cast < uint64_t > ( payload . get ( ) ) ;
readUuid . payload_size = uuid - > payload_size ;
2023-01-18 20:22:32 +00:00
auto ret = ioctl ( PRELIM_I915_DEBUG_IOCTL_READ_UUID , & readUuid ) ;
2022-05-09 15:52:12 +00:00
2023-01-18 20:22:32 +00:00
if ( ret = = 0 ) {
2022-05-09 15:52:12 +00:00
std : : string uuidString = std : : string ( readUuid . uuid , 36 ) ;
2023-12-19 10:42:58 +00:00
uint32_t classIndex = static_cast < uint32_t > ( NEO : : DrmResourceClass : : maxSize ) ;
2022-05-09 15:52:12 +00:00
auto validClassUuid = NEO : : DrmUuid : : getClassUuidIndex ( uuidString , classIndex ) ;
if ( uuidString = = NEO : : uuidL0CommandQueueHash ) {
if ( ( clientHandle = = invalidClientHandle ) | | ( clientHandle = = uuid - > client_handle ) ) {
clientHandle = uuid - > client_handle ;
2022-07-22 12:07:36 +00:00
uint32_t deviceIndex = 0 ;
if ( readUuid . payload_size = = sizeof ( NEO : : DebuggerL0 : : CommandQueueNotification ) ) {
auto notification = reinterpret_cast < NEO : : DebuggerL0 : : CommandQueueNotification * > ( payload . get ( ) ) ;
deviceIndex = notification - > subDeviceIndex ;
UNRECOVERABLE_IF ( notification - > subDeviceCount > 0 & & notification - > subDeviceIndex > = notification - > subDeviceCount ) ;
}
2022-08-16 18:21:08 +00:00
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_PROCESS_ENTRY ;
if ( tileSessionsEnabled ) {
UNRECOVERABLE_IF ( uuidL0CommandQueueHandleToDevice . find ( uuid - > handle ) ! = uuidL0CommandQueueHandleToDevice . end ( ) ) ;
2023-10-06 01:16:32 +00:00
auto tileSession = static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ deviceIndex ] . first ) ;
2022-11-14 15:52:05 +00:00
tileSession - > processEntry ( ) ;
tileSession - > pushApiEvent ( debugEvent ) ;
2022-08-16 18:21:08 +00:00
} else if ( uuidL0CommandQueueHandleToDevice . size ( ) = = 0 ) {
2022-11-14 15:52:05 +00:00
pushApiEvent ( debugEvent ) ;
2022-07-22 12:07:36 +00:00
}
uuidL0CommandQueueHandleToDevice [ uuid - > handle ] = deviceIndex ;
2022-05-09 15:52:12 +00:00
}
}
if ( validClassUuid ) {
if ( clientHandle = = invalidClientHandle ) {
clientHandle = uuid - > client_handle ;
}
std : : string className ( reinterpret_cast < char * > ( readUuid . payload_ptr ) , readUuid . payload_size ) ;
connection - > classHandleToIndex [ uuid - > handle ] = { className , classIndex } ;
} else {
auto & uuidData = connection - > uuidMap [ uuid - > handle ] ;
uuidData . classHandle = uuid - > class_handle ;
uuidData . handle = uuid - > handle ;
uuidData . data = std : : move ( payload ) ;
uuidData . dataSize = uuid - > payload_size ;
2023-12-19 10:42:58 +00:00
uuidData . classIndex = NEO : : DrmResourceClass : : maxSize ;
2022-05-09 15:52:12 +00:00
const auto indexIt = connection - > classHandleToIndex . find ( uuid - > class_handle ) ;
if ( indexIt ! = connection - > classHandleToIndex . end ( ) ) {
uuidData . classIndex = static_cast < NEO : : DrmResourceClass > ( indexIt - > second . second ) ;
}
2023-12-19 10:42:58 +00:00
if ( uuidData . classIndex = = NEO : : DrmResourceClass : : elf ) {
2022-05-09 15:52:12 +00:00
auto cpuVa = extractVaFromUuidString ( uuidString ) ;
uuidData . ptr = cpuVa ;
}
2023-12-19 10:42:58 +00:00
if ( uuidData . classIndex = = NEO : : DrmResourceClass : : l0ZebinModule ) {
2022-05-09 15:52:12 +00:00
uint64_t handle = uuid - > handle ;
auto & newModule = connection - > uuidToModule [ handle ] ;
newModule . segmentCount = 0 ;
2022-11-14 15:52:05 +00:00
newModule . moduleUuidHandle = handle ;
2022-08-08 12:15:29 +00:00
for ( uint32_t i = 0 ; i < NEO : : EngineLimits : : maxHandleCount ; i + + ) {
newModule . segmentVmBindCounter [ i ] = 0 ;
newModule . loadAddresses [ i ] . clear ( ) ;
2022-11-14 15:52:05 +00:00
newModule . moduleLoadEventAcked [ i ] = false ;
2022-08-08 12:15:29 +00:00
}
2022-05-09 15:52:12 +00:00
}
extractUuidData ( uuid - > client_handle , uuidData ) ;
}
2023-01-18 20:22:32 +00:00
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_UUID client_handle = %llu handle = %llu flags = %d uuid = %s ret = %d \n " ,
( uint64_t ) readUuid . client_handle , ( uint64_t ) readUuid . handle , ( int ) readUuid . flags , uuidString . c_str ( ) , ret ) ;
2022-05-09 15:52:12 +00:00
} else {
2023-01-18 20:22:32 +00:00
PRINT_DEBUGGER_ERROR_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_UUID ret = %d errno = %d \n " , ret , errno ) ;
2022-05-09 15:52:12 +00:00
}
} else {
connection - > uuidMap [ uuid - > handle ] . classHandle = uuid - > class_handle ;
connection - > uuidMap [ uuid - > handle ] . handle = uuid - > handle ;
}
}
} break ;
case PRELIM_DRM_I915_DEBUG_EVENT_VM : {
prelim_drm_i915_debug_event_vm * vm = reinterpret_cast < prelim_drm_i915_debug_event_vm * > ( event ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_VM flags = %d size = %llu client_handle = %llu handle = %llu \n " ,
( int ) event - > flags , ( uint64_t ) event - > size , ( uint64_t ) vm - > client_handle , ( uint64_t ) vm - > handle ) ;
if ( event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE ) {
UNRECOVERABLE_IF ( clientHandleToConnection . find ( vm - > client_handle ) = = clientHandleToConnection . end ( ) ) ;
clientHandleToConnection [ vm - > client_handle ] - > vmIds . emplace ( static_cast < uint64_t > ( vm - > handle ) ) ;
}
if ( event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_DESTROY ) {
UNRECOVERABLE_IF ( clientHandleToConnection . find ( vm - > client_handle ) = = clientHandleToConnection . end ( ) ) ;
clientHandleToConnection [ vm - > client_handle ] - > vmIds . erase ( static_cast < uint64_t > ( vm - > handle ) ) ;
}
} break ;
case PRELIM_DRM_I915_DEBUG_EVENT_VM_BIND : {
prelim_drm_i915_debug_event_vm_bind * vmBind = reinterpret_cast < prelim_drm_i915_debug_event_vm_bind * > ( event ) ;
2022-09-29 16:07:22 +00:00
if ( ! handleVmBindEvent ( vmBind ) ) {
if ( event - > flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) {
prelim_drm_i915_debug_event_ack eventToAck = { } ;
eventToAck . type = vmBind - > base . type ;
eventToAck . seqno = vmBind - > base . seqno ;
eventToAck . flags = 0 ;
auto ret = ioctl ( PRELIM_I915_DEBUG_IOCTL_ACK_EVENT , & eventToAck ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu ret = %d errno = %d \n " , ( uint64_t ) eventToAck . seqno , ret , ret ! = 0 ? errno : 0 ) ;
} else {
auto sizeAligned = alignUp ( event - > size , sizeof ( uint64_t ) ) ;
auto pendingEvent = std : : make_unique < uint64_t [ ] > ( sizeAligned / sizeof ( uint64_t ) ) ;
memcpy_s ( pendingEvent . get ( ) , sizeAligned , event , event - > size ) ;
pendingVmBindEvents . push_back ( std : : move ( pendingEvent ) ) ;
}
}
2022-05-09 15:52:12 +00:00
} break ;
case PRELIM_DRM_I915_DEBUG_EVENT_CONTEXT_PARAM : {
prelim_drm_i915_debug_event_context_param * contextParam = reinterpret_cast < prelim_drm_i915_debug_event_context_param * > ( event ) ;
handleContextParamEvent ( contextParam ) ;
} break ;
case PRELIM_DRM_I915_DEBUG_EVENT_EU_ATTENTION : {
prelim_drm_i915_debug_event_eu_attention * attention = reinterpret_cast < prelim_drm_i915_debug_event_eu_attention * > ( event ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_EU_ATTENTION flags = %d, seqno = %d, size = %llu "
" client_handle = %llu flags = %llu class = %lu instance = %lu bitmask_size = %lu ctx_handle = %llu \n " ,
( int ) attention - > base . flags , ( uint64_t ) attention - > base . seqno , ( uint64_t ) attention - > base . size ,
( uint64_t ) attention - > client_handle , ( uint64_t ) attention - > flags , ( uint32_t ) attention - > ci . engine_class ,
( uint32_t ) attention - > ci . engine_instance , ( uint32_t ) attention - > bitmask_size , uint64_t ( attention - > ctx_handle ) ) ;
handleAttentionEvent ( attention ) ;
} break ;
case PRELIM_DRM_I915_DEBUG_EVENT_ENGINES : {
prelim_drm_i915_debug_event_engines * engines = reinterpret_cast < prelim_drm_i915_debug_event_engines * > ( event ) ;
handleEnginesEvent ( engines ) ;
} break ;
2023-08-24 21:44:21 +00:00
case PRELIM_DRM_I915_DEBUG_EVENT_PAGE_FAULT : {
prelim_drm_i915_debug_event_page_fault * pf = reinterpret_cast < prelim_drm_i915_debug_event_page_fault * > ( event ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_PAGE_FAULT flags = %d, address = %llu seqno = %d, size = %llu "
" client_handle = %llu flags = %llu class = %lu instance = %lu bitmask_size = %lu ctx_handle = %llu \n " ,
( int ) pf - > base . flags , ( uint64_t ) pf - > page_fault_address , ( uint64_t ) pf - > base . seqno , ( uint64_t ) pf - > base . size ,
( uint64_t ) pf - > client_handle , ( uint64_t ) pf - > flags , ( uint32_t ) pf - > ci . engine_class ,
( uint32_t ) pf - > ci . engine_instance , ( uint32_t ) pf - > bitmask_size , uint64_t ( pf - > ctx_handle ) ) ;
handlePageFaultEvent ( pf ) ;
} break ;
2022-05-09 15:52:12 +00:00
default :
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: UNHANDLED %d flags = %d size = %llu \n " , ( int ) event - > type , ( int ) event - > flags , ( uint64_t ) event - > size ) ;
break ;
}
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : processPendingVmBindEvents ( ) {
2022-09-29 16:07:22 +00:00
size_t processedEvents = 0 ;
for ( size_t index = 0 ; index < pendingVmBindEvents . size ( ) ; index + + ) {
auto debugEvent = reinterpret_cast < prelim_drm_i915_debug_event_vm_bind * > ( pendingVmBindEvents [ index ] . get ( ) ) ;
if ( handleVmBindEvent ( debugEvent ) = = false ) {
break ;
}
processedEvents + + ;
}
if ( processedEvents > 0 ) {
pendingVmBindEvents . erase ( pendingVmBindEvents . begin ( ) , pendingVmBindEvents . begin ( ) + processedEvents ) ;
}
}
2023-10-06 01:16:32 +00:00
bool DebugSessionLinuxi915 : : checkAllEventsCollected ( ) {
2022-05-09 15:52:12 +00:00
bool allEventsCollected = false ;
bool clientConnected = ( this - > clientHandle ! = invalidClientHandle ) ;
if ( clientConnected ) {
if ( clientHandleToConnection [ clientHandle ] - > vmToModuleDebugAreaBindInfo . size ( ) > 0 ) {
allEventsCollected = true ;
}
}
2023-07-06 14:15:23 +00:00
PRINT_DEBUGGER_INFO_LOG ( " checkAllEventsCollected() returned %d, clientHandle = %ull \n " , static_cast < int > ( allEventsCollected ) , this - > clientHandle ) ;
2022-05-09 15:52:12 +00:00
return allEventsCollected ;
}
2023-10-06 01:16:32 +00:00
bool DebugSessionLinuxi915 : : readModuleDebugArea ( ) {
2022-05-09 15:52:12 +00:00
auto vm = clientHandleToConnection [ clientHandle ] - > vmToModuleDebugAreaBindInfo . begin ( ) - > first ;
auto gpuVa = clientHandleToConnection [ clientHandle ] - > vmToModuleDebugAreaBindInfo . begin ( ) - > second . gpuVa ;
memset ( this - > debugArea . magic , 0 , sizeof ( this - > debugArea . magic ) ) ;
auto retVal = readGpuMemory ( vm , reinterpret_cast < char * > ( & this - > debugArea ) , sizeof ( this - > debugArea ) , gpuVa ) ;
2022-06-14 21:24:58 +00:00
if ( retVal ! = ZE_RESULT_SUCCESS | | strncmp ( this - > debugArea . magic , " dbgarea " , sizeof ( NEO : : DebugAreaHeader : : magic ) ) ! = 0 ) {
2022-05-09 15:52:12 +00:00
PRINT_DEBUGGER_ERROR_LOG ( " Reading Module Debug Area failed, error = %d \n " , retVal ) ;
return false ;
}
return true ;
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : readStateSaveAreaHeader ( ) {
2022-05-09 15:52:12 +00:00
if ( clientHandle = = invalidClientHandle ) {
return ;
}
uint64_t vm = 0 ;
uint64_t gpuVa = 0 ;
size_t totalSize = 0 ;
{
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
2022-05-09 15:52:12 +00:00
if ( clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . size ( ) > 0 ) {
vm = clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . begin ( ) - > first ;
gpuVa = clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . begin ( ) - > second . gpuVa ;
totalSize = clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . begin ( ) - > second . size ;
}
}
if ( gpuVa > 0 ) {
auto headerSize = sizeof ( SIP : : StateSaveAreaHeader ) ;
if ( totalSize < headerSize ) {
PRINT_DEBUGGER_ERROR_LOG ( " Context State Save Area size incorrect \n " , " " ) ;
return ;
} else {
2022-11-08 18:51:55 +00:00
validateAndSetStateSaveAreaHeader ( vm , gpuVa ) ;
2022-05-09 15:52:12 +00:00
}
}
}
2023-10-06 01:16:32 +00:00
ze_result_t DebugSessionLinuxi915 : : readEventImp ( prelim_drm_i915_debug_event * drmDebugEvent ) {
2023-01-18 20:22:32 +00:00
auto ret = ioctl ( PRELIM_I915_DEBUG_IOCTL_READ_EVENT , drmDebugEvent ) ;
if ( ret ! = 0 ) {
PRINT_DEBUGGER_ERROR_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT failed: retCode: %d errno = %d \n " , ret , errno ) ;
2023-08-24 21:44:21 +00:00
return ZE_RESULT_NOT_READY ;
} else if ( drmDebugEvent - > flags & ~ static_cast < uint32_t > ( PRELIM_DRM_I915_DEBUG_EVENT_CREATE | PRELIM_DRM_I915_DEBUG_EVENT_DESTROY | PRELIM_DRM_I915_DEBUG_EVENT_STATE_CHANGE | PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) ) {
PRINT_DEBUGGER_ERROR_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT unsupported flag = %d \n " , ( int ) drmDebugEvent - > flags ) ;
return ZE_RESULT_ERROR_UNKNOWN ;
2022-05-09 15:52:12 +00:00
}
2023-08-24 21:44:21 +00:00
return ZE_RESULT_SUCCESS ;
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
bool DebugSessionLinuxi915 : : handleVmBindEvent ( prelim_drm_i915_debug_event_vm_bind * vmBind ) {
2022-05-09 15:52:12 +00:00
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_VM_BIND flags = %d size = %llu client_handle = %llu vm_handle = %llu va_start = %p va_lenght = %llu num_uuids = %lu \n " ,
( int ) vmBind - > base . flags , ( uint64_t ) vmBind - > base . size , ( uint64_t ) vmBind - > client_handle , ( uint64_t ) vmBind - > vm_handle , ( void * ) vmBind - > va_start , ( uint64_t ) vmBind - > va_length , ( uint32_t ) vmBind - > num_uuids ) ;
const bool createEvent = ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE ) ;
const bool destroyEvent = ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_DESTROY ) ;
bool shouldAckEvent = true ;
if ( vmBind - > num_uuids > 0 & & vmBind - > base . size > sizeof ( prelim_drm_i915_debug_event_vm_bind ) ) {
auto vmHandle = vmBind - > vm_handle ;
auto connection = clientHandleToConnection [ vmBind - > client_handle ] . get ( ) ;
2022-09-07 17:12:17 +00:00
uint32_t index = 0 ;
2022-07-11 13:10:03 +00:00
const auto uuid = vmBind - > uuids [ index ] ;
2022-05-09 15:52:12 +00:00
if ( connection - > uuidMap . find ( uuid ) = = connection - > uuidMap . end ( ) ) {
PRINT_DEBUGGER_ERROR_LOG ( " Unknown UUID handle = %llu \n " , ( uint64_t ) uuid ) ;
2022-09-29 16:07:22 +00:00
return false ;
}
if ( connection - > vmToTile . find ( vmHandle ) = = connection - > vmToTile . end ( ) ) {
2022-09-30 13:00:05 +00:00
DEBUG_BREAK_IF ( connection - > vmToTile . find ( vmHandle ) = = connection - > vmToTile . end ( ) & & ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) & &
2023-12-19 10:42:58 +00:00
( connection - > uuidMap [ uuid ] . classIndex = = NEO : : DrmResourceClass : : isa | | connection - > uuidMap [ uuid ] . classIndex = = NEO : : DrmResourceClass : : moduleHeapDebugArea ) ) ;
2022-09-29 16:07:22 +00:00
return false ;
2022-05-09 15:52:12 +00:00
}
2022-09-14 09:23:40 +00:00
const auto tileIndex = connection - > vmToTile [ vmHandle ] ;
2022-10-04 14:14:01 +00:00
PRINT_DEBUGGER_INFO_LOG ( " UUID handle = %llu class index = %d \n " , static_cast < uint64_t > ( vmBind - > uuids [ index ] ) , static_cast < int > ( clientHandleToConnection [ vmBind - > client_handle ] - > uuidMap [ vmBind - > uuids [ index ] ] . classIndex ) ) ;
2022-05-09 15:52:12 +00:00
auto classUuid = connection - > uuidMap [ uuid ] . classHandle ;
if ( connection - > classHandleToIndex . find ( classUuid ) ! = connection - > classHandleToIndex . end ( ) ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
2022-05-09 15:52:12 +00:00
if ( connection - > classHandleToIndex [ classUuid ] . second = =
2023-12-19 10:42:58 +00:00
static_cast < uint32_t > ( NEO : : DrmResourceClass : : sbaTrackingBuffer ) ) {
2022-05-09 15:52:12 +00:00
connection - > vmToStateBaseAreaBindInfo [ vmHandle ] = { vmBind - > va_start , vmBind - > va_length } ;
}
if ( connection - > classHandleToIndex [ classUuid ] . second = =
2023-12-19 10:42:58 +00:00
static_cast < uint32_t > ( NEO : : DrmResourceClass : : moduleHeapDebugArea ) ) {
2022-05-09 15:52:12 +00:00
connection - > vmToModuleDebugAreaBindInfo [ vmHandle ] = { vmBind - > va_start , vmBind - > va_length } ;
}
if ( connection - > classHandleToIndex [ classUuid ] . second = =
2023-12-19 10:42:58 +00:00
static_cast < uint32_t > ( NEO : : DrmResourceClass : : contextSaveArea ) ) {
2022-05-09 15:52:12 +00:00
connection - > vmToContextStateSaveAreaBindInfo [ vmHandle ] = { vmBind - > va_start , vmBind - > va_length } ;
}
}
2022-09-14 09:23:40 +00:00
bool handleEvent = isTileWithinDeviceBitfield ( tileIndex ) ;
2022-09-07 17:12:17 +00:00
2023-12-19 10:42:58 +00:00
if ( handleEvent & & connection - > uuidMap [ uuid ] . classIndex = = NEO : : DrmResourceClass : : isa ) {
2022-10-04 14:14:01 +00:00
uint32_t deviceBitfield = 0 ;
memcpy_s ( & deviceBitfield , sizeof ( uint32_t ) , connection - > uuidMap [ uuid ] . data . get ( ) , connection - > uuidMap [ uuid ] . dataSize ) ;
const NEO : : DeviceBitfield devices ( deviceBitfield ) ;
PRINT_DEBUGGER_INFO_LOG ( " ISA vm_handle = %llu, tileIndex = %lu, deviceBitfield = %llu " , vmHandle , tileIndex , devices . to_ulong ( ) ) ;
2022-05-09 15:52:12 +00:00
2022-07-11 13:10:03 +00:00
const auto isaUuidHandle = connection - > uuidMap [ uuid ] . handle ;
2022-05-09 15:52:12 +00:00
bool perKernelModules = true ;
int moduleUUIDindex = - 1 ;
2022-07-11 13:10:03 +00:00
bool tileInstanced = false ;
2022-09-14 09:23:40 +00:00
bool allInstancesEventsReceived = true ;
2022-05-09 15:52:12 +00:00
for ( uint32_t uuidIter = 1 ; uuidIter < vmBind - > num_uuids ; uuidIter + + ) {
2023-12-19 10:42:58 +00:00
if ( connection - > uuidMap [ vmBind - > uuids [ uuidIter ] ] . classIndex = = NEO : : DrmResourceClass : : l0ZebinModule ) {
2022-05-09 15:52:12 +00:00
perKernelModules = false ;
moduleUUIDindex = static_cast < int > ( uuidIter ) ;
2023-07-06 14:15:23 +00:00
PRINT_DEBUGGER_INFO_LOG ( " Zebin module uuid = %ull " , ( uint64_t ) vmBind - > uuids [ uuidIter ] ) ;
2022-05-09 15:52:12 +00:00
}
2022-07-11 13:10:03 +00:00
if ( connection - > uuidMap [ vmBind - > uuids [ uuidIter ] ] . classHandle = = isaUuidHandle ) {
tileInstanced = true ;
}
2022-05-09 15:52:12 +00:00
}
2022-08-08 12:15:29 +00:00
if ( connection - > isaMap [ tileIndex ] . find ( vmBind - > va_start ) = = connection - > isaMap [ tileIndex ] . end ( ) & & createEvent ) {
2022-07-11 13:10:03 +00:00
2022-08-08 12:15:29 +00:00
auto & isaMap = connection - > isaMap [ tileIndex ] ;
2022-05-09 15:52:12 +00:00
auto & elfMap = connection - > elfMap ;
auto isa = std : : make_unique < IsaAllocation > ( ) ;
isa - > bindInfo = { vmBind - > va_start , vmBind - > va_length } ;
isa - > vmHandle = vmHandle ;
isa - > elfUuidHandle = invalidHandle ;
isa - > moduleBegin = 0 ;
isa - > moduleEnd = 0 ;
2022-07-11 13:10:03 +00:00
isa - > tileInstanced = tileInstanced ;
2022-08-10 15:24:13 +00:00
isa - > perKernelModule = perKernelModules ;
2022-09-14 09:23:40 +00:00
isa - > deviceBitfield = devices ;
2022-05-09 15:52:12 +00:00
for ( index = 1 ; index < vmBind - > num_uuids ; index + + ) {
2023-12-19 10:42:58 +00:00
if ( connection - > uuidMap [ vmBind - > uuids [ index ] ] . classIndex = = NEO : : DrmResourceClass : : elf ) {
2022-05-09 15:52:12 +00:00
isa - > elfUuidHandle = vmBind - > uuids [ index ] ;
if ( ! perKernelModules ) {
auto & module = connection - > uuidToModule [ vmBind - > uuids [ moduleUUIDindex ] ] ;
DEBUG_BREAK_IF ( module . elfUuidHandle ! = 0 & & connection - > uuidMap [ vmBind - > uuids [ index ] ] . ptr ! = connection - > uuidMap [ module . elfUuidHandle ] . ptr ) ;
module . elfUuidHandle = vmBind - > uuids [ index ] ;
2022-09-26 18:28:04 +00:00
module . deviceBitfield = devices ;
2022-05-09 15:52:12 +00:00
}
}
}
if ( isa - > elfUuidHandle ! = invalidHandle ) {
isa - > moduleBegin = connection - > uuidMap [ isa - > elfUuidHandle ] . ptr ;
isa - > moduleEnd = isa - > moduleBegin + connection - > uuidMap [ isa - > elfUuidHandle ] . dataSize ;
elfMap [ isa - > moduleBegin ] = isa - > elfUuidHandle ;
} else {
PRINT_DEBUGGER_ERROR_LOG ( " No ELF provided by application \n " , " " ) ;
}
2022-06-10 16:02:39 +00:00
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
auto loadAddress = gmmHelper - > canonize ( vmBind - > va_start ) ;
2022-05-09 15:52:12 +00:00
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD ;
debugEvent . info . module . format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF ;
debugEvent . info . module . load = loadAddress ;
debugEvent . info . module . moduleBegin = isa - > moduleBegin ;
debugEvent . info . module . moduleEnd = isa - > moduleEnd ;
std : : unique_lock < std : : mutex > memLock ( asyncThreadMutex ) ;
isaMap [ vmBind - > va_start ] = std : : move ( isa ) ;
2022-06-06 17:23:58 +00:00
2022-06-10 16:02:39 +00:00
// Expect non canonical va_start
DEBUG_BREAK_IF ( gmmHelper - > decanonize ( vmBind - > va_start ) ! = vmBind - > va_start ) ;
2022-08-16 18:21:08 +00:00
bool apiEventNeedsAck = ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) ;
2022-06-06 17:23:58 +00:00
// If ACK flag is not set when triggering MODULE LOAD event, auto-ack immediately
2022-08-16 18:21:08 +00:00
if ( apiEventNeedsAck = = false ) {
2022-08-08 12:15:29 +00:00
isaMap [ vmBind - > va_start ] - > moduleLoadEventAck = true ;
2022-06-06 17:23:58 +00:00
}
2022-08-16 18:21:08 +00:00
if ( tileSessionsEnabled ) {
auto tileAttached = tileSessions [ tileIndex ] . second ;
2022-08-19 15:11:22 +00:00
2022-08-16 18:21:08 +00:00
if ( ! tileAttached ) {
isaMap [ vmBind - > va_start ] - > moduleLoadEventAck = true ;
apiEventNeedsAck = false ;
}
2022-08-19 15:11:22 +00:00
PRINT_DEBUGGER_INFO_LOG ( " TileDebugSession attached = %d, tileIndex = %lu, apiEventNeedsAck = %d " , ( int ) tileAttached , tileIndex , ( int ) apiEventNeedsAck ) ;
2022-08-16 18:21:08 +00:00
}
2022-05-09 15:52:12 +00:00
memLock . unlock ( ) ;
if ( perKernelModules ) {
2023-07-06 14:15:23 +00:00
PRINT_DEBUGGER_INFO_LOG ( " New per-kernel module \n " , " " ) ;
2022-08-16 18:21:08 +00:00
debugEvent . flags = apiEventNeedsAck ? ZET_DEBUG_EVENT_FLAG_NEED_ACK : 0 ;
2022-08-25 17:33:23 +00:00
2022-08-16 18:21:08 +00:00
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
auto tileAttached = static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > insertModule ( debugEvent . info . module ) ;
2022-08-25 17:33:23 +00:00
if ( tileAttached ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > pushApiEvent ( debugEvent ) ;
2022-08-25 17:33:23 +00:00
}
2022-08-16 18:21:08 +00:00
} else {
2022-09-14 09:23:40 +00:00
if ( devices . count ( ) > 1 ) {
allInstancesEventsReceived = checkAllOtherTileIsaAllocationsPresent ( tileIndex , vmBind - > va_start ) ;
}
if ( allInstancesEventsReceived ) {
2022-11-14 15:52:05 +00:00
pushApiEvent ( debugEvent ) ;
2022-09-14 09:23:40 +00:00
}
2022-08-16 18:21:08 +00:00
}
2022-05-09 15:52:12 +00:00
}
}
if ( createEvent ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
2022-11-14 15:52:05 +00:00
if ( ! connection - > isaMap [ tileIndex ] [ vmBind - > va_start ] - > moduleLoadEventAck & & perKernelModules ) {
bool doNotAutoAckEvent = ( ! blockOnFenceMode & & allInstancesEventsReceived ) ; // in block on CPU mode - do not auto-ack last event for isa instance
doNotAutoAckEvent | = blockOnFenceMode ; // in block on fence mode - do not auto-ack any events
if ( doNotAutoAckEvent ) {
PRINT_DEBUGGER_INFO_LOG ( " Add event to ack, seqno = %llu " , ( uint64_t ) vmBind - > base . seqno ) ;
connection - > isaMap [ tileIndex ] [ vmBind - > va_start ] - > ackEvents . push_back ( vmBind - > base ) ;
shouldAckEvent = false ;
}
2022-05-09 15:52:12 +00:00
}
2022-08-08 12:15:29 +00:00
connection - > isaMap [ tileIndex ] [ vmBind - > va_start ] - > vmBindCounter + + ;
2022-05-09 15:52:12 +00:00
}
2022-08-08 12:15:29 +00:00
if ( destroyEvent & & connection - > isaMap [ tileIndex ] . find ( vmBind - > va_start ) ! = connection - > isaMap [ tileIndex ] . end ( ) ) {
DEBUG_BREAK_IF ( connection - > isaMap [ tileIndex ] [ vmBind - > va_start ] - > vmBindCounter = = 0 ) ;
connection - > isaMap [ tileIndex ] [ vmBind - > va_start ] - > vmBindCounter - - ;
if ( connection - > isaMap [ tileIndex ] [ vmBind - > va_start ] - > vmBindCounter = = 0 ) {
const auto & isa = connection - > isaMap [ tileIndex ] [ vmBind - > va_start ] ;
2022-05-09 15:52:12 +00:00
zet_debug_event_t debugEvent = { } ;
2022-06-10 16:02:39 +00:00
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
auto loadAddress = gmmHelper - > canonize ( isa - > bindInfo . gpuVa ) ;
2022-05-09 15:52:12 +00:00
debugEvent . type = ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD ;
debugEvent . info . module . format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF ;
2022-06-10 16:02:39 +00:00
debugEvent . info . module . load = loadAddress ;
2022-05-09 15:52:12 +00:00
debugEvent . info . module . moduleBegin = isa - > moduleBegin ;
debugEvent . info . module . moduleEnd = isa - > moduleEnd ;
if ( perKernelModules ) {
2022-08-16 18:21:08 +00:00
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > removeModule ( debugEvent . info . module ) ;
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > pushApiEvent ( debugEvent ) ;
2022-08-16 18:21:08 +00:00
} else {
2022-09-14 09:23:40 +00:00
bool notifyEvent = true ;
if ( isa - > deviceBitfield . count ( ) > 1 ) {
notifyEvent = checkAllOtherTileIsaAllocationsRemoved ( tileIndex , vmBind - > va_start ) ;
}
if ( notifyEvent ) {
2022-11-14 15:52:05 +00:00
pushApiEvent ( debugEvent ) ;
2022-09-14 09:23:40 +00:00
}
2022-08-16 18:21:08 +00:00
}
2022-05-09 15:52:12 +00:00
}
std : : unique_lock < std : : mutex > memLock ( asyncThreadMutex ) ;
2022-08-08 12:15:29 +00:00
connection - > isaMap [ tileIndex ] . erase ( vmBind - > va_start ) ;
2022-05-09 15:52:12 +00:00
memLock . unlock ( ) ;
}
}
}
2023-01-04 09:55:29 +01:00
if ( handleEvent ) {
2022-05-09 15:52:12 +00:00
2023-01-04 09:55:29 +01:00
for ( uint32_t uuidIter = 0 ; uuidIter < vmBind - > num_uuids ; uuidIter + + ) {
2023-12-19 10:42:58 +00:00
if ( connection - > uuidMap [ vmBind - > uuids [ uuidIter ] ] . classIndex = = NEO : : DrmResourceClass : : l0ZebinModule ) {
2023-01-04 09:55:29 +01:00
uint64_t loadAddress = 0 ;
auto & module = connection - > uuidToModule [ vmBind - > uuids [ uuidIter ] ] ;
2023-09-13 22:35:50 +00:00
auto moduleUsedOnTile = module . deviceBitfield . test ( tileIndex ) | | module . deviceBitfield . count ( ) = = 0 ;
if ( moduleUsedOnTile ) {
if ( createEvent ) {
module . segmentVmBindCounter [ tileIndex ] + + ;
DEBUG_BREAK_IF ( module . loadAddresses [ tileIndex ] . size ( ) > module . segmentCount ) ;
bool canTriggerEvent = module . loadAddresses [ tileIndex ] . size ( ) = = ( module . segmentCount - 1 ) ;
module . loadAddresses [ tileIndex ] . insert ( vmBind - > va_start ) ;
if ( ! blockOnFenceMode ) {
if ( canTriggerEvent & & module . loadAddresses [ tileIndex ] . size ( ) = = module . segmentCount ) {
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
loadAddress = gmmHelper - > canonize ( * std : : min_element ( module . loadAddresses [ tileIndex ] . begin ( ) , module . loadAddresses [ tileIndex ] . end ( ) ) ) ;
PRINT_DEBUGGER_INFO_LOG ( " Zebin module loaded at: %p, with %u isa allocations " , ( void * ) loadAddress , module . segmentCount ) ;
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD ;
debugEvent . info . module . format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF ;
debugEvent . info . module . load = loadAddress ;
debugEvent . info . module . moduleBegin = connection - > uuidMap [ module . elfUuidHandle ] . ptr ;
debugEvent . info . module . moduleEnd = connection - > uuidMap [ module . elfUuidHandle ] . ptr + connection - > uuidMap [ module . elfUuidHandle ] . dataSize ;
if ( ! tileSessionsEnabled ) {
bool allInstancesEventsReceived = true ;
if ( module . deviceBitfield . count ( ) > 1 ) {
allInstancesEventsReceived = checkAllOtherTileModuleSegmentsPresent ( tileIndex , module ) ;
2023-01-04 09:55:29 +01:00
}
2023-09-13 22:35:50 +00:00
if ( allInstancesEventsReceived ) {
if ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) {
debugEvent . flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK ;
module . ackEvents [ tileIndex ] . push_back ( vmBind - > base ) ;
}
pushApiEvent ( debugEvent , vmBind - > uuids [ uuidIter ] ) ;
shouldAckEvent = false ;
}
} else {
2023-10-06 01:16:32 +00:00
auto tileAttached = static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > insertModule ( debugEvent . info . module ) ;
2023-09-13 22:35:50 +00:00
if ( tileAttached ) {
if ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) {
debugEvent . flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK ;
module . ackEvents [ tileIndex ] . push_back ( vmBind - > base ) ;
}
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > pushApiEvent ( debugEvent , vmBind - > uuids [ uuidIter ] ) ;
2023-09-13 22:35:50 +00:00
shouldAckEvent = false ;
2023-01-04 09:55:29 +01:00
}
2022-11-14 15:52:05 +00:00
}
}
2023-09-13 22:35:50 +00:00
} else {
PRINT_DEBUGGER_INFO_LOG ( " Zebin module = %ull has load addresses = %d " , static_cast < uint64_t > ( vmBind - > uuids [ uuidIter ] ) , static_cast < int > ( module . loadAddresses [ tileIndex ] . size ( ) ) ) ;
if ( canTriggerEvent & & module . loadAddresses [ tileIndex ] . size ( ) = = module . segmentCount ) {
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
loadAddress = gmmHelper - > canonize ( * std : : min_element ( module . loadAddresses [ tileIndex ] . begin ( ) , module . loadAddresses [ tileIndex ] . end ( ) ) ) ;
PRINT_DEBUGGER_INFO_LOG ( " Zebin module loaded at: %p, with %u isa allocations " , ( void * ) loadAddress , module . segmentCount ) ;
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD ;
debugEvent . info . module . format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF ;
debugEvent . info . module . load = loadAddress ;
debugEvent . info . module . moduleBegin = connection - > uuidMap [ module . elfUuidHandle ] . ptr ;
debugEvent . info . module . moduleEnd = connection - > uuidMap [ module . elfUuidHandle ] . ptr + connection - > uuidMap [ module . elfUuidHandle ] . dataSize ;
if ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) {
debugEvent . flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK ;
2023-01-04 09:55:29 +01:00
}
2023-09-13 22:35:50 +00:00
if ( ! tileSessionsEnabled ) {
bool allInstancesEventsReceived = true ;
if ( module . deviceBitfield . count ( ) > 1 ) {
allInstancesEventsReceived = checkAllOtherTileModuleSegmentsPresent ( tileIndex , module ) ;
}
if ( allInstancesEventsReceived ) {
pushApiEvent ( debugEvent , vmBind - > uuids [ uuidIter ] ) ;
shouldAckEvent = false ;
}
} else {
2023-10-06 01:16:32 +00:00
auto tileAttached = static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > insertModule ( debugEvent . info . module ) ;
2023-09-13 22:35:50 +00:00
if ( tileAttached ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > pushApiEvent ( debugEvent , vmBind - > uuids [ uuidIter ] ) ;
2023-09-13 22:35:50 +00:00
shouldAckEvent = false ;
}
2023-01-04 09:55:29 +01:00
}
2023-09-13 22:35:50 +00:00
}
{
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
if ( ! module . moduleLoadEventAcked [ tileIndex ] ) {
2023-01-04 09:55:29 +01:00
shouldAckEvent = false ;
}
2022-08-25 17:33:23 +00:00
2023-10-06 01:16:32 +00:00
if ( tileSessionsEnabled & & ! static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > isAttached ) {
2023-09-13 22:35:50 +00:00
shouldAckEvent = true ;
}
if ( ! shouldAckEvent & & ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) ) {
module . ackEvents [ tileIndex ] . push_back ( vmBind - > base ) ;
}
2023-01-04 09:55:29 +01:00
}
2022-08-16 18:21:08 +00:00
}
2022-11-14 15:52:05 +00:00
2023-09-13 22:35:50 +00:00
} else { // destroyEvent
2022-05-09 15:52:12 +00:00
2023-09-13 22:35:50 +00:00
module . segmentVmBindCounter [ tileIndex ] - - ;
2022-05-09 15:52:12 +00:00
2023-09-13 22:35:50 +00:00
if ( module . segmentVmBindCounter [ tileIndex ] = = 0 ) {
2022-05-09 15:52:12 +00:00
2023-09-13 22:35:50 +00:00
zet_debug_event_t debugEvent = { } ;
2022-05-09 15:52:12 +00:00
2023-09-13 22:35:50 +00:00
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
auto loadAddress = gmmHelper - > canonize ( * std : : min_element ( module . loadAddresses [ tileIndex ] . begin ( ) , module . loadAddresses [ tileIndex ] . end ( ) ) ) ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD ;
debugEvent . info . module . format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF ;
debugEvent . info . module . load = loadAddress ;
debugEvent . info . module . moduleBegin = connection - > uuidMap [ module . elfUuidHandle ] . ptr ;
debugEvent . info . module . moduleEnd = connection - > uuidMap [ module . elfUuidHandle ] . ptr + connection - > uuidMap [ module . elfUuidHandle ] . dataSize ;
2022-05-09 15:52:12 +00:00
2023-09-13 22:35:50 +00:00
if ( tileSessionsEnabled ) {
2022-08-25 17:33:23 +00:00
2023-10-06 01:16:32 +00:00
auto tileAttached = static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > removeModule ( debugEvent . info . module ) ;
2022-08-25 17:33:23 +00:00
2023-09-13 22:35:50 +00:00
if ( tileAttached ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > pushApiEvent ( debugEvent , vmBind - > uuids [ uuidIter ] ) ;
2023-09-13 22:35:50 +00:00
}
2022-08-25 17:33:23 +00:00
2023-09-13 22:35:50 +00:00
} else {
bool notifyEvent = true ;
if ( module . deviceBitfield . count ( ) > 1 ) {
notifyEvent = checkAllOtherTileModuleSegmentsRemoved ( tileIndex , module ) ;
}
if ( notifyEvent ) {
pushApiEvent ( debugEvent , vmBind - > uuids [ uuidIter ] ) ;
}
2023-01-04 09:55:29 +01:00
}
2023-09-13 22:35:50 +00:00
module . loadAddresses [ tileIndex ] . clear ( ) ;
module . moduleLoadEventAcked [ tileIndex ] = false ;
2022-09-26 18:28:04 +00:00
}
2022-08-16 18:21:08 +00:00
}
2022-05-09 15:52:12 +00:00
}
2023-01-04 09:55:29 +01:00
break ;
2022-05-09 15:52:12 +00:00
}
}
}
2022-09-30 13:00:05 +00:00
}
2022-05-09 15:52:12 +00:00
2022-09-30 13:00:05 +00:00
if ( shouldAckEvent & & ( vmBind - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK ) ) {
prelim_drm_i915_debug_event_ack eventToAck = { } ;
eventToAck . type = vmBind - > base . type ;
eventToAck . seqno = vmBind - > base . seqno ;
eventToAck . flags = 0 ;
auto ret = ioctl ( PRELIM_I915_DEBUG_IOCTL_ACK_EVENT , & eventToAck ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu ret = %d errno = %d \n " , ( uint64_t ) eventToAck . seqno , ret , ret ! = 0 ? errno : 0 ) ;
2022-05-09 15:52:12 +00:00
}
2022-09-30 13:00:05 +00:00
return true ;
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : handleContextParamEvent ( prelim_drm_i915_debug_event_context_param * contextParam ) {
2022-05-09 15:52:12 +00:00
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_READ_EVENT type: PRELIM_DRM_I915_DEBUG_EVENT_CONTEXT_PARAM flags = %d size = %llu client_handle = %llu ctx_handle = %llu \n " ,
( int ) contextParam - > base . flags , ( uint64_t ) contextParam - > base . size , ( uint64_t ) contextParam - > client_handle , ( uint64_t ) contextParam - > ctx_handle ) ;
if ( clientHandleToConnection [ contextParam - > client_handle ] - > contextsCreated . find ( contextParam - > ctx_handle ) = =
clientHandleToConnection [ contextParam - > client_handle ] - > contextsCreated . end ( ) ) {
PRINT_DEBUGGER_ERROR_LOG ( " CONTEXT handle does not exist \n " , " " ) ;
return ;
}
switch ( contextParam - > param . param ) {
case I915_CONTEXT_PARAM_VM :
PRINT_DEBUGGER_INFO_LOG ( " I915_CONTEXT_PARAM_VM vm = %llu \n " , ( uint64_t ) contextParam - > param . value ) ;
clientHandleToConnection [ contextParam - > client_handle ] - > contextsCreated [ contextParam - > ctx_handle ] . vm = contextParam - > param . value ;
break ;
case I915_CONTEXT_PARAM_ENGINES : {
2022-07-11 13:10:03 +00:00
PRINT_DEBUGGER_INFO_LOG ( " I915_CONTEXT_PARAM_ENGINES ctx_id = %lu param = %llu value = %llu size = %lu " ,
2022-05-09 15:52:12 +00:00
( uint32_t ) contextParam - > param . ctx_id ,
( uint64_t ) contextParam - > param . param ,
( uint64_t ) contextParam - > param . value , ( uint32_t ) contextParam - > param . size ) ;
auto numEngines = ( contextParam - > param . size - sizeof ( i915_context_param_engines ) ) / sizeof ( i915_engine_class_instance ) ;
auto engines = reinterpret_cast < i915_context_param_engines * > ( & ( contextParam - > param . value ) ) ;
clientHandleToConnection [ contextParam - > client_handle ] - > contextsCreated [ contextParam - > ctx_handle ] . engines . clear ( ) ;
for ( uint32_t i = 0 ; i < numEngines ; i + + ) {
clientHandleToConnection [ contextParam - > client_handle ] - > contextsCreated [ contextParam - > ctx_handle ] . engines . push_back ( engines - > engines [ i ] ) ;
}
2022-07-11 13:10:03 +00:00
auto vm = clientHandleToConnection [ contextParam - > client_handle ] - > contextsCreated [ contextParam - > ctx_handle ] . vm ;
if ( numEngines & & vm ! = invalidHandle ) {
NEO : : EngineClassInstance engineClassInstance = { engines - > engines [ 0 ] . engine_class , engines - > engines [ 0 ] . engine_instance } ;
auto tileIndex = DrmHelper : : getEngineTileIndex ( connectedDevice , engineClassInstance ) ;
clientHandleToConnection [ contextParam - > client_handle ] - > vmToTile [ vm ] = tileIndex ;
PRINT_DEBUGGER_INFO_LOG ( " VM = %llu mapped to TILE = %lu \n " , vm , tileIndex ) ;
}
2022-05-09 15:52:12 +00:00
break ;
}
default :
PRINT_DEBUGGER_INFO_LOG ( " I915_CONTEXT_PARAM UNHANDLED = %llu \n " , ( uint64_t ) contextParam - > param . param ) ;
break ;
}
}
2023-10-06 01:16:32 +00:00
uint64_t DebugSessionLinuxi915 : : getVmHandleFromClientAndlrcHandle ( uint64_t clientHandle , uint64_t lrcHandle ) {
2023-08-24 21:44:21 +00:00
if ( clientHandleToConnection . find ( clientHandle ) = = clientHandleToConnection . end ( ) ) {
return invalidHandle ;
}
auto & clientConnection = clientHandleToConnection [ clientHandle ] ;
if ( clientConnection - > lrcToContextHandle . find ( lrcHandle ) = = clientConnection - > lrcToContextHandle . end ( ) ) {
return invalidHandle ;
}
auto contextHandle = clientConnection - > lrcToContextHandle [ lrcHandle ] ;
if ( clientConnection - > contextsCreated . find ( contextHandle ) = = clientConnection - > contextsCreated . end ( ) ) {
return invalidHandle ;
}
return clientConnection - > contextsCreated [ contextHandle ] . vm ;
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : handleAttentionEvent ( prelim_drm_i915_debug_event_eu_attention * attention ) {
2022-05-09 15:52:12 +00:00
NEO : : EngineClassInstance engineClassInstance = { attention - > ci . engine_class , attention - > ci . engine_instance } ;
auto tileIndex = DrmHelper : : getEngineTileIndex ( connectedDevice , engineClassInstance ) ;
if ( interruptSent & & attention - > base . seqno < = euControlInterruptSeqno [ tileIndex ] ) {
PRINT_DEBUGGER_INFO_LOG ( " Discarding EU ATTENTION event for interrupt request. Event seqno == %d <= %d == interrupt seqno \n " ,
( uint32_t ) attention - > base . seqno ,
( uint32_t ) euControlInterruptSeqno [ tileIndex ] ) ;
return ;
}
2023-08-24 21:44:21 +00:00
newAttentionRaised (
tileIndex ) ;
2022-05-09 15:52:12 +00:00
2023-08-24 21:44:21 +00:00
auto vmHandle = getVmHandleFromClientAndlrcHandle ( attention - > client_handle , attention - > lrc_handle ) ;
2022-05-09 15:52:12 +00:00
if ( vmHandle = = invalidHandle ) {
return ;
}
2022-09-07 17:12:17 +00:00
if ( ! connectedDevice - > getNEODevice ( ) - > getDeviceBitfield ( ) . test ( tileIndex ) ) {
return ;
}
2022-05-09 15:52:12 +00:00
auto hwInfo = connectedDevice - > getHwInfo ( ) ;
2023-01-02 13:06:10 +00:00
auto & l0GfxCoreHelper = connectedDevice - > getL0GfxCoreHelper ( ) ;
2022-05-09 15:52:12 +00:00
2023-03-04 09:07:26 +00:00
std : : vector < EuThread : : ThreadId > threadsWithAttention ;
if ( interruptSent ) {
std : : unique_ptr < uint8_t [ ] > bitmask ;
size_t bitmaskSize ;
2023-12-12 14:49:00 +00:00
auto attReadResult = threadControl ( { } , tileIndex , ThreadControlCmd : : stopped , bitmask , bitmaskSize ) ;
2023-03-04 09:07:26 +00:00
if ( attReadResult = = 0 ) {
threadsWithAttention = l0GfxCoreHelper . getThreadsFromAttentionBitmask ( hwInfo , tileIndex , bitmask . get ( ) , bitmaskSize ) ;
}
}
2022-05-09 15:52:12 +00:00
2023-03-04 09:07:26 +00:00
if ( threadsWithAttention . size ( ) = = 0 ) {
threadsWithAttention = l0GfxCoreHelper . getThreadsFromAttentionBitmask ( hwInfo , tileIndex , attention - > bitmask , attention - > bitmask_size ) ;
printBitmask ( attention - > bitmask , attention - > bitmask_size ) ;
}
2022-05-09 15:52:12 +00:00
PRINT_DEBUGGER_THREAD_LOG ( " ATTENTION for tile = %d thread count = %d \n " , tileIndex , ( int ) threadsWithAttention . size ( ) ) ;
2023-04-13 08:26:54 +00:00
if ( threadsWithAttention . size ( ) > 0 ) {
auto gpuVa = getContextStateSaveAreaGpuVa ( vmHandle ) ;
auto stateSaveAreaSize = getContextStateSaveAreaSize ( vmHandle ) ;
auto stateSaveReadResult = ZE_RESULT_ERROR_UNKNOWN ;
std : : unique_lock < std : : mutex > lock ;
2022-05-09 15:52:12 +00:00
2022-08-19 15:11:22 +00:00
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
lock = std : : unique_lock < std : : mutex > ( static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > threadStateMutex ) ;
2022-08-19 15:11:22 +00:00
} else {
2023-04-13 08:26:54 +00:00
lock = std : : unique_lock < std : : mutex > ( threadStateMutex ) ;
}
if ( gpuVa ! = 0 & & stateSaveAreaSize ! = 0 ) {
2023-07-14 18:26:55 +00:00
std : : vector < EuThread : : ThreadId > newThreads ;
getNotStoppedThreads ( threadsWithAttention , newThreads ) ;
if ( newThreads . size ( ) > 0 ) {
2023-07-17 13:44:19 +00:00
allocateStateSaveAreaMemory ( stateSaveAreaSize ) ;
stateSaveReadResult = readGpuMemory ( vmHandle , stateSaveAreaMemory . data ( ) , stateSaveAreaSize , gpuVa ) ;
2023-07-14 18:26:55 +00:00
}
2023-04-13 08:26:54 +00:00
} else {
PRINT_DEBUGGER_ERROR_LOG ( " Context state save area bind info invalid \n " , " " ) ;
DEBUG_BREAK_IF ( true ) ;
}
if ( stateSaveReadResult = = ZE_RESULT_SUCCESS ) {
for ( auto & threadId : threadsWithAttention ) {
PRINT_DEBUGGER_THREAD_LOG ( " ATTENTION event for thread: %s \n " , EuThread : : toString ( threadId ) . c_str ( ) ) ;
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > addThreadToNewlyStoppedFromRaisedAttention ( threadId , vmHandle , stateSaveAreaMemory . data ( ) ) ;
2023-04-13 08:26:54 +00:00
} else {
2023-07-17 13:44:19 +00:00
addThreadToNewlyStoppedFromRaisedAttention ( threadId , vmHandle , stateSaveAreaMemory . data ( ) ) ;
2023-04-13 08:26:54 +00:00
}
}
2022-08-19 15:11:22 +00:00
}
2022-05-09 15:52:12 +00:00
}
2022-08-19 15:11:22 +00:00
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > checkTriggerEventsForAttention ( ) ;
2022-08-19 15:11:22 +00:00
} else {
checkTriggerEventsForAttention ( ) ;
}
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : handlePageFaultEvent ( prelim_drm_i915_debug_event_page_fault * pf ) {
2023-08-24 21:44:21 +00:00
NEO : : EngineClassInstance engineClassInstance = { pf - > ci . engine_class , pf - > ci . engine_instance } ;
auto tileIndex = DrmHelper : : getEngineTileIndex ( connectedDevice , engineClassInstance ) ;
DEBUG_BREAK_IF ( pf - > bitmask_size % 3u ! = 0u ) ;
size_t size = pf - > bitmask_size / 3 ;
uint8_t * bitmaskBefore = & pf - > bitmask [ 0 ] ;
uint8_t * bitmaskAfter = & pf - > bitmask [ size ] ;
uint8_t * bitmaskResolved = & pf - > bitmask [ size * 2 ] ;
PRINT_DEBUGGER_INFO_LOG ( " PageFault event BEFORE " , 0 ) ;
printBitmask ( bitmaskBefore , size ) ;
PRINT_DEBUGGER_INFO_LOG ( " PageFault event AFTER " , 0 ) ;
printBitmask ( bitmaskAfter , size ) ;
PRINT_DEBUGGER_INFO_LOG ( " PageFault event RESOLVED " , 0 ) ;
printBitmask ( bitmaskResolved , size ) ;
auto vmHandle = getVmHandleFromClientAndlrcHandle ( pf - > client_handle , pf - > lrc_handle ) ;
if ( vmHandle = = invalidHandle ) {
return ;
}
if ( ! connectedDevice - > getNEODevice ( ) - > getDeviceBitfield ( ) . test ( tileIndex ) ) {
return ;
}
std : : unique_ptr < uint8_t [ ] > bitmaskPF = std : : make_unique < uint8_t [ ] > ( size ) ;
std : : transform ( bitmaskAfter , bitmaskAfter + size , bitmaskResolved , bitmaskPF . get ( ) , std : : bit_xor < uint8_t > ( ) ) ;
auto hwInfo = connectedDevice - > getHwInfo ( ) ;
auto & l0GfxCoreHelper = connectedDevice - > getL0GfxCoreHelper ( ) ;
auto threadsWithPF = l0GfxCoreHelper . getThreadsFromAttentionBitmask ( hwInfo , tileIndex , bitmaskPF . get ( ) , size ) ;
auto stoppedThreads = l0GfxCoreHelper . getThreadsFromAttentionBitmask ( hwInfo , tileIndex , bitmaskResolved , size ) ;
if ( threadsWithPF . size ( ) = = 0 ) {
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_PAGE_FAULT ;
PRINT_DEBUGGER_INFO_LOG ( " PageFault event for unknown thread " , 0 ) ;
enqueueApiEvent ( debugEvent ) ;
}
auto gpuVa = getContextStateSaveAreaGpuVa ( vmHandle ) ;
auto stateSaveAreaSize = getContextStateSaveAreaSize ( vmHandle ) ;
allocateStateSaveAreaMemory ( stateSaveAreaSize ) ;
auto stateSaveReadResult = readGpuMemory ( vmHandle , stateSaveAreaMemory . data ( ) , stateSaveAreaSize , gpuVa ) ;
if ( stateSaveReadResult = = ZE_RESULT_SUCCESS ) {
std : : unique_lock < std : : mutex > lock ;
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
lock = std : : unique_lock < std : : mutex > ( static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > threadStateMutex ) ;
2023-08-24 21:44:21 +00:00
} else {
lock = std : : unique_lock < std : : mutex > ( threadStateMutex ) ;
}
2023-10-03 15:02:52 +00:00
for ( auto & threadId : threadsWithPF ) {
2023-08-24 21:44:21 +00:00
PRINT_DEBUGGER_INFO_LOG ( " PageFault event for thread %s " , EuThread : : toString ( threadId ) . c_str ( ) ) ;
2023-11-15 21:46:47 +00:00
if ( tileSessionsEnabled ) {
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > allThreads [ threadId ] - > setPageFault ( true ) ;
} else {
allThreads [ threadId ] - > setPageFault ( true ) ;
}
2023-08-24 21:44:21 +00:00
}
2023-10-03 15:02:52 +00:00
for ( auto & threadId : stoppedThreads ) {
2023-08-24 21:44:21 +00:00
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > addThreadToNewlyStoppedFromRaisedAttention ( threadId , vmHandle , stateSaveAreaMemory . data ( ) ) ;
2023-08-24 21:44:21 +00:00
} else {
addThreadToNewlyStoppedFromRaisedAttention ( threadId , vmHandle , stateSaveAreaMemory . data ( ) ) ;
}
}
}
if ( tileSessionsEnabled ) {
2023-10-06 01:16:32 +00:00
static_cast < TileDebugSessionLinuxi915 * > ( tileSessions [ tileIndex ] . first ) - > checkTriggerEventsForAttention ( ) ;
2023-08-24 21:44:21 +00:00
} else {
checkTriggerEventsForAttention ( ) ;
}
return ;
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : handleEnginesEvent ( prelim_drm_i915_debug_event_engines * engines ) {
2022-05-09 15:52:12 +00:00
PRINT_DEBUGGER_INFO_LOG ( " ENGINES event: client_handle = %llu, ctx_handle = %llu, num_engines = %llu %s \n " ,
( uint64_t ) engines - > client_handle ,
( uint64_t ) engines - > ctx_handle ,
( uint64_t ) engines - > num_engines ,
engines - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE ? " CREATE " : engines - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_DESTROY ? " DESTROY "
: " " ) ;
UNRECOVERABLE_IF ( clientHandleToConnection . find ( engines - > client_handle ) = = clientHandleToConnection . end ( ) ) ;
if ( engines - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_CREATE ) {
for ( uint64_t i = 0 ; i < engines - > num_engines ; + + i ) {
auto lrc = engines - > engines [ i ] . lrc_handle ;
if ( lrc ! = 0 ) {
PRINT_DEBUGGER_INFO_LOG ( " lrc%llu = %llu " , i , lrc ) ;
}
clientHandleToConnection [ engines - > client_handle ] - > lrcToContextHandle [ lrc ] = engines - > ctx_handle ;
}
}
if ( engines - > base . flags & PRELIM_DRM_I915_DEBUG_EVENT_DESTROY ) {
for ( uint64_t i = 0 ; i < engines - > num_engines ; + + i ) {
auto lrc = engines - > engines [ i ] . lrc_handle ;
PRINT_DEBUGGER_INFO_LOG ( " lrc%llu = %llu \n " , i , lrc ) ;
clientHandleToConnection [ engines - > client_handle ] - > lrcToContextHandle . erase ( lrc ) ;
}
}
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : extractUuidData ( uint64_t client , const UuidData & uuidData ) {
2023-12-19 10:42:58 +00:00
if ( uuidData . classIndex = = NEO : : DrmResourceClass : : sbaTrackingBuffer | |
uuidData . classIndex = = NEO : : DrmResourceClass : : moduleHeapDebugArea | |
uuidData . classIndex = = NEO : : DrmResourceClass : : contextSaveArea ) {
2022-05-09 15:52:12 +00:00
UNRECOVERABLE_IF ( uuidData . dataSize ! = 8 ) ;
uint64_t * data = ( uint64_t * ) uuidData . data . get ( ) ;
2023-12-19 10:42:58 +00:00
if ( uuidData . classIndex = = NEO : : DrmResourceClass : : sbaTrackingBuffer ) {
2022-05-09 15:52:12 +00:00
clientHandleToConnection [ client ] - > stateBaseAreaGpuVa = * data ;
PRINT_DEBUGGER_INFO_LOG ( " SbaTrackingBuffer GPU VA = %p " , ( void * ) clientHandleToConnection [ clientHandle ] - > stateBaseAreaGpuVa ) ;
}
2023-12-19 10:42:58 +00:00
if ( uuidData . classIndex = = NEO : : DrmResourceClass : : moduleHeapDebugArea ) {
2022-05-09 15:52:12 +00:00
clientHandleToConnection [ client ] - > moduleDebugAreaGpuVa = * data ;
PRINT_DEBUGGER_INFO_LOG ( " ModuleHeapDebugArea GPU VA = %p " , ( void * ) clientHandleToConnection [ clientHandle ] - > moduleDebugAreaGpuVa ) ;
}
2023-12-19 10:42:58 +00:00
if ( uuidData . classIndex = = NEO : : DrmResourceClass : : contextSaveArea ) {
2022-05-09 15:52:12 +00:00
clientHandleToConnection [ client ] - > contextStateSaveAreaGpuVa = * data ;
PRINT_DEBUGGER_INFO_LOG ( " ContextSaveArea GPU VA = %p " , ( void * ) clientHandleToConnection [ clientHandle ] - > contextStateSaveAreaGpuVa ) ;
}
}
2023-12-19 10:42:58 +00:00
if ( uuidData . classIndex = = NEO : : DrmResourceClass : : l0ZebinModule ) {
2022-05-09 15:52:12 +00:00
uint32_t segmentCount = 0 ;
memcpy_s ( & segmentCount , sizeof ( uint32_t ) , uuidData . data . get ( ) , uuidData . dataSize ) ;
clientHandleToConnection [ client ] - > uuidToModule [ uuidData . handle ] . segmentCount = segmentCount ;
2023-07-06 14:15:23 +00:00
PRINT_DEBUGGER_INFO_LOG ( " Zebin module = %ull, segment count = %ul " , uuidData . handle , segmentCount ) ;
2022-05-09 15:52:12 +00:00
}
}
2023-10-06 01:16:32 +00:00
uint64_t DebugSessionLinuxi915 : : extractVaFromUuidString ( std : : string & uuid ) {
2022-05-09 15:52:12 +00:00
const char uuidString [ ] = " %04 " SCNx64 " -%012 " SCNx64 ;
auto subString = uuid . substr ( 19 ) ;
uint64_t parts [ 2 ] = { 0 , 0 } ;
sscanf ( subString . c_str ( ) , uuidString , & parts [ 1 ] , & parts [ 0 ] ) ;
parts [ 0 ] | = ( parts [ 1 ] & 0xFFFF ) < < 48 ;
return parts [ 0 ] ;
}
2024-02-06 16:53:04 +00:00
int DebugSessionLinuxi915 : : euControlIoctl ( ThreadControlCmd threadCmd ,
const NEO : : EngineClassInstance * classInstance ,
std : : unique_ptr < uint8_t [ ] > & bitmask ,
size_t bitmaskSize , uint64_t & seqnoOut , uint64_t & bitmaskSizeOut ) {
2022-05-09 15:52:12 +00:00
struct prelim_drm_i915_debug_eu_control euControl = { } ;
euControl . client_handle = clientHandle ;
euControl . ci . engine_class = classInstance - > engineClass ;
euControl . ci . engine_instance = classInstance - > engineInstance ;
euControl . bitmask_size = 0 ;
euControl . bitmask_ptr = 0 ;
decltype ( prelim_drm_i915_debug_eu_control : : cmd ) command = 0 ;
switch ( threadCmd ) {
2023-12-12 14:49:00 +00:00
case ThreadControlCmd : : interruptAll :
2022-05-09 15:52:12 +00:00
command = PRELIM_I915_DEBUG_EU_THREADS_CMD_INTERRUPT_ALL ;
break ;
2023-12-12 14:49:00 +00:00
case ThreadControlCmd : : interrupt :
2022-05-09 15:52:12 +00:00
command = PRELIM_I915_DEBUG_EU_THREADS_CMD_INTERRUPT ;
break ;
2023-12-12 14:49:00 +00:00
case ThreadControlCmd : : resume :
2022-05-09 15:52:12 +00:00
command = PRELIM_I915_DEBUG_EU_THREADS_CMD_RESUME ;
break ;
2023-12-12 14:49:00 +00:00
case ThreadControlCmd : : stopped :
2022-05-09 15:52:12 +00:00
command = PRELIM_I915_DEBUG_EU_THREADS_CMD_STOPPED ;
break ;
}
euControl . cmd = command ;
2024-02-06 16:53:04 +00:00
euControl . bitmask_size = static_cast < uint32_t > ( bitmaskSize ) ;
euControl . bitmask_ptr = reinterpret_cast < uint64_t > ( bitmask . get ( ) ) ;
2022-05-09 15:52:12 +00:00
if ( command = = PRELIM_I915_DEBUG_EU_THREADS_CMD_RESUME ) {
2022-07-14 14:24:56 +00:00
applyResumeWa ( bitmask . get ( ) , bitmaskSize ) ;
2022-05-09 15:52:12 +00:00
}
printBitmask ( bitmask . get ( ) , bitmaskSize ) ;
2023-03-04 09:07:26 +00:00
auto euControlRetVal = ioctl ( PRELIM_I915_DEBUG_IOCTL_EU_CONTROL , & euControl ) ;
2024-02-06 16:53:04 +00:00
seqnoOut = euControl . seqno ;
bitmaskSizeOut = euControl . bitmask_size ;
2023-03-04 09:07:26 +00:00
return euControlRetVal ;
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
ze_result_t DebugSessionLinuxi915 : : getISAVMHandle ( uint32_t deviceIndex , const zet_debug_memory_space_desc_t * desc , size_t size , uint64_t & vmHandle ) {
2022-09-05 13:08:24 +00:00
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
auto accessVA = gmmHelper - > decanonize ( desc - > address ) ;
2022-08-30 18:06:04 +00:00
auto & isaMap = clientHandleToConnection [ clientHandle ] - > isaMap [ deviceIndex ] ;
2022-05-09 15:52:12 +00:00
ze_result_t status = ZE_RESULT_ERROR_UNINITIALIZED ;
vmHandle = invalidHandle ;
if ( isaMap . size ( ) > 0 ) {
uint64_t baseVa ;
uint64_t ceilVa ;
for ( const auto & isa : isaMap ) {
baseVa = isa . second - > bindInfo . gpuVa ;
ceilVa = isa . second - > bindInfo . gpuVa + isa . second - > bindInfo . size ;
if ( accessVA > = baseVa & & accessVA < ceilVa ) {
if ( accessVA + size > ceilVa ) {
status = ZE_RESULT_ERROR_INVALID_ARGUMENT ;
} else {
vmHandle = isa . second - > vmHandle ;
status = ZE_RESULT_SUCCESS ;
}
break ;
}
}
}
return status ;
}
2023-10-06 01:16:32 +00:00
bool DebugSessionLinuxi915 : : getIsaInfoForAllInstances ( NEO : : DeviceBitfield deviceBitfield , const zet_debug_memory_space_desc_t * desc , size_t size , uint64_t vmHandles [ ] , ze_result_t & status ) {
2022-09-14 09:23:40 +00:00
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
auto accessVA = gmmHelper - > decanonize ( desc - > address ) ;
status = ZE_RESULT_ERROR_UNINITIALIZED ;
bool tileInstancedIsa = false ;
bool invalidIsaRange = false ;
uint32_t isaFound = 0 ;
for ( uint32_t i = 0 ; i < NEO : : EngineLimits : : maxHandleCount ; i + + ) {
vmHandles [ i ] = invalidHandle ;
if ( deviceBitfield . test ( i ) ) {
auto & isaMap = clientHandleToConnection [ clientHandle ] - > isaMap [ i ] ;
if ( isaMap . size ( ) > 0 ) {
uint64_t baseVa ;
uint64_t ceilVa ;
for ( const auto & isa : isaMap ) {
baseVa = isa . second - > bindInfo . gpuVa ;
ceilVa = isa . second - > bindInfo . gpuVa + isa . second - > bindInfo . size ;
if ( accessVA > = baseVa & & accessVA < ceilVa ) {
isaFound + + ;
if ( accessVA + size > ceilVa ) {
invalidIsaRange = true ;
} else {
vmHandles [ i ] = isa . second - > vmHandle ;
}
tileInstancedIsa = isa . second - > tileInstanced ;
break ;
}
}
}
}
}
if ( invalidIsaRange ) {
status = ZE_RESULT_ERROR_INVALID_ARGUMENT ;
} else if ( isaFound > 0 ) {
if ( ( tileInstancedIsa & & deviceBitfield . count ( ) = = isaFound ) | |
! tileInstancedIsa ) {
status = ZE_RESULT_SUCCESS ;
}
}
return isaFound > 0 ;
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : printContextVms ( ) {
2023-11-30 08:32:25 +00:00
if ( NEO : : debugManager . flags . DebuggerLogBitmask . get ( ) & NEO : : DebugVariables : : DEBUGGER_LOG_BITMASK : : LOG_INFO ) {
2022-05-09 15:52:12 +00:00
PRINT_DEBUGGER_LOG ( stdout , " \n INFO: Context - VM map: " , " " ) ;
for ( size_t i = 0 ; i < clientHandleToConnection [ clientHandle ] - > contextsCreated . size ( ) ; i + + ) {
PRINT_DEBUGGER_LOG ( stdout , " \n Context = %llu : %llu " , ( uint64_t ) clientHandleToConnection [ clientHandle ] - > contextsCreated [ i ] . handle ,
( uint64_t ) clientHandleToConnection [ clientHandle ] - > contextsCreated [ i ] . vm ) ;
}
}
}
2023-10-06 01:16:32 +00:00
bool DebugSessionLinuxi915 : : ackIsaEvents ( uint32_t deviceIndex , uint64_t isaVa ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
2022-05-09 15:52:12 +00:00
2022-08-10 15:24:13 +00:00
auto connection = clientHandleToConnection [ clientHandle ] . get ( ) ;
2022-06-10 16:02:39 +00:00
2022-08-10 15:24:13 +00:00
auto gmmHelper = connectedDevice - > getNEODevice ( ) - > getGmmHelper ( ) ;
auto isaVaStart = gmmHelper - > decanonize ( isaVa ) ;
auto isa = connection - > isaMap [ deviceIndex ] . find ( isaVaStart ) ;
2022-05-09 15:52:12 +00:00
2022-08-10 15:24:13 +00:00
if ( isa ! = connection - > isaMap [ deviceIndex ] . end ( ) ) {
2022-05-09 15:52:12 +00:00
2023-01-04 15:00:09 +00:00
// zebin modules do not store ackEvents per ISA
2022-08-10 15:24:13 +00:00
UNRECOVERABLE_IF ( isa - > second - > ackEvents . size ( ) > 0 & & isa - > second - > perKernelModule = = false ) ;
2022-05-09 15:52:12 +00:00
2022-08-10 15:24:13 +00:00
for ( auto & event : isa - > second - > ackEvents ) {
prelim_drm_i915_debug_event_ack eventToAck = { } ;
eventToAck . type = event . type ;
eventToAck . seqno = event . seqno ;
eventToAck . flags = 0 ;
auto ret = ioctl ( PRELIM_I915_DEBUG_IOCTL_ACK_EVENT , & eventToAck ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu, ret = %d errno = %d \n " , ( uint64_t ) event . seqno , ret , ret ! = 0 ? errno : 0 ) ;
}
isa - > second - > ackEvents . clear ( ) ;
isa - > second - > moduleLoadEventAck = true ;
return true ;
}
return false ;
}
2023-10-06 01:16:32 +00:00
bool DebugSessionLinuxi915 : : ackModuleEvents ( uint32_t deviceIndex , uint64_t moduleUuidHandle ) {
2022-11-14 15:52:05 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
auto connection = clientHandleToConnection [ clientHandle ] . get ( ) ;
if ( connection - > uuidToModule . find ( moduleUuidHandle ) ! = connection - > uuidToModule . end ( ) ) {
auto & module = connection - > uuidToModule [ moduleUuidHandle ] ;
for ( auto & event : module . ackEvents [ deviceIndex ] ) {
prelim_drm_i915_debug_event_ack eventToAck = { } ;
eventToAck . type = event . type ;
eventToAck . seqno = event . seqno ;
eventToAck . flags = 0 ;
auto ret = ioctl ( PRELIM_I915_DEBUG_IOCTL_ACK_EVENT , & eventToAck ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu, ret = %d errno = %d \n " , ( uint64_t ) event . seqno , ret , ret ! = 0 ? errno : 0 ) ;
}
module . ackEvents [ deviceIndex ] . clear ( ) ;
module . moduleLoadEventAcked [ deviceIndex ] = true ;
return true ;
}
DEBUG_BREAK_IF ( true ) ;
return false ;
}
2023-10-06 01:16:32 +00:00
void DebugSessionLinuxi915 : : cleanRootSessionAfterDetach ( uint32_t deviceIndex ) {
2022-08-25 17:33:23 +00:00
auto connection = clientHandleToConnection [ clientHandle ] . get ( ) ;
for ( const auto & isa : connection - > isaMap [ deviceIndex ] ) {
2023-01-04 15:00:09 +00:00
// zebin modules do not store ackEvents per ISA
2022-08-25 17:33:23 +00:00
UNRECOVERABLE_IF ( isa . second - > ackEvents . size ( ) > 0 & & isa . second - > perKernelModule = = false ) ;
for ( auto & event : isa . second - > ackEvents ) {
prelim_drm_i915_debug_event_ack eventToAck = { } ;
eventToAck . type = event . type ;
eventToAck . seqno = event . seqno ;
eventToAck . flags = 0 ;
auto ret = ioctl ( PRELIM_I915_DEBUG_IOCTL_ACK_EVENT , & eventToAck ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_I915_DEBUG_IOCTL_ACK_EVENT seqno = %llu, ret = %d errno = %d \n " , ( uint64_t ) event . seqno , ret , ret ! = 0 ? errno : 0 ) ;
}
isa . second - > ackEvents . clear ( ) ;
isa . second - > moduleLoadEventAck = true ;
}
}
2023-10-06 01:16:32 +00:00
ze_result_t DebugSessionLinuxi915 : : acknowledgeEvent ( const zet_debug_event_t * event ) {
2022-08-10 15:24:13 +00:00
const zet_debug_event_t apiEventToAck = * event ;
{
2022-11-14 15:52:05 +00:00
std : : unique_lock < std : : mutex > lock ( asyncThreadMutex ) ;
2022-08-10 15:24:13 +00:00
for ( size_t i = 0 ; i < eventsToAck . size ( ) ; i + + ) {
if ( apiEventCompare ( apiEventToAck , eventsToAck [ i ] . first ) ) {
2022-05-09 15:52:12 +00:00
2022-11-14 15:52:05 +00:00
auto moduleUUID = eventsToAck [ i ] . second ;
2022-08-10 15:24:13 +00:00
auto iter = eventsToAck . begin ( ) + i ;
eventsToAck . erase ( iter ) ;
2022-11-14 15:52:05 +00:00
lock . unlock ( ) ;
for ( uint32_t i = 0 ; i < NEO : : EngineLimits : : maxHandleCount ; i + + ) {
if ( connectedDevice - > getNEODevice ( ) - > getDeviceBitfield ( ) . test ( i ) ) {
ackModuleEvents ( i , moduleUUID ) ;
}
}
2022-08-10 15:24:13 +00:00
return ZE_RESULT_SUCCESS ;
2022-05-09 15:52:12 +00:00
}
2022-08-10 15:24:13 +00:00
}
}
2022-05-09 15:52:12 +00:00
2022-08-10 15:24:13 +00:00
if ( apiEventToAck . type = = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD ) {
2022-09-14 09:23:40 +00:00
bool allIsaAcked = true ;
for ( uint32_t i = 0 ; i < NEO : : EngineLimits : : maxHandleCount ; i + + ) {
if ( connectedDevice - > getNEODevice ( ) - > getDeviceBitfield ( ) . test ( i ) ) {
if ( ! ackIsaEvents ( i , apiEventToAck . info . module . load ) ) {
allIsaAcked = false ;
}
}
}
if ( allIsaAcked ) {
2022-05-09 15:52:12 +00:00
return ZE_RESULT_SUCCESS ;
}
}
2022-08-10 15:24:13 +00:00
return ZE_RESULT_ERROR_UNINITIALIZED ;
2022-05-09 15:52:12 +00:00
}
2023-10-06 01:16:32 +00:00
ze_result_t DebugSessionLinuxi915 : : readSbaBuffer ( EuThread : : ThreadId threadId , NEO : : SbaTrackedAddresses & sbaBuffer ) {
2022-05-09 15:52:12 +00:00
auto vmHandle = allThreads [ threadId ] - > getMemoryHandle ( ) ;
if ( vmHandle = = invalidHandle ) {
return ZE_RESULT_ERROR_NOT_AVAILABLE ;
}
auto gpuVa = getSbaBufferGpuVa ( vmHandle ) ;
if ( gpuVa = = 0 ) {
return ZE_RESULT_ERROR_UNKNOWN ;
}
return readGpuMemory ( vmHandle , reinterpret_cast < char * > ( & sbaBuffer ) , sizeof ( sbaBuffer ) , gpuVa ) ;
}
2023-10-06 01:16:32 +00:00
uint64_t DebugSessionLinuxi915 : : getSbaBufferGpuVa ( uint64_t memoryHandle ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
2022-05-09 15:52:12 +00:00
auto bindInfo = clientHandleToConnection [ clientHandle ] - > vmToStateBaseAreaBindInfo . find ( memoryHandle ) ;
if ( bindInfo = = clientHandleToConnection [ clientHandle ] - > vmToStateBaseAreaBindInfo . end ( ) ) {
return 0 ;
}
return bindInfo - > second . gpuVa ;
}
2023-10-06 01:16:32 +00:00
uint64_t DebugSessionLinuxi915 : : getContextStateSaveAreaGpuVa ( uint64_t memoryHandle ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
2022-05-09 15:52:12 +00:00
auto bindInfo = clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . find ( memoryHandle ) ;
if ( bindInfo = = clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . end ( ) ) {
return 0 ;
}
return bindInfo - > second . gpuVa ;
}
2023-10-06 01:16:32 +00:00
size_t DebugSessionLinuxi915 : : getContextStateSaveAreaSize ( uint64_t memoryHandle ) {
2023-04-13 08:26:54 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
if ( clientHandleToConnection [ clientHandle ] - > contextStateSaveAreaSize ! = 0 ) {
return clientHandleToConnection [ clientHandle ] - > contextStateSaveAreaSize ;
}
auto bindInfo = clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . find ( memoryHandle ) ;
if ( bindInfo = = clientHandleToConnection [ clientHandle ] - > vmToContextStateSaveAreaBindInfo . end ( ) ) {
return 0 ;
}
clientHandleToConnection [ clientHandle ] - > contextStateSaveAreaSize = static_cast < size_t > ( bindInfo - > second . size ) ;
return clientHandleToConnection [ clientHandle ] - > contextStateSaveAreaSize ;
}
2023-10-06 01:16:32 +00:00
void TileDebugSessionLinuxi915 : : readStateSaveAreaHeader ( ) {
2022-07-29 11:26:12 +00:00
2022-08-16 18:21:08 +00:00
const auto header = rootDebugSession - > getStateSaveAreaHeader ( ) ;
if ( header ) {
auto headerSize = rootDebugSession - > stateSaveAreaHeader . size ( ) ;
this - > stateSaveAreaHeader . assign ( reinterpret_cast < const char * > ( header ) , reinterpret_cast < const char * > ( header ) + headerSize ) ;
2023-01-20 15:13:50 +00:00
this - > sipSupportsSlm = rootDebugSession - > sipSupportsSlm ;
2022-08-16 18:21:08 +00:00
}
2022-07-29 11:26:12 +00:00
} ;
2023-10-06 01:16:32 +00:00
bool TileDebugSessionLinuxi915 : : insertModule ( zet_debug_event_info_module_t module ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
modules . insert ( { module . load , module } ) ;
return isAttached ;
}
2023-10-06 01:16:32 +00:00
bool TileDebugSessionLinuxi915 : : removeModule ( zet_debug_event_info_module_t module ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
modules . erase ( module . load ) ;
return isAttached ;
}
2023-10-06 01:16:32 +00:00
bool TileDebugSessionLinuxi915 : : processEntry ( ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
processEntryState = true ;
return isAttached ;
}
2023-10-06 01:16:32 +00:00
bool TileDebugSessionLinuxi915 : : processExit ( ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
processEntryState = false ;
return isAttached ;
}
2023-10-06 01:16:32 +00:00
void TileDebugSessionLinuxi915 : : attachTile ( ) {
2022-08-25 17:33:23 +00:00
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
// clear apiEvents queue
apiEvents = decltype ( apiEvents ) { } ;
if ( detached ) {
zet_debug_event_t debugEvent = { } ;
debugEvent . type = ZET_DEBUG_EVENT_TYPE_DETACHED ;
debugEvent . info . detached . reason = ZET_DEBUG_DETACH_REASON_INVALID ;
apiEvents . push ( debugEvent ) ;
} else {
if ( processEntryState ) {
zet_debug_event_t event = { } ;
event . type = ZET_DEBUG_EVENT_TYPE_PROCESS_ENTRY ;
event . flags = 0 ;
apiEvents . push ( event ) ;
}
if ( modules . size ( ) ) {
zet_debug_event_t event = { } ;
event . type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD ;
event . flags = 0 ;
for ( const auto & module : modules ) {
memcpy_s ( & event . info . module , sizeof ( event . info . module ) , & module . second , sizeof ( module . second ) ) ;
apiEvents . push ( event ) ;
}
}
}
isAttached = true ;
}
2023-10-06 01:16:32 +00:00
void TileDebugSessionLinuxi915 : : detachTile ( ) {
2022-11-14 15:52:05 +00:00
std : : vector < uint64_t > moduleUuids ;
2022-08-25 17:33:23 +00:00
{
std : : lock_guard < std : : mutex > lock ( asyncThreadMutex ) ;
2022-11-14 15:52:05 +00:00
for ( const auto & eventToAck : eventsToAck ) {
auto moduleUUID = eventToAck . second ;
moduleUuids . push_back ( moduleUUID ) ;
2022-08-25 17:33:23 +00:00
}
eventsToAck . clear ( ) ;
2022-11-14 15:52:05 +00:00
isAttached = false ;
}
for ( const auto & uuid : moduleUuids ) {
rootDebugSession - > ackModuleEvents ( this - > tileIndex , uuid ) ;
2022-08-25 17:33:23 +00:00
}
}
2022-05-09 15:52:12 +00:00
} // namespace L0