@@ -80,6 +80,7 @@ struct xe_oa_open_param {
8080 int engine_instance ;
8181 struct xe_exec_queue * exec_q ;
8282 struct xe_hw_engine * hwe ;
83+ bool no_preempt ;
8384};
8485
8586struct xe_oa_config_bo {
@@ -1013,11 +1014,55 @@ static void xe_oa_stream_disable(struct xe_oa_stream *stream)
10131014 hrtimer_cancel (& stream -> poll_check_timer );
10141015}
10151016
1017+ static int xe_oa_enable_preempt_timeslice (struct xe_oa_stream * stream )
1018+ {
1019+ struct xe_exec_queue * q = stream -> exec_q ;
1020+ int ret1 , ret2 ;
1021+
1022+ /* Best effort recovery: try to revert both to original, irrespective of error */
1023+ ret1 = q -> ops -> set_timeslice (q , stream -> hwe -> eclass -> sched_props .timeslice_us );
1024+ ret2 = q -> ops -> set_preempt_timeout (q , stream -> hwe -> eclass -> sched_props .preempt_timeout_us );
1025+ if (ret1 || ret2 )
1026+ goto err ;
1027+ return 0 ;
1028+ err :
1029+ drm_dbg (& stream -> oa -> xe -> drm , "%s failed ret1 %d ret2 %d\n" , __func__ , ret1 , ret2 );
1030+ return ret1 ?: ret2 ;
1031+ }
1032+
1033+ static int xe_oa_disable_preempt_timeslice (struct xe_oa_stream * stream )
1034+ {
1035+ struct xe_exec_queue * q = stream -> exec_q ;
1036+ int ret ;
1037+
1038+ /* Setting values to 0 will disable timeslice and preempt_timeout */
1039+ ret = q -> ops -> set_timeslice (q , 0 );
1040+ if (ret )
1041+ goto err ;
1042+
1043+ ret = q -> ops -> set_preempt_timeout (q , 0 );
1044+ if (ret )
1045+ goto err ;
1046+
1047+ return 0 ;
1048+ err :
1049+ xe_oa_enable_preempt_timeslice (stream );
1050+ drm_dbg (& stream -> oa -> xe -> drm , "%s failed %d\n" , __func__ , ret );
1051+ return ret ;
1052+ }
1053+
10161054static int xe_oa_enable_locked (struct xe_oa_stream * stream )
10171055{
10181056 if (stream -> enabled )
10191057 return 0 ;
10201058
1059+ if (stream -> no_preempt ) {
1060+ int ret = xe_oa_disable_preempt_timeslice (stream );
1061+
1062+ if (ret )
1063+ return ret ;
1064+ }
1065+
10211066 xe_oa_stream_enable (stream );
10221067
10231068 stream -> enabled = true;
@@ -1026,13 +1071,18 @@ static int xe_oa_enable_locked(struct xe_oa_stream *stream)
10261071
10271072static int xe_oa_disable_locked (struct xe_oa_stream * stream )
10281073{
1074+ int ret = 0 ;
1075+
10291076 if (!stream -> enabled )
10301077 return 0 ;
10311078
10321079 xe_oa_stream_disable (stream );
10331080
1081+ if (stream -> no_preempt )
1082+ ret = xe_oa_enable_preempt_timeslice (stream );
1083+
10341084 stream -> enabled = false;
1035- return 0 ;
1085+ return ret ;
10361086}
10371087
10381088static long xe_oa_config_locked (struct xe_oa_stream * stream , u64 arg )
@@ -1307,6 +1357,7 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
13071357 stream -> sample = param -> sample ;
13081358 stream -> periodic = param -> period_exponent > 0 ;
13091359 stream -> period_exponent = param -> period_exponent ;
1360+ stream -> no_preempt = param -> no_preempt ;
13101361
13111362 /*
13121363 * For Xe2+, when overrun mode is enabled, there are no partial reports at the end
@@ -1651,6 +1702,13 @@ static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value,
16511702 return 0 ;
16521703}
16531704
1705+ static int xe_oa_set_no_preempt (struct xe_oa * oa , u64 value ,
1706+ struct xe_oa_open_param * param )
1707+ {
1708+ param -> no_preempt = value ;
1709+ return 0 ;
1710+ }
1711+
16541712typedef int (* xe_oa_set_property_fn )(struct xe_oa * oa , u64 value ,
16551713 struct xe_oa_open_param * param );
16561714static const xe_oa_set_property_fn xe_oa_set_property_funcs [] = {
@@ -1662,6 +1720,7 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
16621720 [DRM_XE_OA_PROPERTY_OA_DISABLED ] = xe_oa_set_prop_disabled ,
16631721 [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID ] = xe_oa_set_prop_exec_queue_id ,
16641722 [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE ] = xe_oa_set_prop_engine_instance ,
1723+ [DRM_XE_OA_PROPERTY_NO_PREEMPT ] = xe_oa_set_no_preempt ,
16651724};
16661725
16671726static int xe_oa_user_ext_set_property (struct xe_oa * oa , u64 extension ,
@@ -1766,6 +1825,15 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
17661825 if (param .exec_q && !param .sample )
17671826 privileged_op = false;
17681827
1828+ if (param .no_preempt ) {
1829+ if (!param .exec_q ) {
1830+ drm_dbg (& oa -> xe -> drm , "Preemption disable without exec_q!\n" );
1831+ ret = - EINVAL ;
1832+ goto err_exec_q ;
1833+ }
1834+ privileged_op = true;
1835+ }
1836+
17691837 if (privileged_op && xe_perf_stream_paranoid && !perfmon_capable ()) {
17701838 drm_dbg (& oa -> xe -> drm , "Insufficient privileges to open xe perf stream\n" );
17711839 ret = - EACCES ;
0 commit comments