diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 19:45:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 19:45:02 -0400 |
commit | bdc7ccfc0631797636837b10df7f87bc1e2e4ae3 (patch) | |
tree | 70f09f8ffee07486d41ca254b8abb05692713d1e /kernel/sched.c | |
parent | 4d4abdcb1dee03a4f9d6d2021622ed07e14dfd17 (diff) | |
parent | 0f3171438fc917b9f6b8b60dbb7a3fff9a0f68fd (diff) |
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (24 commits)
sched: Cleanup duplicate local variable in [enqueue|dequeue]_task_fair
sched: Replace use of entity_key()
sched: Separate group-scheduling code more clearly
sched: Reorder root_domain to remove 64 bit alignment padding
sched: Do not attempt to destroy uninitialized rt_bandwidth
sched: Remove unused function cpu_cfs_rq()
sched: Fix (harmless) typo 'CONFG_FAIR_GROUP_SCHED'
sched, cgroup: Optimize load_balance_fair()
sched: Don't update shares twice on on_rq parent
sched: update correct entity's runtime in check_preempt_wakeup()
xtensa: Use generic config PREEMPT definition
h8300: Use generic config PREEMPT definition
m32r: Use generic PREEMPT config
sched: Skip autogroup when looking for all rt sched groups
sched: Simplify mutex_spin_on_owner()
sched: Remove rcu_read_lock() from wake_affine()
sched: Generalize sleep inside spinlock detection
sched: Make sleeping inside spinlock detection working in !CONFIG_PREEMPT
sched: Isolate preempt counting in its own config option
sched: Remove pointless in_atomic() definition check
...
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 117 |
1 files changed, 36 insertions, 81 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 84b9e076812e..9aaf567c5da5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -124,7 +124,7 @@ | |||
124 | 124 | ||
125 | static inline int rt_policy(int policy) | 125 | static inline int rt_policy(int policy) |
126 | { | 126 | { |
127 | if (unlikely(policy == SCHED_FIFO || policy == SCHED_RR)) | 127 | if (policy == SCHED_FIFO || policy == SCHED_RR) |
128 | return 1; | 128 | return 1; |
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
@@ -422,6 +422,7 @@ struct rt_rq { | |||
422 | */ | 422 | */ |
423 | struct root_domain { | 423 | struct root_domain { |
424 | atomic_t refcount; | 424 | atomic_t refcount; |
425 | atomic_t rto_count; | ||
425 | struct rcu_head rcu; | 426 | struct rcu_head rcu; |
426 | cpumask_var_t span; | 427 | cpumask_var_t span; |
427 | cpumask_var_t online; | 428 | cpumask_var_t online; |
@@ -431,7 +432,6 @@ struct root_domain { | |||
431 | * one runnable RT task. | 432 | * one runnable RT task. |
432 | */ | 433 | */ |
433 | cpumask_var_t rto_mask; | 434 | cpumask_var_t rto_mask; |
434 | atomic_t rto_count; | ||
435 | struct cpupri cpupri; | 435 | struct cpupri cpupri; |
436 | }; | 436 | }; |
437 | 437 | ||
@@ -1568,38 +1568,6 @@ static unsigned long cpu_avg_load_per_task(int cpu) | |||
1568 | return rq->avg_load_per_task; | 1568 | return rq->avg_load_per_task; |
1569 | } | 1569 | } |
1570 | 1570 | ||
1571 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
1572 | |||
1573 | /* | ||
1574 | * Compute the cpu's hierarchical load factor for each task group. | ||
1575 | * This needs to be done in a top-down fashion because the load of a child | ||
1576 | * group is a fraction of its parents load. | ||
1577 | */ | ||
1578 | static int tg_load_down(struct task_group *tg, void *data) | ||
1579 | { | ||
1580 | unsigned long load; | ||
1581 | long cpu = (long)data; | ||
1582 | |||
1583 | if (!tg->parent) { | ||
1584 | load = cpu_rq(cpu)->load.weight; | ||
1585 | } else { | ||
1586 | load = tg->parent->cfs_rq[cpu]->h_load; | ||
1587 | load *= tg->se[cpu]->load.weight; | ||
1588 | load /= tg->parent->cfs_rq[cpu]->load.weight + 1; | ||
1589 | } | ||
1590 | |||
1591 | tg->cfs_rq[cpu]->h_load = load; | ||
1592 | |||
1593 | return 0; | ||
1594 | } | ||
1595 | |||
1596 | static void update_h_load(long cpu) | ||
1597 | { | ||
1598 | walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); | ||
1599 | } | ||
1600 | |||
1601 | #endif | ||
1602 | |||
1603 | #ifdef CONFIG_PREEMPT | 1571 | #ifdef CONFIG_PREEMPT |
1604 | 1572 | ||
1605 | static void double_rq_lock(struct rq *rq1, struct rq *rq2); | 1573 | static void double_rq_lock(struct rq *rq1, struct rq *rq2); |
@@ -2497,7 +2465,7 @@ ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags) | |||
2497 | if (p->sched_class->task_woken) | 2465 | if (p->sched_class->task_woken) |
2498 | p->sched_class->task_woken(rq, p); | 2466 | p->sched_class->task_woken(rq, p); |
2499 | 2467 | ||
2500 | if (unlikely(rq->idle_stamp)) { | 2468 | if (rq->idle_stamp) { |
2501 | u64 delta = rq->clock - rq->idle_stamp; | 2469 | u64 delta = rq->clock - rq->idle_stamp; |
2502 | u64 max = 2*sysctl_sched_migration_cost; | 2470 | u64 max = 2*sysctl_sched_migration_cost; |
2503 | 2471 | ||
@@ -2886,7 +2854,7 @@ void sched_fork(struct task_struct *p) | |||
2886 | #if defined(CONFIG_SMP) | 2854 | #if defined(CONFIG_SMP) |
2887 | p->on_cpu = 0; | 2855 | p->on_cpu = 0; |
2888 | #endif | 2856 | #endif |
2889 | #ifdef CONFIG_PREEMPT | 2857 | #ifdef CONFIG_PREEMPT_COUNT |
2890 | /* Want to start with kernel preemption disabled. */ | 2858 | /* Want to start with kernel preemption disabled. */ |
2891 | task_thread_info(p)->preempt_count = 1; | 2859 | task_thread_info(p)->preempt_count = 1; |
2892 | #endif | 2860 | #endif |
@@ -4338,11 +4306,8 @@ EXPORT_SYMBOL(schedule); | |||
4338 | 4306 | ||
4339 | static inline bool owner_running(struct mutex *lock, struct task_struct *owner) | 4307 | static inline bool owner_running(struct mutex *lock, struct task_struct *owner) |
4340 | { | 4308 | { |
4341 | bool ret = false; | ||
4342 | |||
4343 | rcu_read_lock(); | ||
4344 | if (lock->owner != owner) | 4309 | if (lock->owner != owner) |
4345 | goto fail; | 4310 | return false; |
4346 | 4311 | ||
4347 | /* | 4312 | /* |
4348 | * Ensure we emit the owner->on_cpu, dereference _after_ checking | 4313 | * Ensure we emit the owner->on_cpu, dereference _after_ checking |
@@ -4352,11 +4317,7 @@ static inline bool owner_running(struct mutex *lock, struct task_struct *owner) | |||
4352 | */ | 4317 | */ |
4353 | barrier(); | 4318 | barrier(); |
4354 | 4319 | ||
4355 | ret = owner->on_cpu; | 4320 | return owner->on_cpu; |
4356 | fail: | ||
4357 | rcu_read_unlock(); | ||
4358 | |||
4359 | return ret; | ||
4360 | } | 4321 | } |
4361 | 4322 | ||
4362 | /* | 4323 | /* |
@@ -4368,21 +4329,21 @@ int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner) | |||
4368 | if (!sched_feat(OWNER_SPIN)) | 4329 | if (!sched_feat(OWNER_SPIN)) |
4369 | return 0; | 4330 | return 0; |
4370 | 4331 | ||
4332 | rcu_read_lock(); | ||
4371 | while (owner_running(lock, owner)) { | 4333 | while (owner_running(lock, owner)) { |
4372 | if (need_resched()) | 4334 | if (need_resched()) |
4373 | return 0; | 4335 | break; |
4374 | 4336 | ||
4375 | arch_mutex_cpu_relax(); | 4337 | arch_mutex_cpu_relax(); |
4376 | } | 4338 | } |
4339 | rcu_read_unlock(); | ||
4377 | 4340 | ||
4378 | /* | 4341 | /* |
4379 | * If the owner changed to another task there is likely | 4342 | * We break out the loop above on need_resched() and when the |
4380 | * heavy contention, stop spinning. | 4343 | * owner changed, which is a sign for heavy contention. Return |
4344 | * success only when lock->owner is NULL. | ||
4381 | */ | 4345 | */ |
4382 | if (lock->owner) | 4346 | return lock->owner == NULL; |
4383 | return 0; | ||
4384 | |||
4385 | return 1; | ||
4386 | } | 4347 | } |
4387 | #endif | 4348 | #endif |
4388 | 4349 | ||
@@ -7898,17 +7859,10 @@ int in_sched_functions(unsigned long addr) | |||
7898 | && addr < (unsigned long)__sched_text_end); | 7859 | && addr < (unsigned long)__sched_text_end); |
7899 | } | 7860 | } |
7900 | 7861 | ||
7901 | static void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq) | 7862 | static void init_cfs_rq(struct cfs_rq *cfs_rq) |
7902 | { | 7863 | { |
7903 | cfs_rq->tasks_timeline = RB_ROOT; | 7864 | cfs_rq->tasks_timeline = RB_ROOT; |
7904 | INIT_LIST_HEAD(&cfs_rq->tasks); | 7865 | INIT_LIST_HEAD(&cfs_rq->tasks); |
7905 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
7906 | cfs_rq->rq = rq; | ||
7907 | /* allow initial update_cfs_load() to truncate */ | ||
7908 | #ifdef CONFIG_SMP | ||
7909 | cfs_rq->load_stamp = 1; | ||
7910 | #endif | ||
7911 | #endif | ||
7912 | cfs_rq->min_vruntime = (u64)(-(1LL << 20)); | 7866 | cfs_rq->min_vruntime = (u64)(-(1LL << 20)); |
7913 | #ifndef CONFIG_64BIT | 7867 | #ifndef CONFIG_64BIT |
7914 | cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime; | 7868 | cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime; |
@@ -7928,13 +7882,9 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) | |||
7928 | /* delimiter for bitsearch: */ | 7882 | /* delimiter for bitsearch: */ |
7929 | __set_bit(MAX_RT_PRIO, array->bitmap); | 7883 | __set_bit(MAX_RT_PRIO, array->bitmap); |
7930 | 7884 | ||
7931 | #if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED | 7885 | #if defined CONFIG_SMP |
7932 | rt_rq->highest_prio.curr = MAX_RT_PRIO; | 7886 | rt_rq->highest_prio.curr = MAX_RT_PRIO; |
7933 | #ifdef CONFIG_SMP | ||
7934 | rt_rq->highest_prio.next = MAX_RT_PRIO; | 7887 | rt_rq->highest_prio.next = MAX_RT_PRIO; |
7935 | #endif | ||
7936 | #endif | ||
7937 | #ifdef CONFIG_SMP | ||
7938 | rt_rq->rt_nr_migratory = 0; | 7888 | rt_rq->rt_nr_migratory = 0; |
7939 | rt_rq->overloaded = 0; | 7889 | rt_rq->overloaded = 0; |
7940 | plist_head_init(&rt_rq->pushable_tasks); | 7890 | plist_head_init(&rt_rq->pushable_tasks); |
@@ -7944,11 +7894,6 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) | |||
7944 | rt_rq->rt_throttled = 0; | 7894 | rt_rq->rt_throttled = 0; |
7945 | rt_rq->rt_runtime = 0; | 7895 | rt_rq->rt_runtime = 0; |
7946 | raw_spin_lock_init(&rt_rq->rt_runtime_lock); | 7896 | raw_spin_lock_init(&rt_rq->rt_runtime_lock); |
7947 | |||
7948 | #ifdef CONFIG_RT_GROUP_SCHED | ||
7949 | rt_rq->rt_nr_boosted = 0; | ||
7950 | rt_rq->rq = rq; | ||
7951 | #endif | ||
7952 | } | 7897 | } |
7953 | 7898 | ||
7954 | #ifdef CONFIG_FAIR_GROUP_SCHED | 7899 | #ifdef CONFIG_FAIR_GROUP_SCHED |
@@ -7957,11 +7902,17 @@ static void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq, | |||
7957 | struct sched_entity *parent) | 7902 | struct sched_entity *parent) |
7958 | { | 7903 | { |
7959 | struct rq *rq = cpu_rq(cpu); | 7904 | struct rq *rq = cpu_rq(cpu); |
7960 | tg->cfs_rq[cpu] = cfs_rq; | 7905 | |
7961 | init_cfs_rq(cfs_rq, rq); | ||
7962 | cfs_rq->tg = tg; | 7906 | cfs_rq->tg = tg; |
7907 | cfs_rq->rq = rq; | ||
7908 | #ifdef CONFIG_SMP | ||
7909 | /* allow initial update_cfs_load() to truncate */ | ||
7910 | cfs_rq->load_stamp = 1; | ||
7911 | #endif | ||
7963 | 7912 | ||
7913 | tg->cfs_rq[cpu] = cfs_rq; | ||
7964 | tg->se[cpu] = se; | 7914 | tg->se[cpu] = se; |
7915 | |||
7965 | /* se could be NULL for root_task_group */ | 7916 | /* se could be NULL for root_task_group */ |
7966 | if (!se) | 7917 | if (!se) |
7967 | return; | 7918 | return; |
@@ -7984,12 +7935,14 @@ static void init_tg_rt_entry(struct task_group *tg, struct rt_rq *rt_rq, | |||
7984 | { | 7935 | { |
7985 | struct rq *rq = cpu_rq(cpu); | 7936 | struct rq *rq = cpu_rq(cpu); |
7986 | 7937 | ||
7987 | tg->rt_rq[cpu] = rt_rq; | 7938 | rt_rq->highest_prio.curr = MAX_RT_PRIO; |
7988 | init_rt_rq(rt_rq, rq); | 7939 | rt_rq->rt_nr_boosted = 0; |
7940 | rt_rq->rq = rq; | ||
7989 | rt_rq->tg = tg; | 7941 | rt_rq->tg = tg; |
7990 | rt_rq->rt_runtime = tg->rt_bandwidth.rt_runtime; | ||
7991 | 7942 | ||
7943 | tg->rt_rq[cpu] = rt_rq; | ||
7992 | tg->rt_se[cpu] = rt_se; | 7944 | tg->rt_se[cpu] = rt_se; |
7945 | |||
7993 | if (!rt_se) | 7946 | if (!rt_se) |
7994 | return; | 7947 | return; |
7995 | 7948 | ||
@@ -8071,7 +8024,7 @@ void __init sched_init(void) | |||
8071 | rq->nr_running = 0; | 8024 | rq->nr_running = 0; |
8072 | rq->calc_load_active = 0; | 8025 | rq->calc_load_active = 0; |
8073 | rq->calc_load_update = jiffies + LOAD_FREQ; | 8026 | rq->calc_load_update = jiffies + LOAD_FREQ; |
8074 | init_cfs_rq(&rq->cfs, rq); | 8027 | init_cfs_rq(&rq->cfs); |
8075 | init_rt_rq(&rq->rt, rq); | 8028 | init_rt_rq(&rq->rt, rq); |
8076 | #ifdef CONFIG_FAIR_GROUP_SCHED | 8029 | #ifdef CONFIG_FAIR_GROUP_SCHED |
8077 | root_task_group.shares = root_task_group_load; | 8030 | root_task_group.shares = root_task_group_load; |
@@ -8185,7 +8138,7 @@ void __init sched_init(void) | |||
8185 | scheduler_running = 1; | 8138 | scheduler_running = 1; |
8186 | } | 8139 | } |
8187 | 8140 | ||
8188 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 8141 | #ifdef CONFIG_DEBUG_ATOMIC_SLEEP |
8189 | static inline int preempt_count_equals(int preempt_offset) | 8142 | static inline int preempt_count_equals(int preempt_offset) |
8190 | { | 8143 | { |
8191 | int nested = (preempt_count() & ~PREEMPT_ACTIVE) + rcu_preempt_depth(); | 8144 | int nested = (preempt_count() & ~PREEMPT_ACTIVE) + rcu_preempt_depth(); |
@@ -8195,7 +8148,6 @@ static inline int preempt_count_equals(int preempt_offset) | |||
8195 | 8148 | ||
8196 | void __might_sleep(const char *file, int line, int preempt_offset) | 8149 | void __might_sleep(const char *file, int line, int preempt_offset) |
8197 | { | 8150 | { |
8198 | #ifdef in_atomic | ||
8199 | static unsigned long prev_jiffy; /* ratelimiting */ | 8151 | static unsigned long prev_jiffy; /* ratelimiting */ |
8200 | 8152 | ||
8201 | if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || | 8153 | if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || |
@@ -8217,7 +8169,6 @@ void __might_sleep(const char *file, int line, int preempt_offset) | |||
8217 | if (irqs_disabled()) | 8169 | if (irqs_disabled()) |
8218 | print_irqtrace_events(current); | 8170 | print_irqtrace_events(current); |
8219 | dump_stack(); | 8171 | dump_stack(); |
8220 | #endif | ||
8221 | } | 8172 | } |
8222 | EXPORT_SYMBOL(__might_sleep); | 8173 | EXPORT_SYMBOL(__might_sleep); |
8223 | #endif | 8174 | #endif |
@@ -8376,6 +8327,7 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) | |||
8376 | if (!se) | 8327 | if (!se) |
8377 | goto err_free_rq; | 8328 | goto err_free_rq; |
8378 | 8329 | ||
8330 | init_cfs_rq(cfs_rq); | ||
8379 | init_tg_cfs_entry(tg, cfs_rq, se, i, parent->se[i]); | 8331 | init_tg_cfs_entry(tg, cfs_rq, se, i, parent->se[i]); |
8380 | } | 8332 | } |
8381 | 8333 | ||
@@ -8403,7 +8355,7 @@ static inline void unregister_fair_sched_group(struct task_group *tg, int cpu) | |||
8403 | list_del_leaf_cfs_rq(tg->cfs_rq[cpu]); | 8355 | list_del_leaf_cfs_rq(tg->cfs_rq[cpu]); |
8404 | raw_spin_unlock_irqrestore(&rq->lock, flags); | 8356 | raw_spin_unlock_irqrestore(&rq->lock, flags); |
8405 | } | 8357 | } |
8406 | #else /* !CONFG_FAIR_GROUP_SCHED */ | 8358 | #else /* !CONFIG_FAIR_GROUP_SCHED */ |
8407 | static inline void free_fair_sched_group(struct task_group *tg) | 8359 | static inline void free_fair_sched_group(struct task_group *tg) |
8408 | { | 8360 | { |
8409 | } | 8361 | } |
@@ -8424,7 +8376,8 @@ static void free_rt_sched_group(struct task_group *tg) | |||
8424 | { | 8376 | { |
8425 | int i; | 8377 | int i; |
8426 | 8378 | ||
8427 | destroy_rt_bandwidth(&tg->rt_bandwidth); | 8379 | if (tg->rt_se) |
8380 | destroy_rt_bandwidth(&tg->rt_bandwidth); | ||
8428 | 8381 | ||
8429 | for_each_possible_cpu(i) { | 8382 | for_each_possible_cpu(i) { |
8430 | if (tg->rt_rq) | 8383 | if (tg->rt_rq) |
@@ -8465,6 +8418,8 @@ int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent) | |||
8465 | if (!rt_se) | 8418 | if (!rt_se) |
8466 | goto err_free_rq; | 8419 | goto err_free_rq; |
8467 | 8420 | ||
8421 | init_rt_rq(rt_rq, cpu_rq(i)); | ||
8422 | rt_rq->rt_runtime = tg->rt_bandwidth.rt_runtime; | ||
8468 | init_tg_rt_entry(tg, rt_rq, rt_se, i, parent->rt_se[i]); | 8423 | init_tg_rt_entry(tg, rt_rq, rt_se, i, parent->rt_se[i]); |
8469 | } | 8424 | } |
8470 | 8425 | ||