@@ -914,12 +914,17 @@ static void set_thread_membind(thread_data_t *data, numaset_data_t * numa_data)
914
914
* sched_priority is only meaningful for RT tasks. Otherwise, it must be
915
915
* set to 0 for the setattr syscall to succeed.
916
916
*/
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 )
918
918
{
919
+ int prio = sched_data -> prio ;
920
+
921
+ if (prio == THREAD_PRIORITY_UNCHANGED )
922
+ prio = curr_prio ;
923
+
919
924
switch (sched_data -> policy ) {
920
925
case rr :
921
926
case fifo :
922
- return sched_data -> prio ;
927
+ return prio ;
923
928
}
924
929
925
930
return 0 ;
@@ -945,7 +950,13 @@ static bool __set_thread_policy_priority(thread_data_t *data,
945
950
struct sched_param param ;
946
951
int ret ;
947
952
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 );
949
960
950
961
ret = pthread_setschedparam (pthread_self (),
951
962
sched_data -> policy ,
@@ -1013,12 +1024,20 @@ static void _set_thread_rt(thread_data_t *data, sched_data_t *sched_data)
1013
1024
}
1014
1025
1015
1026
/* 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 )
1017
1029
{
1018
1030
struct sched_attr sa_params = {0 };
1019
1031
unsigned int flags = 0 ;
1020
1032
pid_t tid ;
1021
1033
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 ;
1022
1041
1023
1042
log_debug ("[%d] setting scheduler %s exec %lu, deadline %lu"
1024
1043
" period %lu" ,
@@ -1036,7 +1055,7 @@ static void _set_thread_deadline(thread_data_t *data, sched_data_t *sched_data)
1036
1055
sa_params .size = sizeof (struct sched_attr );
1037
1056
sa_params .sched_flags = 0 ;
1038
1057
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 );
1040
1059
sa_params .sched_runtime = sched_data -> runtime ;
1041
1060
sa_params .sched_deadline = sched_data -> deadline ;
1042
1061
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)
1051
1070
}
1052
1071
}
1053
1072
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 )
1055
1074
{
1056
1075
struct sched_attr sa_params = {0 };
1057
1076
unsigned int flags = 0 ;
1058
1077
pid_t tid ;
1059
1078
int ret ;
1079
+ policy_t policy ;
1080
+ int curr_prio ;
1060
1081
1061
1082
if ((sched_data -> util_min == -2 &&
1062
1083
sched_data -> util_max == -2 ))
1063
1084
return ;
1064
1085
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 );
1067
1106
sa_params .size = sizeof (struct sched_attr );
1068
1107
sa_params .sched_flags = SCHED_FLAG_KEEP_ALL ;
1069
1108
tid = gettid ();
@@ -1099,37 +1138,51 @@ static void _set_thread_uclamp(thread_data_t *data, sched_data_t *sched_data)
1099
1138
1100
1139
static void set_thread_param (thread_data_t * data , sched_data_t * sched_data )
1101
1140
{
1141
+ sched_data_t * curr_sched_data = data -> curr_sched_data ;
1142
+
1102
1143
if (!sched_data )
1103
1144
return ;
1104
1145
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 ;
1107
1152
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
+ }
1111
1157
1112
1158
switch (sched_data -> policy ) {
1113
1159
case rr :
1114
1160
case fifo :
1115
1161
_set_thread_rt (data , sched_data );
1116
- _set_thread_uclamp (data , sched_data );
1162
+ _set_thread_uclamp (data , sched_data , curr_sched_data );
1117
1163
break ;
1118
1164
case other :
1119
1165
case idle :
1120
1166
_set_thread_cfs (data , sched_data );
1121
- _set_thread_uclamp (data , sched_data );
1167
+ _set_thread_uclamp (data , sched_data , curr_sched_data );
1122
1168
data -> lock_pages = 0 ; /* forced off */
1123
1169
break ;
1124
1170
case deadline :
1125
- _set_thread_deadline (data , sched_data );
1171
+ _set_thread_deadline (data , sched_data , curr_sched_data );
1126
1172
break ;
1127
1173
default :
1128
1174
log_error ("Unknown scheduling policy %d" ,
1129
1175
sched_data -> policy );
1130
1176
exit (EXIT_FAILURE );
1131
1177
}
1132
1178
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
+
1133
1186
data -> curr_sched_data = sched_data ;
1134
1187
}
1135
1188
0 commit comments