diff options
| -rw-r--r-- | include/linux/sched.h | 1 | ||||
| -rw-r--r-- | kernel/sched/core.c | 14 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 20 |
3 files changed, 25 insertions, 10 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index c2413703f45d..959a8588e365 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -1504,6 +1504,7 @@ static inline int task_nice(const struct task_struct *p) | |||
| 1504 | extern int can_nice(const struct task_struct *p, const int nice); | 1504 | extern int can_nice(const struct task_struct *p, const int nice); |
| 1505 | extern int task_curr(const struct task_struct *p); | 1505 | extern int task_curr(const struct task_struct *p); |
| 1506 | extern int idle_cpu(int cpu); | 1506 | extern int idle_cpu(int cpu); |
| 1507 | extern int available_idle_cpu(int cpu); | ||
| 1507 | extern int sched_setscheduler(struct task_struct *, int, const struct sched_param *); | 1508 | extern int sched_setscheduler(struct task_struct *, int, const struct sched_param *); |
| 1508 | extern int sched_setscheduler_nocheck(struct task_struct *, int, const struct sched_param *); | 1509 | extern int sched_setscheduler_nocheck(struct task_struct *, int, const struct sched_param *); |
| 1509 | extern int sched_setattr(struct task_struct *, const struct sched_attr *); | 1510 | extern int sched_setattr(struct task_struct *, const struct sched_attr *); |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 102c36c317dc..d1555185c054 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -4009,6 +4009,20 @@ int idle_cpu(int cpu) | |||
| 4009 | return 0; | 4009 | return 0; |
| 4010 | #endif | 4010 | #endif |
| 4011 | 4011 | ||
| 4012 | return 1; | ||
| 4013 | } | ||
| 4014 | |||
| 4015 | /** | ||
| 4016 | * available_idle_cpu - is a given CPU idle for enqueuing work. | ||
| 4017 | * @cpu: the CPU in question. | ||
| 4018 | * | ||
| 4019 | * Return: 1 if the CPU is currently idle. 0 otherwise. | ||
| 4020 | */ | ||
| 4021 | int available_idle_cpu(int cpu) | ||
| 4022 | { | ||
| 4023 | if (!idle_cpu(cpu)) | ||
| 4024 | return 0; | ||
| 4025 | |||
| 4012 | if (vcpu_is_preempted(cpu)) | 4026 | if (vcpu_is_preempted(cpu)) |
| 4013 | return 0; | 4027 | return 0; |
| 4014 | 4028 | ||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index f32b97d4c63b..748cb054fefd 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -5899,8 +5899,8 @@ wake_affine_idle(int this_cpu, int prev_cpu, int sync) | |||
| 5899 | * a cpufreq perspective, it's better to have higher utilisation | 5899 | * a cpufreq perspective, it's better to have higher utilisation |
| 5900 | * on one CPU. | 5900 | * on one CPU. |
| 5901 | */ | 5901 | */ |
| 5902 | if (idle_cpu(this_cpu) && cpus_share_cache(this_cpu, prev_cpu)) | 5902 | if (available_idle_cpu(this_cpu) && cpus_share_cache(this_cpu, prev_cpu)) |
| 5903 | return idle_cpu(prev_cpu) ? prev_cpu : this_cpu; | 5903 | return available_idle_cpu(prev_cpu) ? prev_cpu : this_cpu; |
| 5904 | 5904 | ||
| 5905 | if (sync && cpu_rq(this_cpu)->nr_running == 1) | 5905 | if (sync && cpu_rq(this_cpu)->nr_running == 1) |
| 5906 | return this_cpu; | 5906 | return this_cpu; |
| @@ -6143,7 +6143,7 @@ find_idlest_group_cpu(struct sched_group *group, struct task_struct *p, int this | |||
| 6143 | 6143 | ||
| 6144 | /* Traverse only the allowed CPUs */ | 6144 | /* Traverse only the allowed CPUs */ |
| 6145 | for_each_cpu_and(i, sched_group_span(group), &p->cpus_allowed) { | 6145 | for_each_cpu_and(i, sched_group_span(group), &p->cpus_allowed) { |
| 6146 | if (idle_cpu(i)) { | 6146 | if (available_idle_cpu(i)) { |
| 6147 | struct rq *rq = cpu_rq(i); | 6147 | struct rq *rq = cpu_rq(i); |
| 6148 | struct cpuidle_state *idle = idle_get_state(rq); | 6148 | struct cpuidle_state *idle = idle_get_state(rq); |
| 6149 | if (idle && idle->exit_latency < min_exit_latency) { | 6149 | if (idle && idle->exit_latency < min_exit_latency) { |
| @@ -6272,7 +6272,7 @@ void __update_idle_core(struct rq *rq) | |||
| 6272 | if (cpu == core) | 6272 | if (cpu == core) |
| 6273 | continue; | 6273 | continue; |
| 6274 | 6274 | ||
| 6275 | if (!idle_cpu(cpu)) | 6275 | if (!available_idle_cpu(cpu)) |
| 6276 | goto unlock; | 6276 | goto unlock; |
| 6277 | } | 6277 | } |
| 6278 | 6278 | ||
| @@ -6304,7 +6304,7 @@ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int | |||
| 6304 | 6304 | ||
| 6305 | for_each_cpu(cpu, cpu_smt_mask(core)) { | 6305 | for_each_cpu(cpu, cpu_smt_mask(core)) { |
| 6306 | cpumask_clear_cpu(cpu, cpus); | 6306 | cpumask_clear_cpu(cpu, cpus); |
| 6307 | if (!idle_cpu(cpu)) | 6307 | if (!available_idle_cpu(cpu)) |
| 6308 | idle = false; | 6308 | idle = false; |
| 6309 | } | 6309 | } |
| 6310 | 6310 | ||
| @@ -6333,7 +6333,7 @@ static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int t | |||
| 6333 | for_each_cpu(cpu, cpu_smt_mask(target)) { | 6333 | for_each_cpu(cpu, cpu_smt_mask(target)) { |
| 6334 | if (!cpumask_test_cpu(cpu, &p->cpus_allowed)) | 6334 | if (!cpumask_test_cpu(cpu, &p->cpus_allowed)) |
| 6335 | continue; | 6335 | continue; |
| 6336 | if (idle_cpu(cpu)) | 6336 | if (available_idle_cpu(cpu)) |
| 6337 | return cpu; | 6337 | return cpu; |
| 6338 | } | 6338 | } |
| 6339 | 6339 | ||
| @@ -6396,7 +6396,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t | |||
| 6396 | return -1; | 6396 | return -1; |
| 6397 | if (!cpumask_test_cpu(cpu, &p->cpus_allowed)) | 6397 | if (!cpumask_test_cpu(cpu, &p->cpus_allowed)) |
| 6398 | continue; | 6398 | continue; |
| 6399 | if (idle_cpu(cpu)) | 6399 | if (available_idle_cpu(cpu)) |
| 6400 | break; | 6400 | break; |
| 6401 | } | 6401 | } |
| 6402 | 6402 | ||
| @@ -6416,13 +6416,13 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) | |||
| 6416 | struct sched_domain *sd; | 6416 | struct sched_domain *sd; |
| 6417 | int i, recent_used_cpu; | 6417 | int i, recent_used_cpu; |
| 6418 | 6418 | ||
| 6419 | if (idle_cpu(target)) | 6419 | if (available_idle_cpu(target)) |
| 6420 | return target; | 6420 | return target; |
| 6421 | 6421 | ||
| 6422 | /* | 6422 | /* |
| 6423 | * If the previous CPU is cache affine and idle, don't be stupid: | 6423 | * If the previous CPU is cache affine and idle, don't be stupid: |
| 6424 | */ | 6424 | */ |
| 6425 | if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev)) | 6425 | if (prev != target && cpus_share_cache(prev, target) && available_idle_cpu(prev)) |
| 6426 | return prev; | 6426 | return prev; |
| 6427 | 6427 | ||
| 6428 | /* Check a recently used CPU as a potential idle candidate: */ | 6428 | /* Check a recently used CPU as a potential idle candidate: */ |
| @@ -6430,7 +6430,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) | |||
| 6430 | if (recent_used_cpu != prev && | 6430 | if (recent_used_cpu != prev && |
| 6431 | recent_used_cpu != target && | 6431 | recent_used_cpu != target && |
| 6432 | cpus_share_cache(recent_used_cpu, target) && | 6432 | cpus_share_cache(recent_used_cpu, target) && |
| 6433 | idle_cpu(recent_used_cpu) && | 6433 | available_idle_cpu(recent_used_cpu) && |
| 6434 | cpumask_test_cpu(p->recent_used_cpu, &p->cpus_allowed)) { | 6434 | cpumask_test_cpu(p->recent_used_cpu, &p->cpus_allowed)) { |
| 6435 | /* | 6435 | /* |
| 6436 | * Replace recent_used_cpu with prev as it is a potential | 6436 | * Replace recent_used_cpu with prev as it is a potential |
