diff options
author | Christoph Lameter <clameter@sgi.com> | 2006-12-10 05:20:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-10 12:55:42 -0500 |
commit | 7835b98bc6de2ca10afa45572d272304b000b048 (patch) | |
tree | 6c029f271821b00d18f5f318526b80511b409838 /kernel/sched.c | |
parent | fe2eea3fafb3df2f5b8a55a48bcbb0d23b3b5618 (diff) |
[PATCH] sched: extract load calculation from rebalance_tick
A load calculation is always done in rebalance_tick() in addition to the real
load balancing activities that only take place when certain jiffie counts have
been reached. Move that processing into a separate function and call it
directly from scheduler_tick().
Also extract the time slice handling from scheduler_tick and put it into a
separate function. Then we can clean up scheduler_tick significantly. It
will no longer have any gotos.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Cc: Peter Williams <pwil3058@bigpond.net.au>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Christoph Lameter <clameter@sgi.com>
Cc: "Siddha, Suresh B" <suresh.b.siddha@intel.com>
Cc: "Chen, Kenneth W" <kenneth.w.chen@intel.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 96 |
1 files changed, 54 insertions, 42 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index d327511d268e..3c1b74aa1b07 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2833,20 +2833,9 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu) | |||
2833 | spin_unlock(&target_rq->lock); | 2833 | spin_unlock(&target_rq->lock); |
2834 | } | 2834 | } |
2835 | 2835 | ||
2836 | /* | 2836 | static void update_load(struct rq *this_rq) |
2837 | * rebalance_tick will get called every timer tick, on every CPU. | ||
2838 | * | ||
2839 | * It checks each scheduling domain to see if it is due to be balanced, | ||
2840 | * and initiates a balancing operation if so. | ||
2841 | * | ||
2842 | * Balancing parameters are set up in arch_init_sched_domains. | ||
2843 | */ | ||
2844 | |||
2845 | static void | ||
2846 | rebalance_tick(int this_cpu, struct rq *this_rq, enum idle_type idle) | ||
2847 | { | 2837 | { |
2848 | unsigned long this_load, interval; | 2838 | unsigned long this_load; |
2849 | struct sched_domain *sd; | ||
2850 | int i, scale; | 2839 | int i, scale; |
2851 | 2840 | ||
2852 | this_load = this_rq->raw_weighted_load; | 2841 | this_load = this_rq->raw_weighted_load; |
@@ -2866,6 +2855,22 @@ rebalance_tick(int this_cpu, struct rq *this_rq, enum idle_type idle) | |||
2866 | new_load += scale-1; | 2855 | new_load += scale-1; |
2867 | this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) / scale; | 2856 | this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) / scale; |
2868 | } | 2857 | } |
2858 | } | ||
2859 | |||
2860 | /* | ||
2861 | * rebalance_tick will get called every timer tick, on every CPU. | ||
2862 | * | ||
2863 | * It checks each scheduling domain to see if it is due to be balanced, | ||
2864 | * and initiates a balancing operation if so. | ||
2865 | * | ||
2866 | * Balancing parameters are set up in arch_init_sched_domains. | ||
2867 | */ | ||
2868 | |||
2869 | static void | ||
2870 | rebalance_tick(int this_cpu, struct rq *this_rq, enum idle_type idle) | ||
2871 | { | ||
2872 | unsigned long interval; | ||
2873 | struct sched_domain *sd; | ||
2869 | 2874 | ||
2870 | for_each_domain(this_cpu, sd) { | 2875 | for_each_domain(this_cpu, sd) { |
2871 | if (!(sd->flags & SD_LOAD_BALANCE)) | 2876 | if (!(sd->flags & SD_LOAD_BALANCE)) |
@@ -2897,12 +2902,15 @@ rebalance_tick(int this_cpu, struct rq *this_rq, enum idle_type idle) | |||
2897 | /* | 2902 | /* |
2898 | * on UP we do not need to balance between CPUs: | 2903 | * on UP we do not need to balance between CPUs: |
2899 | */ | 2904 | */ |
2900 | static inline void rebalance_tick(int cpu, struct rq *rq, enum idle_type idle) | 2905 | static inline void rebalance_tick(int cpu, struct rq *rq) |
2901 | { | 2906 | { |
2902 | } | 2907 | } |
2903 | static inline void idle_balance(int cpu, struct rq *rq) | 2908 | static inline void idle_balance(int cpu, struct rq *rq) |
2904 | { | 2909 | { |
2905 | } | 2910 | } |
2911 | static inline void update_load(struct rq *this_rq) | ||
2912 | { | ||
2913 | } | ||
2906 | #endif | 2914 | #endif |
2907 | 2915 | ||
2908 | static inline int wake_priority_sleeper(struct rq *rq) | 2916 | static inline int wake_priority_sleeper(struct rq *rq) |
@@ -3052,35 +3060,12 @@ void account_steal_time(struct task_struct *p, cputime_t steal) | |||
3052 | cpustat->steal = cputime64_add(cpustat->steal, tmp); | 3060 | cpustat->steal = cputime64_add(cpustat->steal, tmp); |
3053 | } | 3061 | } |
3054 | 3062 | ||
3055 | /* | 3063 | static void task_running_tick(struct rq *rq, struct task_struct *p) |
3056 | * This function gets called by the timer code, with HZ frequency. | ||
3057 | * We call it with interrupts disabled. | ||
3058 | * | ||
3059 | * It also gets called by the fork code, when changing the parent's | ||
3060 | * timeslices. | ||
3061 | */ | ||
3062 | void scheduler_tick(void) | ||
3063 | { | 3064 | { |
3064 | unsigned long long now = sched_clock(); | ||
3065 | struct task_struct *p = current; | ||
3066 | int cpu = smp_processor_id(); | ||
3067 | struct rq *rq = cpu_rq(cpu); | ||
3068 | |||
3069 | update_cpu_clock(p, rq, now); | ||
3070 | |||
3071 | rq->timestamp_last_tick = now; | ||
3072 | |||
3073 | if (p == rq->idle) { | ||
3074 | if (wake_priority_sleeper(rq)) | ||
3075 | goto out; | ||
3076 | rebalance_tick(cpu, rq, SCHED_IDLE); | ||
3077 | return; | ||
3078 | } | ||
3079 | |||
3080 | /* Task might have expired already, but not scheduled off yet */ | ||
3081 | if (p->array != rq->active) { | 3065 | if (p->array != rq->active) { |
3066 | /* Task has expired but was not scheduled yet */ | ||
3082 | set_tsk_need_resched(p); | 3067 | set_tsk_need_resched(p); |
3083 | goto out; | 3068 | return; |
3084 | } | 3069 | } |
3085 | spin_lock(&rq->lock); | 3070 | spin_lock(&rq->lock); |
3086 | /* | 3071 | /* |
@@ -3148,8 +3133,35 @@ void scheduler_tick(void) | |||
3148 | } | 3133 | } |
3149 | out_unlock: | 3134 | out_unlock: |
3150 | spin_unlock(&rq->lock); | 3135 | spin_unlock(&rq->lock); |
3151 | out: | 3136 | } |
3152 | rebalance_tick(cpu, rq, NOT_IDLE); | 3137 | |
3138 | /* | ||
3139 | * This function gets called by the timer code, with HZ frequency. | ||
3140 | * We call it with interrupts disabled. | ||
3141 | * | ||
3142 | * It also gets called by the fork code, when changing the parent's | ||
3143 | * timeslices. | ||
3144 | */ | ||
3145 | void scheduler_tick(void) | ||
3146 | { | ||
3147 | unsigned long long now = sched_clock(); | ||
3148 | struct task_struct *p = current; | ||
3149 | int cpu = smp_processor_id(); | ||
3150 | struct rq *rq = cpu_rq(cpu); | ||
3151 | enum idle_type idle = NOT_IDLE; | ||
3152 | |||
3153 | update_cpu_clock(p, rq, now); | ||
3154 | |||
3155 | rq->timestamp_last_tick = now; | ||
3156 | |||
3157 | if (p == rq->idle) { | ||
3158 | /* Task on the idle queue */ | ||
3159 | if (!wake_priority_sleeper(rq)) | ||
3160 | idle = SCHED_IDLE; | ||
3161 | } else | ||
3162 | task_running_tick(rq, p); | ||
3163 | update_load(rq); | ||
3164 | rebalance_tick(cpu, rq, idle); | ||
3153 | } | 3165 | } |
3154 | 3166 | ||
3155 | #ifdef CONFIG_SCHED_SMT | 3167 | #ifdef CONFIG_SCHED_SMT |