diff --git a/kernel/sched/walt/sysctl.c b/kernel/sched/walt/sysctl.c index 0e8439d33799..56a5608bf11f 100644 --- a/kernel/sched/walt/sysctl.c +++ b/kernel/sched/walt/sysctl.c @@ -47,6 +47,8 @@ unsigned int sysctl_sched_wake_up_idle[2]; unsigned int sysctl_input_boost_ms; unsigned int sysctl_input_boost_freq[8]; unsigned int sysctl_sched_boost_on_input; +unsigned int sysctl_sched_early_up[MAX_MARGIN_LEVELS]; +unsigned int sysctl_sched_early_down[MAX_MARGIN_LEVELS]; /* sysctl nodes accesed by other files */ unsigned int __read_mostly sysctl_sched_coloc_downmigrate_ns; @@ -457,6 +459,69 @@ int sched_updown_migrate_handler(struct ctl_table *table, int write, /* update individual cpu thresholds */ sched_update_updown_migrate_values(data == &sysctl_sched_capacity_margin_up_pct[0]); +unlock_mutex: + mutex_unlock(&mutex); + + return ret; +} + +int sched_updown_early_migrate_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret, i; + unsigned int *data = (unsigned int *)table->data; + static DEFINE_MUTEX(mutex); + int cap_margin_levels = num_sched_clusters ? num_sched_clusters - 1 : 0; + int val[MAX_MARGIN_LEVELS]; + struct ctl_table tmp = { + .data = &val, + .maxlen = sizeof(int) * cap_margin_levels, + .mode = table->mode, + }; + + if (cap_margin_levels <= 0) + return -EINVAL; + + mutex_lock(&mutex); + + if (!write) { + ret = proc_dointvec(table, write, buffer, lenp, ppos); + goto unlock_mutex; + } + + ret = proc_dointvec(&tmp, write, buffer, lenp, ppos); + if (ret) + goto unlock_mutex; + + for (i = 0; i < cap_margin_levels; i++) { + if (val[i] < 1024) { + ret = -EINVAL; + goto unlock_mutex; + } + } + + /* check up pct is greater than dn pct */ + if (data == &sysctl_sched_early_up[0]) { + for (i = 0; i < cap_margin_levels; i++) { + if (val[i] >= sysctl_sched_early_down[i]) { + ret = -EINVAL; + goto unlock_mutex; + } + } + } else { + for (i = 0; i < cap_margin_levels; i++) { + if (sysctl_sched_early_up[i] >= val[i]) { + ret = -EINVAL; + goto unlock_mutex; + } + } + } + + /* all things checkout update the value */ + for (i = 0; i < cap_margin_levels; i++) + data[i] = val[i]; + unlock_mutex: mutex_unlock(&mutex); @@ -721,6 +786,20 @@ struct ctl_table walt_table[] = { .mode = 0644, .proc_handler = sched_updown_migrate_handler, }, + { + .procname = "sched_early_upmigrate", + .data = &sysctl_sched_early_up, + .maxlen = sizeof(unsigned int) * MAX_MARGIN_LEVELS, + .mode = 0644, + .proc_handler = sched_updown_early_migrate_handler, + }, + { + .procname = "sched_early_downmigrate", + .data = &sysctl_sched_early_down, + .maxlen = sizeof(unsigned int) * MAX_MARGIN_LEVELS, + .mode = 0644, + .proc_handler = sched_updown_early_migrate_handler, + }, { .procname = "walt_rtg_cfs_boost_prio", .data = &sysctl_walt_rtg_cfs_boost_prio, @@ -951,6 +1030,8 @@ void walt_tunables(void) for (i = 0; i < MAX_MARGIN_LEVELS; i++) { sysctl_sched_capacity_margin_up_pct[i] = 95; /* ~5% margin */ sysctl_sched_capacity_margin_dn_pct[i] = 85; /* ~15% margin */ + sysctl_sched_early_up[i] = 1077; + sysctl_sched_early_down[i] = 1204; } sysctl_sched_group_upmigrate_pct = 100; diff --git a/kernel/sched/walt/walt.h b/kernel/sched/walt/walt.h index 42dd9a79ab99..df2bfb1d2737 100644 --- a/kernel/sched/walt/walt.h +++ b/kernel/sched/walt/walt.h @@ -740,6 +740,15 @@ static inline unsigned int walt_nr_rtg_high_prio(int cpu) return wrq->walt_stats.nr_rtg_high_prio_tasks; } +static inline bool task_in_related_thread_group(struct task_struct *p) +{ + struct walt_task_struct *wts = (struct walt_task_struct *) p->android_vendor_data1; + + return (rcu_access_pointer(wts->grp) != NULL); +} + +extern unsigned int sysctl_sched_early_up[MAX_MARGIN_LEVELS]; +extern unsigned int sysctl_sched_early_down[MAX_MARGIN_LEVELS]; static inline bool task_fits_capacity(struct task_struct *p, long capacity, int cpu) @@ -751,21 +760,27 @@ static inline bool task_fits_capacity(struct task_struct *p, /* * Derive upmigration/downmigrate margin wrt the src/dest CPU. */ - if (src_wrq->cluster->id > dst_wrq->cluster->id) + if (src_wrq->cluster->id > dst_wrq->cluster->id) { margin = sched_capacity_margin_down[cpu]; - else + if (task_in_related_thread_group(p)) { + if (is_min_cluster_cpu(cpu)) + margin = sysctl_sched_early_down[0]; + else if (!is_max_cluster_cpu(cpu)) + margin = sysctl_sched_early_down[1]; + } + } else { margin = sched_capacity_margin_up[task_cpu(p)]; + if (task_in_related_thread_group(p)) { + if (is_min_cluster_cpu(task_cpu(p))) + margin = sysctl_sched_early_up[0]; + else if (!is_max_cluster_cpu(task_cpu(p))) + margin = sysctl_sched_early_up[1]; + } + } return capacity * 1024 > uclamp_task_util(p) * margin; } -static inline bool task_in_related_thread_group(struct task_struct *p) -{ - struct walt_task_struct *wts = (struct walt_task_struct *) p->android_vendor_data1; - - return (rcu_access_pointer(wts->grp) != NULL); -} - static inline bool task_fits_max(struct task_struct *p, int cpu) { unsigned long capacity = capacity_orig_of(cpu);