diff options
author | Paul Turner <pjt@google.com> | 2012-10-04 07:18:31 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-10-24 04:27:28 -0400 |
commit | 48a1675323fa1b7844e479ad2a4469f4558c0f79 (patch) | |
tree | 1f3127f19be8fca16574d6adfadd22693b8766f2 | |
parent | 82958366cfea1a50e7e90907b2d55ae29ed69974 (diff) |
sched: Refactor update_shares_cpu() -> update_blocked_avgs()
Now that running entities maintain their own load-averages the work we must do
in update_shares() is largely restricted to the periodic decay of blocked
entities. This allows us to be a little less pessimistic regarding our
occupancy on rq->lock and the associated rq->clock updates required.
Signed-off-by: Paul Turner <pjt@google.com>
Reviewed-by: Ben Segall <bsegall@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20120823141507.133999170@google.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | kernel/sched/fair.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 57fae95eed99..dcc27d8ae6ba 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -3639,20 +3639,15 @@ next: | |||
3639 | /* | 3639 | /* |
3640 | * update tg->load_weight by folding this cpu's load_avg | 3640 | * update tg->load_weight by folding this cpu's load_avg |
3641 | */ | 3641 | */ |
3642 | static int update_shares_cpu(struct task_group *tg, int cpu) | 3642 | static void __update_blocked_averages_cpu(struct task_group *tg, int cpu) |
3643 | { | 3643 | { |
3644 | struct sched_entity *se; | 3644 | struct sched_entity *se = tg->se[cpu]; |
3645 | struct cfs_rq *cfs_rq; | 3645 | struct cfs_rq *cfs_rq = tg->cfs_rq[cpu]; |
3646 | unsigned long flags; | ||
3647 | struct rq *rq; | ||
3648 | |||
3649 | rq = cpu_rq(cpu); | ||
3650 | se = tg->se[cpu]; | ||
3651 | cfs_rq = tg->cfs_rq[cpu]; | ||
3652 | 3646 | ||
3653 | raw_spin_lock_irqsave(&rq->lock, flags); | 3647 | /* throttled entities do not contribute to load */ |
3648 | if (throttled_hierarchy(cfs_rq)) | ||
3649 | return; | ||
3654 | 3650 | ||
3655 | update_rq_clock(rq); | ||
3656 | update_cfs_rq_blocked_load(cfs_rq, 1); | 3651 | update_cfs_rq_blocked_load(cfs_rq, 1); |
3657 | 3652 | ||
3658 | if (se) { | 3653 | if (se) { |
@@ -3669,32 +3664,33 @@ static int update_shares_cpu(struct task_group *tg, int cpu) | |||
3669 | if (!se->avg.runnable_avg_sum && !cfs_rq->nr_running) | 3664 | if (!se->avg.runnable_avg_sum && !cfs_rq->nr_running) |
3670 | list_del_leaf_cfs_rq(cfs_rq); | 3665 | list_del_leaf_cfs_rq(cfs_rq); |
3671 | } else { | 3666 | } else { |
3667 | struct rq *rq = rq_of(cfs_rq); | ||
3672 | update_rq_runnable_avg(rq, rq->nr_running); | 3668 | update_rq_runnable_avg(rq, rq->nr_running); |
3673 | } | 3669 | } |
3674 | |||
3675 | raw_spin_unlock_irqrestore(&rq->lock, flags); | ||
3676 | |||
3677 | return 0; | ||
3678 | } | 3670 | } |
3679 | 3671 | ||
3680 | static void update_shares(int cpu) | 3672 | static void update_blocked_averages(int cpu) |
3681 | { | 3673 | { |
3682 | struct cfs_rq *cfs_rq; | ||
3683 | struct rq *rq = cpu_rq(cpu); | 3674 | struct rq *rq = cpu_rq(cpu); |
3675 | struct cfs_rq *cfs_rq; | ||
3676 | unsigned long flags; | ||
3684 | 3677 | ||
3685 | rcu_read_lock(); | 3678 | raw_spin_lock_irqsave(&rq->lock, flags); |
3679 | update_rq_clock(rq); | ||
3686 | /* | 3680 | /* |
3687 | * Iterates the task_group tree in a bottom up fashion, see | 3681 | * Iterates the task_group tree in a bottom up fashion, see |
3688 | * list_add_leaf_cfs_rq() for details. | 3682 | * list_add_leaf_cfs_rq() for details. |
3689 | */ | 3683 | */ |
3690 | for_each_leaf_cfs_rq(rq, cfs_rq) { | 3684 | for_each_leaf_cfs_rq(rq, cfs_rq) { |
3691 | /* throttled entities do not contribute to load */ | 3685 | /* |
3692 | if (throttled_hierarchy(cfs_rq)) | 3686 | * Note: We may want to consider periodically releasing |
3693 | continue; | 3687 | * rq->lock about these updates so that creating many task |
3694 | 3688 | * groups does not result in continually extending hold time. | |
3695 | update_shares_cpu(cfs_rq->tg, cpu); | 3689 | */ |
3690 | __update_blocked_averages_cpu(cfs_rq->tg, rq->cpu); | ||
3696 | } | 3691 | } |
3697 | rcu_read_unlock(); | 3692 | |
3693 | raw_spin_unlock_irqrestore(&rq->lock, flags); | ||
3698 | } | 3694 | } |
3699 | 3695 | ||
3700 | /* | 3696 | /* |
@@ -3746,7 +3742,7 @@ static unsigned long task_h_load(struct task_struct *p) | |||
3746 | return load; | 3742 | return load; |
3747 | } | 3743 | } |
3748 | #else | 3744 | #else |
3749 | static inline void update_shares(int cpu) | 3745 | static inline void update_blocked_averages(int cpu) |
3750 | { | 3746 | { |
3751 | } | 3747 | } |
3752 | 3748 | ||
@@ -4813,7 +4809,7 @@ void idle_balance(int this_cpu, struct rq *this_rq) | |||
4813 | */ | 4809 | */ |
4814 | raw_spin_unlock(&this_rq->lock); | 4810 | raw_spin_unlock(&this_rq->lock); |
4815 | 4811 | ||
4816 | update_shares(this_cpu); | 4812 | update_blocked_averages(this_cpu); |
4817 | rcu_read_lock(); | 4813 | rcu_read_lock(); |
4818 | for_each_domain(this_cpu, sd) { | 4814 | for_each_domain(this_cpu, sd) { |
4819 | unsigned long interval; | 4815 | unsigned long interval; |
@@ -5068,7 +5064,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle) | |||
5068 | int update_next_balance = 0; | 5064 | int update_next_balance = 0; |
5069 | int need_serialize; | 5065 | int need_serialize; |
5070 | 5066 | ||
5071 | update_shares(cpu); | 5067 | update_blocked_averages(cpu); |
5072 | 5068 | ||
5073 | rcu_read_lock(); | 5069 | rcu_read_lock(); |
5074 | for_each_domain(cpu, sd) { | 5070 | for_each_domain(cpu, sd) { |