2017-12-21 00:45:38 +01:00
/*
2025-01-06 22:12:14 +00:00
* Copyright ( C ) 2018 - 2025 Intel Corporation
2017-12-21 00:45:38 +01:00
*
2018-09-18 09:11:08 +02:00
* SPDX - License - Identifier : MIT
2017-12-21 00:45:38 +01:00
*
*/
2022-11-25 07:53:05 +00:00
# include "shared/source/os_interface/linux/drm_neo.h"
2019-02-27 11:39:32 +01:00
2025-02-11 14:31:01 +00:00
# include "shared/source/command_stream/command_stream_receiver.h"
2022-11-04 09:43:54 +00:00
# include "shared/source/command_stream/submission_status.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/debug_settings/debug_settings_manager.h"
2020-03-17 07:26:46 +01:00
# include "shared/source/execution_environment/execution_environment.h"
2020-07-07 09:34:31 +02:00
# include "shared/source/execution_environment/root_device_environment.h"
2022-04-19 19:24:19 +00:00
# include "shared/source/gmm_helper/cache_settings_helper.h"
2022-04-11 17:13:44 +00:00
# include "shared/source/gmm_helper/client_context/gmm_client_context.h"
2022-11-25 07:53:05 +00:00
# include "shared/source/gmm_helper/gmm.h"
2022-04-19 19:24:19 +00:00
# include "shared/source/gmm_helper/resource_info.h"
2023-10-02 14:26:33 +00:00
# include "shared/source/helpers/basic_math.h"
2020-04-02 11:28:38 +02:00
# include "shared/source/helpers/constants.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/helpers/debug_helpers.h"
2025-07-23 10:29:50 +00:00
# include "shared/source/helpers/device_caps_reader.h"
2023-02-01 16:23:01 +00:00
# include "shared/source/helpers/gfx_core_helper.h"
2024-05-11 07:43:42 +00:00
# include "shared/source/helpers/gpu_page_fault_helper.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/helpers/hw_info.h"
2020-06-09 15:51:26 +02:00
# include "shared/source/helpers/ptr_math.h"
2020-11-05 15:40:03 +03:00
# include "shared/source/os_interface/driver_info.h"
2022-04-07 17:14:49 +00:00
# include "shared/source/os_interface/linux/cache_info.h"
2022-07-26 18:39:17 +02:00
# include "shared/source/os_interface/linux/drm_buffer_object.h"
2022-02-11 13:46:23 +00:00
# include "shared/source/os_interface/linux/drm_engine_mapper.h"
2021-05-21 01:17:57 +02:00
# include "shared/source/os_interface/linux/drm_gem_close_worker.h"
# include "shared/source/os_interface/linux/drm_memory_manager.h"
2022-02-15 17:28:38 +00:00
# include "shared/source/os_interface/linux/drm_memory_operations_handler_bind.h"
2022-05-17 21:40:34 +00:00
# include "shared/source/os_interface/linux/drm_wrappers.h"
2023-01-23 14:55:52 +00:00
# include "shared/source/os_interface/linux/engine_info.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/os_interface/linux/hw_device_id.h"
2021-12-14 09:46:01 +00:00
# include "shared/source/os_interface/linux/ioctl_helper.h"
2023-01-23 14:55:52 +00:00
# include "shared/source/os_interface/linux/memory_info.h"
2021-09-01 16:28:18 +00:00
# include "shared/source/os_interface/linux/os_context_linux.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/os_interface/linux/os_inc.h"
2021-05-20 00:36:24 +02:00
# include "shared/source/os_interface/linux/pci_path.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/os_interface/linux/sys_calls.h"
2020-11-24 16:00:33 +01:00
# include "shared/source/os_interface/linux/system_info.h"
2024-12-17 11:48:52 +00:00
# include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h"
2020-03-17 07:26:46 +01:00
# include "shared/source/os_interface/os_environment.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/os_interface/os_interface.h"
2023-03-10 12:28:11 +00:00
# include "shared/source/os_interface/product_helper.h"
2024-07-25 14:35:48 +00:00
# include "shared/source/release_helper/release_helper.h"
2022-11-18 14:38:56 +00:00
# include "shared/source/utilities/api_intercept.h"
2025-01-24 03:59:30 +00:00
# include "shared/source/utilities/cpu_info.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/utilities/directory.h"
2024-05-17 17:33:25 +00:00
# include "shared/source/utilities/io_functions.h"
2019-02-27 11:39:32 +01:00
2025-04-29 16:41:39 +00:00
# include "xe_drm.h"
2017-12-21 00:45:38 +01:00
# include <cstdio>
# include <cstring>
2022-11-18 14:38:56 +00:00
# include <fcntl.h>
2022-12-01 19:42:57 +00:00
# include <fstream>
2022-02-28 13:31:18 +00:00
# include <map>
2022-12-15 16:01:37 +00:00
# include <sstream>
2017-12-21 00:45:38 +01:00
2019-03-26 11:59:46 +01:00
namespace NEO {
2017-12-21 00:45:38 +01:00
2021-10-21 12:37:31 +00:00
Drm : : Drm ( std : : unique_ptr < HwDeviceIdDrm > & & hwDeviceIdIn , RootDeviceEnvironment & rootDeviceEnvironment )
2023-12-13 16:09:52 +00:00
: DriverModel ( DriverModelType : : drm ) ,
2021-05-21 01:17:57 +02:00
hwDeviceId ( std : : move ( hwDeviceIdIn ) ) , rootDeviceEnvironment ( rootDeviceEnvironment ) {
2021-02-05 15:27:21 +00:00
pagingFence . fill ( 0u ) ;
fenceVal . fill ( 0u ) ;
2025-06-20 09:23:25 +00:00
minimalChunkingSize = MemoryConstants : : pageSize2M ;
2020-07-15 08:07:53 +02:00
}
2022-11-04 09:43:54 +00:00
SubmissionStatus Drm : : getSubmissionStatusFromReturnCode ( int32_t retCode ) {
switch ( retCode ) {
case 0 :
2023-12-13 09:17:24 +00:00
return SubmissionStatus : : success ;
2022-11-04 09:43:54 +00:00
case EWOULDBLOCK :
case ENOMEM :
case ENOSPC :
2023-12-13 09:17:24 +00:00
return SubmissionStatus : : outOfHostMemory ;
2022-11-04 09:43:54 +00:00
case ENXIO :
2023-12-13 09:17:24 +00:00
return SubmissionStatus : : outOfMemory ;
2022-11-04 09:43:54 +00:00
default :
2023-12-13 09:17:24 +00:00
return SubmissionStatus : : failed ;
2022-11-04 09:43:54 +00:00
}
}
2022-05-04 13:59:12 +00:00
void Drm : : queryAndSetVmBindPatIndexProgrammingSupport ( ) {
2023-01-02 11:52:22 +00:00
auto & productHelper = rootDeviceEnvironment . getHelper < ProductHelper > ( ) ;
this - > vmBindPatIndexProgrammingSupported = productHelper . isVmBindPatIndexProgrammingSupported ( ) ;
2022-05-04 13:59:12 +00:00
}
2022-05-25 17:05:52 +00:00
int Drm : : ioctl ( DrmIoctl request , void * arg ) {
auto requestValue = getIoctlRequestValue ( request , ioctlHelper . get ( ) ) ;
2017-12-21 00:45:38 +01:00
int ret ;
2022-10-18 18:37:33 +00:00
int returnedErrno = 0 ;
2017-12-21 00:45:38 +01:00
SYSTEM_ENTER ( ) ;
do {
2024-02-07 16:19:02 +00:00
auto measureTime = debugManager . flags . PrintKmdTimes . get ( ) ;
2021-04-21 13:52:11 +00:00
std : : chrono : : steady_clock : : time_point start ;
std : : chrono : : steady_clock : : time_point end ;
2023-11-30 08:32:25 +00:00
auto printIoctl = debugManager . flags . PrintIoctlEntries . get ( ) ;
2021-04-22 13:37:02 +00:00
if ( printIoctl ) {
2025-06-21 18:05:09 +00:00
PRINT_DEBUG_STRING ( true , stdout , " IOCTL %s called \n " , ioctlHelper - > getIoctlString ( request ) . c_str ( ) ) ;
2021-04-22 13:37:02 +00:00
}
2021-08-19 15:26:34 +00:00
if ( measureTime ) {
start = std : : chrono : : steady_clock : : now ( ) ;
}
2022-05-25 17:05:52 +00:00
ret = SysCalls : : ioctl ( getFileDescriptor ( ) , requestValue , arg ) ;
2021-04-21 13:52:11 +00:00
2022-10-18 18:37:33 +00:00
if ( ret ! = 0 ) {
returnedErrno = getErrno ( ) ;
}
2021-05-12 15:09:01 +00:00
2021-04-21 13:52:11 +00:00
if ( measureTime ) {
end = std : : chrono : : steady_clock : : now ( ) ;
2021-08-19 15:26:34 +00:00
long long elapsedTime = std : : chrono : : duration_cast < std : : chrono : : nanoseconds > ( end - start ) . count ( ) ;
2021-04-21 13:52:11 +00:00
2025-03-05 14:50:30 +00:00
static std : : mutex mtx ;
std : : lock_guard lock ( mtx ) ;
2021-08-19 15:26:34 +00:00
IoctlStatisticsEntry ioctlData { } ;
2021-04-21 13:52:11 +00:00
auto ioctlDataIt = this - > ioctlStatistics . find ( request ) ;
if ( ioctlDataIt ! = this - > ioctlStatistics . end ( ) ) {
ioctlData = ioctlDataIt - > second ;
}
2021-08-19 15:26:34 +00:00
ioctlData . totalTime + = elapsedTime ;
ioctlData . count + + ;
ioctlData . minTime = std : : min ( ioctlData . minTime , elapsedTime ) ;
ioctlData . maxTime = std : : max ( ioctlData . maxTime , elapsedTime ) ;
2021-04-21 13:52:11 +00:00
this - > ioctlStatistics [ request ] = ioctlData ;
}
2021-08-19 15:26:34 +00:00
if ( printIoctl ) {
2021-12-31 01:38:08 +00:00
if ( ret = = 0 ) {
2025-06-21 18:05:09 +00:00
PRINT_DEBUG_STRING ( true , stdout , " IOCTL %s returns %d \n " ,
ioctlHelper - > getIoctlString ( request ) . c_str ( ) , ret ) ;
2021-12-31 01:38:08 +00:00
} else {
2025-06-21 18:05:09 +00:00
PRINT_DEBUG_STRING ( true , stdout , " IOCTL %s returns %d, errno %d(%s) \n " ,
ioctlHelper - > getIoctlString ( request ) . c_str ( ) , ret , returnedErrno , strerror ( returnedErrno ) ) ;
2021-12-31 01:38:08 +00:00
}
2021-08-19 15:26:34 +00:00
}
2022-10-18 18:37:33 +00:00
} while ( ret = = - 1 & & checkIfIoctlReinvokeRequired ( returnedErrno , request , ioctlHelper . get ( ) ) ) ;
2017-12-21 00:45:38 +01:00
SYSTEM_LEAVE ( request ) ;
return ret ;
}
2022-06-06 15:48:31 +00:00
int Drm : : getParamIoctl ( DrmParam param , int * dstValue ) {
2022-05-24 16:13:02 +00:00
GetParam getParam { } ;
2024-12-17 14:41:33 +00:00
getParam . param = ioctlHelper - > getDrmParamValue ( param ) ;
2018-03-12 12:03:20 +01:00
getParam . value = dstValue ;
2017-12-21 00:45:38 +01:00
2024-12-17 14:41:33 +00:00
int retVal = ioctlHelper - > ioctl ( DrmIoctl : : getparam , & getParam ) ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . PrintIoctlEntries . get ( ) ) {
2021-06-25 12:28:28 +00:00
printf ( " DRM_IOCTL_I915_GETPARAM: param: %s, output value: %d, retCode:% d \n " ,
2024-12-17 14:41:33 +00:00
ioctlHelper - > getDrmParamString ( param ) . c_str ( ) ,
2021-06-25 12:28:28 +00:00
* getParam . value ,
retVal ) ;
}
2020-01-31 16:10:03 +01:00
return retVal ;
2018-03-12 12:03:20 +01:00
}
2017-12-21 00:45:38 +01:00
int Drm : : enableTurboBoost ( ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { } ;
2017-12-21 00:45:38 +01:00
2022-07-27 08:00:15 +00:00
contextParam . param = contextPrivateParamBoost ;
2017-12-21 00:45:38 +01:00
contextParam . value = 1 ;
2023-12-12 08:48:32 +00:00
return ioctlHelper - > ioctl ( DrmIoctl : : gemContextSetparam , & contextParam ) ;
2017-12-21 00:45:38 +01:00
}
int Drm : : getEnabledPooledEu ( int & enabled ) {
2023-12-13 09:05:31 +00:00
return getParamIoctl ( DrmParam : : paramHasPooledEu , & enabled ) ;
2017-12-21 00:45:38 +01:00
}
2025-03-07 13:45:49 +00:00
std : : string Drm : : getSysFsPciPathBaseName ( ) {
auto fullPath = getSysFsPciPath ( ) ;
size_t pos = fullPath . rfind ( " / " ) ;
if ( std : : string : : npos = = pos ) {
return fullPath ;
}
return fullPath . substr ( pos + 1 , std : : string : : npos ) ;
}
2020-04-08 18:14:19 +02:00
std : : string Drm : : getSysFsPciPath ( ) {
std : : string path = std : : string ( Os : : sysFsPciPathPrefix ) + hwDeviceId - > getPciPath ( ) + " /drm " ;
std : : string expectedFilePrefix = path + " /card " ;
auto files = Directory : : getFiles ( path . c_str ( ) ) ;
for ( auto & file : files ) {
if ( file . find ( expectedFilePrefix . c_str ( ) ) ! = std : : string : : npos ) {
return file ;
2017-12-21 00:45:38 +01:00
}
}
2020-04-08 18:14:19 +02:00
return { } ;
2017-12-21 00:45:38 +01:00
}
2022-06-30 08:04:45 +00:00
bool Drm : : readSysFsAsString ( const std : : string & relativeFilePath , std : : string & readString ) {
auto devicePath = getSysFsPciPath ( ) ;
if ( devicePath . empty ( ) ) {
return false ;
}
2025-01-15 02:11:43 +01:00
const std : : string fileName = devicePath + relativeFilePath ;
2022-06-30 08:04:45 +00:00
int fd = SysCalls : : open ( fileName . c_str ( ) , O_RDONLY ) ;
if ( fd < 0 ) {
return false ;
}
ssize_t bytesRead = SysCalls : : pread ( fd , readString . data ( ) , readString . size ( ) - 1 , 0 ) ;
NEO : : SysCalls : : close ( fd ) ;
if ( bytesRead < = 0 ) {
return false ;
}
std : : replace ( readString . begin ( ) , readString . end ( ) , ' \n ' , ' \0 ' ) ;
return true ;
}
2024-03-28 08:46:55 +00:00
int Drm : : queryGttSize ( uint64_t & gttSizeOutput , bool alignUpToFullRange ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { 0 } ;
2023-12-13 09:05:31 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamGttSize ) ;
2019-04-23 15:42:33 +02:00
2023-12-12 08:48:32 +00:00
int ret = ioctlHelper - > ioctl ( DrmIoctl : : gemContextGetparam , & contextParam ) ;
2019-04-23 15:42:33 +02:00
if ( ret = = 0 ) {
2024-03-28 08:46:55 +00:00
if ( alignUpToFullRange ) {
gttSizeOutput = Drm : : alignUpGttSize ( contextParam . value ) ;
} else {
gttSizeOutput = contextParam . value ;
}
2019-04-23 15:42:33 +02:00
}
2019-12-17 15:17:52 +01:00
return ret ;
2017-12-21 00:45:38 +01:00
}
2022-02-04 16:03:36 +00:00
bool Drm : : isGpuHangDetected ( OsContext & osContext ) {
2024-02-26 09:53:24 +00:00
bool ret = checkResetStatus ( osContext ) ;
2024-04-08 18:37:35 +00:00
auto threshold = getGpuFaultCheckThreshold ( ) ;
2024-05-07 16:58:28 +00:00
if ( checkGpuPageFaultRequired ( ) ) {
2024-04-08 18:37:35 +00:00
if ( gpuFaultCheckCounter > = threshold ) {
2024-02-26 09:53:24 +00:00
auto memoryManager = static_cast < DrmMemoryManager * > ( this - > rootDeviceEnvironment . executionEnvironment . memoryManager . get ( ) ) ;
memoryManager - > checkUnexpectedGpuPageFault ( ) ;
gpuFaultCheckCounter = 0 ;
return false ;
}
gpuFaultCheckCounter + + ;
}
return ret ;
}
bool Drm : : checkResetStatus ( OsContext & osContext ) {
2022-02-04 16:03:36 +00:00
const auto osContextLinux = static_cast < OsContextLinux * > ( & osContext ) ;
2022-01-20 16:56:19 +00:00
const auto & drmContextIds = osContextLinux - > getDrmContextIds ( ) ;
for ( const auto drmContextId : drmContextIds ) {
2022-05-24 15:06:15 +00:00
ResetStats resetStats { } ;
resetStats . contextId = drmContextId ;
2024-02-26 07:57:36 +00:00
ResetStatsFault fault { } ;
uint32_t status = 0 ;
const auto retVal { ioctlHelper - > getResetStats ( resetStats , & status , & fault ) } ;
2022-01-20 16:56:19 +00:00
UNRECOVERABLE_IF ( retVal ! = 0 ) ;
2025-01-27 23:44:23 +00:00
auto debuggingEnabled = rootDeviceEnvironment . executionEnvironment . isDebuggingEnabled ( ) ;
2025-04-10 20:04:10 +00:00
if ( checkToDisableScratchPage ( ) & & ioctlHelper - > validPageFault ( fault . flags ) ) {
2024-05-11 07:43:42 +00:00
bool banned = ( ( status & ioctlHelper - > getStatusForResetStats ( true ) ) ! = 0 ) ;
2025-04-10 20:04:10 +00:00
if ( ! banned & & debuggingEnabled ) {
return false ;
}
2024-10-25 18:28:00 +00:00
IoFunctions : : fprintf ( stderr , " Segmentation fault from GPU at 0x%llx, ctx_id: %u (%s) type: %d (%s), level: %d (%s), access: %d (%s), banned: %d, aborting. \n " ,
2024-05-17 17:33:25 +00:00
fault . addr ,
resetStats . contextId ,
EngineHelpers : : engineTypeToString ( osContext . getEngineType ( ) ) . c_str ( ) ,
fault . type , GpuPageFaultHelpers : : faultTypeToString ( static_cast < FaultType > ( fault . type ) ) . c_str ( ) ,
fault . level , GpuPageFaultHelpers : : faultLevelToString ( static_cast < FaultLevel > ( fault . level ) ) . c_str ( ) ,
fault . access , GpuPageFaultHelpers : : faultAccessToString ( static_cast < FaultAccess > ( fault . access ) ) . c_str ( ) ,
banned ) ;
2024-10-25 18:28:00 +00:00
IoFunctions : : fprintf ( stdout , " Segmentation fault from GPU at 0x%llx, ctx_id: %u (%s) type: %d (%s), level: %d (%s), access: %d (%s), banned: %d, aborting. \n " ,
2024-05-17 17:33:25 +00:00
fault . addr ,
resetStats . contextId ,
EngineHelpers : : engineTypeToString ( osContext . getEngineType ( ) ) . c_str ( ) ,
fault . type , GpuPageFaultHelpers : : faultTypeToString ( static_cast < FaultType > ( fault . type ) ) . c_str ( ) ,
fault . level , GpuPageFaultHelpers : : faultLevelToString ( static_cast < FaultLevel > ( fault . level ) ) . c_str ( ) ,
fault . access , GpuPageFaultHelpers : : faultAccessToString ( static_cast < FaultAccess > ( fault . access ) ) . c_str ( ) ,
banned ) ;
2024-02-26 07:57:36 +00:00
UNRECOVERABLE_IF ( true ) ;
}
2022-05-24 15:06:15 +00:00
if ( resetStats . batchActive > 0 | | resetStats . batchPending > 0 ) {
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " ERROR: GPU HANG detected! \n " ) ;
2023-01-10 17:20:07 +00:00
osContextLinux - > setHangDetected ( ) ;
2022-01-20 16:56:19 +00:00
return true ;
}
}
return false ;
}
2018-12-07 15:03:23 +01:00
void Drm : : checkPreemptionSupport ( ) {
2024-04-04 11:58:45 +00:00
preemptionSupported = ioctlHelper - > isPreemptionSupported ( ) ;
2017-12-21 00:45:38 +01:00
}
2019-08-21 03:50:47 -07:00
void Drm : : checkQueueSliceSupport ( ) {
sliceCountChangeSupported = getQueueSliceCount ( & sseu ) = = 0 ? true : false ;
}
2018-12-11 08:21:56 +01:00
void Drm : : setLowPriorityContextParam ( uint32_t drmContextId ) {
2022-05-20 15:04:07 +00:00
GemContextParam gcp = { } ;
gcp . contextId = drmContextId ;
2023-12-13 09:05:31 +00:00
gcp . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamPriority ) ;
2017-12-21 00:45:38 +01:00
gcp . value = - 1023 ;
2023-12-12 08:48:32 +00:00
auto retVal = ioctlHelper - > ioctl ( DrmIoctl : : gemContextSetparam , & gcp ) ;
2018-12-11 08:21:56 +01:00
UNRECOVERABLE_IF ( retVal ! = 0 ) ;
}
2022-05-19 12:30:26 +00:00
int Drm : : getQueueSliceCount ( GemContextParamSseu * sseu ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { } ;
2023-12-13 09:05:31 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamSseu ) ;
sseu - > engine . engineClass = ioctlHelper - > getDrmParamValue ( DrmParam : : engineClassRender ) ;
sseu - > engine . engineInstance = ioctlHelper - > getDrmParamValue ( DrmParam : : execDefault ) ;
2019-08-21 03:50:47 -07:00
contextParam . value = reinterpret_cast < uint64_t > ( sseu ) ;
2022-05-19 12:30:26 +00:00
contextParam . size = sizeof ( struct GemContextParamSseu ) ;
2019-08-21 03:50:47 -07:00
2023-12-12 08:48:32 +00:00
return ioctlHelper - > ioctl ( DrmIoctl : : gemContextGetparam , & contextParam ) ;
2019-08-21 03:50:47 -07:00
}
uint64_t Drm : : getSliceMask ( uint64_t sliceCount ) {
2019-11-27 18:00:52 +01:00
return maxNBitValue ( sliceCount ) ;
2019-08-21 03:50:47 -07:00
}
bool Drm : : setQueueSliceCount ( uint64_t sliceCount ) {
if ( sliceCountChangeSupported ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { } ;
2022-05-19 12:30:26 +00:00
sseu . sliceMask = getSliceMask ( sliceCount ) ;
2019-08-21 03:50:47 -07:00
2023-12-13 09:05:31 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamSseu ) ;
2022-05-20 15:04:07 +00:00
contextParam . contextId = 0 ;
2019-08-21 03:50:47 -07:00
contextParam . value = reinterpret_cast < uint64_t > ( & sseu ) ;
2022-05-19 12:30:26 +00:00
contextParam . size = sizeof ( struct GemContextParamSseu ) ;
2023-12-12 08:48:32 +00:00
int retVal = ioctlHelper - > ioctl ( DrmIoctl : : gemContextSetparam , & contextParam ) ;
2019-08-21 03:50:47 -07:00
if ( retVal = = 0 ) {
return true ;
}
}
return false ;
}
2020-02-10 08:05:32 -08:00
void Drm : : checkNonPersistentContextsSupport ( ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { } ;
2023-12-13 09:05:31 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamPersistence ) ;
2020-02-10 08:05:32 -08:00
2023-12-12 08:48:32 +00:00
auto retVal = ioctlHelper - > ioctl ( DrmIoctl : : gemContextGetparam , & contextParam ) ;
2020-02-10 08:05:32 -08:00
if ( retVal = = 0 & & contextParam . value = = 1 ) {
nonPersistentContextsSupported = true ;
} else {
nonPersistentContextsSupported = false ;
}
2019-12-18 19:38:22 +01:00
}
2019-12-24 12:20:23 +01:00
void Drm : : setNonPersistentContext ( uint32_t drmContextId ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { } ;
contextParam . contextId = drmContextId ;
2023-12-13 09:05:31 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamPersistence ) ;
2019-12-18 19:38:22 +01:00
2023-12-12 08:48:32 +00:00
ioctlHelper - > ioctl ( DrmIoctl : : gemContextSetparam , & contextParam ) ;
2019-12-18 19:38:22 +01:00
}
2021-09-09 21:16:11 +00:00
void Drm : : setUnrecoverableContext ( uint32_t drmContextId ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { } ;
contextParam . contextId = drmContextId ;
2023-12-13 09:05:31 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamRecoverable ) ;
2021-09-09 21:16:11 +00:00
contextParam . value = 0 ;
contextParam . size = 0 ;
2023-12-12 08:48:32 +00:00
ioctlHelper - > ioctl ( DrmIoctl : : gemContextSetparam , & contextParam ) ;
2021-09-09 21:16:11 +00:00
}
2023-02-11 22:03:06 +00:00
int Drm : : createDrmContext ( uint32_t drmVmId , bool isDirectSubmissionRequested , bool isCooperativeContextRequested ) {
2022-05-24 14:36:24 +00:00
GemContextCreateExt gcc { } ;
2021-09-03 17:32:33 +02:00
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . DirectSubmissionDrmContext . get ( ) ! = - 1 ) {
isDirectSubmissionRequested = debugManager . flags . DirectSubmissionDrmContext . get ( ) ;
2022-02-16 12:35:03 +00:00
}
if ( isDirectSubmissionRequested ) {
gcc . flags | = ioctlHelper - > getDirectSubmissionFlag ( ) ;
}
2021-09-03 17:32:33 +02:00
2022-05-23 15:05:47 +00:00
GemContextCreateExtSetParam extSetparam = { } ;
2025-02-26 07:46:54 +00:00
GemContextCreateExtSetParam extSetparamLowLatency = { } ;
2022-02-16 12:35:03 +00:00
if ( drmVmId > 0 ) {
2023-12-13 09:05:31 +00:00
extSetparam . base . name = ioctlHelper - > getDrmParamValue ( DrmParam : : contextCreateExtSetparam ) ;
extSetparam . param . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamVm ) ;
2022-02-16 12:35:03 +00:00
extSetparam . param . value = drmVmId ;
2025-02-26 07:46:54 +00:00
if ( ioctlHelper - > hasContextFreqHint ( ) ) {
extSetparam . base . nextExtension = reinterpret_cast < uint64_t > ( & extSetparamLowLatency . base ) ;
ioctlHelper - > fillExtSetparamLowLatency ( extSetparamLowLatency ) ;
}
2022-02-16 12:35:03 +00:00
gcc . extensions = reinterpret_cast < uint64_t > ( & extSetparam ) ;
2023-12-13 09:05:31 +00:00
gcc . flags | = ioctlHelper - > getDrmParamValue ( DrmParam : : contextCreateFlagsUseExtensions ) ;
2022-02-16 12:35:03 +00:00
}
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . CreateContextWithAccessCounters . get ( ) > 0 ) {
2022-06-29 16:49:29 +00:00
return ioctlHelper - > createContextWithAccessCounters ( gcc ) ;
2022-02-16 12:35:03 +00:00
}
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . ForceRunAloneContext . get ( ) ! = - 1 ) {
isCooperativeContextRequested = debugManager . flags . ForceRunAloneContext . get ( ) ;
2022-02-16 12:35:03 +00:00
}
if ( isCooperativeContextRequested ) {
2022-06-29 16:49:29 +00:00
return ioctlHelper - > createCooperativeContext ( gcc ) ;
2022-02-16 12:35:03 +00:00
}
2023-12-12 08:48:32 +00:00
auto ioctlResult = ioctlHelper - > ioctl ( DrmIoctl : : gemContextCreateExt , & gcc ) ;
2022-02-16 12:35:03 +00:00
2023-02-11 22:03:06 +00:00
if ( ioctlResult < 0 ) {
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " WARNING: GemContextCreateExt ioctl failed. Not exposing this root device \n " ) ;
2023-02-11 22:03:06 +00:00
return ioctlResult ;
}
2022-05-24 14:36:24 +00:00
return gcc . contextId ;
2021-09-03 17:32:33 +02:00
}
2018-12-11 08:21:56 +01:00
void Drm : : destroyDrmContext ( uint32_t drmContextId ) {
2022-05-24 15:06:15 +00:00
GemContextDestroy destroy { } ;
destroy . contextId = drmContextId ;
2023-12-12 08:48:32 +00:00
auto retVal = ioctlHelper - > ioctl ( DrmIoctl : : gemContextDestroy , & destroy ) ;
2022-11-03 11:26:33 +00:00
UNRECOVERABLE_IF ( ( retVal ! = 0 ) & & ( errno ! = ENODEV ) ) ;
2017-12-21 00:45:38 +01:00
}
2020-07-07 09:34:31 +02:00
void Drm : : destroyDrmVirtualMemory ( uint32_t drmVmId ) {
2022-05-24 15:06:15 +00:00
GemVmControl ctl = { } ;
ctl . vmId = drmVmId ;
2023-12-12 08:48:32 +00:00
auto ret = ioctlHelper - > ioctl ( DrmIoctl : : gemVmDestroy , & ctl ) ;
2022-11-03 11:26:33 +00:00
UNRECOVERABLE_IF ( ( ret ! = 0 ) & & ( errno ! = ENODEV ) ) ;
2020-07-07 09:34:31 +02:00
}
2020-08-31 07:04:58 +02:00
int Drm : : queryVmId ( uint32_t drmContextId , uint32_t & vmId ) {
2022-05-20 15:04:07 +00:00
GemContextParam param { } ;
param . contextId = drmContextId ;
2020-08-17 12:07:39 +02:00
param . value = 0 ;
2023-12-13 09:05:31 +00:00
param . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamVm ) ;
2023-12-12 08:48:32 +00:00
auto retVal = ioctlHelper - > ioctl ( DrmIoctl : : gemContextGetparam , & param ) ;
2020-08-17 12:07:39 +02:00
2020-08-31 07:04:58 +02:00
vmId = static_cast < uint32_t > ( param . value ) ;
2020-08-17 12:07:39 +02:00
2020-08-31 07:04:58 +02:00
return retVal ;
2020-08-17 12:07:39 +02:00
}
2021-08-09 14:33:44 +00:00
std : : unique_lock < std : : mutex > Drm : : lockBindFenceMutex ( ) {
return std : : unique_lock < std : : mutex > ( this - > bindFenceMutex ) ;
}
2017-12-21 00:45:38 +01:00
int Drm : : getEuTotal ( int & euTotal ) {
2023-12-13 09:05:31 +00:00
return getParamIoctl ( DrmParam : : paramEuTotal , & euTotal ) ;
2017-12-21 00:45:38 +01:00
}
int Drm : : getSubsliceTotal ( int & subsliceTotal ) {
2023-12-13 09:05:31 +00:00
return getParamIoctl ( DrmParam : : paramSubsliceTotal , & subsliceTotal ) ;
2017-12-21 00:45:38 +01:00
}
int Drm : : getMinEuInPool ( int & minEUinPool ) {
2023-12-13 09:05:31 +00:00
return getParamIoctl ( DrmParam : : paramMinEuInPool , & minEUinPool ) ;
2017-12-21 00:45:38 +01:00
}
2018-02-28 12:09:48 +01:00
int Drm : : getErrno ( ) {
return errno ;
}
2022-06-07 15:03:52 +00:00
int Drm : : setupHardwareInfo ( const DeviceDescriptor * device , bool setupFeatureTableAndWorkaroundTable ) {
2024-07-03 11:44:23 +00:00
const auto usDeviceIdOverride = rootDeviceEnvironment . getHardwareInfo ( ) - > platform . usDeviceID ;
const auto usRevIdOverride = rootDeviceEnvironment . getHardwareInfo ( ) - > platform . usRevId ;
2022-08-08 19:04:04 +00:00
2024-07-03 11:44:23 +00:00
// reset hwInfo and apply overrides
2023-06-06 11:41:57 +00:00
rootDeviceEnvironment . setHwInfo ( device - > pHwInfo ) ;
2024-07-03 11:44:23 +00:00
HardwareInfo * hwInfo = rootDeviceEnvironment . getMutableHardwareInfo ( ) ;
hwInfo - > platform . usDeviceID = usDeviceIdOverride ;
hwInfo - > platform . usRevId = usRevIdOverride ;
2023-06-06 11:41:57 +00:00
rootDeviceEnvironment . initProductHelper ( ) ;
rootDeviceEnvironment . initGfxCoreHelper ( ) ;
2025-03-17 11:54:26 +00:00
rootDeviceEnvironment . initializeGfxCoreHelperFromProductHelper ( ) ;
2023-06-06 11:41:57 +00:00
rootDeviceEnvironment . initApiGfxCoreHelper ( ) ;
rootDeviceEnvironment . initCompilerProductHelper ( ) ;
2023-11-28 15:15:25 +00:00
rootDeviceEnvironment . initAilConfigurationHelper ( ) ;
2025-03-27 14:00:16 +00:00
rootDeviceEnvironment . initWaitUtils ( ) ;
2023-11-28 15:15:25 +00:00
auto result = rootDeviceEnvironment . initAilConfiguration ( ) ;
if ( false = = result ) {
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " FATAL: AIL creation failed! \n " ) ;
return - 1 ;
}
2019-10-18 10:15:09 +02:00
2022-01-28 21:00:05 +00:00
const auto productFamily = hwInfo - > platform . eProductFamily ;
setupIoctlHelper ( productFamily ) ;
2023-05-22 15:15:17 +00:00
ioctlHelper - > setupIpVersion ( ) ;
2023-06-06 11:41:57 +00:00
rootDeviceEnvironment . initReleaseHelper ( ) ;
2021-04-27 14:45:13 +00:00
2024-07-25 14:35:48 +00:00
auto releaseHelper = rootDeviceEnvironment . getReleaseHelper ( ) ;
device - > setupHardwareInfo ( hwInfo , setupFeatureTableAndWorkaroundTable , releaseHelper ) ;
2025-05-16 18:59:54 +00:00
this - > adjustSharedSystemMemCapabilities ( ) ;
2024-07-25 14:35:48 +00:00
2024-07-24 16:19:00 +00:00
querySystemInfo ( ) ;
if ( systemInfo ) {
systemInfo - > checkSysInfoMismatch ( hwInfo ) ;
setupSystemInfo ( hwInfo , systemInfo . get ( ) ) ;
2024-10-16 12:05:13 +00:00
2024-10-18 11:59:51 +00:00
auto numRegions = systemInfo - > getNumRegions ( ) ;
if ( numRegions > 0 ) {
hwInfo - > featureTable . regionCount = numRegions ;
}
2025-08-20 17:36:09 +00:00
hwInfo - > gtSystemInfo . NumThreadsPerEu = systemInfo - > getNumThreadsPerEu ( ) ;
2024-07-24 16:19:00 +00:00
}
2025-07-23 10:29:50 +00:00
auto & productHelper = rootDeviceEnvironment . getProductHelper ( ) ;
auto capsReader = productHelper . getDeviceCapsReader ( * this ) ;
if ( capsReader ) {
if ( ! productHelper . setupHardwareInfo ( * hwInfo , * capsReader ) )
return - 1 ;
}
2024-07-25 14:35:48 +00:00
if ( ! queryMemoryInfo ( ) ) {
setPerContextVMRequired ( true ) ;
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " WARNING: Failed to query memory info \n " ) ;
2025-04-09 21:32:48 +00:00
} else if ( getMemoryInfo ( ) - > isSmallBarDetected ( ) ) {
IoFunctions : : fprintf ( stderr , " WARNING: Small BAR detected for device %s \n " , getPciPath ( ) . c_str ( ) ) ;
2025-05-29 09:51:18 +00:00
if ( ! ioctlHelper - > isSmallBarConfigAllowed ( ) ) {
return - 1 ;
}
2024-07-25 14:35:48 +00:00
}
if ( ! queryEngineInfo ( ) ) {
setPerContextVMRequired ( true ) ;
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " WARNING: Failed to query engine info \n " ) ;
}
2020-06-09 15:51:26 +02:00
2025-08-07 01:39:46 +02:00
if ( ! hwInfo - > gtSystemInfo . L3BankCount ) {
hwInfo - > gtSystemInfo . L3BankCount = hwInfo - > gtSystemInfo . MaxDualSubSlicesSupported ;
}
2024-07-24 16:19:00 +00:00
DrmQueryTopologyData topologyData = { } ;
2024-07-25 05:18:41 +02:00
2024-07-24 16:19:00 +00:00
if ( ! queryTopology ( * hwInfo , topologyData ) ) {
topologyData . sliceCount = hwInfo - > gtSystemInfo . SliceCount ;
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " WARNING: Topology query failed! \n " ) ;
2020-06-09 15:51:26 +02:00
2022-08-08 19:04:04 +00:00
auto ret = getEuTotal ( topologyData . euCount ) ;
2020-06-09 15:51:26 +02:00
if ( ret ! = 0 ) {
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " FATAL: Cannot query EU total parameter! \n " ) ;
2020-06-09 15:51:26 +02:00
return ret ;
}
2019-10-18 10:15:09 +02:00
2021-04-27 14:45:13 +00:00
ret = getSubsliceTotal ( topologyData . subSliceCount ) ;
2020-06-09 15:51:26 +02:00
if ( ret ! = 0 ) {
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " FATAL: Cannot query subslice total parameter! \n " ) ;
2020-06-09 15:51:26 +02:00
return ret ;
}
2019-10-18 10:15:09 +02:00
}
2021-04-27 14:45:13 +00:00
hwInfo - > gtSystemInfo . SliceCount = static_cast < uint32_t > ( topologyData . sliceCount ) ;
2024-07-31 13:40:41 +00:00
if ( ! topologyMap . empty ( ) ) {
hwInfo - > gtSystemInfo . IsDynamicallyPopulated = true ;
std : : bitset < GT_MAX_SLICE > totalSliceMask { maxNBitValue ( GT_MAX_SLICE ) } ;
uint32_t latestSliceIndex = 0 ;
for ( auto & mapping : topologyMap ) {
std : : bitset < GT_MAX_SLICE > sliceMask ;
DEBUG_BREAK_IF ( mapping . second . sliceIndices . empty ( ) ) ;
for ( auto & slice : mapping . second . sliceIndices ) {
sliceMask . set ( slice ) ;
latestSliceIndex = slice ;
}
totalSliceMask & = sliceMask ;
}
for ( uint32_t slice = 0 ; slice < GT_MAX_SLICE ; slice + + ) {
hwInfo - > gtSystemInfo . SliceInfo [ slice ] . Enabled = totalSliceMask . test ( slice ) ;
}
if ( totalSliceMask . none ( ) ) {
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " FATAL: Incorrect slice mask from topology map! \n " ) ;
return - 1 ;
}
if ( totalSliceMask . count ( ) = = 1u ) {
std : : bitset < GT_MAX_SUBSLICE_PER_SLICE > totalSubSliceMask { maxNBitValue ( GT_MAX_SUBSLICE_PER_SLICE ) } ;
for ( auto & mapping : topologyMap ) {
std : : bitset < GT_MAX_SUBSLICE_PER_SLICE > subSliceMask ;
DEBUG_BREAK_IF ( mapping . second . subsliceIndices . empty ( ) ) ;
for ( auto & subslice : mapping . second . subsliceIndices ) {
if ( subslice > = GT_MAX_SUBSLICE_PER_SLICE ) {
subSliceMask = { } ;
break ;
}
subSliceMask . set ( subslice ) ;
}
totalSubSliceMask & = subSliceMask ;
}
2024-07-24 16:19:00 +00:00
2024-07-31 13:40:41 +00:00
for ( uint32_t subslice = 0 ; subslice < GT_MAX_SUBSLICE_PER_SLICE ; subslice + + ) {
hwInfo - > gtSystemInfo . SliceInfo [ latestSliceIndex ] . SubSliceInfo [ subslice ] . Enabled = totalSubSliceMask . test ( subslice ) ;
}
}
2024-07-24 16:19:00 +00:00
}
2021-04-27 14:45:13 +00:00
hwInfo - > gtSystemInfo . SubSliceCount = static_cast < uint32_t > ( topologyData . subSliceCount ) ;
2021-06-01 13:07:41 +00:00
hwInfo - > gtSystemInfo . DualSubSliceCount = static_cast < uint32_t > ( topologyData . subSliceCount ) ;
2024-07-25 14:35:48 +00:00
2024-07-26 16:46:59 +00:00
if ( ! hwInfo - > gtSystemInfo . MaxEuPerSubSlice ) {
hwInfo - > gtSystemInfo . MaxEuPerSubSlice = topologyData . maxEusPerSubSlice ;
}
2024-07-24 16:19:00 +00:00
auto maxEuCount = static_cast < uint32_t > ( topologyData . subSliceCount ) * hwInfo - > gtSystemInfo . MaxEuPerSubSlice ;
2024-07-25 14:35:48 +00:00
2024-07-24 16:19:00 +00:00
if ( topologyData . euCount = = 0 | | static_cast < uint32_t > ( topologyData . euCount ) > maxEuCount ) {
hwInfo - > gtSystemInfo . EUCount = maxEuCount ;
} else {
hwInfo - > gtSystemInfo . EUCount = static_cast < uint32_t > ( topologyData . euCount ) ;
2023-11-15 10:05:30 +00:00
}
2024-07-24 16:19:00 +00:00
if ( ! hwInfo - > gtSystemInfo . EUCount ) {
return - 1 ;
2024-07-25 05:18:41 +02:00
}
2024-07-24 15:02:50 +00:00
2025-05-23 14:25:55 +00:00
if ( debugManager . flags . OverrideNumThreadsPerEu . get ( ) ! = - 1 ) {
2025-08-20 17:36:09 +00:00
hwInfo - > gtSystemInfo . NumThreadsPerEu = debugManager . flags . OverrideNumThreadsPerEu . get ( ) ;
2025-05-23 14:25:55 +00:00
}
2024-07-24 15:02:50 +00:00
2025-08-20 17:36:09 +00:00
hwInfo - > gtSystemInfo . ThreadCount = hwInfo - > gtSystemInfo . NumThreadsPerEu * hwInfo - > gtSystemInfo . EUCount ;
2024-07-24 16:19:00 +00:00
2025-08-14 01:49:14 +00:00
if ( ioctlHelper - > overrideMaxSlicesSupported ( ) ) {
hwInfo - > gtSystemInfo . MaxSlicesSupported = hwInfo - > gtSystemInfo . SliceCount ;
}
2024-07-24 16:19:00 +00:00
2025-08-07 01:39:46 +02:00
auto calculatedMaxSubSliceCount = topologyData . maxSlices * topologyData . maxSubSlicesPerSlice ;
auto maxSubSliceCount = std : : max ( static_cast < uint32_t > ( calculatedMaxSubSliceCount ) , hwInfo - > gtSystemInfo . MaxSubSlicesSupported ) ;
2024-07-24 16:19:00 +00:00
2025-08-07 01:39:46 +02:00
hwInfo - > gtSystemInfo . MaxSubSlicesSupported = maxSubSliceCount ;
hwInfo - > gtSystemInfo . MaxDualSubSlicesSupported = maxSubSliceCount ;
2024-07-24 16:19:00 +00:00
if ( topologyData . numL3Banks > 0 ) {
hwInfo - > gtSystemInfo . L3BankCount = topologyData . numL3Banks ;
}
2022-10-05 18:48:44 +00:00
2024-07-24 16:19:00 +00:00
if ( systemInfo ) {
2025-08-19 12:26:44 +00:00
if ( systemInfo - > getNumL3BanksPerGroup ( ) > 0 & & systemInfo - > getNumL3BankGroups ( ) > 0 ) {
hwInfo - > gtSystemInfo . L3BankCount = systemInfo - > getNumL3BanksPerGroup ( ) * systemInfo - > getNumL3BankGroups ( ) ;
}
2024-07-29 10:43:24 +00:00
hwInfo - > gtSystemInfo . L3CacheSizeInKb = systemInfo - > getL3BankSizeInKb ( ) * hwInfo - > gtSystemInfo . L3BankCount ;
2020-11-24 16:00:33 +01:00
}
2024-07-24 16:19:00 +00:00
rootDeviceEnvironment . setRcsExposure ( ) ;
2021-01-29 22:23:06 +00:00
setupCacheInfo ( * hwInfo ) ;
2024-07-03 11:44:23 +00:00
hwInfo - > capabilityTable . deviceName = device - > devName ;
2021-01-29 22:23:06 +00:00
2024-09-12 13:00:25 +00:00
rootDeviceEnvironment . initializeGfxCoreHelperFromHwInfo ( ) ;
2019-10-18 10:15:09 +02:00
return 0 ;
}
2023-03-01 09:29:12 +00:00
void appendHwDeviceId ( std : : vector < std : : unique_ptr < HwDeviceId > > & hwDeviceIds , int fileDescriptor , const char * pciPath , const char * devNodePath ) {
2020-04-08 11:27:04 +02:00
if ( fileDescriptor > = 0 ) {
2022-05-19 17:22:41 +00:00
if ( Drm : : isDrmSupported ( fileDescriptor ) ) {
2023-03-01 09:29:12 +00:00
hwDeviceIds . push_back ( std : : make_unique < HwDeviceIdDrm > ( fileDescriptor , pciPath , devNodePath ) ) ;
2020-04-08 11:27:04 +02:00
} else {
SysCalls : : close ( fileDescriptor ) ;
}
}
}
2021-05-27 19:44:47 +02:00
std : : vector < std : : unique_ptr < HwDeviceId > > Drm : : discoverDevices ( ExecutionEnvironment & executionEnvironment ) {
2021-10-11 15:34:03 +00:00
std : : string str = " " ;
return Drm : : discoverDevices ( executionEnvironment , str ) ;
}
std : : vector < std : : unique_ptr < HwDeviceId > > Drm : : discoverDevice ( ExecutionEnvironment & executionEnvironment , std : : string & osPciPath ) {
return Drm : : discoverDevices ( executionEnvironment , osPciPath ) ;
}
std : : vector < std : : unique_ptr < HwDeviceId > > Drm : : discoverDevices ( ExecutionEnvironment & executionEnvironment , std : : string & osPciPath ) {
2020-02-17 16:14:22 +01:00
std : : vector < std : : unique_ptr < HwDeviceId > > hwDeviceIds ;
2020-03-17 07:26:46 +01:00
executionEnvironment . osEnvironment = std : : make_unique < OsEnvironment > ( ) ;
2020-04-08 11:27:04 +02:00
size_t numRootDevices = 0u ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . CreateMultipleRootDevices . get ( ) ) {
numRootDevices = debugManager . flags . CreateMultipleRootDevices . get ( ) ;
2020-02-17 16:14:22 +01:00
}
2020-04-08 11:27:04 +02:00
2025-07-28 14:51:46 +00:00
errno = 0 ;
2020-04-08 11:27:04 +02:00
std : : vector < std : : string > files = Directory : : getFiles ( Os : : pciDevicesDirectory ) ;
2025-07-28 14:51:46 +00:00
int returnedErrno = errno ;
2020-04-08 11:27:04 +02:00
if ( files . size ( ) = = 0 ) {
2025-07-28 14:51:46 +00:00
if ( returnedErrno = = EACCES | | returnedErrno = = EPERM ) {
executionEnvironment . setDevicePermissionError ( true ) ;
}
2020-04-08 11:27:04 +02:00
const char * pathPrefix = " /dev/dri/renderD " ;
const unsigned int maxDrmDevices = 64 ;
unsigned int startNum = 128 ;
for ( unsigned int i = 0 ; i < maxDrmDevices ; i + + ) {
std : : string path = std : : string ( pathPrefix ) + std : : to_string ( i + startNum ) ;
2023-05-05 08:59:45 +00:00
int fileDescriptor = SysCalls : : open ( path . c_str ( ) , O_RDWR | O_CLOEXEC ) ;
2021-03-29 13:43:50 +02:00
2023-10-10 08:28:06 +00:00
if ( fileDescriptor < 0 ) {
2025-07-28 14:51:46 +00:00
returnedErrno = errno ;
if ( returnedErrno = = EACCES | | returnedErrno = = EPERM ) {
executionEnvironment . setDevicePermissionError ( true ) ;
}
2023-10-10 08:28:06 +00:00
continue ;
}
2021-05-20 00:36:24 +02:00
auto pciPath = NEO : : getPciPath ( fileDescriptor ) ;
2021-03-29 13:43:50 +02:00
2023-03-01 09:29:12 +00:00
appendHwDeviceId ( hwDeviceIds , fileDescriptor , pciPath . value_or ( " 0000:00:02.0 " ) . c_str ( ) , path . c_str ( ) ) ;
2020-05-21 13:01:07 +02:00
if ( ! hwDeviceIds . empty ( ) & & hwDeviceIds . size ( ) = = numRootDevices ) {
break ;
}
2020-02-07 14:32:02 +01:00
}
2025-07-28 14:51:46 +00:00
if ( ! hwDeviceIds . empty ( ) ) {
executionEnvironment . setDevicePermissionError ( false ) ;
}
2020-02-17 16:14:22 +01:00
return hwDeviceIds ;
2020-02-07 14:32:02 +01:00
}
2020-04-08 11:27:04 +02:00
do {
2021-10-26 17:29:17 +00:00
const char * renderDeviceSuffix = " -render " ;
2020-04-08 11:27:04 +02:00
for ( std : : vector < std : : string > : : iterator file = files . begin ( ) ; file ! = files . end ( ) ; + + file ) {
2021-10-26 17:29:17 +00:00
std : : string_view devicePathView ( file - > c_str ( ) , file - > size ( ) ) ;
devicePathView = devicePathView . substr ( strlen ( Os : : pciDevicesDirectory ) ) ;
auto rdsPos = devicePathView . rfind ( renderDeviceSuffix ) ;
if ( rdsPos = = std : : string : : npos ) {
continue ;
}
if ( rdsPos < devicePathView . size ( ) - strlen ( renderDeviceSuffix ) ) {
continue ;
}
// at least 'pci-0000:00:00.0' -> 16
if ( rdsPos < 16 | | devicePathView [ rdsPos - 13 ] ! = ' - ' ) {
2020-04-08 11:27:04 +02:00
continue ;
2020-02-07 14:32:02 +01:00
}
2021-10-26 17:29:17 +00:00
std : : string pciPath ( devicePathView . substr ( rdsPos - 12 , 12 ) ) ;
2020-04-08 11:27:04 +02:00
2021-10-11 15:34:03 +00:00
if ( ! osPciPath . empty ( ) ) {
if ( osPciPath . compare ( pciPath ) ! = 0 ) {
2025-07-28 14:51:46 +00:00
// if osPciPath is non-empty, then interest is only in discovering device having same bdf as osPciPath. Skip all other devices.
2021-10-11 15:34:03 +00:00
continue ;
}
}
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . FilterBdfPath . get ( ) ! = " unk " ) {
if ( devicePathView . find ( debugManager . flags . FilterBdfPath . get ( ) . c_str ( ) ) = = std : : string : : npos ) {
2022-01-31 17:43:42 +00:00
continue ;
}
}
2023-05-05 08:59:45 +00:00
int fileDescriptor = SysCalls : : open ( file - > c_str ( ) , O_RDWR | O_CLOEXEC ) ;
2025-07-28 14:51:46 +00:00
if ( fileDescriptor < 0 ) {
returnedErrno = errno ;
if ( returnedErrno = = EACCES | | returnedErrno = = EPERM ) {
executionEnvironment . setDevicePermissionError ( true ) ;
}
continue ;
}
2023-03-01 09:29:12 +00:00
appendHwDeviceId ( hwDeviceIds , fileDescriptor , pciPath . c_str ( ) , file - > c_str ( ) ) ;
2020-05-21 13:01:07 +02:00
if ( ! hwDeviceIds . empty ( ) & & hwDeviceIds . size ( ) = = numRootDevices ) {
break ;
}
2020-02-07 14:32:02 +01:00
}
2020-04-08 11:27:04 +02:00
if ( hwDeviceIds . empty ( ) ) {
return hwDeviceIds ;
}
} while ( hwDeviceIds . size ( ) < numRootDevices ) ;
2025-07-28 14:51:46 +00:00
if ( ! hwDeviceIds . empty ( ) ) {
executionEnvironment . setDevicePermissionError ( false ) ;
}
2020-02-17 16:14:22 +01:00
return hwDeviceIds ;
2020-02-07 14:32:02 +01:00
}
2022-05-19 17:22:41 +00:00
std : : string Drm : : getDrmVersion ( int fileDescriptor ) {
2022-05-24 16:13:02 +00:00
DrmVersion version = { } ;
2020-02-07 14:32:02 +01:00
char name [ 5 ] = { } ;
version . name = name ;
2022-05-24 16:13:02 +00:00
version . nameLen = 5 ;
2020-02-07 14:32:02 +01:00
2023-12-12 08:48:32 +00:00
auto requestValue = getIoctlRequestValue ( DrmIoctl : : version , nullptr ) ;
2022-08-08 14:02:17 +00:00
int ret = SysCalls : : ioctl ( fileDescriptor , requestValue , & version ) ;
2020-02-07 14:32:02 +01:00
if ( ret ) {
2022-05-19 17:22:41 +00:00
return { } ;
2020-02-07 14:32:02 +01:00
}
name [ 4 ] = ' \0 ' ;
2022-05-19 17:22:41 +00:00
return std : : string ( name ) ;
2020-02-07 14:32:02 +01:00
}
2023-10-02 14:26:33 +00:00
template < typename DataType >
std : : vector < DataType > Drm : : query ( uint32_t queryId , uint32_t queryItemFlags ) {
2022-05-24 16:13:02 +00:00
Query query { } ;
2022-05-17 21:40:34 +00:00
QueryItem queryItem { } ;
queryItem . queryId = queryId ;
2020-06-09 15:51:26 +02:00
queryItem . length = 0 ; // query length first
2020-11-19 12:04:17 +01:00
queryItem . flags = queryItemFlags ;
2022-05-24 16:13:02 +00:00
query . itemsPtr = reinterpret_cast < uint64_t > ( & queryItem ) ;
query . numItems = 1 ;
2020-06-09 15:51:26 +02:00
2023-12-12 08:48:32 +00:00
auto ret = ioctlHelper - > ioctl ( DrmIoctl : : query , & query ) ;
2020-06-09 15:51:26 +02:00
if ( ret ! = 0 | | queryItem . length < = 0 ) {
2021-12-22 14:25:53 +00:00
return { } ;
2020-06-09 15:51:26 +02:00
}
2023-10-02 14:26:33 +00:00
auto data = std : : vector < DataType > ( Math : : divideAndRoundUp ( queryItem . length , sizeof ( DataType ) ) , 0 ) ;
2022-05-17 21:40:34 +00:00
queryItem . dataPtr = castToUint64 ( data . data ( ) ) ;
2020-06-09 15:51:26 +02:00
2023-12-12 08:48:32 +00:00
ret = ioctlHelper - > ioctl ( DrmIoctl : : query , & query ) ;
2020-06-09 15:51:26 +02:00
if ( ret ! = 0 | | queryItem . length < = 0 ) {
2021-12-22 14:25:53 +00:00
return { } ;
2020-06-09 15:51:26 +02:00
}
return data ;
}
2021-04-21 13:52:11 +00:00
void Drm : : printIoctlStatistics ( ) {
2024-02-07 16:19:02 +00:00
if ( ! debugManager . flags . PrintKmdTimes . get ( ) ) {
2021-04-21 13:52:11 +00:00
return ;
}
2021-05-11 12:56:07 +00:00
printf ( " \n --- Ioctls statistics --- \n " ) ;
2021-08-19 15:26:34 +00:00
printf ( " %41s %15s %10s %20s %20s %20s " , " Request " , " Total time(ns) " , " Count " , " Avg time per ioctl " , " Min " , " Max \n " ) ;
2021-04-21 13:52:11 +00:00
for ( const auto & ioctlData : this - > ioctlStatistics ) {
2021-08-19 15:26:34 +00:00
printf ( " %41s %15llu %10lu %20f %20lld %20lld \n " ,
2024-12-17 14:41:33 +00:00
ioctlHelper - > getIoctlString ( ioctlData . first ) . c_str ( ) ,
2021-08-19 15:26:34 +00:00
ioctlData . second . totalTime ,
static_cast < unsigned long > ( ioctlData . second . count ) ,
ioctlData . second . totalTime / static_cast < double > ( ioctlData . second . count ) ,
ioctlData . second . minTime ,
ioctlData . second . maxTime ) ;
2021-04-21 13:52:11 +00:00
}
printf ( " \n " ) ;
}
2020-07-07 09:34:31 +02:00
bool Drm : : createVirtualMemoryAddressSpace ( uint32_t vmCount ) {
for ( auto i = 0u ; i < vmCount ; i + + ) {
2021-03-16 17:47:26 +00:00
uint32_t id = i ;
2020-07-14 04:36:16 +02:00
if ( 0 ! = createDrmVirtualMemory ( id ) ) {
return false ;
}
2020-07-07 09:34:31 +02:00
virtualMemoryIds . push_back ( id ) ;
}
return true ;
}
void Drm : : destroyVirtualMemoryAddressSpace ( ) {
for ( auto id : virtualMemoryIds ) {
destroyDrmVirtualMemory ( id ) ;
}
2020-08-04 10:23:54 +02:00
virtualMemoryIds . clear ( ) ;
2020-07-07 09:34:31 +02:00
}
2022-07-25 11:50:32 +00:00
uint32_t Drm : : getVirtualMemoryAddressSpace ( uint32_t vmId ) const {
2020-07-14 04:36:16 +02:00
if ( vmId < virtualMemoryIds . size ( ) ) {
return virtualMemoryIds [ vmId ] ;
}
return 0 ;
2020-07-07 09:34:31 +02:00
}
2023-01-17 14:26:25 +00:00
void Drm : : setNewResourceBoundToVM ( BufferObject * bo , uint32_t vmHandleId ) {
2023-12-24 07:46:47 +01:00
if ( ! this - > rootDeviceEnvironment . getProductHelper ( ) . isTlbFlushRequired ( ) ) {
2023-01-12 06:17:26 +00:00
return ;
}
2023-04-26 10:36:25 +00:00
const auto & engines = this - > rootDeviceEnvironment . executionEnvironment . memoryManager - > getRegisteredEngines ( bo - > getRootDeviceIndex ( ) ) ;
2022-06-22 16:39:36 +02:00
for ( const auto & engine : engines ) {
2023-01-02 12:36:07 +00:00
if ( engine . osContext - > getDeviceBitfield ( ) . test ( vmHandleId ) ) {
2022-06-22 16:39:36 +02:00
auto osContextLinux = static_cast < OsContextLinux * > ( engine . osContext ) ;
2023-04-26 10:36:25 +00:00
osContextLinux - > setNewResourceBound ( ) ;
2021-09-01 16:28:18 +00:00
}
}
}
2020-11-05 15:40:03 +03:00
PhysicalDevicePciBusInfo Drm : : getPciBusInfo ( ) const {
2022-05-09 17:40:30 +00:00
PhysicalDevicePciBusInfo pciBusInfo ( PhysicalDevicePciBusInfo : : invalidValue , PhysicalDevicePciBusInfo : : invalidValue , PhysicalDevicePciBusInfo : : invalidValue , PhysicalDevicePciBusInfo : : invalidValue ) ;
2020-11-05 15:40:03 +03:00
2021-05-31 16:58:10 +00:00
if ( adapterBDF . Data ! = std : : numeric_limits < uint32_t > : : max ( ) ) {
2021-10-21 16:09:45 +00:00
pciBusInfo . pciDomain = this - > pciDomain ;
2021-05-31 16:58:10 +00:00
pciBusInfo . pciBus = adapterBDF . Bus ;
pciBusInfo . pciDevice = adapterBDF . Device ;
pciBusInfo . pciFunction = adapterBDF . Function ;
2020-11-05 15:40:03 +03:00
}
return pciBusInfo ;
}
2022-07-19 17:13:51 +00:00
void Drm : : cleanup ( ) {
2020-07-07 09:34:31 +02:00
destroyVirtualMemoryAddressSpace ( ) ;
2022-07-19 17:13:51 +00:00
}
Drm : : ~ Drm ( ) {
2021-04-21 13:52:11 +00:00
this - > printIoctlStatistics ( ) ;
2020-07-07 09:34:31 +02:00
}
2020-02-13 15:04:21 +01:00
2021-05-31 16:58:10 +00:00
int Drm : : queryAdapterBDF ( ) {
2021-10-06 01:57:55 +00:00
constexpr int pciBusInfoTokensNum = 4 ;
2022-01-17 11:59:54 +00:00
uint16_t domain = - 1 ;
uint8_t bus = - 1 , device = - 1 , function = - 1 ;
2021-04-23 14:30:04 +00:00
2022-01-17 11:59:54 +00:00
if ( NEO : : parseBdfString ( hwDeviceId - > getPciPath ( ) , domain , bus , device , function ) ! = pciBusInfoTokensNum ) {
2021-05-31 16:58:10 +00:00
adapterBDF . Data = std : : numeric_limits < uint32_t > : : max ( ) ;
return 1 ;
2021-04-23 14:30:04 +00:00
}
2021-10-06 01:57:55 +00:00
setPciDomain ( domain ) ;
2021-04-23 14:30:04 +00:00
adapterBDF . Bus = bus ;
adapterBDF . Function = function ;
adapterBDF . Device = device ;
2021-05-31 16:58:10 +00:00
return 0 ;
2021-04-23 14:30:04 +00:00
}
2021-05-21 01:17:57 +02:00
void Drm : : setGmmInputArgs ( void * args ) {
auto gmmInArgs = reinterpret_cast < GMM_INIT_IN_ARGS * > ( args ) ;
2021-05-26 11:23:04 +00:00
# if defined(__linux__)
2021-05-21 01:17:57 +02:00
gmmInArgs - > FileDescriptor = adapterBDF . Data ;
2021-05-26 11:23:04 +00:00
# endif
2021-05-21 01:17:57 +02:00
gmmInArgs - > ClientType = GMM_CLIENT : : GMM_OCL_VISTA ;
}
2021-05-07 15:29:28 +00:00
const std : : vector < int > & Drm : : getSliceMappings ( uint32_t deviceIndex ) {
return topologyMap [ deviceIndex ] . sliceIndices ;
}
2021-06-15 11:31:12 +00:00
int Drm : : waitHandle ( uint32_t waitHandle , int64_t timeout ) {
2021-08-16 14:12:33 +00:00
UNRECOVERABLE_IF ( isVmBindAvailable ( ) ) ;
2022-05-24 15:06:15 +00:00
GemWait wait { } ;
wait . boHandle = waitHandle ;
wait . timeoutNs = timeout ;
2021-06-04 12:23:20 +00:00
2025-04-07 13:54:45 +00:00
StackVec < std : : unique_lock < NEO : : CommandStreamReceiver : : MutexType > , 1 > locks { } ;
2025-02-11 14:31:01 +00:00
if ( this - > rootDeviceEnvironment . executionEnvironment . memoryManager ) {
const auto & mulitEngines = this - > rootDeviceEnvironment . executionEnvironment . memoryManager - > getRegisteredEngines ( ) ;
for ( const auto & engines : mulitEngines ) {
for ( const auto & engine : engines ) {
2025-02-13 14:14:28 +00:00
if ( engine . osContext - > isDirectSubmissionLightActive ( ) ) {
2025-04-07 13:54:45 +00:00
locks . push_back ( engine . commandStreamReceiver - > obtainUniqueOwnership ( ) ) ;
engine . commandStreamReceiver - > stopDirectSubmission ( false , false ) ;
2025-02-13 14:14:28 +00:00
}
2025-02-11 14:31:01 +00:00
}
}
}
2023-12-12 08:48:32 +00:00
int ret = ioctlHelper - > ioctl ( DrmIoctl : : gemWait , & wait ) ;
2021-06-15 11:31:12 +00:00
if ( ret ! = 0 ) {
int err = errno ;
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(I915_GEM_WAIT) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
2021-06-15 11:31:12 +00:00
}
return ret ;
2021-06-04 12:23:20 +00:00
}
2021-06-25 12:28:28 +00:00
int Drm : : getTimestampFrequency ( int & frequency ) {
frequency = 0 ;
2023-12-13 09:05:31 +00:00
return getParamIoctl ( DrmParam : : paramCsTimestampFrequency , & frequency ) ;
2021-06-25 12:28:28 +00:00
}
2023-04-18 13:19:12 +00:00
int Drm : : getOaTimestampFrequency ( int & frequency ) {
2023-04-25 17:31:35 +00:00
frequency = 0 ;
2023-12-13 09:05:31 +00:00
return getParamIoctl ( DrmParam : : paramOATimestampFrequency , & frequency ) ;
2023-04-25 17:31:35 +00:00
}
2021-09-03 15:20:44 +00:00
bool Drm : : queryEngineInfo ( ) {
2024-07-25 15:30:26 +00:00
UNRECOVERABLE_IF ( ! memoryInfoQueried ) ;
2024-07-25 15:08:16 +00:00
UNRECOVERABLE_IF ( engineInfoQueried ) ;
engineInfoQueried = true ;
2021-09-03 15:20:44 +00:00
return Drm : : queryEngineInfo ( false ) ;
}
bool Drm : : sysmanQueryEngineInfo ( ) {
return Drm : : queryEngineInfo ( true ) ;
}
2022-03-25 18:51:25 +00:00
bool Drm : : isDebugAttachAvailable ( ) {
2024-01-23 22:32:35 +00:00
int enableEuDebug = getEuDebugSysFsEnable ( ) ;
return ( enableEuDebug = = 1 ) & & ioctlHelper - > isDebugAttachAvailable ( ) ;
}
int Drm : : getEuDebugSysFsEnable ( ) {
return ioctlHelper - > getEuDebugSysFsEnable ( ) ;
2022-03-25 18:51:25 +00:00
}
2021-09-07 11:27:41 +00:00
int getMaxGpuFrequencyOfDevice ( Drm & drm , std : : string & sysFsPciPath , int & maxGpuFrequency ) {
maxGpuFrequency = 0 ;
2022-09-21 12:13:25 +00:00
std : : string clockSysFsPath = sysFsPciPath + drm . getIoctlHelper ( ) - > getFileForMaxGpuFrequency ( ) ;
2021-09-07 11:27:41 +00:00
std : : ifstream ifs ( clockSysFsPath . c_str ( ) , std : : ifstream : : in ) ;
if ( ifs . fail ( ) ) {
return - 1 ;
}
ifs > > maxGpuFrequency ;
ifs . close ( ) ;
return 0 ;
}
int getMaxGpuFrequencyOfSubDevice ( Drm & drm , std : : string & sysFsPciPath , int subDeviceId , int & maxGpuFrequency ) {
maxGpuFrequency = 0 ;
2022-09-21 12:13:25 +00:00
std : : string clockSysFsPath = sysFsPciPath + drm . getIoctlHelper ( ) - > getFileForMaxGpuFrequencyOfSubDevice ( subDeviceId ) ;
2021-09-07 11:27:41 +00:00
std : : ifstream ifs ( clockSysFsPath . c_str ( ) , std : : ifstream : : in ) ;
if ( ifs . fail ( ) ) {
return - 1 ;
}
ifs > > maxGpuFrequency ;
ifs . close ( ) ;
return 0 ;
}
int Drm : : getMaxGpuFrequency ( HardwareInfo & hwInfo , int & maxGpuFrequency ) {
int ret = 0 ;
std : : string sysFsPciPath = getSysFsPciPath ( ) ;
auto tileCount = hwInfo . gtSystemInfo . MultiTileArchInfo . TileCount ;
if ( hwInfo . gtSystemInfo . MultiTileArchInfo . IsValid & & tileCount > 0 ) {
for ( auto tileId = 0 ; tileId < tileCount ; tileId + + ) {
int maxGpuFreqOfSubDevice = 0 ;
ret | = getMaxGpuFrequencyOfSubDevice ( * this , sysFsPciPath , tileId , maxGpuFreqOfSubDevice ) ;
maxGpuFrequency = std : : max ( maxGpuFrequency , maxGpuFreqOfSubDevice ) ;
}
if ( ret = = 0 ) {
return 0 ;
}
}
return getMaxGpuFrequencyOfDevice ( * this , sysFsPciPath , maxGpuFrequency ) ;
}
2022-06-30 08:04:45 +00:00
bool Drm : : getDeviceMemoryMaxClockRateInMhz ( uint32_t tileId , uint32_t & clkRate ) {
2022-09-21 12:13:25 +00:00
const std : : string relativefilePath = ioctlHelper - > getFileForMaxMemoryFrequencyOfSubDevice ( tileId ) ;
2022-06-30 08:04:45 +00:00
std : : string readString ( 64 , ' \0 ' ) ;
errno = 0 ;
if ( readSysFsAsString ( relativefilePath , readString ) = = false ) {
return false ;
}
char * endPtr = nullptr ;
uint32_t retClkRate = static_cast < uint32_t > ( std : : strtoul ( readString . data ( ) , & endPtr , 10 ) ) ;
if ( ( endPtr = = readString . data ( ) ) | | ( errno ! = 0 ) ) {
return false ;
}
clkRate = retClkRate ;
return true ;
}
bool Drm : : getDeviceMemoryPhysicalSizeInBytes ( uint32_t tileId , uint64_t & physicalSize ) {
2025-03-06 09:57:13 +00:00
if ( memoryInfo = = nullptr | | memoryInfo - > getLocalMemoryRegions ( ) . size ( ) = = 0U ) {
physicalSize = 0U ;
2022-06-30 08:04:45 +00:00
return false ;
}
2025-03-06 09:57:13 +00:00
physicalSize = memoryInfo - > getLocalMemoryRegionSize ( tileId ) ;
2022-06-30 08:04:45 +00:00
return true ;
}
2021-11-18 21:36:55 +00:00
bool Drm : : useVMBindImmediate ( ) const {
2023-09-26 10:44:11 +00:00
bool useBindImmediate = isDirectSubmissionActive ( ) | | hasPageFaultSupport ( ) | | ioctlHelper - > isImmediateVmBindRequired ( ) ;
2021-11-18 21:36:55 +00:00
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . EnableImmediateVmBindExt . get ( ) ! = - 1 ) {
useBindImmediate = debugManager . flags . EnableImmediateVmBindExt . get ( ) ;
2021-11-18 21:36:55 +00:00
}
return useBindImmediate ;
}
2021-11-12 17:34:33 +00:00
void Drm : : setupSystemInfo ( HardwareInfo * hwInfo , SystemInfo * sysInfo ) {
GT_SYSTEM_INFO * gtSysInfo = & hwInfo - > gtSystemInfo ;
2024-07-17 12:00:53 +00:00
gtSysInfo - > MaxEuPerSubSlice = sysInfo - > getMaxEuPerDualSubSlice ( ) ;
2024-07-23 16:01:56 +02:00
gtSysInfo - > MemoryType = sysInfo - > getMemoryType ( ) ;
2021-11-12 17:34:33 +00:00
gtSysInfo - > MaxSlicesSupported = sysInfo - > getMaxSlicesSupported ( ) ;
2024-06-26 14:44:19 +00:00
gtSysInfo - > MaxSubSlicesSupported = sysInfo - > getMaxDualSubSlicesSupported ( ) ;
gtSysInfo - > MaxDualSubSlicesSupported = sysInfo - > getMaxDualSubSlicesSupported ( ) ;
2024-06-26 13:33:30 +00:00
gtSysInfo - > CsrSizeInMb = sysInfo - > getCsrSizeInMb ( ) ;
2024-06-26 13:00:29 +00:00
gtSysInfo - > SLMSizeInKb = sysInfo - > getSlmSizePerDss ( ) ;
2021-11-12 17:34:33 +00:00
}
2022-02-03 11:13:44 +00:00
void Drm : : setupCacheInfo ( const HardwareInfo & hwInfo ) {
2024-08-10 12:11:45 +00:00
auto & productHelper = rootDeviceEnvironment . getHelper < ProductHelper > ( ) ;
2022-02-03 11:13:44 +00:00
2025-02-25 16:08:04 +00:00
if ( debugManager . flags . ForceStaticL2ClosReservation . get ( ) ) {
if ( debugManager . flags . L2ClosNumCacheWays . get ( ) = = - 1 ) {
debugManager . flags . L2ClosNumCacheWays . set ( 2U ) ;
}
}
auto getL2CacheReservationLimits { [ & productHelper ] ( ) {
CacheReservationParameters out { } ;
if ( productHelper . getNumCacheRegions ( ) = = 0 ) {
return out ;
}
if ( auto numCacheWays { debugManager . flags . L2ClosNumCacheWays . get ( ) } ; numCacheWays ! = - 1 ) {
out . maxSize = 1U ;
out . maxNumRegions = 1U ;
out . maxNumWays = static_cast < uint16_t > ( numCacheWays ) ;
return out ;
}
return out ;
} } ;
2025-02-13 17:01:04 +00:00
auto getL3CacheReservationLimits { [ & hwInfo , & productHelper ] ( ) {
CacheReservationParameters out { } ;
if ( debugManager . flags . ClosEnabled . get ( ) = = 0 | | productHelper . getNumCacheRegions ( ) = = 0 ) {
return out ;
}
2022-02-03 11:13:44 +00:00
2025-02-25 16:08:04 +00:00
constexpr uint16_t totalMaxNumWays = 32U ;
constexpr uint16_t globalReservationLimit = 16U ;
constexpr uint16_t clientReservationLimit = 8U ;
2024-12-02 16:47:42 +00:00
const size_t totalCacheSize = hwInfo . gtSystemInfo . L3CacheSizeInKb * MemoryConstants : : kiloByte ;
2022-02-03 11:13:44 +00:00
2025-02-13 17:01:04 +00:00
out . maxNumWays = std : : min ( globalReservationLimit , clientReservationLimit ) ;
out . maxSize = ( totalCacheSize * out . maxNumWays ) / totalMaxNumWays ;
out . maxNumRegions = productHelper . getNumCacheRegions ( ) - 1 ;
return out ;
2024-12-02 16:47:42 +00:00
} } ;
2022-02-03 11:13:44 +00:00
2025-02-25 16:08:04 +00:00
this - > cacheInfo . reset ( new CacheInfo ( * ioctlHelper , getL2CacheReservationLimits ( ) , getL3CacheReservationLimits ( ) ) ) ;
if ( debugManager . flags . ForceStaticL2ClosReservation . get ( ) ) {
[[maybe_unused]] bool isReserved { this - > cacheInfo - > getCacheRegion ( getL2CacheReservationLimits ( ) . maxSize , CacheRegion : : region3 ) } ;
DEBUG_BREAK_IF ( ! isReserved ) ;
}
2022-02-03 11:13:44 +00:00
}
2021-12-08 10:10:27 +00:00
void Drm : : getPrelimVersion ( std : : string & prelimVersion ) {
std : : string sysFsPciPath = getSysFsPciPath ( ) ;
std : : string prelimVersionPath = sysFsPciPath + " /prelim_uapi_version " ;
std : : ifstream ifs ( prelimVersionPath . c_str ( ) , std : : ifstream : : in ) ;
if ( ifs . fail ( ) ) {
prelimVersion = " " ;
} else {
ifs > > prelimVersion ;
}
ifs . close ( ) ;
}
2024-05-07 11:47:34 +00:00
int Drm : : waitUserFence ( uint32_t ctxId , uint64_t address , uint64_t value , ValueWidth dataWidth , int64_t timeout , uint16_t flags , bool userInterrupt , uint32_t externalInterruptId , GraphicsAllocation * allocForInterruptWait ) {
return ioctlHelper - > waitUserFence ( ctxId , address , value , static_cast < uint32_t > ( dataWidth ) , timeout , flags , userInterrupt , externalInterruptId , allocForInterruptWait ) ;
2021-12-14 09:46:01 +00:00
}
bool Drm : : querySystemInfo ( ) {
2024-07-26 11:59:53 +00:00
if ( systemInfoQueried ) {
return this - > systemInfo ! = nullptr ;
}
systemInfoQueried = true ;
2023-12-13 09:05:31 +00:00
auto request = ioctlHelper - > getDrmParamValue ( DrmParam : : queryHwconfigTable ) ;
2023-10-02 14:26:33 +00:00
auto deviceBlobQuery = this - > query < uint32_t > ( request , 0 ) ;
2021-12-22 14:25:53 +00:00
if ( deviceBlobQuery . empty ( ) ) {
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stdout , " %s " , " INFO: System Info query failed! \n " ) ;
2021-12-14 09:46:01 +00:00
return false ;
}
2021-12-22 14:25:53 +00:00
this - > systemInfo . reset ( new SystemInfo ( deviceBlobQuery ) ) ;
2021-12-14 09:46:01 +00:00
return true ;
}
2023-10-02 14:26:33 +00:00
std : : vector < uint64_t > Drm : : getMemoryRegions ( ) {
2023-12-13 09:05:31 +00:00
auto request = ioctlHelper - > getDrmParamValue ( DrmParam : : queryMemoryRegions ) ;
2023-10-02 14:26:33 +00:00
return this - > query < uint64_t > ( request , 0 ) ;
2021-12-28 15:56:13 +00:00
}
bool Drm : : queryMemoryInfo ( ) {
2024-07-25 13:49:47 +00:00
UNRECOVERABLE_IF ( memoryInfoQueried ) ;
2023-04-29 00:37:13 +00:00
this - > memoryInfo = ioctlHelper - > createMemoryInfo ( ) ;
2024-07-25 13:49:47 +00:00
memoryInfoQueried = true ;
2023-04-29 00:37:13 +00:00
return this - > memoryInfo ! = nullptr ;
2021-12-28 15:56:13 +00:00
}
2022-01-04 14:48:05 +00:00
bool Drm : : queryEngineInfo ( bool isSysmanEnabled ) {
2023-04-29 00:37:13 +00:00
this - > engineInfo = ioctlHelper - > createEngineInfo ( isSysmanEnabled ) ;
2024-05-21 17:10:41 +00:00
if ( this - > engineInfo & & ( this - > engineInfo - > hasEngines ( ) = = false ) ) {
2024-04-25 15:08:27 +00:00
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " FATAL: Engine info size is equal to 0. \n " ) ;
}
2023-04-29 00:37:13 +00:00
return this - > engineInfo ! = nullptr ;
2022-01-04 14:48:05 +00:00
}
2022-01-20 18:13:07 +00:00
bool Drm : : completionFenceSupport ( ) {
std : : call_once ( checkCompletionFenceOnce , [ this ] ( ) {
2022-02-16 09:42:58 +00:00
const bool vmBindAvailable = isVmBindAvailable ( ) ;
2022-05-27 11:01:46 +00:00
bool support = ioctlHelper - > completionFenceExtensionSupported ( vmBindAvailable ) ;
2023-11-30 08:32:25 +00:00
int32_t overrideCompletionFence = debugManager . flags . EnableDrmCompletionFence . get ( ) ;
2022-01-20 18:13:07 +00:00
if ( overrideCompletionFence ! = - 1 ) {
support = ! ! overrideCompletionFence ;
}
completionFenceSupported = support ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . PrintCompletionFenceUsage . get ( ) ) {
2022-10-11 12:36:19 +00:00
std : : cout < < " Completion fence supported: " < < completionFenceSupported < < std : : endl ;
}
2022-01-20 18:13:07 +00:00
} ) ;
return completionFenceSupported ;
}
2022-01-28 21:00:05 +00:00
void Drm : : setupIoctlHelper ( const PRODUCT_FAMILY productFamily ) {
2022-06-08 15:12:31 +02:00
if ( ! this - > ioctlHelper ) {
2024-12-18 14:03:21 +00:00
auto drmVersion = Drm : : getDrmVersion ( getFileDescriptor ( ) ) ;
2024-12-18 09:45:58 +00:00
auto productSpecificIoctlHelperCreator = ioctlHelperFactory [ productFamily ] ;
2024-12-18 11:37:17 +00:00
if ( productSpecificIoctlHelperCreator & & ! debugManager . flags . IgnoreProductSpecificIoctlHelper . get ( ) ) {
2024-12-18 09:45:58 +00:00
this - > ioctlHelper = productSpecificIoctlHelperCreator . value ( ) ( * this ) ;
2024-12-18 14:03:21 +00:00
} else if ( " xe " = = drmVersion ) {
this - > ioctlHelper = IoctlHelperXe : : create ( * this ) ;
2024-12-18 09:45:58 +00:00
} else {
std : : string prelimVersion = " " ;
getPrelimVersion ( prelimVersion ) ;
this - > ioctlHelper = IoctlHelper : : getI915Helper ( productFamily , prelimVersion , * this ) ;
}
2022-09-12 12:50:07 +00:00
this - > ioctlHelper - > initialize ( ) ;
2022-06-08 15:12:31 +02:00
}
2022-01-28 21:00:05 +00:00
}
2023-06-20 07:34:12 +00:00
bool Drm : : queryTopology ( const HardwareInfo & hwInfo , DrmQueryTopologyData & topologyData ) {
2024-07-26 15:00:47 +00:00
UNRECOVERABLE_IF ( ! systemInfoQueried ) ;
2024-07-24 16:19:00 +00:00
UNRECOVERABLE_IF ( ! engineInfoQueried ) ;
2024-07-26 12:53:49 +00:00
UNRECOVERABLE_IF ( topologyQueried ) ;
topologyQueried = true ;
2023-06-20 07:34:12 +00:00
auto result = this - > ioctlHelper - > getTopologyDataAndMap ( hwInfo , topologyData , topologyMap ) ;
return result ;
2022-01-21 12:39:11 +00:00
}
2022-02-10 16:16:37 +00:00
void Drm : : queryPageFaultSupport ( ) {
2023-02-05 17:20:25 +00:00
const auto & productHelper = this - > getRootDeviceEnvironment ( ) . getHelper < ProductHelper > ( ) ;
if ( ! productHelper . isPageFaultSupported ( ) ) {
return ;
}
2022-02-10 16:16:37 +00:00
2024-08-13 11:27:54 +00:00
pageFaultSupported = this - > ioctlHelper - > isPageFaultSupported ( ) ;
2022-02-10 16:16:37 +00:00
}
2022-04-13 10:05:04 +00:00
bool Drm : : hasPageFaultSupport ( ) const {
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . EnableRecoverablePageFaults . get ( ) ! = - 1 ) {
return ! ! debugManager . flags . EnableRecoverablePageFaults . get ( ) ;
2022-04-13 10:05:04 +00:00
}
2023-01-27 14:09:11 +00:00
return pageFaultSupported ;
2022-04-13 10:05:04 +00:00
}
2023-05-17 00:17:32 +00:00
bool Drm : : hasKmdMigrationSupport ( ) const {
const auto & productHelper = this - > getRootDeviceEnvironment ( ) . getHelper < ProductHelper > ( ) ;
2025-01-23 03:25:47 +01:00
auto kmdMigrationSupported = hasPageFaultSupport ( ) & & productHelper . isKmdMigrationSupported ( ) ;
2023-05-17 00:17:32 +00:00
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . UseKmdMigration . get ( ) ! = - 1 ) {
return ! ! debugManager . flags . UseKmdMigration . get ( ) ;
2023-05-17 00:17:32 +00:00
}
return kmdMigrationSupported ;
}
2024-05-14 14:03:52 +00:00
void Drm : : configureScratchPagePolicy ( ) {
if ( debugManager . flags . DisableScratchPages . get ( ) ! = - 1 ) {
disableScratch = ! ! debugManager . flags . DisableScratchPages . get ( ) ;
return ;
}
const auto & productHelper = this - > getRootDeviceEnvironment ( ) . getHelper < ProductHelper > ( ) ;
2025-01-28 20:58:22 +00:00
if ( rootDeviceEnvironment . executionEnvironment . isDebuggingEnabled ( ) ) {
disableScratch = productHelper . isDisableScratchPagesRequiredForDebugger ( ) ;
} else {
disableScratch = productHelper . isDisableScratchPagesSupported ( ) ;
}
2024-04-08 18:37:35 +00:00
}
2024-05-14 14:03:52 +00:00
void Drm : : configureGpuFaultCheckThreshold ( ) {
2024-04-08 18:37:35 +00:00
if ( debugManager . flags . GpuFaultCheckThreshold . get ( ) ! = - 1 ) {
2024-05-14 14:03:52 +00:00
gpuFaultCheckThreshold = debugManager . flags . GpuFaultCheckThreshold . get ( ) ;
2024-04-08 18:37:35 +00:00
}
}
2024-10-08 13:23:41 +00:00
unsigned int Drm : : bindDrmContext ( uint32_t drmContextId , uint32_t deviceIndex , aub_stream : : EngineType engineType ) {
2022-02-11 13:46:23 +00:00
auto engineInfo = this - > engineInfo . get ( ) ;
2022-06-14 16:47:02 +00:00
auto retVal = static_cast < unsigned int > ( ioctlHelper - > getDrmParamValue ( DrmEngineMapper : : engineNodeMap ( engineType ) ) ) ;
2022-02-11 13:46:23 +00:00
if ( ! engineInfo ) {
2022-06-14 16:47:02 +00:00
return retVal ;
2022-02-11 13:46:23 +00:00
}
auto engine = engineInfo - > getEngineInstance ( deviceIndex , engineType ) ;
if ( ! engine ) {
2022-06-14 16:47:02 +00:00
return retVal ;
2022-02-11 13:46:23 +00:00
}
2024-10-08 13:23:41 +00:00
bool useVirtualEnginesForCcs = true ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . UseDrmVirtualEnginesForCcs . get ( ) ! = - 1 ) {
useVirtualEnginesForCcs = ! ! debugManager . flags . UseDrmVirtualEnginesForCcs . get ( ) ;
2022-02-11 13:46:23 +00:00
}
auto numberOfCCS = rootDeviceEnvironment . getHardwareInfo ( ) - > gtSystemInfo . CCSInfo . NumberOfCCSEnabled ;
constexpr uint32_t maxEngines = 9u ;
2022-07-04 15:46:15 +00:00
bool useVirtualEnginesForBcs = EngineHelpers : : isBcsVirtualEngineEnabled ( engineType ) ;
2022-02-11 13:46:23 +00:00
auto numberOfBCS = rootDeviceEnvironment . getHardwareInfo ( ) - > featureTable . ftrBcsInfo . count ( ) ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . LimitEngineCountForVirtualBcs . get ( ) ! = - 1 ) {
numberOfBCS = debugManager . flags . LimitEngineCountForVirtualBcs . get ( ) ;
2022-02-11 13:46:23 +00:00
}
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . LimitEngineCountForVirtualCcs . get ( ) ! = - 1 ) {
numberOfCCS = debugManager . flags . LimitEngineCountForVirtualCcs . get ( ) ;
2022-02-11 13:46:23 +00:00
}
uint32_t numEnginesInContext = 1 ;
2024-03-21 14:47:48 +00:00
ContextParamEngines < > contextEngines { } ;
2022-07-27 15:28:43 +00:00
ContextEnginesLoadBalance < maxEngines > balancer { } ;
2022-02-11 13:46:23 +00:00
2024-03-21 14:47:48 +00:00
ioctlHelper - > insertEngineToContextParams ( contextEngines , 0u , engine , deviceIndex , false ) ;
2022-02-11 13:46:23 +00:00
bool setupVirtualEngines = false ;
unsigned int engineCount = static_cast < unsigned int > ( numberOfCCS ) ;
2023-12-13 09:05:31 +00:00
if ( useVirtualEnginesForCcs & & engine - > engineClass = = ioctlHelper - > getDrmParamValue ( DrmParam : : engineClassCompute ) & & numberOfCCS > 1u ) {
2022-02-11 13:46:23 +00:00
numEnginesInContext = numberOfCCS + 1 ;
2022-07-27 15:28:43 +00:00
balancer . numSiblings = numberOfCCS ;
2022-02-11 13:46:23 +00:00
setupVirtualEngines = true ;
}
bool includeMainCopyEngineInGroup = false ;
2023-12-13 09:05:31 +00:00
if ( useVirtualEnginesForBcs & & engine - > engineClass = = ioctlHelper - > getDrmParamValue ( DrmParam : : engineClassCopy ) & & numberOfBCS > 1u ) {
2022-02-11 13:46:23 +00:00
numEnginesInContext = static_cast < uint32_t > ( numberOfBCS ) + 1 ;
2022-07-27 15:28:43 +00:00
balancer . numSiblings = numberOfBCS ;
2022-02-11 13:46:23 +00:00
setupVirtualEngines = true ;
engineCount = static_cast < unsigned int > ( rootDeviceEnvironment . getHardwareInfo ( ) - > featureTable . ftrBcsInfo . size ( ) ) ;
if ( EngineHelpers : : getBcsIndex ( engineType ) = = 0u ) {
includeMainCopyEngineInGroup = true ;
} else {
engineCount - - ;
2022-07-27 15:28:43 +00:00
balancer . numSiblings = numberOfBCS - 1 ;
2022-02-11 13:46:23 +00:00
numEnginesInContext = static_cast < uint32_t > ( numberOfBCS ) ;
}
}
if ( setupVirtualEngines ) {
2023-12-13 09:05:31 +00:00
balancer . base . name = ioctlHelper - > getDrmParamValue ( DrmParam : : contextEnginesExtLoadBalance ) ;
2022-02-11 13:46:23 +00:00
contextEngines . extensions = castToUint64 ( & balancer ) ;
2024-03-21 14:47:48 +00:00
ioctlHelper - > insertEngineToContextParams ( contextEngines , 0u , nullptr , deviceIndex , true ) ;
2022-02-11 13:46:23 +00:00
for ( auto engineIndex = 0u ; engineIndex < engineCount ; engineIndex + + ) {
2023-12-13 09:05:31 +00:00
if ( useVirtualEnginesForBcs & & engine - > engineClass = = ioctlHelper - > getDrmParamValue ( DrmParam : : engineClassCopy ) ) {
2022-07-01 09:35:58 +00:00
auto mappedBcsEngineType = static_cast < aub_stream : : EngineType > ( EngineHelpers : : mapBcsIndexToEngineType ( engineIndex , includeMainCopyEngineInGroup ) ) ;
2022-02-11 13:46:23 +00:00
bool isBcsEnabled = rootDeviceEnvironment . getHardwareInfo ( ) - > featureTable . ftrBcsInfo . test ( EngineHelpers : : getBcsIndex ( mappedBcsEngineType ) ) ;
if ( ! isBcsEnabled ) {
continue ;
}
engine = engineInfo - > getEngineInstance ( deviceIndex , mappedBcsEngineType ) ;
}
UNRECOVERABLE_IF ( ! engine ) ;
2023-12-13 09:05:31 +00:00
if ( useVirtualEnginesForCcs & & engine - > engineClass = = ioctlHelper - > getDrmParamValue ( DrmParam : : engineClassCompute ) ) {
2022-02-11 13:46:23 +00:00
engine = engineInfo - > getEngineInstance ( deviceIndex , static_cast < aub_stream : : EngineType > ( EngineHelpers : : mapCcsIndexToEngineType ( engineIndex ) ) ) ;
}
UNRECOVERABLE_IF ( ! engine ) ;
balancer . engines [ engineIndex ] = { engine - > engineClass , engine - > engineInstance } ;
2024-03-21 14:47:48 +00:00
ioctlHelper - > insertEngineToContextParams ( contextEngines , engineIndex , engine , deviceIndex , true ) ;
2022-02-11 13:46:23 +00:00
}
}
2022-05-20 15:04:07 +00:00
GemContextParam param { } ;
param . contextId = drmContextId ;
2024-03-21 14:47:48 +00:00
param . size = static_cast < uint32_t > ( ptrDiff ( contextEngines . enginesData , & contextEngines ) + sizeof ( EngineClassInstance ) * numEnginesInContext ) ;
2023-12-13 09:05:31 +00:00
param . param = ioctlHelper - > getDrmParamValue ( DrmParam : : contextParamEngines ) ;
2022-02-11 13:46:23 +00:00
param . value = castToUint64 ( & contextEngines ) ;
2023-12-12 08:48:32 +00:00
auto ioctlValue = ioctlHelper - > ioctl ( DrmIoctl : : gemContextSetparam , & param ) ;
2022-06-14 16:47:02 +00:00
UNRECOVERABLE_IF ( ioctlValue ! = 0 ) ;
2022-02-11 13:46:23 +00:00
2023-12-13 09:05:31 +00:00
retVal = static_cast < unsigned int > ( ioctlHelper - > getDrmParamValue ( DrmParam : : execDefault ) ) ;
2022-06-14 16:47:02 +00:00
return retVal ;
2022-02-11 13:46:23 +00:00
}
2022-02-11 15:03:58 +00:00
void Drm : : waitForBind ( uint32_t vmHandleId ) {
2025-02-05 06:40:13 +00:00
auto fenceAddressAndValToWait = getFenceAddressAndValToWait ( vmHandleId , false ) ;
const auto fenceAddressToWait = fenceAddressAndValToWait . first ;
const auto fenceValToWait = fenceAddressAndValToWait . second ;
if ( fenceAddressToWait ! = 0u ) {
waitUserFence ( 0u , fenceAddressToWait , fenceValToWait , ValueWidth : : u64 , - 1 , ioctlHelper - > getWaitUserFenceSoftFlag ( ) , false , NEO : : InterruptId : : notUsed , nullptr ) ;
}
}
std : : pair < uint64_t , uint64_t > Drm : : getFenceAddressAndValToWait ( uint32_t vmHandleId , bool isLocked ) {
std : : pair < uint64_t , uint64_t > fenceAddressAndValToWait = std : : make_pair ( 0 , 0 ) ;
std : : unique_lock < std : : mutex > lock ;
if ( ! isLocked ) {
lock = this - > lockBindFenceMutex ( ) ;
2022-02-11 15:03:58 +00:00
}
2022-11-09 14:17:43 +00:00
2025-02-05 06:40:13 +00:00
if ( ! ( * ioctlHelper - > getPagingFenceAddress ( vmHandleId , nullptr ) > = fenceVal [ vmHandleId ] ) ) {
auto fenceAddress = castToUint64 ( ioctlHelper - > getPagingFenceAddress ( vmHandleId , nullptr ) ) ;
auto fenceValue = this - > fenceVal [ vmHandleId ] ;
fenceAddressAndValToWait = std : : make_pair ( fenceAddress , fenceValue ) ;
}
if ( ! isLocked ) {
lock . unlock ( ) ;
}
return fenceAddressAndValToWait ;
2022-02-11 15:03:58 +00:00
}
2022-09-20 07:07:59 +00:00
bool Drm : : isSetPairAvailable ( ) {
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . EnableSetPair . get ( ) = = 1 ) {
2022-12-07 20:54:48 +00:00
std : : call_once ( checkSetPairOnce , [ this ] ( ) {
int ret = ioctlHelper - > isSetPairAvailable ( ) ;
setPairAvailable = ret ;
} ) ;
2022-11-10 04:01:36 +00:00
}
2022-09-20 07:07:59 +00:00
return setPairAvailable ;
}
2023-03-08 04:06:00 +00:00
bool Drm : : isChunkingAvailable ( ) {
2024-05-21 04:31:45 +00:00
if ( debugManager . flags . EnableBOChunking . get ( ) ! = 0 ) {
2023-03-08 04:06:00 +00:00
std : : call_once ( checkChunkingOnce , [ this ] ( ) {
int ret = ioctlHelper - > isChunkingAvailable ( ) ;
if ( ret ) {
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . EnableBOChunking . get ( ) = = - 1 ) {
2023-11-03 15:46:58 +00:00
chunkingMode = chunkingModeDevice ;
} else {
2023-11-30 08:32:25 +00:00
chunkingMode = debugManager . flags . EnableBOChunking . get ( ) ;
2024-05-21 04:31:45 +00:00
if ( ! ( hasKmdMigrationSupport ( ) ) ) {
chunkingMode & = ( ~ ( chunkingModeShared ) ) ;
}
2023-11-03 15:46:58 +00:00
}
2023-03-08 04:06:00 +00:00
}
2024-05-21 04:31:45 +00:00
if ( chunkingMode > 0 ) {
chunkingAvailable = true ;
}
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . MinimalAllocationSizeForChunking . get ( ) ! = - 1 ) {
minimalChunkingSize = debugManager . flags . MinimalAllocationSizeForChunking . get ( ) ;
2023-07-05 21:41:17 +00:00
}
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintBOChunkingLogs . get ( ) , stdout ,
2023-07-05 21:41:17 +00:00
" Chunking available: %d; enabled for: shared allocations %d, device allocations %d; minimalChunkingSize: %zd \n " ,
chunkingAvailable ,
2023-11-03 15:46:58 +00:00
( chunkingMode & chunkingModeShared ) ,
( chunkingMode & chunkingModeDevice ) ,
2023-07-05 21:41:17 +00:00
minimalChunkingSize ) ;
2023-03-08 04:06:00 +00:00
} ) ;
}
return chunkingAvailable ;
}
2022-02-15 14:00:35 +00:00
bool Drm : : isVmBindAvailable ( ) {
std : : call_once ( checkBindOnce , [ this ] ( ) {
2024-01-29 16:57:35 +00:00
bindAvailable = ioctlHelper - > isVmBindAvailable ( ) ;
2022-02-15 14:00:35 +00:00
Drm : : overrideBindSupport ( bindAvailable ) ;
2022-05-04 13:59:12 +00:00
queryAndSetVmBindPatIndexProgrammingSupport ( ) ;
2022-02-15 14:00:35 +00:00
} ) ;
return bindAvailable ;
}
2023-10-12 14:06:59 +00:00
uint64_t Drm : : getPatIndex ( Gmm * gmm , AllocationType allocationType , CacheRegion cacheRegion , CachePolicy cachePolicy , bool closEnabled , bool isSystemMemory ) const {
2023-11-30 08:32:25 +00:00
if ( ( debugManager . flags . OverridePatIndexForSystemMemory . get ( ) ! = - 1 ) & & isSystemMemory ) {
return static_cast < uint64_t > ( debugManager . flags . OverridePatIndexForSystemMemory . get ( ) ) ;
2023-10-12 14:06:59 +00:00
}
2023-11-30 08:32:25 +00:00
if ( ( debugManager . flags . OverridePatIndexForDeviceMemory . get ( ) ! = - 1 ) & & ! isSystemMemory ) {
return static_cast < uint64_t > ( debugManager . flags . OverridePatIndexForDeviceMemory . get ( ) ) ;
2023-10-12 14:06:59 +00:00
}
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . OverridePatIndex . get ( ) ! = - 1 ) {
return static_cast < uint64_t > ( debugManager . flags . OverridePatIndex . get ( ) ) ;
2022-04-11 17:13:44 +00:00
}
2024-02-02 15:03:27 +00:00
auto & productHelper = rootDeviceEnvironment . getProductHelper ( ) ;
2025-04-09 12:25:15 +00:00
GMM_RESOURCE_USAGE_TYPE usageType = CacheSettingsHelper : : getGmmUsageType ( allocationType , false , productHelper , getHardwareInfo ( ) ) ;
2024-02-02 15:03:27 +00:00
auto isUncachedType = CacheSettingsHelper : : isUncachedType ( usageType ) ;
if ( isUncachedType & & debugManager . flags . OverridePatIndexForUncachedTypes . get ( ) ! = - 1 ) {
return static_cast < uint64_t > ( debugManager . flags . OverridePatIndexForUncachedTypes . get ( ) ) ;
}
if ( ! isUncachedType & & debugManager . flags . OverridePatIndexForCachedTypes . get ( ) ! = - 1 ) {
return static_cast < uint64_t > ( debugManager . flags . OverridePatIndexForCachedTypes . get ( ) ) ;
}
2022-05-04 13:59:12 +00:00
if ( ! this - > vmBindPatIndexProgrammingSupported ) {
2022-04-19 19:24:19 +00:00
return CommonConstants : : unsupportedPatIndex ;
}
GMM_RESOURCE_INFO * resourceInfo = nullptr ;
2025-09-19 11:54:48 +00:00
bool cacheable = ! CacheSettingsHelper : : isUncachedType ( usageType ) ;
2022-09-21 12:49:45 +00:00
bool compressed = false ;
2022-04-19 19:24:19 +00:00
if ( gmm ) {
resourceInfo = gmm - > gmmResourceInfo - > peekGmmResourceInfo ( ) ;
usageType = gmm - > resourceParams . Usage ;
2024-03-25 14:44:36 +00:00
compressed = gmm - > isCompressionEnabled ( ) ;
2025-09-19 11:54:48 +00:00
cacheable = gmm - > gmmResourceInfo - > getResourceFlags ( ) - > Info . Cacheable ;
2022-04-19 19:24:19 +00:00
}
2025-09-19 11:54:48 +00:00
uint64_t patIndex = rootDeviceEnvironment . getGmmClientContext ( ) - > cachePolicyGetPATIndex ( resourceInfo , usageType , compressed , cacheable ) ;
2024-02-15 15:45:12 +00:00
patIndex = productHelper . overridePatIndex ( isUncachedType , patIndex , allocationType ) ;
2022-04-19 19:24:19 +00:00
2022-10-25 13:59:32 +00:00
UNRECOVERABLE_IF ( patIndex = = static_cast < uint64_t > ( GMM_PAT_ERROR ) ) ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . ClosEnabled . get ( ) ! = - 1 ) {
closEnabled = ! ! debugManager . flags . ClosEnabled . get ( ) ;
2022-04-11 17:13:44 +00:00
}
2022-10-25 13:59:32 +00:00
if ( closEnabled ) {
2024-08-10 12:11:45 +00:00
patIndex = productHelper . getPatIndex ( cacheRegion , cachePolicy ) ;
2022-04-11 17:13:44 +00:00
}
return patIndex ;
}
2024-03-12 23:56:09 +00:00
void programUserFence ( Drm * drm , OsContext * osContext , BufferObject * bo , VmBindExtUserFenceT & vmBindExtUserFence , uint32_t vmHandleId , uint64_t nextExtension ) {
auto ioctlHelper = drm - > getIoctlHelper ( ) ;
uint64_t address = 0 ;
uint64_t value = 0 ;
if ( drm - > isPerContextVMRequired ( ) ) {
auto osContextLinux = static_cast < OsContextLinux * > ( osContext ) ;
2024-09-20 17:16:45 +00:00
address = castToUint64 ( ioctlHelper - > getPagingFenceAddress ( vmHandleId , osContextLinux ) ) ;
2024-03-12 23:56:09 +00:00
value = osContextLinux - > getNextFenceVal ( vmHandleId ) ;
} else {
2024-09-20 17:16:45 +00:00
address = castToUint64 ( ioctlHelper - > getPagingFenceAddress ( vmHandleId , nullptr ) ) ;
2024-03-12 23:56:09 +00:00
value = drm - > getNextFenceVal ( vmHandleId ) ;
}
ioctlHelper - > fillVmBindExtUserFence ( vmBindExtUserFence , address , value , nextExtension ) ;
}
2025-02-05 06:40:13 +00:00
int changeBufferObjectBinding ( Drm * drm , OsContext * osContext , uint32_t vmHandleId , BufferObject * bo , bool bind , const bool forcePagingFence ) {
2022-10-01 11:39:49 +02:00
auto vmId = drm - > getVirtualMemoryAddressSpace ( vmHandleId ) ;
auto ioctlHelper = drm - > getIoctlHelper ( ) ;
2022-02-15 17:28:38 +00:00
uint64_t flags = 0u ;
2022-10-01 11:39:49 +02:00
if ( drm - > isPerContextVMRequired ( ) ) {
2022-02-15 17:28:38 +00:00
auto osContextLinux = static_cast < const OsContextLinux * > ( osContext ) ;
UNRECOVERABLE_IF ( osContextLinux - > getDrmVmIds ( ) . size ( ) < = vmHandleId ) ;
vmId = osContextLinux - > getDrmVmIds ( ) [ vmHandleId ] ;
}
2025-02-05 06:40:13 +00:00
// Use only when debugger is disabled
2025-06-03 02:47:41 +00:00
auto debuggingEnabled = drm - > getRootDeviceEnvironment ( ) . executionEnvironment . isDebuggingEnabled ( ) ;
const bool guaranteePagingFence = forcePagingFence & & ! debuggingEnabled ;
2025-02-05 06:40:13 +00:00
2022-02-15 17:28:38 +00:00
std : : unique_ptr < uint8_t [ ] > extensions ;
if ( bind ) {
bool allowUUIDsForDebug = ! osContext - > isInternalEngine ( ) & & ! EngineHelpers : : isBcs ( osContext - > getEngineType ( ) ) ;
if ( bo - > getBindExtHandles ( ) . size ( ) > 0 & & allowUUIDsForDebug ) {
2025-01-06 22:12:14 +00:00
extensions = ioctlHelper - > prepareVmBindExt ( bo - > getBindExtHandles ( ) , bo - > getRegisteredBindHandleCookie ( ) ) ;
2022-02-15 17:28:38 +00:00
}
2025-06-03 02:47:41 +00:00
bool bindCapture = debuggingEnabled & & bo - > isMarkedForCapture ( ) ;
2022-02-15 17:28:38 +00:00
bool bindImmediate = bo - > isImmediateBindingRequired ( ) ;
bool bindMakeResident = false ;
2024-03-27 12:52:30 +00:00
bool readOnlyResource = bo - > isReadOnlyGpuResource ( ) ;
2025-02-05 06:40:13 +00:00
if ( drm - > useVMBindImmediate ( ) | | guaranteePagingFence ) {
2024-10-02 14:31:25 +00:00
bindMakeResident = bo - > isExplicitResidencyRequired ( ) ;
2022-02-15 17:28:38 +00:00
bindImmediate = true ;
}
2024-10-02 14:31:25 +00:00
bool bindLock = bo - > isExplicitLockedMemoryRequired ( ) ;
2024-03-28 08:06:58 +00:00
flags | = ioctlHelper - > getFlagsForVmBind ( bindCapture , bindImmediate , bindMakeResident , bindLock , readOnlyResource ) ;
2022-02-15 17:28:38 +00:00
}
2022-04-06 15:46:32 +00:00
auto & bindAddresses = bo - > getColourAddresses ( ) ;
2022-02-15 17:28:38 +00:00
auto bindIterations = bindAddresses . size ( ) ;
if ( bindIterations = = 0 ) {
bindIterations = 1 ;
}
int ret = 0 ;
for ( size_t i = 0 ; i < bindIterations ; i + + ) {
VmBindParams vmBind { } ;
vmBind . vmId = static_cast < uint32_t > ( vmId ) ;
vmBind . flags = flags ;
vmBind . handle = bo - > peekHandle ( ) ;
vmBind . length = bo - > peekSize ( ) ;
vmBind . offset = 0 ;
vmBind . start = bo - > peekAddress ( ) ;
2024-03-22 10:57:14 +00:00
vmBind . userptr = bo - > getUserptr ( ) ;
2025-01-24 03:59:30 +00:00
vmBind . sharedSystemUsmEnabled = drm - > isSharedSystemAllocEnabled ( ) ;
vmBind . sharedSystemUsmBind = false ;
2022-02-15 17:28:38 +00:00
if ( bo - > getColourWithBind ( ) ) {
vmBind . length = bo - > getColourChunk ( ) ;
vmBind . offset = bo - > getColourChunk ( ) * i ;
vmBind . start = bindAddresses [ i ] ;
}
2022-04-05 17:04:53 +02:00
VmBindExtSetPatT vmBindExtSetPat { } ;
2022-02-15 17:28:38 +00:00
2022-10-01 11:39:49 +02:00
if ( drm - > isVmBindPatIndexProgrammingSupported ( ) ) {
2022-04-19 19:24:19 +00:00
UNRECOVERABLE_IF ( bo - > peekPatIndex ( ) = = CommonConstants : : unsupportedPatIndex ) ;
2024-03-04 22:17:47 +00:00
if ( ioctlHelper - > isVmBindPatIndexExtSupported ( ) ) {
ioctlHelper - > fillVmBindExtSetPat ( vmBindExtSetPat , bo - > peekPatIndex ( ) , castToUint64 ( extensions . get ( ) ) ) ;
vmBind . extensions = castToUint64 ( vmBindExtSetPat ) ;
} else {
vmBind . extensions = castToUint64 ( extensions . get ( ) ) ;
}
2023-12-06 13:47:26 +00:00
vmBind . patIndex = bo - > peekPatIndex ( ) ;
2022-02-15 17:28:38 +00:00
} else {
vmBind . extensions = castToUint64 ( extensions . get ( ) ) ;
}
2023-03-17 13:00:44 +00:00
std : : unique_lock < std : : mutex > lock ;
VmBindExtUserFenceT vmBindExtUserFence { } ;
2023-04-17 13:56:47 +00:00
bool incrementFenceValue = false ;
2025-02-05 06:40:13 +00:00
if ( ( ioctlHelper - > isWaitBeforeBindRequired ( bind ) & & drm - > useVMBindImmediate ( ) ) | | guaranteePagingFence ) {
lock = drm - > lockBindFenceMutex ( ) ;
auto nextExtension = vmBind . extensions ;
incrementFenceValue = true ;
programUserFence ( drm , osContext , bo , vmBindExtUserFence , vmHandleId , nextExtension ) ;
ioctlHelper - > setVmBindUserFence ( vmBind , vmBindExtUserFence ) ;
2023-03-17 13:00:44 +00:00
}
2025-02-05 06:40:13 +00:00
2023-03-17 13:00:44 +00:00
if ( bind ) {
2022-06-29 16:49:29 +00:00
ret = ioctlHelper - > vmBind ( vmBind ) ;
2022-02-15 17:28:38 +00:00
if ( ret ) {
break ;
}
2023-01-17 14:26:25 +00:00
drm - > setNewResourceBoundToVM ( bo , vmHandleId ) ;
2023-04-17 13:56:47 +00:00
2022-02-15 17:28:38 +00:00
} else {
vmBind . handle = 0u ;
2022-06-29 16:49:29 +00:00
ret = ioctlHelper - > vmUnbind ( vmBind ) ;
2022-02-15 17:28:38 +00:00
if ( ret ) {
break ;
}
}
2025-02-05 06:40:13 +00:00
2023-04-17 13:56:47 +00:00
if ( incrementFenceValue ) {
2025-02-05 06:40:13 +00:00
auto osContextLinux = static_cast < OsContextLinux * > ( osContext ) ;
std : : pair < uint64_t , uint64_t > fenceAddressAndValToWait = osContextLinux - > getFenceAddressAndValToWait ( vmHandleId , true ) ;
2023-05-23 16:06:03 +00:00
if ( drm - > isPerContextVMRequired ( ) ) {
osContextLinux - > incFenceVal ( vmHandleId ) ;
} else {
drm - > incFenceVal ( vmHandleId ) ;
}
2025-02-05 06:40:13 +00:00
lock . unlock ( ) ;
const auto fenceAddressToWait = fenceAddressAndValToWait . first ;
const auto fenceValToWait = fenceAddressAndValToWait . second ;
if ( fenceAddressToWait ! = 0u ) {
bool waitOnUserFenceAfterBindAndUnbind = false ;
if ( debugManager . flags . EnableWaitOnUserFenceAfterBindAndUnbind . get ( ) ! = - 1 ) {
waitOnUserFenceAfterBindAndUnbind = ! ! debugManager . flags . EnableWaitOnUserFenceAfterBindAndUnbind . get ( ) ;
}
if ( ( ioctlHelper - > isWaitBeforeBindRequired ( bind ) & & waitOnUserFenceAfterBindAndUnbind & & drm - > useVMBindImmediate ( ) ) | | guaranteePagingFence ) {
drm - > waitUserFence ( 0u , fenceAddressToWait , fenceValToWait , Drm : : ValueWidth : : u64 , - 1 , ioctlHelper - > getWaitUserFenceSoftFlag ( ) , false , NEO : : InterruptId : : notUsed , nullptr ) ;
}
}
2023-04-17 13:56:47 +00:00
}
2022-02-15 17:28:38 +00:00
}
return ret ;
}
2025-02-05 06:40:13 +00:00
int Drm : : bindBufferObject ( OsContext * osContext , uint32_t vmHandleId , BufferObject * bo , const bool forcePagingFence ) {
auto ret = changeBufferObjectBinding ( this , osContext , vmHandleId , bo , true , forcePagingFence ) ;
2022-02-15 17:28:38 +00:00
if ( ret ! = 0 ) {
2022-10-01 11:39:49 +02:00
static_cast < DrmMemoryOperationsHandlerBind * > ( this - > rootDeviceEnvironment . memoryOperationsInterface . get ( ) ) - > evictUnusedAllocations ( false , false ) ;
2025-02-05 06:40:13 +00:00
ret = changeBufferObjectBinding ( this , osContext , vmHandleId , bo , true , forcePagingFence ) ;
2022-02-15 17:28:38 +00:00
}
return ret ;
}
int Drm : : unbindBufferObject ( OsContext * osContext , uint32_t vmHandleId , BufferObject * bo ) {
2025-02-05 06:40:13 +00:00
return changeBufferObjectBinding ( this , osContext , vmHandleId , bo , false , false ) ;
2022-02-15 17:28:38 +00:00
}
2022-02-16 10:37:44 +00:00
int Drm : : createDrmVirtualMemory ( uint32_t & drmVmId ) {
2022-05-24 15:06:15 +00:00
GemVmControl ctl { } ;
2022-02-16 10:37:44 +00:00
std : : optional < MemoryClassInstance > regionInstanceClass ;
uint32_t memoryBank = 1 < < drmVmId ;
auto hwInfo = this - > getRootDeviceEnvironment ( ) . getHardwareInfo ( ) ;
auto memInfo = this - > getMemoryInfo ( ) ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . UseTileMemoryBankInVirtualMemoryCreation . get ( ) ! = 0 ) {
2022-12-09 15:11:27 +00:00
if ( memInfo & & rootDeviceEnvironment . getHelper < GfxCoreHelper > ( ) . getEnableLocalMemory ( * hwInfo ) ) {
2022-02-16 10:37:44 +00:00
regionInstanceClass = memInfo - > getMemoryRegionClassAndInstance ( memoryBank , * this - > rootDeviceEnvironment . getHardwareInfo ( ) ) ;
}
}
auto vmControlExtRegion = ioctlHelper - > createVmControlExtRegion ( regionInstanceClass ) ;
if ( vmControlExtRegion ) {
ctl . extensions = castToUint64 ( vmControlExtRegion . get ( ) ) ;
}
2022-04-21 16:59:48 +00:00
bool useVmBind = isVmBindAvailable ( ) ;
bool enablePageFault = hasPageFaultSupport ( ) & & useVmBind ;
2022-02-16 10:37:44 +00:00
2024-04-08 18:37:35 +00:00
ctl . flags = ioctlHelper - > getFlagsForVmCreate ( checkToDisableScratchPage ( ) , enablePageFault , useVmBind ) ;
2022-02-16 10:37:44 +00:00
2023-12-12 08:48:32 +00:00
auto ret = ioctlHelper - > ioctl ( DrmIoctl : : gemVmCreate , & ctl ) ;
2022-02-16 10:37:44 +00:00
if ( ret = = 0 ) {
2022-05-24 15:06:15 +00:00
drmVmId = ctl . vmId ;
2025-01-24 03:59:30 +00:00
if ( isSharedSystemAllocEnabled ( ) ) {
2025-09-06 21:04:00 +00:00
auto & productHelper = rootDeviceEnvironment . getHelper < ProductHelper > ( ) ;
2025-01-24 03:59:30 +00:00
VmBindParams vmBind { } ;
vmBind . vmId = static_cast < uint32_t > ( ctl . vmId ) ;
2025-04-29 16:41:39 +00:00
vmBind . flags = DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR ;
2025-07-29 15:29:57 +00:00
vmBind . length = this - > getSharedSystemAllocAddressRange ( ) ;
2025-01-24 03:59:30 +00:00
vmBind . sharedSystemUsmEnabled = true ;
vmBind . sharedSystemUsmBind = true ;
2025-09-06 21:04:00 +00:00
vmBind . patIndex = productHelper . getSharedSystemPatIndex ( ) ;
2025-01-24 03:59:30 +00:00
VmBindExtUserFenceT vmBindExtUserFence { } ;
ioctlHelper - > fillVmBindExtUserFence ( vmBindExtUserFence ,
castToUint64 ( ioctlHelper - > getPagingFenceAddress ( 0 , nullptr ) ) ,
getNextFenceVal ( 0 ) ,
vmBind . extensions ) ;
ioctlHelper - > setVmBindUserFence ( vmBind , vmBindExtUserFence ) ;
if ( ioctlHelper - > vmBind ( vmBind ) ) {
setSharedSystemAllocEnable ( false ) ;
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr ,
" INFO: Shared System USM capability not detected \n " ) ;
}
}
2022-05-24 15:06:15 +00:00
if ( ctl . vmId = = 0 ) {
2022-02-16 10:37:44 +00:00
// 0 is reserved for invalid/unassigned ppgtt
return - 1 ;
}
} else {
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr ,
2022-02-16 10:37:44 +00:00
" INFO: Cannot create Virtual Memory at memory bank 0x%x info present %d return code %d \n " ,
memoryBank , memoryInfo ! = nullptr , ret ) ;
}
return ret ;
}
2022-02-28 13:31:18 +00:00
2022-10-14 13:02:37 +00:00
PhysicalDevicePciSpeedInfo Drm : : getPciSpeedInfo ( ) const {
2022-02-28 13:31:18 +00:00
2022-10-14 13:02:37 +00:00
PhysicalDevicePciSpeedInfo pciSpeedInfo = { } ;
2022-02-28 13:31:18 +00:00
std : : string pathPrefix { } ;
bool isIntegratedDevice = rootDeviceEnvironment . getHardwareInfo ( ) - > capabilityTable . isIntegratedDevice ;
// If integrated device, read properties from the specific device path.
// If discrete device, read properties from the root path of the pci device.
if ( isIntegratedDevice ) {
auto devicePath = NEO : : getPciLinkPath ( getFileDescriptor ( ) ) ;
if ( ! devicePath . has_value ( ) ) {
return pciSpeedInfo ;
}
pathPrefix = " /sys/class/drm/ " + devicePath . value ( ) + " /device/ " ;
} else {
auto rootPath = NEO : : getPciRootPath ( getFileDescriptor ( ) ) ;
if ( ! rootPath . has_value ( ) ) {
return pciSpeedInfo ;
}
pathPrefix + = " /sys/devices " + rootPath . value ( ) ;
}
std : : array < char , 32 > readString = { ' \0 ' } ;
errno = 0 ;
auto readFile = [ ] ( const std : : string fileName , const std : : string_view pathPrefix , std : : array < char , 32 > & readString ) {
std : : ostringstream linkWidthStream { } ;
linkWidthStream < < pathPrefix < < fileName ;
int fd = NEO : : SysCalls : : open ( linkWidthStream . str ( ) . c_str ( ) , O_RDONLY ) ;
2022-10-14 13:02:37 +00:00
if ( fd < 0 ) {
2022-03-28 17:55:03 +00:00
return false ;
}
2022-02-28 13:31:18 +00:00
ssize_t bytesRead = NEO : : SysCalls : : pread ( fd , readString . data ( ) , readString . size ( ) - 1 , 0 ) ;
NEO : : SysCalls : : close ( fd ) ;
if ( bytesRead < = 0 ) {
return false ;
}
std : : replace ( readString . begin ( ) , readString . end ( ) , ' \n ' , ' \0 ' ) ;
return true ;
} ;
// read max link width
if ( readFile ( " /max_link_width " , pathPrefix , readString ) ! = true ) {
return pciSpeedInfo ;
}
char * endPtr = nullptr ;
uint32_t linkWidth = static_cast < uint32_t > ( std : : strtoul ( readString . data ( ) , & endPtr , 10 ) ) ;
if ( ( endPtr = = readString . data ( ) ) | | ( errno ! = 0 ) ) {
return pciSpeedInfo ;
}
pciSpeedInfo . width = linkWidth ;
// read max link speed
if ( readFile ( " /max_link_speed " , pathPrefix , readString ) ! = true ) {
return pciSpeedInfo ;
}
endPtr = nullptr ;
const auto maxSpeed = strtod ( readString . data ( ) , & endPtr ) ;
if ( ( endPtr = = readString . data ( ) ) | | ( errno ! = 0 ) ) {
return pciSpeedInfo ;
}
double gen3EncodingLossFactor = 128.0 / 130.0 ;
std : : map < double , std : : pair < int32_t , double > > maxSpeedToGenAndEncodingLossMapping {
//{max link speed, {pci generation, encoding loss factor}}
{ 2.5 , { 1 , 0.2 } } ,
{ 5.0 , { 2 , 0.2 } } ,
{ 8.0 , { 3 , gen3EncodingLossFactor } } ,
{ 16.0 , { 4 , gen3EncodingLossFactor } } ,
{ 32.0 , { 5 , gen3EncodingLossFactor } } } ;
if ( maxSpeedToGenAndEncodingLossMapping . find ( maxSpeed ) = = maxSpeedToGenAndEncodingLossMapping . end ( ) ) {
return pciSpeedInfo ;
}
pciSpeedInfo . genVersion = maxSpeedToGenAndEncodingLossMapping [ maxSpeed ] . first ;
constexpr double gigaBitsPerSecondToBytesPerSecondMultiplier = 125000000 ;
const auto maxSpeedWithEncodingLoss = maxSpeed * gigaBitsPerSecondToBytesPerSecondMultiplier * maxSpeedToGenAndEncodingLossMapping [ maxSpeed ] . second ;
2022-03-21 14:33:46 +00:00
pciSpeedInfo . maxBandwidth = static_cast < int64_t > ( maxSpeedWithEncodingLoss * pciSpeedInfo . width ) ;
2022-02-28 13:31:18 +00:00
return pciSpeedInfo ;
}
2022-04-25 11:49:22 +00:00
2024-05-07 16:58:28 +00:00
int Drm : : waitOnUserFences ( OsContextLinux & osContext , uint64_t address , uint64_t value , uint32_t numActiveTiles , int64_t timeout , uint32_t postSyncOffset , bool userInterrupt ,
2024-05-07 11:47:34 +00:00
uint32_t externalInterruptId , GraphicsAllocation * allocForInterruptWait ) {
2024-05-07 16:58:28 +00:00
int ret = waitOnUserFencesImpl ( static_cast < const OsContextLinux & > ( osContext ) , address , value , numActiveTiles ,
timeout , postSyncOffset , userInterrupt , externalInterruptId , allocForInterruptWait ) ;
if ( ret ! = 0 & & getErrno ( ) = = EIO & & checkGpuPageFaultRequired ( ) ) {
checkResetStatus ( osContext ) ;
}
return ret ;
}
int Drm : : waitOnUserFencesImpl ( const OsContextLinux & osContext , uint64_t address , uint64_t value , uint32_t numActiveTiles , int64_t timeout , uint32_t postSyncOffset , bool userInterrupt ,
uint32_t externalInterruptId , GraphicsAllocation * allocForInterruptWait ) {
2022-04-25 11:49:22 +00:00
auto & drmContextIds = osContext . getDrmContextIds ( ) ;
UNRECOVERABLE_IF ( numActiveTiles > drmContextIds . size ( ) ) ;
auto completionFenceCpuAddress = address ;
2024-04-25 12:03:39 +00:00
const auto selectedTimeout = osContext . isHangDetected ( ) ? 1 : timeout ;
2023-01-10 17:20:07 +00:00
2022-04-25 11:49:22 +00:00
for ( auto drmIterator = 0u ; drmIterator < numActiveTiles ; drmIterator + + ) {
if ( * reinterpret_cast < uint32_t * > ( completionFenceCpuAddress ) < value ) {
2023-01-10 17:20:07 +00:00
static constexpr uint16_t flags = 0 ;
2024-05-07 11:47:34 +00:00
int retVal = waitUserFence ( drmContextIds [ drmIterator ] , completionFenceCpuAddress , value , Drm : : ValueWidth : : u64 , selectedTimeout , flags , userInterrupt , externalInterruptId , allocForInterruptWait ) ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . PrintCompletionFenceUsage . get ( ) ) {
2022-10-11 12:36:19 +00:00
std : : cout < < " Completion fence waited. "
< < " Status: " < < retVal
< < " , CPU address: " < < std : : hex < < completionFenceCpuAddress < < std : : dec
< < " , current value: " < < * reinterpret_cast < uint32_t * > ( completionFenceCpuAddress )
< < " , wait value: " < < value < < std : : endl ;
}
2024-04-25 12:03:39 +00:00
if ( retVal ! = 0 ) {
return retVal ;
}
2023-11-30 08:32:25 +00:00
} else if ( debugManager . flags . PrintCompletionFenceUsage . get ( ) ) {
2022-10-11 12:36:19 +00:00
std : : cout < < " Completion fence already completed. "
< < " CPU address: " < < std : : hex < < completionFenceCpuAddress < < std : : dec
< < " , current value: " < < * reinterpret_cast < uint32_t * > ( completionFenceCpuAddress )
< < " , wait value: " < < value < < std : : endl ;
2022-04-25 11:49:22 +00:00
}
2024-04-26 14:39:26 +00:00
if ( externalInterruptId ! = NEO : : InterruptId : : notUsed ) {
break ;
}
2022-04-25 11:49:22 +00:00
completionFenceCpuAddress = ptrOffset ( completionFenceCpuAddress , postSyncOffset ) ;
}
2024-04-25 12:03:39 +00:00
return 0 ;
2022-04-25 11:49:22 +00:00
}
2023-10-18 10:00:43 +02:00
const HardwareInfo * Drm : : getHardwareInfo ( ) const { return rootDeviceEnvironment . getHardwareInfo ( ) ; }
2024-03-28 08:46:55 +00:00
uint64_t Drm : : alignUpGttSize ( uint64_t inputGttSize ) {
constexpr uint64_t gttSize47bit = ( 1ull < < 47 ) ;
constexpr uint64_t gttSize48bit = ( 1ull < < 48 ) ;
if ( inputGttSize > gttSize47bit & & inputGttSize < gttSize48bit ) {
return gttSize48bit ;
}
return inputGttSize ;
}
2024-12-17 11:48:52 +00:00
bool Drm : : isDrmSupported ( int fileDescriptor ) {
auto drmVersion = Drm : : getDrmVersion ( fileDescriptor ) ;
return " i915 " = = drmVersion | | " xe " = = drmVersion ;
}
bool Drm : : queryDeviceIdAndRevision ( ) {
auto drmVersion = Drm : : getDrmVersion ( getFileDescriptor ( ) ) ;
if ( " xe " = = drmVersion ) {
this - > setPerContextVMRequired ( false ) ;
2024-12-18 14:03:21 +00:00
return IoctlHelperXe : : queryDeviceIdAndRevision ( * this ) ;
2024-12-17 11:48:52 +00:00
}
2024-12-17 14:41:33 +00:00
return IoctlHelperI915 : : queryDeviceIdAndRevision ( * this ) ;
2024-12-17 11:48:52 +00:00
}
2025-05-16 18:59:54 +00:00
void Drm : : adjustSharedSystemMemCapabilities ( ) {
2025-08-01 06:14:40 +00:00
if ( this - > isSharedSystemAllocEnabled ( ) ) {
uint64_t gpuAddressLength = ( this - > getRootDeviceEnvironment ( ) . getMutableHardwareInfo ( ) - > capabilityTable . gpuAddressSpace + 1 ) ;
uint64_t cpuAddressLength = ( 0x1ull < < ( NEO : : CpuInfo : : getInstance ( ) . getVirtualAddressSize ( ) ) ) ;
if ( ( cpuAddressLength > ( maxNBitValue ( 48 ) + 1 ) ) & & ! ( CpuInfo : : getInstance ( ) . isCpuFlagPresent ( " la57 " ) ) ) {
cpuAddressLength = ( maxNBitValue ( 48 ) + 1 ) ;
}
if ( gpuAddressLength < cpuAddressLength ) {
this - > setSharedSystemAllocEnable ( false ) ;
this - > getRootDeviceEnvironment ( ) . getMutableHardwareInfo ( ) - > capabilityTable . sharedSystemMemCapabilities = 0 ;
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " Shared System USM NOT allowed: CPU address range > GPU address range \n " ) ;
} else {
this - > setSharedSystemAllocAddressRange ( cpuAddressLength ) ;
this - > setPageFaultSupported ( true ) ;
}
} else {
2025-05-16 18:59:54 +00:00
this - > getRootDeviceEnvironment ( ) . getMutableHardwareInfo ( ) - > capabilityTable . sharedSystemMemCapabilities = 0 ;
}
}
2025-01-31 15:26:12 +00:00
uint32_t Drm : : getAggregatedProcessCount ( ) const {
return ioctlHelper - > getNumProcesses ( ) ;
}
2025-06-20 09:32:34 +00:00
uint32_t Drm : : getVmIdForContext ( OsContext & osContext , uint32_t vmHandleId ) const {
auto osContextLinux = static_cast < const OsContextLinux * > ( & osContext ) ;
return osContextLinux - > getDrmVmIds ( ) . size ( ) > 0 ? osContextLinux - > getDrmVmIds ( ) [ vmHandleId ] : getVirtualMemoryAddressSpace ( vmHandleId ) ;
}
2023-10-02 14:26:33 +00:00
template std : : vector < uint16_t > Drm : : query < uint16_t > ( uint32_t queryId , uint32_t queryItemFlags ) ;
template std : : vector < uint32_t > Drm : : query < uint32_t > ( uint32_t queryId , uint32_t queryItemFlags ) ;
template std : : vector < uint64_t > Drm : : query < uint64_t > ( uint32_t queryId , uint32_t queryItemFlags ) ;
2019-03-26 11:59:46 +01:00
} // namespace NEO