diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched/core.c | 2 | ||||
| -rw-r--r-- | kernel/sched/hmp.c | 56 | ||||
| -rw-r--r-- | kernel/sched/sched.h | 4 |
3 files changed, 56 insertions, 6 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2990a1376a4e..f4379f106e16 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7806,6 +7806,7 @@ void __init sched_init_smp(void) hotcpu_notifier(cpuset_cpu_inactive, CPU_PRI_CPUSET_INACTIVE); update_cluster_topology(); + init_sched_hmp_boost_policy(); init_hrtick(); @@ -7854,6 +7855,7 @@ void __init sched_init(void) BUG_ON(num_possible_cpus() > BITS_PER_LONG); + sched_hmp_parse_dt(); init_clusters(); #ifdef CONFIG_FAIR_GROUP_SCHED diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index ba5048fe350a..fa1f7a503220 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -17,6 +17,7 @@ #include <linux/cpufreq.h> #include <linux/list_sort.h> #include <linux/syscore_ops.h> +#include <linux/of.h> #include "sched.h" #include "core_ctl.h" @@ -225,6 +226,52 @@ fail: return ret; } +/* + * It is possible that CPUs of the same micro architecture can have slight + * difference in the efficiency due to other factors like cache size. The + * BOOST_ON_BIG policy may not be optimial for such systems. The required + * boost policy can be specified via device tree to handle this. + */ +static int __read_mostly sched_boost_policy = SCHED_BOOST_NONE; + +/* + * This should be called after clusters are populated and + * the respective efficiency values are initialized. + */ +void init_sched_hmp_boost_policy(void) +{ + /* + * Initialize the boost type here if it is not passed from + * device tree. + */ + if (sched_boost_policy == SCHED_BOOST_NONE) { + if (max_possible_efficiency != min_possible_efficiency) + sched_boost_policy = SCHED_BOOST_ON_BIG; + else + sched_boost_policy = SCHED_BOOST_ON_ALL; + } +} + +void sched_hmp_parse_dt(void) +{ + struct device_node *sn; + const char *boost_policy; + + if (!sched_enable_hmp) + return; + + sn = of_find_node_by_path("/sched-hmp"); + if (!sn) + return; + + if (!of_property_read_string(sn, "boost-policy", &boost_policy)) { + if (!strcmp(boost_policy, "boost-on-big")) + sched_boost_policy = SCHED_BOOST_ON_BIG; + else if (!strcmp(boost_policy, "boost-on-all")) + sched_boost_policy = SCHED_BOOST_ON_ALL; + } +} + unsigned int max_possible_efficiency = 1; unsigned int min_possible_efficiency = UINT_MAX; @@ -1162,12 +1209,9 @@ int task_load_will_fit(struct task_struct *p, u64 task_load, int cpu, enum sched_boost_type sched_boost_type(void) { - if (sched_boost()) { - if (min_possible_efficiency != max_possible_efficiency) - return SCHED_BOOST_ON_BIG; - else - return SCHED_BOOST_ON_ALL; - } + if (sched_boost()) + return sched_boost_policy; + return SCHED_BOOST_NONE; } diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 45ef4238a547..2480ea0c36fa 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1398,6 +1398,8 @@ extern u64 cpu_upmigrate_discourage_read_u64(struct cgroup_subsys_state *css, struct cftype *cft); extern int cpu_upmigrate_discourage_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, u64 upmigrate_discourage); +extern void sched_hmp_parse_dt(void); +extern void init_sched_hmp_boost_policy(void); #else /* CONFIG_SCHED_HMP */ @@ -1588,6 +1590,8 @@ static inline void post_big_task_count_change(void) { } static inline void set_hmp_defaults(void) { } static inline void clear_reserved(int cpu) { } +static inline void sched_hmp_parse_dt(void) {} +static inline void init_sched_hmp_boost_policy(void) {} #define trace_sched_cpu_load(...) #define trace_sched_cpu_load_lb(...) |
