diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/core.c | 1 | ||||
-rw-r--r-- | kernel/sched/fair.c | 31 | ||||
-rw-r--r-- | kernel/sched/sched.h | 1 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 9 |
4 files changed, 42 insertions, 0 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 7f1da77b83f3..699ff1499a8a 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -6024,6 +6024,7 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd) | |||
6024 | return; | 6024 | return; |
6025 | 6025 | ||
6026 | update_group_power(sd, cpu); | 6026 | update_group_power(sd, cpu); |
6027 | atomic_set(&sg->sgp->nr_busy_cpus, sg->group_weight); | ||
6027 | } | 6028 | } |
6028 | 6029 | ||
6029 | int __weak arch_sd_sibling_asym_packing(void) | 6030 | int __weak arch_sd_sibling_asym_packing(void) |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 50c06b0e9fab..e050563e97a4 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -4901,6 +4901,36 @@ static void nohz_balancer_kick(int cpu) | |||
4901 | return; | 4901 | return; |
4902 | } | 4902 | } |
4903 | 4903 | ||
4904 | static inline void set_cpu_sd_state_busy(void) | ||
4905 | { | ||
4906 | struct sched_domain *sd; | ||
4907 | int cpu = smp_processor_id(); | ||
4908 | |||
4909 | if (!test_bit(NOHZ_IDLE, nohz_flags(cpu))) | ||
4910 | return; | ||
4911 | clear_bit(NOHZ_IDLE, nohz_flags(cpu)); | ||
4912 | |||
4913 | rcu_read_lock(); | ||
4914 | for_each_domain(cpu, sd) | ||
4915 | atomic_inc(&sd->groups->sgp->nr_busy_cpus); | ||
4916 | rcu_read_unlock(); | ||
4917 | } | ||
4918 | |||
4919 | void set_cpu_sd_state_idle(void) | ||
4920 | { | ||
4921 | struct sched_domain *sd; | ||
4922 | int cpu = smp_processor_id(); | ||
4923 | |||
4924 | if (test_bit(NOHZ_IDLE, nohz_flags(cpu))) | ||
4925 | return; | ||
4926 | set_bit(NOHZ_IDLE, nohz_flags(cpu)); | ||
4927 | |||
4928 | rcu_read_lock(); | ||
4929 | for_each_domain(cpu, sd) | ||
4930 | atomic_dec(&sd->groups->sgp->nr_busy_cpus); | ||
4931 | rcu_read_unlock(); | ||
4932 | } | ||
4933 | |||
4904 | /* | 4934 | /* |
4905 | * This routine will try to nominate the ilb (idle load balancing) | 4935 | * This routine will try to nominate the ilb (idle load balancing) |
4906 | * owner among the cpus whose ticks are stopped. ilb owner will do the idle | 4936 | * owner among the cpus whose ticks are stopped. ilb owner will do the idle |
@@ -5135,6 +5165,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) | |||
5135 | * We may be recently in ticked or tickless idle mode. At the first | 5165 | * We may be recently in ticked or tickless idle mode. At the first |
5136 | * busy tick after returning from idle, we will update the busy stats. | 5166 | * busy tick after returning from idle, we will update the busy stats. |
5137 | */ | 5167 | */ |
5168 | set_cpu_sd_state_busy(); | ||
5138 | if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) | 5169 | if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) |
5139 | clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); | 5170 | clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); |
5140 | 5171 | ||
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index cf7d02662bc2..91810f0ee3af 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
@@ -1069,6 +1069,7 @@ extern void account_cfs_bandwidth_used(int enabled, int was_enabled); | |||
1069 | enum rq_nohz_flag_bits { | 1069 | enum rq_nohz_flag_bits { |
1070 | NOHZ_TICK_STOPPED, | 1070 | NOHZ_TICK_STOPPED, |
1071 | NOHZ_BALANCE_KICK, | 1071 | NOHZ_BALANCE_KICK, |
1072 | NOHZ_IDLE, | ||
1072 | }; | 1073 | }; |
1073 | 1074 | ||
1074 | #define nohz_flags(cpu) (&cpu_rq(cpu)->nohz_flags) | 1075 | #define nohz_flags(cpu) (&cpu_rq(cpu)->nohz_flags) |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 40420644d0ba..31cc06163ed5 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -297,6 +297,15 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
297 | ts = &per_cpu(tick_cpu_sched, cpu); | 297 | ts = &per_cpu(tick_cpu_sched, cpu); |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * Update the idle state in the scheduler domain hierarchy | ||
301 | * when tick_nohz_stop_sched_tick() is called from the idle loop. | ||
302 | * State will be updated to busy during the first busy tick after | ||
303 | * exiting idle. | ||
304 | */ | ||
305 | if (inidle) | ||
306 | set_cpu_sd_state_idle(); | ||
307 | |||
308 | /* | ||
300 | * Call to tick_nohz_start_idle stops the last_update_time from being | 309 | * Call to tick_nohz_start_idle stops the last_update_time from being |
301 | * updated. Thus, it must not be called in the event we are called from | 310 | * updated. Thus, it must not be called in the event we are called from |
302 | * irq_exit() with the prior state different than idle. | 311 | * irq_exit() with the prior state different than idle. |