diff options
-rw-r--r-- | kernel/sched/core.c | 44 | ||||
-rw-r--r-- | kernel/sched/sched.h | 2 |
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 |
7075 | static 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 | }; |