Skip to content

Xe KMD: OAM support #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions external/drm/xe_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,9 @@ enum drm_xe_oa_unit_type {

/** @DRM_XE_OA_UNIT_TYPE_OAM: OAM OA unit */
DRM_XE_OA_UNIT_TYPE_OAM,

/** @DRM_XE_OA_UNIT_TYPE_OAM_SAG: OAM_SAG OA unit */
DRM_XE_OA_UNIT_TYPE_OAM_SAG,
};

/**
Expand All @@ -1488,6 +1491,7 @@ struct drm_xe_oa_unit {
#define DRM_XE_OA_CAPS_SYNCS (1 << 1)
#define DRM_XE_OA_CAPS_OA_BUFFER_SIZE (1 << 2)
#define DRM_XE_OA_CAPS_WAIT_NUM_REPORTS ( 1 << 3 )
#define DRM_XE_OA_CAPS_OAM (1 << 4)

/** @oa_timestamp_freq: OA timestamp freq */
__u64 oa_timestamp_freq;
Expand Down
2 changes: 1 addition & 1 deletion inc/common/instrumentation/api/metrics_discovery_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ SPDX-License-Identifier: MIT
//////////////////////////////////////////////////////////////////////////////////
// API build number:
//////////////////////////////////////////////////////////////////////////////////
#define MD_API_BUILD_NUMBER_CURRENT 180
#define MD_API_BUILD_NUMBER_CURRENT 181

namespace MetricsDiscovery
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ namespace MetricsDiscoveryInternal

virtual TCompletionCode GetOaBufferSize( const int32_t streamId, uint32_t& oaBufferSize ) = 0;
virtual TCompletionCode GetOaBufferSupportedSizes( const uint32_t platformId, uint32_t& minSize, uint32_t& maxSize ) = 0;
virtual TCompletionCode GetOaBufferCount( CMetricsDevice& metricsDevice, uint32_t& oaBufferCount ) = 0;
virtual uint32_t GetOaBufferCount( CMetricsDevice& metricsDevice ) = 0;
virtual TCompletionCode GetL3NodeTotalCount( CMetricsDevice& metricsDevice, uint32_t& l3NodeCount ) = 0;
virtual TCompletionCode GetL3BankTotalCount( CMetricsDevice& metricsDevice, uint32_t& l3BankCount ) = 0;
virtual TCompletionCode GetCopyEngineTotalCount( CMetricsDevice& metricsDevice, uint32_t& copyEngineCount ) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ namespace MetricsDiscoveryInternal

virtual TCompletionCode GetOaBufferSize( const int32_t streamId, uint32_t& oaBufferSize );
virtual TCompletionCode GetOaBufferSupportedSizes( const uint32_t platformId, uint32_t& minSize, uint32_t& maxSize );
virtual TCompletionCode GetOaBufferCount( CMetricsDevice& metricsDevice, uint32_t& oaBufferCount );
virtual uint32_t GetOaBufferCount( CMetricsDevice& metricsDevice );
virtual TCompletionCode GetL3NodeTotalCount( CMetricsDevice& metricsDevice, uint32_t& l3NodeCount );
virtual TCompletionCode GetL3BankTotalCount( CMetricsDevice& metricsDevice, uint32_t& l3BankCount );
virtual TCompletionCode GetCopyEngineTotalCount( CMetricsDevice& metricsDevice, uint32_t& copyEngineCount );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ namespace MetricsDiscoveryInternal
{
bool IsConfigurableOaBufferSize;
bool IsOaNotifyNumReportsSupported;
bool IsOamScmiSupported;
bool IsOamSagSupported;
} TXeObservationCapabilities;

//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -112,7 +114,7 @@ namespace MetricsDiscoveryInternal
virtual TCompletionCode GetRevisionId( int32_t& revisionId );
virtual TCompletionCode GetOaBufferSize( const int32_t streamId, uint32_t& oaBufferSize );
virtual TCompletionCode GetOaBufferSupportedSizes( const uint32_t platformId, uint32_t& minSize, uint32_t& maxSize );
virtual TCompletionCode GetOaBufferCount( CMetricsDevice& metricsDevice, uint32_t& oaBufferCount );
virtual uint32_t GetOaBufferCount( CMetricsDevice& metricsDevice );
virtual TCompletionCode GetL3NodeTotalCount( CMetricsDevice& metricsDevice, uint32_t& l3NodeCount );
virtual TCompletionCode GetL3BankTotalCount( CMetricsDevice& metricsDevice, uint32_t& l3BankCount );
virtual TCompletionCode GetCopyEngineTotalCount( CMetricsDevice& metricsDevice, uint32_t& copyEngineCount );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -897,16 +897,9 @@ namespace MetricsDiscoveryInternal
break;

