| @@ -889,6 +889,23 @@ unsigned int sysctl_sched_uclamp_util_min = SCHED_CAPACITY_SCALE; · 888 unmodified lines |
| 889 | 889 | /* Max allowed maximum utilization */ |
| 890 | 890 | unsigned int sysctl_sched_uclamp_util_max = SCHED_CAPACITY_SCALE; |
| 891 | 891 | |
| 892 | +/* |
| 893 | + * By default RT tasks run at the maximum performance point/capacity of the |
| 894 | + * system. Uclamp enforces this by always setting UCLAMP_MIN of RT tasks to |
| 895 | + * SCHED_CAPACITY_SCALE. |
| 896 | + * |
| 897 | + * This knob allows admins to change the default behavior when uclamp is being |
| 898 | + * used. In battery powered devices, particularly, running at the maximum |
| 899 | + * capacity and frequency will increase energy consumption and shorten the |
| 900 | + * battery life. |
| 901 | + * |
| 902 | + * This knob only affects RT tasks that their uclamp_se->user_defined == false. |
| 903 | + * |
| 904 | + * This knob will not override the system default sched_util_clamp_min defined |
| 905 | + * above. |
| 906 | + */ |
| 907 | +unsigned int sysctl_sched_uclamp_util_min_rt_default = SCHED_CAPACITY_SCALE; |
| 908 | + |
| 892 | 909 | /* All clamps are required to be less or equal than these values */ |
| 893 | 910 | static struct uclamp_se uclamp_default[UCLAMP_CNT]; |
| 894 | 911 | |
| @@ -991,6 +1008,64 @@ unsigned int uclamp_rq_max_value(struct rq *rq, enum uclamp_id clamp_id, · 96 unmodified lines |
| 991 | 1008 | return uclamp_idle_value(rq, clamp_id, clamp_value); |
| 992 | 1009 | } |
| 993 | 1010 | |
| 1011 | +static void __uclamp_update_util_min_rt_default(struct task_struct *p) |
| 1012 | +{ |
| 1013 | + unsigned int default_util_min; |
| 1014 | + struct uclamp_se *uc_se; |
| 1015 | + |
| 1016 | + lockdep_assert_held(&p->pi_lock); |
| 1017 | + |
| 1018 | + uc_se = &p->uclamp_req[UCLAMP_MIN]; |
| 1019 | + |
| 1020 | + /* Only sync if user didn't override the default */ |
| 1021 | + if (uc_se->user_defined) |
| 1022 | + return; |
| 1023 | + |
| 1024 | + default_util_min = sysctl_sched_uclamp_util_min_rt_default; |
| 1025 | + uclamp_se_set(uc_se, default_util_min, false); |
| 1026 | +} |
| 1027 | + |
| 1028 | +static void uclamp_update_util_min_rt_default(struct task_struct *p) |
| 1029 | +{ |
| 1030 | + struct rq_flags rf; |
| 1031 | + struct rq *rq; |
| 1032 | + |
| 1033 | + if (!rt_task(p)) |
| 1034 | + return; |
| 1035 | + |
| 1036 | + /* Protect updates to p->uclamp_* */ |
| 1037 | + rq = task_rq_lock(p, &rf); |
| 1038 | + __uclamp_update_util_min_rt_default(p); |
| 1039 | + task_rq_unlock(rq, p, &rf); |
| 1040 | +} |
| 1041 | + |
| 1042 | +static void uclamp_sync_util_min_rt_default(void) |
| 1043 | +{ |
| 1044 | + struct task_struct *g, *p; |
| 1045 | + |
| 1046 | + /* |
| 1047 | + * copy_process() sysctl_uclamp |
| 1048 | + * uclamp_min_rt = X; |
| 1049 | + * write_lock(&tasklist_lock) read_lock(&tasklist_lock) |
| 1050 | + * // link thread smp_mb__after_spinlock() |
| 1051 | + * write_unlock(&tasklist_lock) read_unlock(&tasklist_lock); |
| 1052 | + * sched_post_fork() for_each_process_thread() |
| 1053 | + * __uclamp_sync_rt() __uclamp_sync_rt() |
| 1054 | + * |
| 1055 | + * Ensures that either sched_post_fork() will observe the new |
| 1056 | + * uclamp_min_rt or for_each_process_thread() will observe the new |
| 1057 | + * task. |
| 1058 | + */ |
| 1059 | + read_lock(&tasklist_lock); |
| 1060 | + smp_mb__after_spinlock(); |
| 1061 | + read_unlock(&tasklist_lock); |
| 1062 | + |
| 1063 | + rcu_read_lock(); |
| 1064 | + for_each_process_thread(g, p) |
| 1065 | + uclamp_update_util_min_rt_default(p); |
| 1066 | + rcu_read_unlock(); |
| 1067 | +} |
| 1068 | + |
| 994 | 1069 | static inline struct uclamp_se |
| 995 | 1070 | uclamp_tg_restrict(struct task_struct *p, enum uclamp_id clamp_id) |
| 996 | 1071 | { |
| @@ -1278,12 +1353,13 @@ int sysctl_sched_uclamp_handler(struct ctl_table *table, int write, · 281 unmodified lines |
| 1278 | 1353 | void *buffer, size_t *lenp, loff_t *ppos) |
| 1279 | 1354 | { |
| 1280 | 1355 | bool update_root_tg = false; |
| 1281 | | − int old_min, old_max; |
| 1356 | + int old_min, old_max, old_min_rt; |
| 1282 | 1357 | int result; |
| 1283 | 1358 | |
| 1284 | 1359 | mutex_lock(&uclamp_mutex); |
| 1285 | 1360 | old_min = sysctl_sched_uclamp_util_min; |
| 1286 | 1361 | old_max = sysctl_sched_uclamp_util_max; |
| 1362 | + old_min_rt = sysctl_sched_uclamp_util_min_rt_default; |
| 1287 | 1363 | |
| 1288 | 1364 | result = proc_dointvec(table, write, buffer, lenp, ppos); |
| 1289 | 1365 | if (result) |
| @@ -1292,7 +1368,9 @@ int sysctl_sched_uclamp_handler(struct ctl_table *table, int write, · 2 unmodified lines |
| 1292 | 1368 | goto done; |
| 1293 | 1369 | |
| 1294 | 1370 | if (sysctl_sched_uclamp_util_min > sysctl_sched_uclamp_util_max || |
| 1295 | | − sysctl_sched_uclamp_util_max > SCHED_CAPACITY_SCALE) { |
| 1371 | + sysctl_sched_uclamp_util_max > SCHED_CAPACITY_SCALE || |
| 1372 | + sysctl_sched_uclamp_util_min_rt_default > SCHED_CAPACITY_SCALE) { |
| 1373 | + |
| 1296 | 1374 | result = -EINVAL; |
| 1297 | 1375 | goto undo; |
| 1298 | 1376 | } |
| @@ -1313,6 +1391,11 @@ int sysctl_sched_uclamp_handler(struct ctl_table *table, int write, · 14 unmodified lines |
| 1313 | 1391 | uclamp_update_root_tg(); |
| 1314 | 1392 | } |
| 1315 | 1393 | |
| 1394 | + if (old_min_rt != sysctl_sched_uclamp_util_min_rt_default) { |
| 1395 | + static_branch_enable(&sched_uclamp_used); |
| 1396 | + uclamp_sync_util_min_rt_default(); |
| 1397 | + } |
| 1398 | + |
| 1316 | 1399 | /* |
| 1317 | 1400 | * We update all RUNNABLE tasks only when task groups are in use. |
| 1318 | 1401 | * Otherwise, keep it simple and do just a lazy update at each next |
| @@ -1324,6 +1407,7 @@ int sysctl_sched_uclamp_handler(struct ctl_table *table, int write, · 5 unmodified lines |
| 1324 | 1407 | undo: |
| 1325 | 1408 | sysctl_sched_uclamp_util_min = old_min; |
| 1326 | 1409 | sysctl_sched_uclamp_util_max = old_max; |
| 1410 | + sysctl_sched_uclamp_util_min_rt_default = old_min_rt; |
| 1327 | 1411 | done: |
| 1328 | 1412 | mutex_unlock(&uclamp_mutex); |
| 1329 | 1413 | |
| @@ -1369,17 +1453,20 @@ static void __setscheduler_uclamp(struct task_struct *p, · 39 unmodified lines |
| 1369 | 1453 | */ |
| 1370 | 1454 | for_each_clamp_id(clamp_id) { |
| 1371 | 1455 | struct uclamp_se *uc_se = &p->uclamp_req[clamp_id]; |
| 1372 | | − unsigned int clamp_value = uclamp_none(clamp_id); |
| 1373 | 1456 | |
| 1374 | 1457 | /* Keep using defined clamps across class changes */ |
| 1375 | 1458 | if (uc_se->user_defined) |
| 1376 | 1459 | continue; |
| 1377 | 1460 | |
| 1378 | | − /* By default, RT tasks always get 100% boost */ |
| 1461 | + /* |
| 1462 | + * RT by default have a 100% boost value that could be modified |
| 1463 | + * at runtime. |
| 1464 | + */ |
| 1379 | 1465 | if (unlikely(rt_task(p) && clamp_id == UCLAMP_MIN)) |
| 1380 | | − clamp_value = uclamp_none(UCLAMP_MAX); |
| 1466 | + __uclamp_update_util_min_rt_default(p); |
| 1467 | + else |
| 1468 | + uclamp_se_set(uc_se, uclamp_none(clamp_id), false); |
| 1381 | 1469 | |
| 1382 | | − uclamp_se_set(uc_se, clamp_value, false); |
| 1383 | 1470 | } |
| 1384 | 1471 | |
| 1385 | 1472 | if (likely(!(attr->sched_flags & SCHED_FLAG_UTIL_CLAMP))) |
| @@ -1400,6 +1487,10 @@ static void uclamp_fork(struct task_struct *p) · 14 unmodified lines |
| 1400 | 1487 | { |
| 1401 | 1488 | enum uclamp_id clamp_id; |
| 1402 | 1489 | |
| 1490 | + /* |
| 1491 | + * We don't need to hold task_rq_lock() when updating p->uclamp_* here |
| 1492 | + * as the task is still at its early fork stages. |
| 1493 | + */ |
| 1403 | 1494 | for_each_clamp_id(clamp_id) |
| 1404 | 1495 | p->uclamp[clamp_id].active = false; |
| 1405 | 1496 | |
| @@ -1412,6 +1503,11 @@ static void uclamp_fork(struct task_struct *p) · 6 unmodified lines |
| 1412 | 1503 | } |
| 1413 | 1504 | } |
| 1414 | 1505 | |
| 1506 | +static void uclamp_post_fork(struct task_struct *p) |
| 1507 | +{ |
| 1508 | + uclamp_update_util_min_rt_default(p); |
| 1509 | +} |
| 1510 | + |
| 1415 | 1511 | static void __init init_uclamp_rq(struct rq *rq) |
| 1416 | 1512 | { |
| 1417 | 1513 | enum uclamp_id clamp_id; |
| @@ -1462,6 +1558,7 @@ static inline int uclamp_validate(struct task_struct *p, · 44 unmodified lines |
| 1462 | 1558 | static void __setscheduler_uclamp(struct task_struct *p, |
| 1463 | 1559 | const struct sched_attr *attr) { } |
| 1464 | 1560 | static inline void uclamp_fork(struct task_struct *p) { } |
| 1561 | +static inline void uclamp_post_fork(struct task_struct *p) { } |
| 1465 | 1562 | static inline void init_uclamp(void) { } |
| 1466 | 1563 | #endif /* CONFIG_UCLAMP_TASK */ |
| 1467 | 1564 | |
| @@ -3205,6 +3302,11 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) · 1737 unmodified lines |
| 3205 | 3302 | return 0; |
| 3206 | 3303 | } |
| 3207 | 3304 | |
| 3305 | +void sched_post_fork(struct task_struct *p) |
| 3306 | +{ |
| 3307 | + uclamp_post_fork(p); |
| 3308 | +} |
| 3309 | + |
| 3208 | 3310 | unsigned long to_ratio(u64 period, u64 runtime) |
| 3209 | 3311 | { |
| 3210 | 3312 | if (runtime == RUNTIME_INF) |
| @@ -5724,6 +5826,11 @@ SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, · 2513 unmodified lines |
| 5724 | 5826 | kattr.sched_nice = task_nice(p); |
| 5725 | 5827 | |
| 5726 | 5828 | #ifdef CONFIG_UCLAMP_TASK |
| 5829 | + /* |
| 5830 | + * This could race with another potential updater, but this is fine |
| 5831 | + * because it'll correctly read the old or the new value. We don't need |
| 5832 | + * to guarantee who wins the race as long as it doesn't return garbage. |
| 5833 | + */ |
| 5727 | 5834 | kattr.sched_util_min = p->uclamp_req[UCLAMP_MIN].value; |
| 5728 | 5835 | kattr.sched_util_max = p->uclamp_req[UCLAMP_MAX].value; |
| 5729 | 5836 | #endif |