@@ -914,12 +914,17 @@ static void set_thread_membind(thread_data_t *data, numaset_data_t * numa_data)
914914 * sched_priority is only meaningful for RT tasks. Otherwise, it must be
915915 * set to 0 for the setattr syscall to succeed.
916916 */
917- static int __sched_priority (thread_data_t * data , sched_data_t * sched_data )
917+ static int __sched_priority (thread_data_t * data , sched_data_t * sched_data , int curr_prio )
918918{
919+ int prio = sched_data -> prio ;
920+
921+ if (prio == THREAD_PRIORITY_UNCHANGED )
922+ prio = curr_prio ;
923+
919924 switch (sched_data -> policy ) {
920925 case rr :
921926 case fifo :
922- return sched_data -> prio ;
927+ return prio ;
923928 }
924929
925930 return 0 ;
@@ -945,7 +950,13 @@ static bool __set_thread_policy_priority(thread_data_t *data,
945950 struct sched_param param ;
946951 int ret ;
947952
948- param .sched_priority = __sched_priority (data , sched_data );
953+ if (sched_data -> prio == THREAD_PRIORITY_UNCHANGED ) {
954+ log_error ("Cannot resolve the priority of the thread %s" ,
955+ data -> name );
956+ exit (EXIT_FAILURE );
957+ }
958+
959+ param .sched_priority = __sched_priority (data , sched_data , sched_data -> prio );
949960
950961 ret = pthread_setschedparam (pthread_self (),
951962 sched_data -> policy ,
@@ -1013,12 +1024,20 @@ static void _set_thread_rt(thread_data_t *data, sched_data_t *sched_data)
10131024}
10141025
10151026/* deadline can't rely on the default __set_thread_policy_priority */
1016- static void _set_thread_deadline (thread_data_t * data , sched_data_t * sched_data )
1027+ static void _set_thread_deadline (thread_data_t * data , sched_data_t * sched_data ,
1028+ sched_data_t * curr_sched_data )
10171029{
10181030 struct sched_attr sa_params = {0 };
10191031 unsigned int flags = 0 ;
10201032 pid_t tid ;
10211033 int ret ;
1034+ int curr_prio ;
1035+
1036+ if (curr_sched_data )
1037+ curr_prio = curr_sched_data -> prio ;
1038+ else
1039+ /* The value does not matter as it will not be used */
1040+ curr_prio = THREAD_PRIORITY_UNCHANGED ;
10221041
10231042 log_debug ("[%d] setting scheduler %s exec %lu, deadline %lu"
10241043 " period %lu" ,
@@ -1036,7 +1055,7 @@ static void _set_thread_deadline(thread_data_t *data, sched_data_t *sched_data)
10361055 sa_params .size = sizeof (struct sched_attr );
10371056 sa_params .sched_flags = 0 ;
10381057 sa_params .sched_policy = SCHED_DEADLINE ;
1039- sa_params .sched_priority = __sched_priority (data , sched_data );
1058+ sa_params .sched_priority = __sched_priority (data , sched_data , curr_prio );
10401059 sa_params .sched_runtime = sched_data -> runtime ;
10411060 sa_params .sched_deadline = sched_data -> deadline ;
10421061 sa_params .sched_period = sched_data -> period ;
@@ -1051,19 +1070,39 @@ static void _set_thread_deadline(thread_data_t *data, sched_data_t *sched_data)
10511070 }
10521071}
10531072
1054- static void _set_thread_uclamp (thread_data_t * data , sched_data_t * sched_data )
1073+ static void _set_thread_uclamp (thread_data_t * data , sched_data_t * sched_data , sched_data_t * curr_sched_data )
10551074{
10561075 struct sched_attr sa_params = {0 };
10571076 unsigned int flags = 0 ;
10581077 pid_t tid ;
10591078 int ret ;
1079+ policy_t policy ;
1080+ int curr_prio ;
10601081
10611082 if ((sched_data -> util_min == -2 &&
10621083 sched_data -> util_max == -2 ))
10631084 return ;
10641085
1065- sa_params .sched_policy = sched_data -> policy ;
1066- sa_params .sched_priority = __sched_priority (data , sched_data );
1086+ if (curr_sched_data ) {
1087+ if (sched_data -> policy == same )
1088+ policy = curr_sched_data -> policy ;
1089+ else
1090+ policy = sched_data -> policy ;
1091+
1092+ curr_prio = curr_sched_data -> prio ;
1093+ } else {
1094+ curr_prio = THREAD_PRIORITY_UNCHANGED ;
1095+ }
1096+
1097+
1098+ if (policy == same ) {
1099+ log_error ("Cannot resolve the policy of the thread %s" ,
1100+ data -> name );
1101+ exit (EXIT_FAILURE );
1102+ }
1103+
1104+ sa_params .sched_policy = policy ;
1105+ sa_params .sched_priority = __sched_priority (data , sched_data , curr_prio );
10671106 sa_params .size = sizeof (struct sched_attr );
10681107 sa_params .sched_flags = SCHED_FLAG_KEEP_ALL ;
10691108 tid = gettid ();
@@ -1099,37 +1138,51 @@ static void _set_thread_uclamp(thread_data_t *data, sched_data_t *sched_data)
10991138
11001139static void set_thread_param (thread_data_t * data , sched_data_t * sched_data )
11011140{
1141+ sched_data_t * curr_sched_data = data -> curr_sched_data ;
1142+
11021143 if (!sched_data )
11031144 return ;
11041145
1105- if (data -> curr_sched_data == sched_data )
1106- return ;
1146+ if (curr_sched_data ) {
1147+ if (curr_sched_data == sched_data )
1148+ return ;
1149+
1150+ if (sched_data -> prio == curr_sched_data -> prio )
1151+ sched_data -> prio = THREAD_PRIORITY_UNCHANGED ;
11071152
1108- /* if no policy is specified, reuse the previous one */
1109- if ((sched_data -> policy == same ) && data -> curr_sched_data )
1110- sched_data -> policy = data -> curr_sched_data -> policy ;
1153+ /* if no policy is specified, reuse the previous one */
1154+ if (sched_data -> policy == same )
1155+ sched_data -> policy = curr_sched_data -> policy ;
1156+ }
11111157
11121158 switch (sched_data -> policy ) {
11131159 case rr :
11141160 case fifo :
11151161 _set_thread_rt (data , sched_data );
1116- _set_thread_uclamp (data , sched_data );
1162+ _set_thread_uclamp (data , sched_data , curr_sched_data );
11171163 break ;
11181164 case other :
11191165 case idle :
11201166 _set_thread_cfs (data , sched_data );
1121- _set_thread_uclamp (data , sched_data );
1167+ _set_thread_uclamp (data , sched_data , curr_sched_data );
11221168 data -> lock_pages = 0 ; /* forced off */
11231169 break ;
11241170 case deadline :
1125- _set_thread_deadline (data , sched_data );
1171+ _set_thread_deadline (data , sched_data , curr_sched_data );
11261172 break ;
11271173 default :
11281174 log_error ("Unknown scheduling policy %d" ,
11291175 sched_data -> policy );
11301176 exit (EXIT_FAILURE );
11311177 }
11321178
1179+ /* Ensure we have an actual valid priority in curr_sched_data at all
1180+ * time, since it could be needed in a later phase for sched_setattr()
1181+ * syscall
1182+ */
1183+ if (sched_data -> prio == THREAD_PRIORITY_UNCHANGED )
1184+ sched_data -> prio = curr_sched_data -> prio ;
1185+
11331186 data -> curr_sched_data = sched_data ;
11341187}
11351188
0 commit comments