case GTDI_DEVICE_PARAM_OA_BUFFERS_COUNT:
{
uint32_t oaBufferCount = 0;

ret = GetOaBufferCount( metricsDevice, oaBufferCount );
MD_CHECK_CC_RET_A( m_adapterId, ret );

out.ValueType = GTDI_DEVICE_PARAM_VALUE_TYPE_UINT32;
out.ValueUint32 = oaBufferCount;
out.ValueUint32 = GetOaBufferCount( metricsDevice );
break;
}

case GTDI_DEVICE_PARAM_L3_BANK_TOTAL_COUNT:
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ namespace MetricsDiscoveryInternal
break;

default:
MD_LOG_A( m_adapterId, LOG_ERROR, "Unknown engine type" );
MD_LOG_A( m_adapterId, LOG_ERROR, "Unknown engine type: %u", engine.engine_class );
MD_ASSERT_A( m_adapterId, 0 );
break;
}
Expand Down Expand Up @@ -2425,16 +2425,15 @@ namespace MetricsDiscoveryInternal
// Returns oa buffer count for current platform.
//
// Input:
// CMetricsDevice& metricsDevice - (IN) metrics device
// uint32_t& oaBufferCount - (OUT) oa buffer count
// CMetricsDevice& metricsDevice - metrics device
//
// Output:
// TCompletionCode - *CC_OK* means success
// uint32_t - oa buffer count
//
//////////////////////////////////////////////////////////////////////////////
TCompletionCode CDriverInterfaceLinuxPerf::GetOaBufferCount( CMetricsDevice& metricsDevice, uint32_t& oaBufferCount )
uint32_t CDriverInterfaceLinuxPerf::GetOaBufferCount( CMetricsDevice& metricsDevice )
{
oaBufferCount = 1; // OAG/OA buffer
uint32_t oaBufferCount = 1; // OAG/OA buffer

if( IsOamSupported() && IsSubDeviceSupported() )
{
Expand All @@ -2452,7 +2451,7 @@ namespace MetricsDiscoveryInternal
oaBufferCount += videoEngineCount;
}

return CC_OK;
return oaBufferCount;
}

//////////////////////////////////////////////////////////////////////////////
Expand Down
142 changes: 112 additions & 30 deletions instrumentation/metrics_discovery/linux/md_driver_ifc_linux_xe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ using namespace MetricsDiscovery;

