2017-12-21 00:45:38 +01:00
/*
2023-01-02 11:52:22 +00:00
* Copyright ( C ) 2018 - 2023 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
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-01-17 14:26:25 +00:00
# include "shared/source/helpers/aligned_memory.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"
2023-02-01 16:23:01 +00:00
# include "shared/source/helpers/gfx_core_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"
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"
2022-11-18 14:38:56 +00:00
# include "shared/source/utilities/api_intercept.h"
2020-02-23 22:44:01 +01:00
# include "shared/source/utilities/directory.h"
2019-02-27 11:39:32 +01:00
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 )
2021-05-21 01:17:57 +02:00
: DriverModel ( DriverModelType : : DRM ) ,
hwDeviceId ( std : : move ( hwDeviceIdIn ) ) , rootDeviceEnvironment ( rootDeviceEnvironment ) {
2021-02-05 15:27:21 +00:00
pagingFence . fill ( 0u ) ;
fenceVal . fill ( 0u ) ;
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 :
return SubmissionStatus : : SUCCESS ;
case EWOULDBLOCK :
case ENOMEM :
case ENOSPC :
return SubmissionStatus : : OUT_OF_HOST_MEMORY ;
case ENXIO :
return SubmissionStatus : : OUT_OF_MEMORY ;
default :
return SubmissionStatus : : FAILED ;
}
}
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 {
2021-04-21 13:52:11 +00:00
auto measureTime = DebugManager . flags . PrintIoctlTimes . get ( ) ;
std : : chrono : : steady_clock : : time_point start ;
std : : chrono : : steady_clock : : time_point end ;
2021-04-22 13:37:02 +00:00
auto printIoctl = DebugManager . flags . PrintIoctlEntries . get ( ) ;
if ( printIoctl ) {
2022-07-14 15:32:26 +00:00
printf ( " IOCTL %s called \n " , getIoctlString ( request , ioctlHelper . get ( ) ) . 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
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 ) {
printf ( " IOCTL %s returns %d \n " ,
2022-07-14 15:32:26 +00:00
getIoctlString ( request , ioctlHelper . get ( ) ) . c_str ( ) , ret ) ;
2021-12-31 01:38:08 +00:00
} else {
printf ( " IOCTL %s returns %d, errno %d(%s) \n " ,
2022-07-14 15:32:26 +00:00
getIoctlString ( request , ioctlHelper . get ( ) ) . 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 { } ;
2022-06-06 15:48:31 +00:00
getParam . param = getDrmParamValue ( param , ioctlHelper . get ( ) ) ;
2018-03-12 12:03:20 +01:00
getParam . value = dstValue ;
2017-12-21 00:45:38 +01:00
2022-06-29 16:49:29 +00:00
int retVal = ioctlHelper ? ioctlHelper - > ioctl ( DrmIoctl : : Getparam , & getParam ) : ioctl ( DrmIoctl : : Getparam , & getParam ) ;
2021-06-25 12:28:28 +00:00
if ( DebugManager . flags . PrintIoctlEntries . get ( ) ) {
printf ( " DRM_IOCTL_I915_GETPARAM: param: %s, output value: %d, retCode:% d \n " ,
2022-07-14 15:32:26 +00:00
getDrmParamString ( param , ioctlHelper . get ( ) ) . 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 : : getExecSoftPin ( int & execSoftPin ) {
2022-06-06 15:48:31 +00:00
return getParamIoctl ( DrmParam : : ParamHasExecSoftpin , & execSoftPin ) ;
2017-12-21 00:45:38 +01:00
}
2022-06-08 12:43:51 +00:00
bool Drm : : queryI915DeviceIdAndRevision ( ) {
2022-08-08 19:04:04 +00:00
HardwareInfo * hwInfo = rootDeviceEnvironment . getMutableHardwareInfo ( ) ;
int deviceId = hwInfo - > platform . usDeviceID ;
int revisionId = hwInfo - > platform . usRevId ;
auto ret = getParamIoctl ( DrmParam : : ParamChipsetId , & deviceId ) ;
2022-06-08 12:43:51 +00:00
if ( ret ! = 0 ) {
printDebugString ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " FATAL: Cannot query device ID parameter! \n " ) ;
return false ;
}
2022-08-08 19:04:04 +00:00
ret = getParamIoctl ( DrmParam : : ParamRevision , & revisionId ) ;
2022-06-08 12:43:51 +00:00
if ( ret ! = 0 ) {
printDebugString ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " FATAL: Cannot query device Rev ID parameter! \n " ) ;
return false ;
}
2022-08-08 19:04:04 +00:00
hwInfo - > platform . usDeviceID = deviceId ;
hwInfo - > platform . usRevId = revisionId ;
2022-06-08 12:43:51 +00:00
return true ;
}
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 ;
2022-06-29 16:49:29 +00:00
return ioctlHelper - > ioctl ( DrmIoctl : : GemContextSetparam , & contextParam ) ;
2017-12-21 00:45:38 +01:00
}
int Drm : : getEnabledPooledEu ( int & enabled ) {
2022-06-06 15:48:31 +00:00
return getParamIoctl ( DrmParam : : ParamHasPooledEu , & enabled ) ;
2017-12-21 00:45:38 +01:00
}
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 ;
}
const std : : string fileName = devicePath + relativeFilePath ;
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 ;
}
2019-12-17 15:17:52 +01:00
int Drm : : queryGttSize ( uint64_t & gttSizeOutput ) {
2022-05-20 15:04:07 +00:00
GemContextParam contextParam = { 0 } ;
2022-07-27 08:32:08 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamGttSize ) ;
2019-04-23 15:42:33 +02:00
2022-06-29 16:49:29 +00:00
int ret = ioctlHelper - > ioctl ( DrmIoctl : : GemContextGetparam , & contextParam ) ;
2019-04-23 15:42:33 +02:00
if ( ret = = 0 ) {
2019-12-17 15:17:52 +01:00
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 ) {
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 ;
2022-01-20 16:56:19 +00:00
2022-06-29 16:49:29 +00:00
const auto retVal { ioctlHelper - > ioctl ( DrmIoctl : : GetResetStats , & resetStats ) } ;
2022-01-20 16:56:19 +00:00
UNRECOVERABLE_IF ( retVal ! = 0 ) ;
2022-05-24 15:06:15 +00:00
if ( resetStats . batchActive > 0 | | resetStats . batchPending > 0 ) {
2022-02-14 19:03:10 +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 ( ) {
2017-12-21 00:45:38 +01:00
int value = 0 ;
2022-06-06 15:48:31 +00:00
auto ret = getParamIoctl ( DrmParam : : ParamHasScheduler , & value ) ;
2022-08-08 14:02:17 +00:00
auto schedulerCapPreemption = ioctlHelper - > getDrmParamValue ( DrmParam : : SchedulerCapPreemption ) ;
preemptionSupported = ( ( 0 = = ret ) & & ( value & schedulerCapPreemption ) ) ;
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 ;
2022-07-27 08:32:08 +00:00
gcp . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamPriority ) ;
2017-12-21 00:45:38 +01:00
gcp . value = - 1023 ;
2022-06-29 16:49:29 +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 = { } ;
2022-07-27 08:32:08 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamSseu ) ;
2022-06-01 13:04:38 +00:00
sseu - > engine . engineClass = ioctlHelper - > getDrmParamValue ( DrmParam : : EngineClassRender ) ;
2022-06-14 16:47:02 +00:00
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
2022-06-29 16:49:29 +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
2022-07-27 08:32:08 +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 ) ;
2022-06-29 16:49:29 +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 = { } ;
2022-07-27 08:32:08 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamPersistence ) ;
2020-02-10 08:05:32 -08:00
2022-06-29 16:49:29 +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 ;
2022-07-27 08:32:08 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamPersistence ) ;
2019-12-18 19:38:22 +01:00
2022-06-29 16:49:29 +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 ;
2022-07-27 08:32:08 +00:00
contextParam . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamRecoverable ) ;
2021-09-09 21:16:11 +00:00
contextParam . value = 0 ;
contextParam . size = 0 ;
2022-06-29 16:49:29 +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
2022-02-16 12:35:03 +00:00
if ( DebugManager . flags . DirectSubmissionDrmContext . get ( ) ! = - 1 ) {
isDirectSubmissionRequested = DebugManager . flags . DirectSubmissionDrmContext . get ( ) ;
}
if ( isDirectSubmissionRequested ) {
gcc . flags | = ioctlHelper - > getDirectSubmissionFlag ( ) ;
}
2021-09-03 17:32:33 +02:00
2022-05-23 15:05:47 +00:00
GemContextCreateExtSetParam extSetparam = { } ;
2021-09-03 17:32:33 +02:00
2022-02-16 12:35:03 +00:00
if ( drmVmId > 0 ) {
2022-08-08 14:02:17 +00:00
extSetparam . base . name = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextCreateExtSetparam ) ;
2022-07-27 08:32:08 +00:00
extSetparam . param . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamVm ) ;
2022-02-16 12:35:03 +00:00
extSetparam . param . value = drmVmId ;
gcc . extensions = reinterpret_cast < uint64_t > ( & extSetparam ) ;
2022-08-08 14:02:17 +00:00
gcc . flags | = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextCreateFlagsUseExtensions ) ;
2022-02-16 12:35:03 +00:00
}
if ( DebugManager . flags . CreateContextWithAccessCounters . get ( ) ! = - 1 ) {
2022-06-29 16:49:29 +00:00
return ioctlHelper - > createContextWithAccessCounters ( gcc ) ;
2022-02-16 12:35:03 +00:00
}
if ( DebugManager . flags . ForceRunAloneContext . get ( ) ! = - 1 ) {
isCooperativeContextRequested = DebugManager . flags . ForceRunAloneContext . get ( ) ;
}
if ( isCooperativeContextRequested ) {
2022-06-29 16:49:29 +00:00
return ioctlHelper - > createCooperativeContext ( gcc ) ;
2022-02-16 12:35:03 +00:00
}
2022-06-29 16:49:29 +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 ) {
PRINT_DEBUG_STRING ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " WARNING: GemContextCreateExt ioctl failed. Not exposing this root device \n " ) ;
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 ;
2022-06-29 16:49:29 +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 ;
2022-07-19 17:13:51 +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 ;
2022-07-27 08:32:08 +00:00
param . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamVm ) ;
2022-06-29 16:49:29 +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 ) {
2022-06-06 15:48:31 +00:00
return getParamIoctl ( DrmParam : : ParamEuTotal , & euTotal ) ;
2017-12-21 00:45:38 +01:00
}
int Drm : : getSubsliceTotal ( int & subsliceTotal ) {
2022-06-06 15:48:31 +00:00
return getParamIoctl ( DrmParam : : ParamSubsliceTotal , & subsliceTotal ) ;
2017-12-21 00:45:38 +01:00
}
int Drm : : getMinEuInPool ( int & minEUinPool ) {
2022-06-06 15:48: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 ) {
HardwareInfo * hwInfo = rootDeviceEnvironment . getMutableHardwareInfo ( ) ;
2022-08-08 19:04:04 +00:00
auto deviceId = hwInfo - > platform . usDeviceID ;
auto revisionId = hwInfo - > platform . usRevId ;
2023-01-03 10:27:35 +00:00
rootDeviceEnvironment . setHwInfoAndInitHelpers ( device - > pHwInfo ) ;
2019-10-18 10:15:09 +02:00
2022-08-08 19:04:04 +00:00
hwInfo - > platform . usDeviceID = deviceId ;
hwInfo - > platform . usRevId = revisionId ;
2022-06-07 15:03:52 +00:00
2022-01-28 21:00:05 +00:00
const auto productFamily = hwInfo - > platform . eProductFamily ;
setupIoctlHelper ( productFamily ) ;
2021-04-27 14:45:13 +00:00
Drm : : QueryTopologyData topologyData = { } ;
bool status = queryTopology ( * hwInfo , topologyData ) ;
2020-06-09 15:51:26 +02:00
if ( ! status ) {
2020-09-25 11:24:15 +02: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 ) {
2020-09-25 11:24:15 +02: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 ) {
2020-09-25 11:24:15 +02: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 ) ;
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 ) ;
2021-04-27 14:45:13 +00:00
hwInfo - > gtSystemInfo . EUCount = static_cast < uint32_t > ( topologyData . euCount ) ;
2022-10-05 18:48:44 +00:00
if ( topologyData . maxSubSliceCount > 0 ) {
hwInfo - > gtSystemInfo . MaxSubSlicesSupported = static_cast < uint32_t > ( topologyData . maxSubSliceCount ) ;
hwInfo - > gtSystemInfo . MaxDualSubSlicesSupported = static_cast < uint32_t > ( topologyData . maxSubSliceCount ) ;
}
2021-04-27 14:45:13 +00:00
2020-11-24 16:00:33 +01:00
status = querySystemInfo ( ) ;
2023-03-08 09:30:38 +00:00
auto & compilerProductHelper = rootDeviceEnvironment . getHelper < CompilerProductHelper > ( ) ;
device - > setupHardwareInfo ( hwInfo , setupFeatureTableAndWorkaroundTable , compilerProductHelper ) ;
2023-01-04 17:15:35 +00:00
2021-06-15 10:43:12 +00:00
if ( status ) {
2023-01-04 17:15:35 +00:00
systemInfo - > checkSysInfoMismatch ( hwInfo ) ;
2021-06-15 10:43:12 +00:00
setupSystemInfo ( hwInfo , systemInfo . get ( ) ) ;
2022-10-05 18:48:44 +00:00
uint32_t bankCount = ( hwInfo - > gtSystemInfo . L3BankCount > 0 ) ? hwInfo - > gtSystemInfo . L3BankCount : hwInfo - > gtSystemInfo . MaxDualSubSlicesSupported ;
hwInfo - > gtSystemInfo . L3CacheSizeInKb = systemInfo - > getL3BankSizeInKb ( ) * bankCount ;
2020-11-24 16:00:33 +01:00
}
2022-10-05 18:48:44 +00:00
2021-01-29 22:23:06 +00:00
setupCacheInfo ( * hwInfo ) ;
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 ;
2020-02-17 16:14:22 +01:00
if ( DebugManager . flags . CreateMultipleRootDevices . get ( ) ) {
numRootDevices = DebugManager . flags . CreateMultipleRootDevices . get ( ) ;
}
2020-04-08 11:27:04 +02:00
std : : vector < std : : string > files = Directory : : getFiles ( Os : : pciDevicesDirectory ) ;
if ( files . size ( ) = = 0 ) {
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
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
}
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 ) {
// if osPciPath is non-empty, then interest is only in discovering device having same bdf as ocPciPath. Skip all other devices.
continue ;
}
}
2022-01-31 17:43:42 +00:00
if ( DebugManager . flags . FilterBdfPath . get ( ) ! = " unk " ) {
if ( devicePathView . find ( DebugManager . flags . FilterBdfPath . get ( ) . c_str ( ) ) = = std : : string : : npos ) {
continue ;
}
}
2023-05-05 08:59:45 +00:00
int fileDescriptor = SysCalls : : open ( file - > c_str ( ) , O_RDWR | O_CLOEXEC ) ;
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 ) ;
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
2022-08-08 14:02:17 +00:00
auto requestValue = getIoctlRequestValue ( DrmIoctl : : Version , nullptr ) ;
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
}
2021-12-22 14:25:53 +00:00
std : : vector < uint8_t > 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
2022-06-29 16:49:29 +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
}
2021-12-22 14:25:53 +00:00
auto data = std : : vector < uint8_t > ( queryItem . length , 0 ) ;
2022-05-17 21:40:34 +00:00
queryItem . dataPtr = castToUint64 ( data . data ( ) ) ;
2020-06-09 15:51:26 +02:00
2022-06-29 16:49:29 +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 ( ) {
if ( ! DebugManager . flags . PrintIoctlTimes . get ( ) ) {
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 " ,
2022-07-14 15:32:26 +00:00
getIoctlString ( ioctlData . first , ioctlHelper . get ( ) ) . 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 ) {
if ( ! this - > rootDeviceEnvironment . getProductHelper ( ) . isTlbFlushRequired ( ) & & isAligned ( bo - > peekAddress ( ) , MemoryConstants : : pageSize2Mb ) ) {
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
}
}
}
2022-05-19 14:06:33 +00:00
bool Drm : : translateTopologyInfo ( const QueryTopologyInfo * queryTopologyInfo , QueryTopologyData & data , TopologyMapping & mapping ) {
2021-05-07 15:29:28 +00:00
int sliceCount = 0 ;
int subSliceCount = 0 ;
int euCount = 0 ;
2021-05-17 15:04:01 +00:00
int maxSliceCount = 0 ;
int maxSubSliceCountPerSlice = 0 ;
2021-04-27 14:45:13 +00:00
std : : vector < int > sliceIndices ;
sliceIndices . reserve ( maxSliceCount ) ;
2021-01-26 11:02:17 +00:00
2022-05-19 14:06:33 +00:00
for ( int x = 0 ; x < queryTopologyInfo - > maxSlices ; x + + ) {
2021-01-26 11:02:17 +00:00
bool isSliceEnable = ( queryTopologyInfo - > data [ x / 8 ] > > ( x % 8 ) ) & 1 ;
if ( ! isSliceEnable ) {
continue ;
}
2021-04-27 14:45:13 +00:00
sliceIndices . push_back ( x ) ;
2021-01-26 11:02:17 +00:00
sliceCount + + ;
2021-05-17 15:04:01 +00:00
std : : vector < int > subSliceIndices ;
2022-05-19 14:06:33 +00:00
subSliceIndices . reserve ( queryTopologyInfo - > maxSubslices ) ;
2021-05-17 15:04:01 +00:00
2022-05-19 14:06:33 +00:00
for ( int y = 0 ; y < queryTopologyInfo - > maxSubslices ; y + + ) {
size_t yOffset = ( queryTopologyInfo - > subsliceOffset + x * queryTopologyInfo - > subsliceStride + y / 8 ) ;
2021-01-26 11:02:17 +00:00
bool isSubSliceEnabled = ( queryTopologyInfo - > data [ yOffset ] > > ( y % 8 ) ) & 1 ;
if ( ! isSubSliceEnabled ) {
continue ;
}
subSliceCount + + ;
2021-05-17 15:04:01 +00:00
subSliceIndices . push_back ( y ) ;
2022-05-19 14:06:33 +00:00
for ( int z = 0 ; z < queryTopologyInfo - > maxEusPerSubslice ; z + + ) {
size_t zOffset = ( queryTopologyInfo - > euOffset + ( x * queryTopologyInfo - > maxSubslices + y ) * queryTopologyInfo - > euStride + z / 8 ) ;
2021-01-26 11:02:17 +00:00
bool isEUEnabled = ( queryTopologyInfo - > data [ zOffset ] > > ( z % 8 ) ) & 1 ;
if ( ! isEUEnabled ) {
continue ;
}
euCount + + ;
}
}
2021-05-17 15:04:01 +00:00
if ( subSliceIndices . size ( ) ) {
maxSubSliceCountPerSlice = std : : max ( maxSubSliceCountPerSlice , subSliceIndices [ subSliceIndices . size ( ) - 1 ] + 1 ) ;
}
2022-01-28 19:08:02 +00:00
// single slice available
if ( sliceCount = = 1 ) {
mapping . subsliceIndices = std : : move ( subSliceIndices ) ;
}
2021-01-26 11:02:17 +00:00
}
2021-04-27 14:45:13 +00:00
if ( sliceIndices . size ( ) ) {
maxSliceCount = sliceIndices [ sliceIndices . size ( ) - 1 ] + 1 ;
2021-05-07 15:29:28 +00:00
mapping . sliceIndices = std : : move ( sliceIndices ) ;
2021-04-27 14:45:13 +00:00
}
2021-05-07 15:29:28 +00:00
2022-01-28 19:08:02 +00:00
if ( sliceCount ! = 1 ) {
mapping . subsliceIndices . clear ( ) ;
}
2021-05-07 15:29:28 +00:00
data . sliceCount = sliceCount ;
data . subSliceCount = subSliceCount ;
data . euCount = euCount ;
data . maxSliceCount = maxSliceCount ;
2021-05-17 15:04:01 +00:00
data . maxSubSliceCount = maxSubSliceCountPerSlice ;
2021-05-07 15:29:28 +00:00
return ( data . sliceCount & & data . subSliceCount & & data . euCount ) ;
2021-01-26 11:02:17 +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 ) ;
auto adapterBDF = this - > getAdapterBDF ( ) ;
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
2022-06-29 16:49:29 +00:00
int ret = ioctlHelper - > ioctl ( DrmIoctl : : GemWait , & wait ) ;
2021-06-15 11:31:12 +00:00
if ( ret ! = 0 ) {
int err = errno ;
PRINT_DEBUG_STRING ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(I915_GEM_WAIT) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
}
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 ;
2022-06-06 15:48:31 +00:00
return getParamIoctl ( DrmParam : : ParamCsTimestampFrequency , & frequency ) ;
2021-06-25 12:28:28 +00:00
}
2021-09-03 15:20:44 +00:00
bool Drm : : queryEngineInfo ( ) {
return Drm : : queryEngineInfo ( false ) ;
}
bool Drm : : sysmanQueryEngineInfo ( ) {
return Drm : : queryEngineInfo ( true ) ;
}
2022-03-25 18:51:25 +00:00
bool Drm : : isDebugAttachAvailable ( ) {
2023-03-15 13:32:29 +00:00
int prelimEnableEuDebug = 0 ;
getPrelimEuDebug ( prelimEnableEuDebug ) ;
return ( prelimEnableEuDebug = = 1 ) & & ioctlHelper - > isDebugAttachAvailable ( ) ;
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 ) {
const std : : string relativefilePath = " /gt/gt " + std : : to_string ( tileId ) + " /addr_range " ;
std : : string readString ( 64 , ' \0 ' ) ;
errno = 0 ;
if ( readSysFsAsString ( relativefilePath , readString ) = = false ) {
return false ;
}
char * endPtr = nullptr ;
uint64_t retSize = static_cast < uint64_t > ( std : : strtoull ( readString . data ( ) , & endPtr , 16 ) ) ;
if ( ( endPtr = = readString . data ( ) ) | | ( errno ! = 0 ) ) {
return false ;
}
physicalSize = retSize ;
return true ;
}
2021-11-18 21:36:55 +00:00
bool Drm : : useVMBindImmediate ( ) const {
bool useBindImmediate = isDirectSubmissionActive ( ) | | hasPageFaultSupport ( ) ;
if ( DebugManager . flags . EnableImmediateVmBindExt . get ( ) ! = - 1 ) {
useBindImmediate = DebugManager . flags . EnableImmediateVmBindExt . get ( ) ;
}
return useBindImmediate ;
}
2021-11-12 17:34:33 +00:00
void Drm : : setupSystemInfo ( HardwareInfo * hwInfo , SystemInfo * sysInfo ) {
GT_SYSTEM_INFO * gtSysInfo = & hwInfo - > gtSystemInfo ;
gtSysInfo - > ThreadCount = gtSysInfo - > EUCount * sysInfo - > getNumThreadsPerEu ( ) ;
gtSysInfo - > MemoryType = sysInfo - > getMemoryType ( ) ;
gtSysInfo - > TotalVsThreads = sysInfo - > getTotalVsThreads ( ) ;
gtSysInfo - > TotalHsThreads = sysInfo - > getTotalHsThreads ( ) ;
gtSysInfo - > TotalDsThreads = sysInfo - > getTotalDsThreads ( ) ;
gtSysInfo - > TotalGsThreads = sysInfo - > getTotalGsThreads ( ) ;
gtSysInfo - > TotalPsThreadsWindowerRange = sysInfo - > getTotalPsThreads ( ) ;
gtSysInfo - > MaxEuPerSubSlice = sysInfo - > getMaxEuPerDualSubSlice ( ) ;
gtSysInfo - > MaxSlicesSupported = sysInfo - > getMaxSlicesSupported ( ) ;
2022-10-05 18:48:44 +00:00
if ( sysInfo - > getMaxDualSubSlicesSupported ( ) > 0 ) {
gtSysInfo - > MaxSubSlicesSupported = sysInfo - > getMaxDualSubSlicesSupported ( ) ;
gtSysInfo - > MaxDualSubSlicesSupported = sysInfo - > getMaxDualSubSlicesSupported ( ) ;
}
2021-11-12 17:34:33 +00:00
}
2022-02-03 11:13:44 +00:00
void Drm : : setupCacheInfo ( const HardwareInfo & hwInfo ) {
2022-12-09 15:11:27 +00:00
auto & gfxCoreHelper = rootDeviceEnvironment . getHelper < GfxCoreHelper > ( ) ;
2022-02-03 11:13:44 +00:00
2022-12-08 12:22:35 +00:00
if ( DebugManager . flags . ClosEnabled . get ( ) = = 0 | | gfxCoreHelper . getNumCacheRegions ( ) = = 0 ) {
2022-04-07 17:14:49 +00:00
this - > cacheInfo . reset ( new CacheInfo ( * this , 0 , 0 , 0 ) ) ;
2022-02-03 11:13:44 +00:00
return ;
}
const GT_SYSTEM_INFO * gtSysInfo = & hwInfo . gtSystemInfo ;
constexpr uint16_t maxNumWays = 32 ;
constexpr uint16_t globalReservationLimit = 16 ;
constexpr uint16_t clientReservationLimit = 8 ;
constexpr uint16_t maxReservationNumWays = std : : min ( globalReservationLimit , clientReservationLimit ) ;
const size_t totalCacheSize = gtSysInfo - > L3CacheSizeInKb * MemoryConstants : : kiloByte ;
const size_t maxReservationCacheSize = ( totalCacheSize * maxReservationNumWays ) / maxNumWays ;
2022-12-08 12:22:35 +00:00
const uint32_t maxReservationNumCacheRegions = gfxCoreHelper . getNumCacheRegions ( ) - 1 ;
2022-02-03 11:13:44 +00:00
2022-04-07 17:14:49 +00:00
this - > cacheInfo . reset ( new CacheInfo ( * this , maxReservationCacheSize , maxReservationNumCacheRegions , maxReservationNumWays ) ) ;
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 ( ) ;
}
2023-03-15 13:32:29 +00:00
void Drm : : getPrelimEuDebug ( int & prelimEuDebug ) {
prelimEuDebug = 0 ;
std : : string sysFsPciPath = getSysFsPciPath ( ) ;
std : : string prelimEuDebugPath = sysFsPciPath + " /prelim_enable_eu_debug " ;
std : : ifstream ifs ( prelimEuDebugPath . c_str ( ) , std : : ifstream : : in ) ;
if ( ! ifs . fail ( ) ) {
ifs > > prelimEuDebug ;
}
ifs . close ( ) ;
}
2021-12-14 09:46:01 +00:00
int Drm : : waitUserFence ( uint32_t ctxId , uint64_t address , uint64_t value , ValueWidth dataWidth , int64_t timeout , uint16_t flags ) {
2022-06-29 16:49:29 +00:00
return ioctlHelper - > waitUserFence ( ctxId , address , value , static_cast < uint32_t > ( dataWidth ) , timeout , flags ) ;
2021-12-14 09:46:01 +00:00
}
bool Drm : : querySystemInfo ( ) {
2022-06-01 16:03:01 +00:00
auto request = ioctlHelper - > getDrmParamValue ( DrmParam : : QueryHwconfigTable ) ;
2022-02-22 17:25:50 +00:00
auto deviceBlobQuery = this - > query ( request , 0 ) ;
2021-12-22 14:25:53 +00:00
if ( deviceBlobQuery . empty ( ) ) {
2021-12-14 09:46:01 +00:00
PRINT_DEBUG_STRING ( DebugManager . flags . PrintDebugMessages . get ( ) , stdout , " %s " , " INFO: System Info query failed! \n " ) ;
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 ;
}
2021-12-28 15:56:13 +00:00
std : : vector < uint8_t > Drm : : getMemoryRegions ( ) {
2022-06-01 18:35:56 +00:00
auto request = ioctlHelper - > getDrmParamValue ( DrmParam : : QueryMemoryRegions ) ;
return this - > query ( request , 0 ) ;
2021-12-28 15:56:13 +00:00
}
bool Drm : : queryMemoryInfo ( ) {
2023-04-29 00:37:13 +00:00
this - > memoryInfo = ioctlHelper - > createMemoryInfo ( ) ;
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 ) ;
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 ) ;
2022-01-20 18:13:07 +00:00
int32_t overrideCompletionFence = DebugManager . flags . EnableDrmCompletionFence . get ( ) ;
if ( overrideCompletionFence ! = - 1 ) {
support = ! ! overrideCompletionFence ;
}
completionFenceSupported = support ;
2022-10-11 12:36:19 +00:00
if ( DebugManager . flags . PrintCompletionFenceUsage . get ( ) ) {
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 ) {
std : : string prelimVersion = " " ;
getPrelimVersion ( prelimVersion ) ;
2023-01-09 11:24:53 +00:00
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
}
bool Drm : : queryTopology ( const HardwareInfo & hwInfo , QueryTopologyData & topologyData ) {
topologyData . sliceCount = 0 ;
topologyData . subSliceCount = 0 ;
topologyData . euCount = 0 ;
int sliceCount = 0 ;
int subSliceCount = 0 ;
int euCount = 0 ;
2022-06-01 18:35:56 +00:00
auto request = ioctlHelper - > getDrmParamValue ( DrmParam : : QueryComputeSlices ) ;
if ( DebugManager . flags . UseNewQueryTopoIoctl . get ( ) & & this - > engineInfo & & hwInfo . gtSystemInfo . MultiTileArchInfo . TileCount > 0 & & request ! = 0 ) {
2022-01-28 21:00:05 +00:00
bool success = true ;
for ( uint32_t i = 0 ; i < hwInfo . gtSystemInfo . MultiTileArchInfo . TileCount ; i + + ) {
auto classInstance = this - > engineInfo - > getEngineInstance ( i , hwInfo . capabilityTable . defaultEngineType ) ;
UNRECOVERABLE_IF ( ! classInstance ) ;
uint32_t flags = classInstance - > engineClass ;
flags | = ( classInstance - > engineInstance < < 8 ) ;
2022-06-01 18:35:56 +00:00
auto dataQuery = this - > query ( request , flags ) ;
2022-01-28 21:00:05 +00:00
if ( dataQuery . empty ( ) ) {
success = false ;
break ;
}
2022-05-19 14:06:33 +00:00
auto data = reinterpret_cast < QueryTopologyInfo * > ( dataQuery . data ( ) ) ;
2022-01-28 21:00:05 +00:00
QueryTopologyData tileTopologyData = { } ;
TopologyMapping mapping ;
if ( ! translateTopologyInfo ( data , tileTopologyData , mapping ) ) {
success = false ;
break ;
}
// pick smallest config
sliceCount = ( sliceCount = = 0 ) ? tileTopologyData . sliceCount : std : : min ( sliceCount , tileTopologyData . sliceCount ) ;
subSliceCount = ( subSliceCount = = 0 ) ? tileTopologyData . subSliceCount : std : : min ( subSliceCount , tileTopologyData . subSliceCount ) ;
euCount = ( euCount = = 0 ) ? tileTopologyData . euCount : std : : min ( euCount , tileTopologyData . euCount ) ;
topologyData . maxSliceCount = std : : max ( topologyData . maxSliceCount , tileTopologyData . maxSliceCount ) ;
topologyData . maxSubSliceCount = std : : max ( topologyData . maxSubSliceCount , tileTopologyData . maxSubSliceCount ) ;
2022-05-19 14:06:33 +00:00
topologyData . maxEuCount = std : : max ( topologyData . maxEuCount , static_cast < int > ( data - > maxEusPerSubslice ) ) ;
2022-01-28 21:00:05 +00:00
this - > topologyMap [ i ] = mapping ;
}
if ( success ) {
topologyData . sliceCount = sliceCount ;
topologyData . subSliceCount = subSliceCount ;
topologyData . euCount = euCount ;
return true ;
}
}
// fallback to DRM_I915_QUERY_TOPOLOGY_INFO
2022-07-26 12:11:50 +00:00
request = ioctlHelper - > getDrmParamValue ( DrmParam : : QueryTopologyInfo ) ;
auto dataQuery = this - > query ( request , 0 ) ;
2022-01-28 21:00:05 +00:00
if ( dataQuery . empty ( ) ) {
return false ;
}
2022-05-19 14:06:33 +00:00
auto data = reinterpret_cast < QueryTopologyInfo * > ( dataQuery . data ( ) ) ;
2022-01-28 21:00:05 +00:00
TopologyMapping mapping ;
auto retVal = translateTopologyInfo ( data , topologyData , mapping ) ;
2022-05-19 14:06:33 +00:00
topologyData . maxEuCount = data - > maxEusPerSubslice ;
2022-01-28 21:00:05 +00:00
this - > topologyMap . clear ( ) ;
this - > topologyMap [ 0 ] = mapping ;
return retVal ;
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
if ( const auto paramId = ioctlHelper - > getHasPageFaultParamId ( ) ; paramId ) {
int support = 0 ;
const auto ret = getParamIoctl ( * paramId , & support ) ;
pageFaultSupported = ( 0 = = ret ) & & ( support > 0 ) ;
}
}
2022-04-13 10:05:04 +00:00
bool Drm : : hasPageFaultSupport ( ) const {
if ( DebugManager . flags . EnableRecoverablePageFaults . get ( ) ! = - 1 ) {
return ! ! DebugManager . flags . EnableRecoverablePageFaults . get ( ) ;
}
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 > ( ) ;
auto kmdMigrationSupported = hasPageFaultSupport ( ) & & productHelper . isKmdMigrationSupported ( ) ;
if ( DebugManager . flags . UseKmdMigration . get ( ) ! = - 1 ) {
return ! ! DebugManager . flags . UseKmdMigration . get ( ) ;
}
return kmdMigrationSupported ;
}
2022-02-11 13:46:23 +00:00
unsigned int Drm : : bindDrmContext ( uint32_t drmContextId , uint32_t deviceIndex , aub_stream : : EngineType engineType , bool engineInstancedDevice ) {
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
}
bool useVirtualEnginesForCcs = ! engineInstancedDevice ;
if ( DebugManager . flags . UseDrmVirtualEnginesForCcs . get ( ) ! = - 1 ) {
useVirtualEnginesForCcs = ! ! DebugManager . flags . UseDrmVirtualEnginesForCcs . get ( ) ;
}
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 ( ) ;
if ( DebugManager . flags . LimitEngineCountForVirtualBcs . get ( ) ! = - 1 ) {
numberOfBCS = DebugManager . flags . LimitEngineCountForVirtualBcs . get ( ) ;
}
if ( DebugManager . flags . LimitEngineCountForVirtualCcs . get ( ) ! = - 1 ) {
numberOfCCS = DebugManager . flags . LimitEngineCountForVirtualCcs . get ( ) ;
}
uint32_t numEnginesInContext = 1 ;
2022-07-27 15:28:43 +00:00
ContextParamEngines < 1 + maxEngines > contextEngines { } ;
ContextEnginesLoadBalance < maxEngines > balancer { } ;
2022-02-11 13:46:23 +00:00
contextEngines . engines [ 0 ] = { engine - > engineClass , engine - > engineInstance } ;
bool setupVirtualEngines = false ;
unsigned int engineCount = static_cast < unsigned int > ( numberOfCCS ) ;
2022-06-01 13:04:38 +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 ;
2022-06-01 13:04:38 +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 ) {
2022-08-08 14:02:17 +00:00
balancer . base . name = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextEnginesExtLoadBalance ) ;
2022-02-11 13:46:23 +00:00
contextEngines . extensions = castToUint64 ( & balancer ) ;
2022-07-27 15:28:43 +00:00
contextEngines . engines [ 0 ] . engineClass = ioctlHelper - > getDrmParamValue ( DrmParam : : EngineClassInvalid ) ;
contextEngines . engines [ 0 ] . engineInstance = ioctlHelper - > getDrmParamValue ( DrmParam : : EngineClassInvalidNone ) ;
2022-02-11 13:46:23 +00:00
for ( auto engineIndex = 0u ; engineIndex < engineCount ; engineIndex + + ) {
2022-06-01 13:04:38 +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 ) ;
2022-06-01 13:04:38 +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 } ;
contextEngines . engines [ 1 + engineIndex ] = { engine - > engineClass , engine - > engineInstance } ;
}
}
2022-05-20 15:04:07 +00:00
GemContextParam param { } ;
param . contextId = drmContextId ;
2022-02-11 13:46:23 +00:00
param . size = static_cast < uint32_t > ( ptrDiff ( contextEngines . engines + numEnginesInContext , & contextEngines ) ) ;
2022-07-27 08:32:08 +00:00
param . param = ioctlHelper - > getDrmParamValue ( DrmParam : : ContextParamEngines ) ;
2022-02-11 13:46:23 +00:00
param . value = castToUint64 ( & contextEngines ) ;
2022-06-29 16:49:29 +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
2022-06-14 16:47:02 +00:00
retVal = static_cast < unsigned int > ( ioctlHelper - > getDrmParamValue ( DrmParam : : ExecDefault ) ) ;
return retVal ;
2022-02-11 13:46:23 +00:00
}
2022-02-11 15:03:58 +00:00
void Drm : : waitForBind ( uint32_t vmHandleId ) {
if ( pagingFence [ vmHandleId ] > = fenceVal [ vmHandleId ] ) {
return ;
}
auto lock = this - > lockBindFenceMutex ( ) ;
2022-11-09 14:17:43 +00:00
auto fenceAddress = castToUint64 ( & this - > pagingFence [ vmHandleId ] ) ;
auto fenceValue = this - > fenceVal [ vmHandleId ] ;
lock . unlock ( ) ;
waitUserFence ( 0u , fenceAddress , fenceValue , ValueWidth : : U64 , - 1 , ioctlHelper - > getWaitUserFenceSoftFlag ( ) ) ;
2022-02-11 15:03:58 +00:00
}
2022-09-20 07:07:59 +00:00
bool Drm : : isSetPairAvailable ( ) {
2022-12-07 20:54:48 +00:00
if ( DebugManager . flags . EnableSetPair . get ( ) = = 1 ) {
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 ;
}
2022-02-15 14:00:35 +00:00
bool Drm : : isVmBindAvailable ( ) {
std : : call_once ( checkBindOnce , [ this ] ( ) {
2022-06-29 16:49:29 +00:00
int ret = ioctlHelper - > isVmBindAvailable ( ) ;
2022-02-15 14:00:35 +00:00
2023-01-02 11:52:22 +00:00
const auto & productHelper = this - > getRootDeviceEnvironment ( ) . getHelper < ProductHelper > ( ) ;
ret & = static_cast < int > ( productHelper . isNewResidencyModelSupported ( ) ) ;
2022-02-15 14:00:35 +00:00
bindAvailable = ret ;
Drm : : overrideBindSupport ( bindAvailable ) ;
2022-05-04 13:59:12 +00:00
queryAndSetVmBindPatIndexProgrammingSupport ( ) ;
2022-02-15 14:00:35 +00:00
} ) ;
return bindAvailable ;
}
2022-04-19 19:24:19 +00:00
uint64_t Drm : : getPatIndex ( Gmm * gmm , AllocationType allocationType , CacheRegion cacheRegion , CachePolicy cachePolicy , bool closEnabled ) const {
2022-04-11 17:13:44 +00:00
if ( DebugManager . flags . OverridePatIndex . get ( ) ! = - 1 ) {
return static_cast < uint64_t > ( DebugManager . flags . OverridePatIndex . get ( ) ) ;
}
2022-05-04 13:59:12 +00:00
if ( ! this - > vmBindPatIndexProgrammingSupported ) {
2022-04-19 19:24:19 +00:00
return CommonConstants : : unsupportedPatIndex ;
}
2022-12-09 15:11:27 +00:00
auto & gfxCoreHelper = rootDeviceEnvironment . getHelper < GfxCoreHelper > ( ) ;
2022-12-25 00:00:07 +00:00
auto & productHelper = rootDeviceEnvironment . getProductHelper ( ) ;
2022-05-05 13:09:02 +00:00
2022-04-19 19:24:19 +00:00
GMM_RESOURCE_INFO * resourceInfo = nullptr ;
2023-01-23 18:44:33 +00:00
GMM_RESOURCE_USAGE_TYPE usageType = CacheSettingsHelper : : getGmmUsageType ( allocationType , false , productHelper ) ;
2022-09-21 12:49:45 +00:00
bool cachable = ! CacheSettingsHelper : : isUncachedType ( usageType ) ;
bool compressed = false ;
2022-04-19 19:24:19 +00:00
if ( gmm ) {
resourceInfo = gmm - > gmmResourceInfo - > peekGmmResourceInfo ( ) ;
usageType = gmm - > resourceParams . Usage ;
2022-09-21 12:49:45 +00:00
compressed = gmm - > isCompressionEnabled ;
cachable = gmm - > gmmResourceInfo - > getResourceFlags ( ) - > Info . Cacheable ;
2022-04-19 19:24:19 +00:00
}
2022-09-21 12:49:45 +00:00
uint64_t patIndex = rootDeviceEnvironment . getGmmClientContext ( ) - > cachePolicyGetPATIndex ( resourceInfo , usageType , compressed , cachable ) ;
2022-12-25 00:00:07 +00:00
patIndex = productHelper . overridePatIndex ( allocationType , patIndex ) ;
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 ) ) ;
2022-04-19 19:24:19 +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 ) {
2022-12-08 12:22:35 +00:00
patIndex = gfxCoreHelper . getPatIndex ( cacheRegion , cachePolicy ) ;
2022-04-11 17:13:44 +00:00
}
return patIndex ;
}
2022-10-01 11:39:49 +02:00
int changeBufferObjectBinding ( Drm * drm , OsContext * osContext , uint32_t vmHandleId , BufferObject * bo , bool bind ) {
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 ] ;
}
std : : unique_ptr < uint8_t [ ] > extensions ;
if ( bind ) {
bool allowUUIDsForDebug = ! osContext - > isInternalEngine ( ) & & ! EngineHelpers : : isBcs ( osContext - > getEngineType ( ) ) ;
if ( bo - > getBindExtHandles ( ) . size ( ) > 0 & & allowUUIDsForDebug ) {
extensions = ioctlHelper - > prepareVmBindExt ( bo - > getBindExtHandles ( ) ) ;
}
bool bindCapture = bo - > isMarkedForCapture ( ) ;
bool bindImmediate = bo - > isImmediateBindingRequired ( ) ;
bool bindMakeResident = false ;
2022-10-01 11:39:49 +02:00
if ( drm - > useVMBindImmediate ( ) ) {
2022-02-15 17:28:38 +00:00
bindMakeResident = bo - > isExplicitResidencyRequired ( ) ;
bindImmediate = true ;
}
flags | = ioctlHelper - > getFlagsForVmBind ( bindCapture , bindImmediate , bindMakeResident ) ;
}
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 ( ) ;
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 ) ;
ioctlHelper - > fillVmBindExtSetPat ( vmBindExtSetPat , bo - > peekPatIndex ( ) , castToUint64 ( extensions . get ( ) ) ) ;
2022-04-05 17:04:53 +02:00
vmBind . extensions = castToUint64 ( vmBindExtSetPat ) ;
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 ;
2022-02-15 17:28:38 +00:00
2023-03-17 13:00:44 +00:00
VmBindExtUserFenceT vmBindExtUserFence { } ;
2023-04-17 13:56:47 +00:00
bool incrementFenceValue = false ;
2023-03-17 13:00:44 +00:00
if ( ioctlHelper - > isWaitBeforeBindRequired ( bind ) ) {
2022-10-01 11:39:49 +02:00
if ( drm - > useVMBindImmediate ( ) ) {
lock = drm - > lockBindFenceMutex ( ) ;
2022-02-15 17:28:38 +00:00
2022-10-01 11:39:49 +02:00
if ( ! drm - > hasPageFaultSupport ( ) | | bo - > isExplicitResidencyRequired ( ) ) {
2022-02-15 17:28:38 +00:00
auto nextExtension = vmBind . extensions ;
2022-10-01 11:39:49 +02:00
auto address = castToUint64 ( drm - > getFenceAddr ( vmHandleId ) ) ;
auto value = drm - > getNextFenceVal ( vmHandleId ) ;
2023-04-17 13:56:47 +00:00
incrementFenceValue = true ;
2022-03-29 17:48:12 +00:00
ioctlHelper - > fillVmBindExtUserFence ( vmBindExtUserFence , address , value , nextExtension ) ;
2022-04-05 17:04:53 +02:00
vmBind . extensions = castToUint64 ( vmBindExtUserFence ) ;
2022-02-15 17:28:38 +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 ;
}
}
2023-04-17 13:56:47 +00:00
if ( incrementFenceValue ) {
drm - > incFenceVal ( vmHandleId ) ;
}
2022-02-15 17:28:38 +00:00
}
return ret ;
}
int Drm : : bindBufferObject ( OsContext * osContext , uint32_t vmHandleId , BufferObject * bo ) {
2022-10-01 11:39:49 +02:00
auto ret = changeBufferObjectBinding ( this , osContext , vmHandleId , bo , true ) ;
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 ) ;
ret = changeBufferObjectBinding ( this , osContext , vmHandleId , bo , true ) ;
2022-02-15 17:28:38 +00:00
}
return ret ;
}
int Drm : : unbindBufferObject ( OsContext * osContext , uint32_t vmHandleId , BufferObject * bo ) {
2022-10-01 11:39:49 +02:00
return changeBufferObjectBinding ( this , osContext , vmHandleId , bo , 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 ( ) ;
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 ( ) ) ;
}
2023-03-13 16:23:21 +00:00
bool disableScratch = false ;
if ( rootDeviceEnvironment . executionEnvironment . isDebuggingEnabled ( ) ) {
disableScratch = false ;
}
if ( DebugManager . flags . DisableScratchPages . get ( ) ! = - 1 ) {
disableScratch = DebugManager . flags . DisableScratchPages . get ( ) ;
}
2022-04-21 16:59:48 +00:00
bool useVmBind = isVmBindAvailable ( ) ;
bool enablePageFault = hasPageFaultSupport ( ) & & useVmBind ;
2022-02-16 10:37:44 +00:00
2022-04-21 16:59:48 +00:00
ctl . flags = ioctlHelper - > getFlagsForVmCreate ( disableScratch , enablePageFault , useVmBind ) ;
2022-02-16 10:37:44 +00:00
2022-06-29 16:49:29 +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 ;
if ( ctl . vmId = = 0 ) {
2022-02-16 10:37:44 +00:00
// 0 is reserved for invalid/unassigned ppgtt
return - 1 ;
}
} else {
printDebugString ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr ,
" 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
void Drm : : waitOnUserFences ( const OsContextLinux & osContext , uint64_t address , uint64_t value , uint32_t numActiveTiles , uint32_t postSyncOffset ) {
auto & drmContextIds = osContext . getDrmContextIds ( ) ;
UNRECOVERABLE_IF ( numActiveTiles > drmContextIds . size ( ) ) ;
auto completionFenceCpuAddress = address ;
2023-01-10 17:20:07 +00:00
static constexpr int64_t defaultTimeout = - 1 ;
const auto selectedTimeout = osContext . isHangDetected ( ) ? 1 : defaultTimeout ;
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 ;
int retVal = waitUserFence ( drmContextIds [ drmIterator ] , completionFenceCpuAddress , value , Drm : : ValueWidth : : U64 , selectedTimeout , flags ) ;
2022-10-11 12:36:19 +00:00
if ( DebugManager . flags . PrintCompletionFenceUsage . get ( ) ) {
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 ;
}
} else if ( DebugManager . flags . PrintCompletionFenceUsage . get ( ) ) {
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
}
completionFenceCpuAddress = ptrOffset ( completionFenceCpuAddress , postSyncOffset ) ;
}
}
2019-03-26 11:59:46 +01:00
} // namespace NEO