@@ -929,12 +929,17 @@ static void set_thread_membind(thread_data_t *data, numaset_data_t * numa_data)
929
929
* sched_priority is only meaningful for RT tasks. Otherwise, it must be
930
930
* set to 0 for the setattr syscall to succeed.
931
931
*/
932
- static int __sched_priority (thread_data_t * data , sched_data_t * sched_data )
932
+ static int __sched_priority (thread_data_t * data , sched_data_t * sched_data , int curr_prio )
933
933
{
934
+ int prio = sched_data -> prio ;
935
+
936
+ if (prio == THREAD_PRIORITY_UNCHANGED )
937
+ prio = curr_prio ;
938
+
934
939
switch (sched_data -> policy ) {
935
940
case rr :
936
941
case fifo :
937
- return sched_data -> prio ;
942
+ return prio ;
938
943
}
939
944
940
945
return 0 ;
@@ -960,7 +965,13 @@ static bool __set_thread_policy_priority(thread_data_t *data,
960
965
struct sched_param param ;
961
966
int ret ;
962
967
963
- param .sched_priority = __sched_priority (data , sched_data );
968
+ if (sched_data -> prio == THREAD_PRIORITY_UNCHANGED ) {
969
+ log_error ("Cannot resolve the priority of the thread %s" ,
970
+ data -> name );
971
+ exit (EXIT_FAILURE );
972
+ }
973
+
974
+ param .sched_priority = __sched_priority (data , sched_data , sched_data -> prio );
964
975
965
976
ret = pthread_setschedparam (pthread_self (),
966
977
sched_data -> policy ,
@@ -1028,12 +1039,20 @@ static void _set_thread_rt(thread_data_t *data, sched_data_t *sched_data)
1028
1039
}
1029
1040
1030
1041
/* deadline can't rely on the default __set_thread_policy_priority */
1031
- static void _set_thread_deadline (thread_data_t * data , sched_data_t * sched_data )
1042
+ static void _set_thread_deadline (thread_data_t * data , sched_data_t * sched_data ,
1043
+ sched_data_t * curr_sched_data )
1032
1044
{
1033
1045
struct sched_attr sa_params = {0 };
1034
1046
unsigned int flags = 0 ;
1035
1047
pid_t tid ;
1036
1048
int ret ;
1049
+ int curr_prio ;
1050
+
1051
+ if (curr_sched_data )
1052
+ curr_prio = curr_sched_data -> prio ;
1053
+ else
1054
+ /* The value does not matter as it will not be used */
1055
+ curr_prio = THREAD_PRIORITY_UNCHANGED ;
1037
1056
1038
1057
log_debug ("[%d] setting scheduler %s exec %lu, deadline %lu"
1039
1058
" period %lu" ,
@@ -1051,7 +1070,7 @@ static void _set_thread_deadline(thread_data_t *data, sched_data_t *sched_data)
1051
1070
sa_params .size = sizeof (struct sched_attr );
1052
1071
sa_params .sched_flags = 0 ;
1053
1072
sa_params .sched_policy = SCHED_DEADLINE ;
1054
- sa_params .sched_priority = __sched_priority (data , sched_data );
1073
+ sa_params .sched_priority = __sched_priority (data , sched_data , curr_prio );
1055
1074
sa_params .sched_runtime = sched_data -> runtime ;
1056
1075
sa_params .sched_deadline = sched_data -> deadline ;
1057
1076
sa_params .sched_period = sched_data -> period ;
@@ -1066,19 +1085,39 @@ static void _set_thread_deadline(thread_data_t *data, sched_data_t *sched_data)
1066
1085
}
1067
1086
}
1068
1087
1069
- static void _set_thread_uclamp (thread_data_t * data , sched_data_t * sched_data )
1088
+ static void _set_thread_uclamp (thread_data_t * data , sched_data_t * sched_data , sched_data_t * curr_sched_data )
1070
1089
{
1071
1090
struct sched_attr sa_params = {0 };
1072
1091
unsigned int flags = 0 ;
1073
1092
pid_t tid ;
1074
1093
int ret ;
1094
+ policy_t policy ;
1095
+ int curr_prio ;
1075
1096
1076
1097
if ((sched_data -> util_min == -2 &&
1077
1098
sched_data -> util_max == -2 ))
1078
1099
return ;
1079
1100
1080
- sa_params .sched_policy = sched_data -> policy ;
1081
- sa_params .sched_priority = __sched_priority (data , sched_data );
1101
+ if (curr_sched_data ) {
1102
+ if (sched_data -> policy == same )
1103
+ policy = curr_sched_data -> policy ;
1104
+ else
1105
+ policy = sched_data -> policy ;
1106
+
1107
+ curr_prio = curr_sched_data -> prio ;
1108
+ } else {
1109
+ curr_prio = THREAD_PRIORITY_UNCHANGED ;
1110
+ }
1111
+
1112
+
1113
+ if (policy == same ) {
1114
+ log_error ("Cannot resolve the policy of the thread %s" ,
1115
+ data -> name );
1116
+ exit (EXIT_FAILURE );
1117
+ }
1118
+
1119
+ sa_params .sched_policy = policy ;
1120
+ sa_params .sched_priority = __sched_priority (data , sched_data , curr_prio );
1082
1121
sa_params .size = sizeof (struct sched_attr );
1083
1122
sa_params .sched_flags = SCHED_FLAG_KEEP_ALL ;
1084
1123
tid = gettid ();
@@ -1114,37 +1153,51 @@ static void _set_thread_uclamp(thread_data_t *data, sched_data_t *sched_data)
1114
1153
1115
1154
static void set_thread_param (thread_data_t * data , sched_data_t * sched_data )
1116
1155
{
1156
+ sched_data_t * curr_sched_data = data -> curr_sched_data ;
1157
+
1117
1158
if (!sched_data )
1118
1159
return ;
1119
1160
1120
- if (data -> curr_sched_data == sched_data )
1121
- return ;
1161
+ if (curr_sched_data ) {
1162
+ if (curr_sched_data == sched_data )
1163
+ return ;
1164
+
1165
+ if (sched_data -> prio == curr_sched_data -> prio )
1166
+ sched_data -> prio = THREAD_PRIORITY_UNCHANGED ;
1122
1167
1123
- /* if no policy is specified, reuse the previous one */
1124
- if ((sched_data -> policy == same ) && data -> curr_sched_data )
1125
- sched_data -> policy = data -> curr_sched_data -> policy ;
1168
+ /* if no policy is specified, reuse the previous one */
1169
+ if (sched_data -> policy == same )
1170
+ sched_data -> policy = curr_sched_data -> policy ;
1171
+ }
1126
1172
1127
1173
switch (sched_data -> policy ) {
1128
1174
case rr :
1129
1175
case fifo :
1130
1176
_set_thread_rt (data , sched_data );
1131
- _set_thread_uclamp (data , sched_data );
1177
+ _set_thread_uclamp (data , sched_data , curr_sched_data );
1132
1178
break ;
1133
1179
case other :
1134
1180
case idle :
1135
1181
_set_thread_cfs (data , sched_data );
1136
- _set_thread_uclamp (data , sched_data );
1182
+ _set_thread_uclamp (data , sched_data , curr_sched_data );
1137
1183
data -> lock_pages = 0 ; /* forced off */
1138
1184
break ;
1139
1185
case deadline :
1140
- _set_thread_deadline (data , sched_data );
1186
+ _set_thread_deadline (data , sched_data , curr_sched_data );
1141
1187
break ;
1142
1188
default :
1143
1189
log_error ("Unknown scheduling policy %d" ,
1144
1190
sched_data -> policy );
1145
1191
exit (EXIT_FAILURE );
1146
1192
}
1147
1193
1194
+ /* Ensure we have an actual valid priority in curr_sched_data at all
1195
+ * time, since it could be needed in a later phase for sched_setattr()
1196
+ * syscall
1197
+ */
1198
+ if (sched_data -> prio == THREAD_PRIORITY_UNCHANGED )
1199
+ sched_data -> prio = curr_sched_data -> prio ;
1200
+
1148
1201
data -> curr_sched_data = sched_data ;
1149
1202
}
1150
1203
0 commit comments