diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-10-03 10:34:58 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-10-03 10:34:58 -0700 |
commit | a6e4924acb6cec26aae85375e294f237afd9f5ae (patch) | |
tree | ec7a955d04785e9e3679036cdb760f6ad2fc1efb /kernel | |
parent | 5a313c5e7435d5688f5cfce7971cd0c0b7e61f99 (diff) | |
parent | f1e9995fe4f21c491e71716e3bc4027fd14954e8 (diff) |
Merge "sched: add a knob to prefer the waker CPU for sync wakeups"
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/fair.c | 33 | ||||
-rw-r--r-- | kernel/sched/hmp.c | 7 | ||||
-rw-r--r-- | kernel/sysctl.c | 9 |
3 files changed, 41 insertions, 8 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 14b8977d1be4..4489bec5d68a 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2590,6 +2590,7 @@ static u32 __compute_runnable_contrib(u64 n) #define SBC_FLAG_COST_CSTATE_PREV_CPU_TIE_BREAKER 0x80 #define SBC_FLAG_CSTATE_LOAD 0x100 #define SBC_FLAG_BEST_SIBLING 0x200 +#define SBC_FLAG_WAKER_CPU 0x400 /* Cluster selection flag */ #define SBC_FLAG_COLOC_CLUSTER 0x10000 @@ -3060,6 +3061,15 @@ wake_to_waker_cluster(struct cpu_select_env *env) task_load(env->p) < sched_small_wakee_task_load; } +static inline bool +bias_to_waker_cpu(struct task_struct *p, int cpu) +{ + return sysctl_sched_prefer_sync_wakee_to_waker && + cpu_rq(cpu)->nr_running == 1 && + cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) && + cpu_active(cpu) && !cpu_isolated(cpu); +} + static inline int cluster_allowed(struct task_struct *p, struct sched_cluster *cluster) { @@ -3080,6 +3090,7 @@ static int select_best_cpu(struct task_struct *p, int target, int reason, struct cluster_cpu_stats stats; struct related_thread_group *grp; unsigned int sbc_flag = 0; + int cpu = raw_smp_processor_id(); struct cpu_select_env env = { .p = p, @@ -3111,14 +3122,20 @@ static int select_best_cpu(struct task_struct *p, int target, int reason, else env.rtg = grp; } else { - cluster = cpu_rq(smp_processor_id())->cluster; - if (wake_to_waker_cluster(&env) && - cluster_allowed(p, cluster)) { - env.need_waker_cluster = 1; - bitmap_zero(env.candidate_list, NR_CPUS); - __set_bit(cluster->id, env.candidate_list); - env.sbc_best_cluster_flag = SBC_FLAG_WAKER_CLUSTER; - + cluster = cpu_rq(cpu)->cluster; + if (wake_to_waker_cluster(&env)) { + if (bias_to_waker_cpu(p, cpu)) { + target = cpu; + sbc_flag = SBC_FLAG_WAKER_CLUSTER | + SBC_FLAG_WAKER_CPU; + goto out; + } else if (cluster_allowed(p, cluster)) { + env.need_waker_cluster = 1; + bitmap_zero(env.candidate_list, NR_CPUS); + __set_bit(cluster->id, env.candidate_list); + env.sbc_best_cluster_flag = + SBC_FLAG_WAKER_CLUSTER; + } } else if (bias_to_prev_cpu(&env, &stats)) { sbc_flag = SBC_FLAG_PREV_CPU; goto out; diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index 3bbf3ee46cf9..61e352aeec00 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -897,6 +897,13 @@ unsigned int __read_mostly sched_spill_load; unsigned int __read_mostly sysctl_sched_spill_load_pct = 100; /* + * Prefer the waker CPU for sync wakee task, if the CPU has only 1 runnable + * task. This eliminates the LPM exit latency associated with the idle + * CPUs in the waker cluster. + */ +unsigned int __read_mostly sysctl_sched_prefer_sync_wakee_to_waker; + +/* * Tasks whose bandwidth consumption on a cpu is more than * sched_upmigrate are considered "big" tasks. Big tasks will be * considered for "up" migration, i.e migrating to a cpu with better diff --git a/kernel/sysctl.c b/kernel/sysctl.c index dad3324e7372..cdce7d0f5a0e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -422,6 +422,15 @@ static struct ctl_table kern_table[] = { .extra2 = &one_hundred, }, { + .procname = "sched_prefer_sync_wakee_to_waker", + .data = &sysctl_sched_prefer_sync_wakee_to_waker, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, + }, + { .procname = "sched_enable_thread_grouping", .data = &sysctl_sched_enable_thread_grouping, .maxlen = sizeof(unsigned int), |