@@ -96,6 +96,7 @@ struct xe_oa_open_param {
96
96
struct drm_xe_sync __user * syncs_user ;
97
97
int num_syncs ;
98
98
struct xe_sync_entry * syncs ;
99
+ size_t oa_buffer_size ;
99
100
};
100
101
101
102
struct xe_oa_config_bo {
@@ -403,11 +404,19 @@ static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf,
403
404
404
405
static void xe_oa_init_oa_buffer (struct xe_oa_stream * stream )
405
406
{
406
- struct xe_mmio * mmio = & stream -> gt -> mmio ;
407
407
u32 gtt_offset = xe_bo_ggtt_addr (stream -> oa_buffer .bo );
408
- u32 oa_buf = gtt_offset | OABUFFER_SIZE_16M | OAG_OABUFFER_MEMORY_SELECT ;
408
+ int size_exponent = __ffs (stream -> oa_buffer .bo -> size );
409
+ u32 oa_buf = gtt_offset | OAG_OABUFFER_MEMORY_SELECT ;
410
+ struct xe_mmio * mmio = & stream -> gt -> mmio ;
409
411
unsigned long flags ;
410
412
413
+ /*
414
+ * If oa buffer size is more than 16MB (exponent greater than 24), the
415
+ * oa buffer size field is multiplied by 8 in xe_oa_enable_metric_set.
416
+ */
417
+ oa_buf |= REG_FIELD_PREP (OABUFFER_SIZE_MASK ,
418
+ size_exponent > 24 ? size_exponent - 20 : size_exponent - 17 );
419
+
411
420
spin_lock_irqsave (& stream -> oa_buffer .ptr_lock , flags );
412
421
413
422
xe_mmio_write32 (mmio , __oa_regs (stream )-> oa_status , 0 );
@@ -901,15 +910,12 @@ static void xe_oa_stream_destroy(struct xe_oa_stream *stream)
901
910
xe_file_put (stream -> xef );
902
911
}
903
912
904
- static int xe_oa_alloc_oa_buffer (struct xe_oa_stream * stream )
913
+ static int xe_oa_alloc_oa_buffer (struct xe_oa_stream * stream , size_t size )
905
914
{
906
915
struct xe_bo * bo ;
907
916
908
- BUILD_BUG_ON_NOT_POWER_OF_2 (XE_OA_BUFFER_SIZE );
909
- BUILD_BUG_ON (XE_OA_BUFFER_SIZE < SZ_128K || XE_OA_BUFFER_SIZE > SZ_16M );
910
-
911
917
bo = xe_bo_create_pin_map (stream -> oa -> xe , stream -> gt -> tile , NULL ,
912
- XE_OA_BUFFER_SIZE , ttm_bo_type_kernel ,
918
+ size , ttm_bo_type_kernel ,
913
919
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_GGTT );
914
920
if (IS_ERR (bo ))
915
921
return PTR_ERR (bo );
@@ -1087,6 +1093,13 @@ static u32 oag_report_ctx_switches(const struct xe_oa_stream *stream)
1087
1093
0 : OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS );
1088
1094
}
1089
1095
1096
+ static u32 oag_buf_size_select (const struct xe_oa_stream * stream )
1097
+ {
1098
+ return _MASKED_FIELD (OAG_OA_DEBUG_BUF_SIZE_SELECT ,
1099
+ stream -> oa_buffer .bo -> size > SZ_16M ?
1100
+ OAG_OA_DEBUG_BUF_SIZE_SELECT : 0 );
1101
+ }
1102
+
1090
1103
static int xe_oa_enable_metric_set (struct xe_oa_stream * stream )
1091
1104
{
1092
1105
struct xe_mmio * mmio = & stream -> gt -> mmio ;
@@ -1119,6 +1132,7 @@ static int xe_oa_enable_metric_set(struct xe_oa_stream *stream)
1119
1132
xe_mmio_write32 (mmio , __oa_regs (stream )-> oa_debug ,
1120
1133
_MASKED_BIT_ENABLE (oa_debug ) |
1121
1134
oag_report_ctx_switches (stream ) |
1135
+ oag_buf_size_select (stream ) |
1122
1136
oag_configure_mmio_trigger (stream , true));
1123
1137
1124
1138
xe_mmio_write32 (mmio , __oa_regs (stream )-> oa_ctx_ctrl , stream -> periodic ?
@@ -1260,6 +1274,17 @@ static int xe_oa_set_prop_syncs_user(struct xe_oa *oa, u64 value,
1260
1274
return 0 ;
1261
1275
}
1262
1276
1277
+ static int xe_oa_set_prop_oa_buffer_size (struct xe_oa * oa , u64 value ,
1278
+ struct xe_oa_open_param * param )
1279
+ {
1280
+ if (!is_power_of_2 (value ) || value < SZ_128K || value > SZ_128M ) {
1281
+ drm_dbg (& oa -> xe -> drm , "OA buffer size invalid %llu\n" , value );
1282
+ return - EINVAL ;
1283
+ }
1284
+ param -> oa_buffer_size = value ;
1285
+ return 0 ;
1286
+ }
1287
+
1263
1288
static int xe_oa_set_prop_ret_inval (struct xe_oa * oa , u64 value ,
1264
1289
struct xe_oa_open_param * param )
1265
1290
{
@@ -1280,6 +1305,7 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs_open[] = {
1280
1305
[DRM_XE_OA_PROPERTY_NO_PREEMPT ] = xe_oa_set_no_preempt ,
1281
1306
[DRM_XE_OA_PROPERTY_NUM_SYNCS ] = xe_oa_set_prop_num_syncs ,
1282
1307
[DRM_XE_OA_PROPERTY_SYNCS ] = xe_oa_set_prop_syncs_user ,
1308
+ [DRM_XE_OA_PROPERTY_OA_BUFFER_SIZE ] = xe_oa_set_prop_oa_buffer_size ,
1283
1309
};
1284
1310
1285
1311
static const xe_oa_set_property_fn xe_oa_set_property_funcs_config [] = {
@@ -1294,6 +1320,7 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs_config[] = {
1294
1320
[DRM_XE_OA_PROPERTY_NO_PREEMPT ] = xe_oa_set_prop_ret_inval ,
1295
1321
[DRM_XE_OA_PROPERTY_NUM_SYNCS ] = xe_oa_set_prop_num_syncs ,
1296
1322
[DRM_XE_OA_PROPERTY_SYNCS ] = xe_oa_set_prop_syncs_user ,
1323
+ [DRM_XE_OA_PROPERTY_OA_BUFFER_SIZE ] = xe_oa_set_prop_ret_inval ,
1297
1324
};
1298
1325
1299
1326
static int xe_oa_user_ext_set_property (struct xe_oa * oa , enum xe_oa_user_extn_from from ,
@@ -1553,7 +1580,7 @@ static long xe_oa_status_locked(struct xe_oa_stream *stream, unsigned long arg)
1553
1580
1554
1581
static long xe_oa_info_locked (struct xe_oa_stream * stream , unsigned long arg )
1555
1582
{
1556
- struct drm_xe_oa_stream_info info = { .oa_buf_size = XE_OA_BUFFER_SIZE , };
1583
+ struct drm_xe_oa_stream_info info = { .oa_buf_size = stream -> oa_buffer . bo -> size , };
1557
1584
void __user * uaddr = (void __user * )arg ;
1558
1585
1559
1586
if (copy_to_user (uaddr , & info , sizeof (info )))
@@ -1639,7 +1666,7 @@ static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma)
1639
1666
}
1640
1667
1641
1668
/* Can mmap the entire OA buffer or nothing (no partial OA buffer mmaps) */
1642
- if (vma -> vm_end - vma -> vm_start != XE_OA_BUFFER_SIZE ) {
1669
+ if (vma -> vm_end - vma -> vm_start != stream -> oa_buffer . bo -> size ) {
1643
1670
drm_dbg (& stream -> oa -> xe -> drm , "Wrong mmap size, must be OA buffer size\n" );
1644
1671
return - EINVAL ;
1645
1672
}
@@ -1783,9 +1810,10 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
1783
1810
if (GRAPHICS_VER (stream -> oa -> xe ) >= 20 &&
1784
1811
stream -> hwe -> oa_unit -> type == DRM_XE_OA_UNIT_TYPE_OAG && stream -> sample )
1785
1812
stream -> oa_buffer .circ_size =
1786
- XE_OA_BUFFER_SIZE - XE_OA_BUFFER_SIZE % stream -> oa_buffer .format -> size ;
1813
+ param -> oa_buffer_size -
1814
+ param -> oa_buffer_size % stream -> oa_buffer .format -> size ;
1787
1815
else
1788
- stream -> oa_buffer .circ_size = XE_OA_BUFFER_SIZE ;
1816
+ stream -> oa_buffer .circ_size = param -> oa_buffer_size ;
1789
1817
1790
1818
if (stream -> exec_q && engine_supports_mi_query (stream -> hwe )) {
1791
1819
/* If we don't find the context offset, just return error */
@@ -1828,7 +1856,7 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
1828
1856
goto err_fw_put ;
1829
1857
}
1830
1858
1831
- ret = xe_oa_alloc_oa_buffer (stream );
1859
+ ret = xe_oa_alloc_oa_buffer (stream , param -> oa_buffer_size );
1832
1860
if (ret )
1833
1861
goto err_fw_put ;
1834
1862
@@ -2125,6 +2153,9 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
2125
2153
drm_dbg (& oa -> xe -> drm , "Using periodic sampling freq %lld Hz\n" , oa_freq_hz );
2126
2154
}
2127
2155
2156
+ if (!param .oa_buffer_size )
2157
+ param .oa_buffer_size = DEFAULT_XE_OA_BUFFER_SIZE ;
2158
+
2128
2159
ret = xe_oa_parse_syncs (oa , & param );
2129
2160
if (ret )
2130
2161
goto err_exec_q ;
0 commit comments