aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/sched/core.c44
-rw-r--r--kernel/sched/sched.h2
2 files changed, 46 insertions, 0 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index c186abed5c6d..8855481857b5 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1166,6 +1166,7 @@ static void __init init_uclamp(void)
1166 uclamp_default[clamp_id] = uc_max; 1166 uclamp_default[clamp_id] = uc_max;
1167#ifdef CONFIG_UCLAMP_TASK_GROUP 1167#ifdef CONFIG_UCLAMP_TASK_GROUP
1168 root_task_group.uclamp_req[clamp_id] = uc_max; 1168 root_task_group.uclamp_req[clamp_id] = uc_max;
1169 root_task_group.uclamp[clamp_id] = uc_max;
1169#endif 1170#endif
1170 } 1171 }
1171} 1172}
@@ -6824,6 +6825,7 @@ static inline void alloc_uclamp_sched_group(struct task_group *tg,
6824 for_each_clamp_id(clamp_id) { 6825 for_each_clamp_id(clamp_id) {
6825 uclamp_se_set(&tg->uclamp_req[clamp_id], 6826 uclamp_se_set(&tg->uclamp_req[clamp_id],
6826 uclamp_none(clamp_id), false); 6827 uclamp_none(clamp_id), false);
6828 tg->uclamp[clamp_id] = parent->uclamp[clamp_id];
6827 } 6829 }
6828#endif 6830#endif
6829} 6831}
@@ -7070,6 +7072,45 @@ static void cpu_cgroup_attach(struct cgroup_taskset *tset)
7070} 7072}
7071 7073
7072#ifdef CONFIG_UCLAMP_TASK_GROUP 7074#ifdef CONFIG_UCLAMP_TASK_GROUP
7075static void cpu_util_update_eff(struct cgroup_subsys_state *css)
7076{
7077 struct cgroup_subsys_state *top_css = css;
7078 struct uclamp_se *uc_parent = NULL;
7079 struct uclamp_se *uc_se = NULL;
7080 unsigned int eff[UCLAMP_CNT];
7081 unsigned int clamp_id;
7082 unsigned int clamps;
7083
7084 css_for_each_descendant_pre(css, top_css) {
7085 uc_parent = css_tg(css)->parent
7086 ? css_tg(css)->parent->uclamp : NULL;
7087
7088 for_each_clamp_id(clamp_id) {
7089 /* Assume effective clamps matches requested clamps */
7090 eff[clamp_id] = css_tg(css)->uclamp_req[clamp_id].value;
7091 /* Cap effective clamps with parent's effective clamps */
7092 if (uc_parent &&
7093 eff[clamp_id] > uc_parent[clamp_id].value) {
7094 eff[clamp_id] = uc_parent[clamp_id].value;
7095 }
7096 }
7097 /* Ensure protection is always capped by limit */
7098 eff[UCLAMP_MIN] = min(eff[UCLAMP_MIN], eff[UCLAMP_MAX]);
7099
7100 /* Propagate most restrictive effective clamps */
7101 clamps = 0x0;
7102 uc_se = css_tg(css)->uclamp;
7103 for_each_clamp_id(clamp_id) {
7104 if (eff[clamp_id] == uc_se[clamp_id].value)
7105 continue;
7106 uc_se[clamp_id].value = eff[clamp_id];
7107 uc_se[clamp_id].bucket_id = uclamp_bucket_id(eff[clamp_id]);
7108 clamps |= (0x1 << clamp_id);
7109 }
7110 if (!clamps)
7111 css = css_rightmost_descendant(css);
7112 }
7113}
7073 7114
7074/* 7115/*
7075 * Integer 10^N with a given N exponent by casting to integer the literal "1eN" 7116 * Integer 10^N with a given N exponent by casting to integer the literal "1eN"
@@ -7138,6 +7179,9 @@ static ssize_t cpu_uclamp_write(struct kernfs_open_file *of, char *buf,
7138 */ 7179 */
7139 tg->uclamp_pct[clamp_id] = req.percent; 7180 tg->uclamp_pct[clamp_id] = req.percent;
7140 7181
7182 /* Update effective clamps to track the most restrictive value */
7183 cpu_util_update_eff(of_css(of));
7184
7141 rcu_read_unlock(); 7185 rcu_read_unlock();
7142 mutex_unlock(&uclamp_mutex); 7186 mutex_unlock(&uclamp_mutex);
7143 7187
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index ae1be61fb279..5b343112a47b 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -397,6 +397,8 @@ struct task_group {
397 unsigned int uclamp_pct[UCLAMP_CNT]; 397 unsigned int uclamp_pct[UCLAMP_CNT];
398 /* Clamp values requested for a task group */ 398 /* Clamp values requested for a task group */
399 struct uclamp_se uclamp_req[UCLAMP_CNT]; 399 struct uclamp_se uclamp_req[UCLAMP_CNT];
400 /* Effective clamp values used for a task group */
401 struct uclamp_se uclamp[UCLAMP_CNT];
400#endif 402#endif
401 403
402}; 404};