aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/sched/fair.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 6482136f8991..a4d2b7abc3cd 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5088,23 +5088,28 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu)
5088 if (rq->nr_running >= 2) 5088 if (rq->nr_running >= 2)
5089 goto need_kick; 5089 goto need_kick;
5090 5090
5091 rcu_read_lock();
5091 for_each_domain(cpu, sd) { 5092 for_each_domain(cpu, sd) {
5092 struct sched_group *sg = sd->groups; 5093 struct sched_group *sg = sd->groups;
5093 struct sched_group_power *sgp = sg->sgp; 5094 struct sched_group_power *sgp = sg->sgp;
5094 int nr_busy = atomic_read(&sgp->nr_busy_cpus); 5095 int nr_busy = atomic_read(&sgp->nr_busy_cpus);
5095 5096
5096 if (sd->flags & SD_SHARE_PKG_RESOURCES && nr_busy > 1) 5097 if (sd->flags & SD_SHARE_PKG_RESOURCES && nr_busy > 1)
5097 goto need_kick; 5098 goto need_kick_unlock;
5098 5099
5099 if (sd->flags & SD_ASYM_PACKING && nr_busy != sg->group_weight 5100 if (sd->flags & SD_ASYM_PACKING && nr_busy != sg->group_weight
5100 && (cpumask_first_and(nohz.idle_cpus_mask, 5101 && (cpumask_first_and(nohz.idle_cpus_mask,
5101 sched_domain_span(sd)) < cpu)) 5102 sched_domain_span(sd)) < cpu))
5102 goto need_kick; 5103 goto need_kick_unlock;
5103 5104
5104 if (!(sd->flags & (SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING))) 5105 if (!(sd->flags & (SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING)))
5105 break; 5106 break;
5106 } 5107 }
5108 rcu_read_unlock();
5107 return 0; 5109 return 0;
5110
5111need_kick_unlock:
5112 rcu_read_unlock();
5108need_kick: 5113need_kick:
5109 return 1; 5114 return 1;
5110} 5115}