namespace MetricsDiscoveryInternal
{
#define DRM_XE_ENGINE_CLASS_GSC 65535
#define DRM_XE_ENGINE_INSTANCE_GSC 65535

//////////////////////////////////////////////////////////////////////////////
//
// Struct:
Expand Down Expand Up @@ -277,11 +280,11 @@ namespace MetricsDiscoveryInternal
{
const bool isRenderEngine = engineParams.EngineId.ClassInstance.Class == DRM_XE_ENGINE_CLASS_RENDER;
const bool isComputeEngine = engineParams.EngineId.ClassInstance.Class == DRM_XE_ENGINE_CLASS_COMPUTE;
const bool isVideoEngine = engineParams.EngineId.ClassInstance.Class == DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
const bool isVideoEnhanceEngine = engineParams.EngineId.ClassInstance.Class == DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE;
const bool isGscEngine = engineParams.EngineId.ClassInstance.Class == DRM_XE_ENGINE_CLASS_GSC;
bool isValidInstance = ( requestedInstance == static_cast<uint32_t>( -1 ) ) || ( engineParams.EngineId.ClassInstance.Instance == requestedInstance );

if( isValidInstance && ( ( isOam && ( isVideoEngine || isVideoEnhanceEngine ) ) || ( !isOam && ( isRenderEngine || isComputeEngine ) ) ) )
if( isValidInstance && ( ( isOam && ( isVideoEnhanceEngine || isGscEngine ) ) || ( !isOam && ( isRenderEngine || isComputeEngine ) ) ) )
{
return true;
}
Expand Down Expand Up @@ -378,13 +381,36 @@ namespace MetricsDiscoveryInternal
const auto oaData = reinterpret_cast<drm_xe_query_oa_units*>( buffer.data() );
auto oaUnitOffset = reinterpret_cast<uint8_t*>( oaData->oa_units );

uint32_t currentGtId = 0;

for( uint32_t i = 0; i < oaData->num_oa_units; ++i )
{
const auto& oaUnit = *reinterpret_cast<drm_xe_oa_unit*>( oaUnitOffset );

for( uint32_t j = 0; j < oaUnit.num_engines; ++j )
if( oaUnit.oa_unit_type == DRM_XE_OA_UNIT_TYPE_OAM_SAG && oaUnit.num_engines == 0 )
{
engines.emplace_back( oaUnit.oa_unit_id, oaUnit.eci[j] );
drm_xe_engine_class_instance eci = {};
eci.engine_class = DRM_XE_ENGINE_CLASS_GSC;
eci.engine_instance = DRM_XE_ENGINE_INSTANCE_GSC;
eci.gt_id = currentGtId + 1;

engines.emplace_back( oaUnit.oa_unit_id, eci );
}
else
{
for( uint32_t j = 0; j < oaUnit.num_engines; ++j )
{
switch( oaUnit.eci[j].engine_class )
{
case DRM_XE_ENGINE_CLASS_RENDER:
case DRM_XE_ENGINE_CLASS_COMPUTE:
case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
engines.emplace_back( oaUnit.oa_unit_id, oaUnit.eci[j] );
currentGtId = oaUnit.eci[j].gt_id;
default:
break;
}
}
}

oaUnitOffset += sizeof( oaUnit ) + oaUnit.num_engines * sizeof( oaUnit.eci[0] );
Expand Down Expand Up @@ -432,7 +458,9 @@ namespace MetricsDiscoveryInternal
// Video engines have different gt_ids than render, compute and copy engines, so a different gt_id does not mean a new sub device.
const bool newDevice =
( engine.gt_id != previousGtId ) &&
( engine.engine_class != DRM_XE_ENGINE_CLASS_VIDEO_DECODE && engine.engine_class != DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE );
( engine.engine_class != DRM_XE_ENGINE_CLASS_VIDEO_DECODE &&
engine.engine_class != DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE &&
engine.engine_class != DRM_XE_ENGINE_CLASS_GSC );

if( newDevice )
{
Expand All @@ -442,16 +470,15 @@ namespace MetricsDiscoveryInternal
switch( engine.engine_class )
{
case DRM_XE_ENGINE_CLASS_RENDER:
case DRM_XE_ENGINE_CLASS_COPY:
case DRM_XE_ENGINE_CLASS_VIDEO_DECODE:
case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
case DRM_XE_ENGINE_CLASS_COMPUTE:
case DRM_XE_ENGINE_CLASS_GSC:
MD_LOG_A( m_adapterId, LOG_DEBUG, "Sub device %u / engine %u:%u / GT ID: %u / OA unit: %u", subDevices.GetAllEnginesCount() - 1, engine.engine_class, engine.engine_instance, engine.gt_id, oaUnit );
subDevices.AddEngine( engine.engine_class, engine.engine_instance, engine.gt_id, oaUnit );
break;

default:
MD_LOG_A( m_adapterId, LOG_ERROR, "Unknown engine type" );
MD_LOG_A( m_adapterId, LOG_ERROR, "Unknown engine type: %u", engine.engine_class );
MD_ASSERT_A( m_adapterId, 0 );
break;
}
Expand Down Expand Up @@ -496,6 +523,7 @@ namespace MetricsDiscoveryInternal
{
TCompletionCode ret = CC_ERROR_GENERAL;
int32_t oaEventFd = -1;
uint32_t requiredEngineInstance = -1;
const bool isOamRequested = IsOamRequested( oaReportType );
const uint32_t subDeviceIndex = metricsDevice.GetSubDeviceIndex();
auto subDevices = metricsDevice.GetAdapter().GetSubDevices();
Expand All @@ -504,6 +532,11 @@ namespace MetricsDiscoveryInternal
drm_xe_ext_set_property properties[DRM_XE_OA_PROPERTY_NO_PREEMPT - DRM_XE_OA_EXTENSION_SET_PROPERTY] = {};
uint32_t currentIndex = 0;

auto isValidValue = []( uint32_t value )
{
return value != static_cast<uint32_t>( -1 );
};

auto addProperty = [&]( const uint64_t key, const uint64_t value )
{
auto& property = properties[currentIndex];
Expand All @@ -520,7 +553,40 @@ namespace MetricsDiscoveryInternal
++currentIndex;
};

ret = subDevices.GetTbsEngineParams( subDeviceIndex, engine, -1, isOamRequested ); // Currently XE KMD supports only one media slice
if( oaBufferType != GTDI_OA_BUFFER_TYPE_OAG )
{
if( const uint32_t oaBufferCount = GetOaBufferCount( metricsDevice );
m_xeObservationCapabilities.IsOamSagSupported && oaBufferType == oaBufferCount - 1 )
{
requiredEngineInstance = DRM_XE_ENGINE_INSTANCE_GSC;
}
else
{
const uint32_t oamBufferSlice = static_cast<uint32_t>( oaBufferType ) - 1;
if( !isValidValue( oamBufferSlice ) )
{
MD_LOG_A( m_adapterId, LOG_ERROR, "ERROR: Incorrect oa buffer type for OAM. oaBufferType: %d, oamBufferSlice: %d", static_cast<uint32_t>( oaBufferType ), oamBufferSlice );
return CC_ERROR_INVALID_PARAMETER;
}

uint32_t baseEngineInstance = 0;
for( uint32_t i = 0; i < subDeviceIndex; ++i )
{
const uint32_t videoEnhanceEngineCount = subDevices.GetClassInstancesCount( i, DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE );

ret = isValidValue( videoEnhanceEngineCount )
? CC_ERROR_GENERAL
: CC_OK;
MD_CHECK_CC_RET_A( m_adapterId, ret );

baseEngineInstance += videoEnhanceEngineCount;
}

requiredEngineInstance = baseEngineInstance + oamBufferSlice;
}
}

ret = subDevices.GetTbsEngineParams( subDeviceIndex, engine, requiredEngineInstance, isOamRequested );
if( ret != CC_OK )
{
MD_LOG_A( m_adapterId, LOG_ERROR, "Error: No requested engine found, unable to open tbs on sub device. subDeviceIndex: %d, isOam: %d", subDeviceIndex, isOamRequested );
Expand Down Expand Up @@ -560,7 +626,7 @@ namespace MetricsDiscoveryInternal
param.observation_op = DRM_XE_OBSERVATION_OP_STREAM_OPEN;
param.param = reinterpret_cast<uint64_t>( properties );

MD_LOG_A( m_adapterId, LOG_DEBUG, "Opening XE OA stream with params: oaMetricSetId: %u, oaReportType: %u, timerPeriodExponent: %u, bufferSize: %u", oaMetricSetId, oaReportType, timerPeriodExponent, bufferSize );
MD_LOG_A( m_adapterId, LOG_DEBUG, "Opening XE OA stream with params: oaUnit: %u, oaMetricSetId: %u, oaReportType: %u, timerPeriodExponent: %u, bufferSize: %u", engine.OaUnit, oaMetricSetId, oaReportType, timerPeriodExponent, bufferSize );

oaEventFd = SendIoctl( m_DrmDeviceHandle, DRM_IOCTL_XE_OBSERVATION, &param );

Expand Down Expand Up @@ -1042,14 +1108,27 @@ namespace MetricsDiscoveryInternal
{
const auto& oaUnit = *reinterpret_cast<drm_xe_oa_unit*>( oaUnitOffset );

if( oaUnit.oa_unit_type == DRM_XE_OA_UNIT_TYPE_OAG )
switch( oaUnit.oa_unit_type )
{
m_xeObservationCapabilities.IsConfigurableOaBufferSize = oaUnit.capabilities & DRM_XE_OA_CAPS_OA_BUFFER_SIZE;
m_xeObservationCapabilities.IsOaNotifyNumReportsSupported = oaUnit.capabilities & DRM_XE_OA_CAPS_WAIT_NUM_REPORTS;
case DRM_XE_OA_UNIT_TYPE_OAG:
m_xeObservationCapabilities.IsConfigurableOaBufferSize = oaUnit.capabilities & DRM_XE_OA_CAPS_OA_BUFFER_SIZE;
m_xeObservationCapabilities.IsOaNotifyNumReportsSupported = oaUnit.capabilities & DRM_XE_OA_CAPS_WAIT_NUM_REPORTS;

MD_LOG_A( m_adapterId, LOG_INFO, "Configurable OA buffer size is%s supported", m_xeObservationCapabilities.IsConfigurableOaBufferSize ? "" : " not" );
MD_LOG_A( m_adapterId, LOG_INFO, "Oa notify num reports is%s supported", m_xeObservationCapabilities.IsOaNotifyNumReportsSupported ? "" : " not" );
break;
MD_LOG_A( m_adapterId, LOG_INFO, "Configurable OA buffer size is%s supported", m_xeObservationCapabilities.IsConfigurableOaBufferSize ? "" : " not" );
MD_LOG_A( m_adapterId, LOG_INFO, "Oa notify num reports is%s supported", m_xeObservationCapabilities.IsOaNotifyNumReportsSupported ? "" : " not" );
break;

case DRM_XE_OA_UNIT_TYPE_OAM:
m_xeObservationCapabilities.IsOamScmiSupported = oaUnit.capabilities & DRM_XE_OA_CAPS_OAM;

MD_LOG_A( m_adapterId, LOG_INFO, "OAM SCMI is%s supported", m_xeObservationCapabilities.IsOamScmiSupported ? "" : " not" );
break;

case DRM_XE_OA_UNIT_TYPE_OAM_SAG:
m_xeObservationCapabilities.IsOamSagSupported = oaUnit.capabilities & DRM_XE_OA_CAPS_OAM;

MD_LOG_A( m_adapterId, LOG_INFO, "OAM SAG is%s supported", m_xeObservationCapabilities.IsOamSagSupported ? "" : " not" );
break;
}

oaUnitOffset += sizeof( oaUnit ) + oaUnit.num_engines * sizeof( oaUnit.eci[0] );
Expand Down Expand Up @@ -1594,31 +1673,34 @@ namespace MetricsDiscoveryInternal
// Returns oa buffer count for current platform.
//
// Input:
// CMetricsDevice& metricsDevice - (IN) metrics device
// uint32_t& oaBufferCount - (OUT) oa buffer count
// CMetricsDevice& metricsDevice - metrics device
//
// Output:
// TCompletionCode - *CC_OK* means success
// uint32_t - oa buffer count
//
//////////////////////////////////////////////////////////////////////////////
TCompletionCode CDriverInterfaceLinuxXe::GetOaBufferCount( CMetricsDevice& metricsDevice, uint32_t& oaBufferCount )
uint32_t CDriverInterfaceLinuxXe::GetOaBufferCount( CMetricsDevice& metricsDevice )
{
oaBufferCount = 1; // OAG/OA buffer
uint32_t oaBufferCount = 1; // OAG/OA buffer

auto subDevices = metricsDevice.GetAdapter().GetSubDevices();
const uint32_t subDeviceIndex = metricsDevice.GetSubDeviceIndex();
const uint32_t videoEngineCount = subDevices.GetClassInstancesCount( subDeviceIndex, DRM_XE_ENGINE_CLASS_VIDEO_DECODE );
const uint32_t videoEnhanceEngineCount = subDevices.GetClassInstancesCount( subDeviceIndex, DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE );
auto subDevices = metricsDevice.GetAdapter().GetSubDevices();
const uint32_t subDeviceIndex = metricsDevice.GetSubDeviceIndex();

if( videoEngineCount != videoEnhanceEngineCount )
if( m_xeObservationCapabilities.IsOamScmiSupported )
{
MD_LOG_A( m_adapterId, LOG_ERROR, "Video engine count (%u) and video enhance engine count (%u) mismatch.", videoEngineCount, videoEnhanceEngineCount );
return CC_ERROR_GENERAL;
const uint32_t videoEnhanceEngineCount = subDevices.GetClassInstancesCount( subDeviceIndex, DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE );

oaBufferCount += videoEnhanceEngineCount; // Video enhance engines map to media slices (OAM SCMI).
}

oaBufferCount += videoEngineCount;
if( m_xeObservationCapabilities.IsOamSagSupported )
{
const uint32_t gscEngineCount = subDevices.GetClassInstancesCount( subDeviceIndex, DRM_XE_ENGINE_CLASS_GSC );

oaBufferCount += gscEngineCount; // OAM SAG
}

return CC_OK;
return oaBufferCount;
}

//////////////////////////////////////////////////////////////////////////////
Expand Down