summaryrefslogtreecommitdiff
path: root/kernel/sched/tune.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched/tune.c')
-rw-r--r--kernel/sched/tune.c189
1 files changed, 187 insertions, 2 deletions
diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c
index 86d04caf1684..a71e94cecdb6 100644
--- a/kernel/sched/tune.c
+++ b/kernel/sched/tune.c
@@ -121,6 +121,33 @@ struct schedtune {
/* Boost value for tasks on that SchedTune CGroup */
int boost;
+#ifdef CONFIG_SCHED_HMP
+ /* Toggle ability to override sched boost enabled */
+ bool sched_boost_no_override;
+
+ /*
+ * Controls whether a cgroup is eligible for sched boost or not. This
+ * can temporariliy be disabled by the kernel based on the no_override
+ * flag above.
+ */
+ bool sched_boost_enabled;
+
+ /*
+ * This tracks the default value of sched_boost_enabled and is used
+ * restore the value following any temporary changes to that flag.
+ */
+ bool sched_boost_enabled_backup;
+
+ /*
+ * Controls whether tasks of this cgroup should be colocated with each
+ * other and tasks of other cgroups that have the same flag turned on.
+ */
+ bool colocate;
+
+ /* Controls whether further updates are allowed to the colocate flag */
+ bool colocate_update_disabled;
+#endif
+
/* Performance Boost (B) region threshold params */
int perf_boost_idx;
@@ -134,7 +161,7 @@ struct schedtune {
static inline struct schedtune *css_st(struct cgroup_subsys_state *css)
{
- return css ? container_of(css, struct schedtune, css) : NULL;
+ return container_of(css, struct schedtune, css);
}
static inline struct schedtune *task_schedtune(struct task_struct *tsk)
@@ -159,6 +186,13 @@ static inline struct schedtune *parent_st(struct schedtune *st)
static struct schedtune
root_schedtune = {
.boost = 0,
+#ifdef CONFIG_SCHED_HMP
+ .sched_boost_no_override = false,
+ .sched_boost_enabled = true,
+ .sched_boost_enabled_backup = true,
+ .colocate = false,
+ .colocate_update_disabled = false,
+#endif
.perf_boost_idx = 0,
.perf_constrain_idx = 0,
.prefer_idle = 0,
@@ -239,6 +273,121 @@ struct boost_groups {
/* Boost groups affecting each CPU in the system */
DEFINE_PER_CPU(struct boost_groups, cpu_boost_groups);
+#ifdef CONFIG_SCHED_HMP
+static inline void init_sched_boost(struct schedtune *st)
+{
+ st->sched_boost_no_override = false;
+ st->sched_boost_enabled = true;
+ st->sched_boost_enabled_backup = st->sched_boost_enabled;
+ st->colocate = false;
+ st->colocate_update_disabled = false;
+}
+
+bool same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2)
+{
+ return task_schedtune(tsk1) == task_schedtune(tsk2);
+}
+
+void update_cgroup_boost_settings(void)
+{
+ int i;
+
+ for (i = 0; i < BOOSTGROUPS_COUNT; i++) {
+ if (!allocated_group[i])
+ break;
+
+ if (allocated_group[i]->sched_boost_no_override)
+ continue;
+
+ allocated_group[i]->sched_boost_enabled = false;
+ }
+}
+
+void restore_cgroup_boost_settings(void)
+{
+ int i;
+
+ for (i = 0; i < BOOSTGROUPS_COUNT; i++) {
+ if (!allocated_group[i])
+ break;
+
+ allocated_group[i]->sched_boost_enabled =
+ allocated_group[i]->sched_boost_enabled_backup;
+ }
+}
+
+bool task_sched_boost(struct task_struct *p)
+{
+ struct schedtune *st = task_schedtune(p);
+
+ return st->sched_boost_enabled;
+}
+
+static u64
+sched_boost_override_read(struct cgroup_subsys_state *css,
+ struct cftype *cft)
+{
+ struct schedtune *st = css_st(css);
+
+ return st->sched_boost_no_override;
+}
+
+static int sched_boost_override_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 override)
+{
+ struct schedtune *st = css_st(css);
+
+ st->sched_boost_no_override = !!override;
+
+ return 0;
+}
+
+static u64 sched_boost_enabled_read(struct cgroup_subsys_state *css,
+ struct cftype *cft)
+{
+ struct schedtune *st = css_st(css);
+
+ return st->sched_boost_enabled;
+}
+
+static int sched_boost_enabled_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 enable)
+{
+ struct schedtune *st = css_st(css);
+
+ st->sched_boost_enabled = !!enable;
+ st->sched_boost_enabled_backup = st->sched_boost_enabled;
+
+ return 0;
+}
+
+static u64 sched_colocate_read(struct cgroup_subsys_state *css,
+ struct cftype *cft)
+{
+ struct schedtune *st = css_st(css);
+
+ return st->colocate;
+}
+
+static int sched_colocate_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 colocate)
+{
+ struct schedtune *st = css_st(css);
+
+ if (st->colocate_update_disabled)
+ return -EPERM;
+
+ st->colocate = !!colocate;
+ st->colocate_update_disabled = true;
+ return 0;
+}
+
+#else /* CONFIG_SCHED_HMP */
+
+static inline void init_sched_boost(struct schedtune *st) { }
+
+#endif /* CONFIG_SCHED_HMP */
+
static void
schedtune_cpu_update(int cpu)
{
@@ -619,6 +768,22 @@ boost_write(struct cgroup_subsys_state *css, struct cftype *cft,
return 0;
}
+static void schedtune_attach(struct cgroup_taskset *tset)
+{
+ struct task_struct *task;
+ struct cgroup_subsys_state *css;
+ struct schedtune *st;
+ bool colocate;
+
+ cgroup_taskset_first(tset, &css);
+ st = css_st(css);
+
+ colocate = st->colocate;
+
+ cgroup_taskset_for_each(task, css, tset)
+ sync_cgroup_colocation(task, colocate);
+}
+
static struct cftype files[] = {
{
.name = "boost",
@@ -630,6 +795,23 @@ static struct cftype files[] = {
.read_u64 = prefer_idle_read,
.write_u64 = prefer_idle_write,
},
+#ifdef CONFIG_SCHED_HMP
+ {
+ .name = "sched_boost_no_override",
+ .read_u64 = sched_boost_override_read,
+ .write_u64 = sched_boost_override_write,
+ },
+ {
+ .name = "sched_boost_enabled",
+ .read_u64 = sched_boost_enabled_read,
+ .write_u64 = sched_boost_enabled_write,
+ },
+ {
+ .name = "colocate",
+ .read_u64 = sched_colocate_read,
+ .write_u64 = sched_colocate_write,
+ },
+#endif
{ } /* terminate */
};
@@ -684,6 +866,7 @@ schedtune_css_alloc(struct cgroup_subsys_state *parent_css)
/* Initialize per CPUs boost group support */
st->idx = idx;
+ init_sched_boost(st);
if (schedtune_boostgroup_init(st))
goto release;
@@ -721,6 +904,7 @@ struct cgroup_subsys schedtune_cgrp_subsys = {
.cancel_attach = schedtune_cancel_attach,
.legacy_cftypes = files,
.early_init = 1,
+ .attach = schedtune_attach,
};
static inline void
@@ -916,7 +1100,8 @@ schedtune_init(void)
*/
sd = rcu_dereference(per_cpu(sd_ea, cpumask_first(cpu_online_mask)));
if (!sd) {
- pr_info("schedtune: no energy model data\n");
+ if (energy_aware())
+ pr_warn("schedtune: no energy model data\n");
goto nodata;
}