@@ -96,6 +96,7 @@ struct xe_oa_open_param {
9696 struct drm_xe_sync __user * syncs_user ;
9797 int num_syncs ;
9898 struct xe_sync_entry * syncs ;
99+ size_t oa_buffer_size ;
99100};
100101
101102struct xe_oa_config_bo {
@@ -403,11 +404,19 @@ static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf,
403404
404405static void xe_oa_init_oa_buffer (struct xe_oa_stream * stream )
405406{
406- struct xe_mmio * mmio = & stream -> gt -> mmio ;
407407 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 ;
409411 unsigned long flags ;
410412
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+
411420 spin_lock_irqsave (& stream -> oa_buffer .ptr_lock , flags );
412421
413422 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)
901910 xe_file_put (stream -> xef );
902911}
903912
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 )
905914{
906915 struct xe_bo * bo ;
907916
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-
911917 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 ,
913919 XE_BO_FLAG_SYSTEM | XE_BO_FLAG_GGTT );
914920 if (IS_ERR (bo ))
915921 return PTR_ERR (bo );
@@ -1087,6 +1093,13 @@ static u32 oag_report_ctx_switches(const struct xe_oa_stream *stream)
10871093 0 : OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS );
10881094}
10891095
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+
10901103static int xe_oa_enable_metric_set (struct xe_oa_stream * stream )
10911104{
10921105 struct xe_mmio * mmio = & stream -> gt -> mmio ;
@@ -1119,6 +1132,7 @@ static int xe_oa_enable_metric_set(struct xe_oa_stream *stream)
11191132 xe_mmio_write32 (mmio , __oa_regs (stream )-> oa_debug ,
11201133 _MASKED_BIT_ENABLE (oa_debug ) |
11211134 oag_report_ctx_switches (stream ) |
1135+ oag_buf_size_select (stream ) |
11221136 oag_configure_mmio_trigger (stream , true));
11231137
11241138 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,
12601274 return 0 ;
12611275}
12621276
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+
12631288static int xe_oa_set_prop_ret_inval (struct xe_oa * oa , u64 value ,
12641289 struct xe_oa_open_param * param )
12651290{
@@ -1280,6 +1305,7 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs_open[] = {
12801305 [DRM_XE_OA_PROPERTY_NO_PREEMPT ] = xe_oa_set_no_preempt ,
12811306 [DRM_XE_OA_PROPERTY_NUM_SYNCS ] = xe_oa_set_prop_num_syncs ,
12821307 [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 ,
12831309};
12841310
12851311static 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[] = {
12941320 [DRM_XE_OA_PROPERTY_NO_PREEMPT ] = xe_oa_set_prop_ret_inval ,
12951321 [DRM_XE_OA_PROPERTY_NUM_SYNCS ] = xe_oa_set_prop_num_syncs ,
12961322 [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 ,
12971324};
12981325
12991326static 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)
15531580
15541581static long xe_oa_info_locked (struct xe_oa_stream * stream , unsigned long arg )
15551582{
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 , };
15571584 void __user * uaddr = (void __user * )arg ;
15581585
15591586 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)
16391666 }
16401667
16411668 /* 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 ) {
16431670 drm_dbg (& stream -> oa -> xe -> drm , "Wrong mmap size, must be OA buffer size\n" );
16441671 return - EINVAL ;
16451672 }
@@ -1783,9 +1810,10 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
17831810 if (GRAPHICS_VER (stream -> oa -> xe ) >= 20 &&
17841811 stream -> hwe -> oa_unit -> type == DRM_XE_OA_UNIT_TYPE_OAG && stream -> sample )
17851812 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 ;
17871815 else
1788- stream -> oa_buffer .circ_size = XE_OA_BUFFER_SIZE ;
1816+ stream -> oa_buffer .circ_size = param -> oa_buffer_size ;
17891817
17901818 if (stream -> exec_q && engine_supports_mi_query (stream -> hwe )) {
17911819 /* 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,
18281856 goto err_fw_put ;
18291857 }
18301858
1831- ret = xe_oa_alloc_oa_buffer (stream );
1859+ ret = xe_oa_alloc_oa_buffer (stream , param -> oa_buffer_size );
18321860 if (ret )
18331861 goto err_fw_put ;
18341862
@@ -2125,6 +2153,9 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
21252153 drm_dbg (& oa -> xe -> drm , "Using periodic sampling freq %lld Hz\n" , oa_freq_hz );
21262154 }
21272155
2156+ if (!param .oa_buffer_size )
2157+ param .oa_buffer_size = DEFAULT_XE_OA_BUFFER_SIZE ;
2158+
21282159 ret = xe_oa_parse_syncs (oa , & param );
21292160 if (ret )
21302161 goto err_exec_q ;
0 commit comments