From d7a8a6765e68ad86f5ba14dfff7c1d8a2f04e7be Mon Sep 17 00:00:00 2001 From: Satya Durga Srinivasu Prabhala Date: Wed, 14 Nov 2018 17:01:12 -0800 Subject: [PATCH] sched: Add snapshot of sched_{up,down}migrate knobs This snapshot is taken from msm-4.19 as of commit 89986132507b822 ("sched: fair: Improve the scheduler"). Change-Id: I9a52e67862ee5086880884128102aa4f8efb04ce Signed-off-by: Satya Durga Srinivasu Prabhala --- include/linux/sched/sysctl.h | 11 +++++++ include/linux/sysctl.h | 3 ++ kernel/sched/fair.c | 23 ++++++++++++--- kernel/sched/sched.h | 2 ++ kernel/sysctl.c | 57 ++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 4 deletions(-) diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 05bc4afc548d..d66f20a74d77 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -20,11 +20,17 @@ extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, enum { sysctl_hung_task_timeout_secs = 0 }; #endif +#define MAX_CLUSTERS 3 +/* MAX_MARGIN_LEVELS should be one less than MAX_CLUSTERS */ +#define MAX_MARGIN_LEVELS (MAX_CLUSTERS - 1) + extern unsigned int sysctl_sched_latency; extern unsigned int sysctl_sched_min_granularity; extern unsigned int sysctl_sched_wakeup_granularity; extern unsigned int sysctl_sched_child_runs_first; #ifdef CONFIG_SCHED_WALT +extern unsigned int __weak sysctl_sched_capacity_margin_up[MAX_MARGIN_LEVELS]; +extern unsigned int __weak sysctl_sched_capacity_margin_down[MAX_MARGIN_LEVELS]; extern unsigned int __weak sysctl_sched_user_hint; extern const int __weak sched_user_hint_max; extern unsigned int __weak sysctl_sched_cpu_high_irqload; @@ -55,6 +61,11 @@ walt_proc_user_hint_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +extern int __weak +sched_updown_migrate_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); + extern int __weak sched_ravg_window_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 39d10afbdce6..40d14f940e28 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -73,6 +73,9 @@ extern int proc_do_large_bitmap(struct ctl_table *, int, extern int proc_do_static_key(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +extern int proc_douintvec_capacity(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); extern int proc_douintvec_ravg_window(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 8d36c9cc28f8..5a41de6de8bc 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -125,6 +125,12 @@ int __weak arch_asym_cpu_priority(int cpu) unsigned int sysctl_sched_cfs_bandwidth_slice = 5000UL; #endif +/* Migration margins */ +unsigned int sched_capacity_margin_up[NR_CPUS] = { + [0 ... NR_CPUS-1] = 1078}; /* ~5% margin */ +unsigned int sched_capacity_margin_down[NR_CPUS] = { + [0 ... NR_CPUS-1] = 1205}; /* ~15% margin */ + unsigned int sched_small_task_threshold = 102; static inline void update_load_add(struct load_weight *lw, unsigned long inc) @@ -3810,9 +3816,18 @@ util_est_dequeue(struct cfs_rq *cfs_rq, struct task_struct *p, bool task_sleep) WRITE_ONCE(p->se.avg.util_est, ue); } -static inline int task_fits_capacity(struct task_struct *p, long capacity) +static inline int task_fits_capacity(struct task_struct *p, + long capacity, + int cpu) { - return fits_capacity(task_util_est(p), capacity); + unsigned int margin; + + if (capacity_orig_of(task_cpu(p)) > capacity_orig_of(cpu)) + margin = sched_capacity_margin_down[task_cpu(p)]; + else + margin = sched_capacity_margin_up[task_cpu(p)]; + + return capacity * 1024 > task_util_est(p) * margin; } static inline void update_misfit_status(struct task_struct *p, struct rq *rq) @@ -3825,7 +3840,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) return; } - if (task_fits_capacity(p, capacity_of(cpu_of(rq)))) { + if (task_fits_capacity(p, capacity_of(cpu_of(rq)), cpu_of(rq))) { rq->misfit_task_load = 0; return; } @@ -6208,7 +6223,7 @@ static int wake_cap(struct task_struct *p, int cpu, int prev_cpu) /* Bring task utilization in sync with prev_cpu */ sync_entity_load_avg(&p->se); - return !task_fits_capacity(p, min_cap); + return !task_fits_capacity(p, min_cap, cpu); } /* diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 2ccf94a75c07..e76e7710d6da 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -85,6 +85,8 @@ struct rq; struct cpuidle_state; extern __read_mostly bool sched_predl; +extern unsigned int sched_capacity_margin_up[NR_CPUS]; +extern unsigned int sched_capacity_margin_down[NR_CPUS]; struct sched_walt_cpu_load { unsigned long prev_window_util; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index e28fb2d87ca4..db4732e80428 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -504,6 +504,20 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = sched_ravg_window_handler, }, + { + .procname = "sched_upmigrate", + .data = &sysctl_sched_capacity_margin_up, + .maxlen = sizeof(unsigned int) * MAX_MARGIN_LEVELS, + .mode = 0644, + .proc_handler = sched_updown_migrate_handler, + }, + { + .procname = "sched_downmigrate", + .data = &sysctl_sched_capacity_margin_down, + .maxlen = sizeof(unsigned int) * MAX_MARGIN_LEVELS, + .mode = 0644, + .proc_handler = sched_updown_migrate_handler, + }, #endif #ifdef CONFIG_SCHED_DEBUG { @@ -3531,6 +3545,43 @@ int proc_do_large_bitmap(struct ctl_table *table, int write, return err; } +static int do_proc_douintvec_capacity_conv(bool *negp, unsigned long *lvalp, + int *valp, int write, void *data) +{ + if (write) { + /* + * The sched_upmigrate/sched_downmigrate tunables are + * accepted in percentage. Limit them to 100. + */ + if (*negp || *lvalp == 0 || *lvalp > 100) + return -EINVAL; + *valp = SCHED_FIXEDPOINT_SCALE * 100 / *lvalp; + } else { + *negp = false; + *lvalp = SCHED_FIXEDPOINT_SCALE * 100 / *valp; + } + + return 0; +} + +/** + * proc_douintvec_capacity - read a vector of integers in percentage and convert + * into sched capacity + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position + * + * Returns 0 on success. + */ +int proc_douintvec_capacity(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return do_proc_dointvec(table, write, buffer, lenp, ppos, + do_proc_douintvec_capacity_conv, NULL); +} + static int do_proc_douintvec_rwin(bool *negp, unsigned long *lvalp, int *valp, int write, void *data) { @@ -3629,6 +3680,12 @@ int proc_douintvec_ravg_window(struct ctl_table *table, int write, return -ENOSYS; } +int proc_douintvec_capacity(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return -ENOSYS; +} + #endif /* CONFIG_PROC_SYSCTL */ #if defined(CONFIG_SYSCTL)