diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched.c | 47 | ||||
| -rw-r--r-- | kernel/sched_fair.c | 28 |
2 files changed, 33 insertions, 42 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index c92670f8e097..33c903573132 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -1811,6 +1811,20 @@ static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares) | |||
| 1811 | 1811 | ||
| 1812 | static void calc_load_account_active(struct rq *this_rq); | 1812 | static void calc_load_account_active(struct rq *this_rq); |
| 1813 | 1813 | ||
| 1814 | static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu) | ||
| 1815 | { | ||
| 1816 | set_task_rq(p, cpu); | ||
| 1817 | #ifdef CONFIG_SMP | ||
| 1818 | /* | ||
| 1819 | * After ->cpu is set up to a new value, task_rq_lock(p, ...) can be | ||
| 1820 | * successfuly executed on another CPU. We must ensure that updates of | ||
| 1821 | * per-task data have been completed by this moment. | ||
| 1822 | */ | ||
| 1823 | smp_wmb(); | ||
| 1824 | task_thread_info(p)->cpu = cpu; | ||
| 1825 | #endif | ||
| 1826 | } | ||
| 1827 | |||
| 1814 | #include "sched_stats.h" | 1828 | #include "sched_stats.h" |
| 1815 | #include "sched_idletask.c" | 1829 | #include "sched_idletask.c" |
| 1816 | #include "sched_fair.c" | 1830 | #include "sched_fair.c" |
| @@ -1967,20 +1981,6 @@ inline int task_curr(const struct task_struct *p) | |||
| 1967 | return cpu_curr(task_cpu(p)) == p; | 1981 | return cpu_curr(task_cpu(p)) == p; |
| 1968 | } | 1982 | } |
| 1969 | 1983 | ||
| 1970 | static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu) | ||
| 1971 | { | ||
| 1972 | set_task_rq(p, cpu); | ||
| 1973 | #ifdef CONFIG_SMP | ||
| 1974 | /* | ||
| 1975 | * After ->cpu is set up to a new value, task_rq_lock(p, ...) can be | ||
| 1976 | * successfuly executed on another CPU. We must ensure that updates of | ||
| 1977 | * per-task data have been completed by this moment. | ||
| 1978 | */ | ||
| 1979 | smp_wmb(); | ||
| 1980 | task_thread_info(p)->cpu = cpu; | ||
| 1981 | #endif | ||
| 1982 | } | ||
| 1983 | |||
| 1984 | static inline void check_class_changed(struct rq *rq, struct task_struct *p, | 1984 | static inline void check_class_changed(struct rq *rq, struct task_struct *p, |
| 1985 | const struct sched_class *prev_class, | 1985 | const struct sched_class *prev_class, |
| 1986 | int oldprio, int running) | 1986 | int oldprio, int running) |
| @@ -2552,7 +2552,6 @@ static void __sched_fork(struct task_struct *p) | |||
| 2552 | void sched_fork(struct task_struct *p, int clone_flags) | 2552 | void sched_fork(struct task_struct *p, int clone_flags) |
| 2553 | { | 2553 | { |
| 2554 | int cpu = get_cpu(); | 2554 | int cpu = get_cpu(); |
| 2555 | unsigned long flags; | ||
| 2556 | 2555 | ||
| 2557 | __sched_fork(p); | 2556 | __sched_fork(p); |
| 2558 | 2557 | ||
| @@ -2586,13 +2585,13 @@ void sched_fork(struct task_struct *p, int clone_flags) | |||
| 2586 | if (!rt_prio(p->prio)) | 2585 | if (!rt_prio(p->prio)) |
| 2587 | p->sched_class = &fair_sched_class; | 2586 | p->sched_class = &fair_sched_class; |
| 2588 | 2587 | ||
| 2588 | if (p->sched_class->task_fork) | ||
| 2589 | p->sched_class->task_fork(p); | ||
| 2590 | |||
| 2589 | #ifdef CONFIG_SMP | 2591 | #ifdef CONFIG_SMP |
| 2590 | cpu = select_task_rq(p, SD_BALANCE_FORK, 0); | 2592 | cpu = select_task_rq(p, SD_BALANCE_FORK, 0); |
| 2591 | #endif | 2593 | #endif |
| 2592 | local_irq_save(flags); | ||
| 2593 | update_rq_clock(cpu_rq(cpu)); | ||
| 2594 | set_task_cpu(p, cpu); | 2594 | set_task_cpu(p, cpu); |
| 2595 | local_irq_restore(flags); | ||
| 2596 | 2595 | ||
| 2597 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 2596 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) |
| 2598 | if (likely(sched_info_on())) | 2597 | if (likely(sched_info_on())) |
| @@ -2625,17 +2624,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
| 2625 | rq = task_rq_lock(p, &flags); | 2624 | rq = task_rq_lock(p, &flags); |
| 2626 | BUG_ON(p->state != TASK_RUNNING); | 2625 | BUG_ON(p->state != TASK_RUNNING); |
| 2627 | update_rq_clock(rq); | 2626 | update_rq_clock(rq); |
| 2628 | 2627 | activate_task(rq, p, 0); | |
| 2629 | if (!p->sched_class->task_new || !current->se.on_rq) { | ||
| 2630 | activate_task(rq, p, 0); | ||
| 2631 | } else { | ||
| 2632 | /* | ||
| 2633 | * Let the scheduling class do new task startup | ||
| 2634 | * management (if any): | ||
| 2635 | */ | ||
| 2636 | p->sched_class->task_new(rq, p); | ||
| 2637 | inc_nr_running(rq); | ||
| 2638 | } | ||
| 2639 | trace_sched_wakeup_new(rq, p, 1); | 2628 | trace_sched_wakeup_new(rq, p, 1); |
| 2640 | check_preempt_curr(rq, p, WF_FORK); | 2629 | check_preempt_curr(rq, p, WF_FORK); |
| 2641 | #ifdef CONFIG_SMP | 2630 | #ifdef CONFIG_SMP |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 613c1c749677..44ec80ccfa85 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
| @@ -1922,28 +1922,30 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued) | |||
| 1922 | } | 1922 | } |
| 1923 | 1923 | ||
| 1924 | /* | 1924 | /* |
| 1925 | * Share the fairness runtime between parent and child, thus the | 1925 | * called on fork with the child task as argument from the parent's context |
| 1926 | * total amount of pressure for CPU stays equal - new tasks | 1926 | * - child not yet on the tasklist |
| 1927 | * get a chance to run but frequent forkers are not allowed to | 1927 | * - preemption disabled |
| 1928 | * monopolize the CPU. Note: the parent runqueue is locked, | ||
| 1929 | * the child is not running yet. | ||
| 1930 | */ | 1928 | */ |
| 1931 | static void task_new_fair(struct rq *rq, struct task_struct *p) | 1929 | static void task_fork_fair(struct task_struct *p) |
| 1932 | { | 1930 | { |
| 1933 | struct cfs_rq *cfs_rq = task_cfs_rq(p); | 1931 | struct cfs_rq *cfs_rq = task_cfs_rq(current); |
| 1934 | struct sched_entity *se = &p->se, *curr = cfs_rq->curr; | 1932 | struct sched_entity *se = &p->se, *curr = cfs_rq->curr; |
| 1935 | int this_cpu = smp_processor_id(); | 1933 | int this_cpu = smp_processor_id(); |
| 1934 | struct rq *rq = this_rq(); | ||
| 1935 | unsigned long flags; | ||
| 1936 | |||
| 1937 | spin_lock_irqsave(&rq->lock, flags); | ||
| 1936 | 1938 | ||
| 1937 | sched_info_queued(p); | 1939 | if (unlikely(task_cpu(p) != this_cpu)) |
| 1940 | __set_task_cpu(p, this_cpu); | ||
| 1938 | 1941 | ||
| 1939 | update_curr(cfs_rq); | 1942 | update_curr(cfs_rq); |
| 1943 | |||
| 1940 | if (curr) | 1944 | if (curr) |
| 1941 | se->vruntime = curr->vruntime; | 1945 | se->vruntime = curr->vruntime; |
| 1942 | place_entity(cfs_rq, se, 1); | 1946 | place_entity(cfs_rq, se, 1); |
| 1943 | 1947 | ||
| 1944 | /* 'curr' will be NULL if the child belongs to a different group */ | 1948 | if (sysctl_sched_child_runs_first && curr && entity_before(curr, se)) { |
| 1945 | if (sysctl_sched_child_runs_first && this_cpu == task_cpu(p) && | ||
| 1946 | curr && entity_before(curr, se)) { | ||
| 1947 | /* | 1949 | /* |
| 1948 | * Upon rescheduling, sched_class::put_prev_task() will place | 1950 | * Upon rescheduling, sched_class::put_prev_task() will place |
| 1949 | * 'current' within the tree based on its new key value. | 1951 | * 'current' within the tree based on its new key value. |
| @@ -1952,7 +1954,7 @@ static void task_new_fair(struct rq *rq, struct task_struct *p) | |||
| 1952 | resched_task(rq->curr); | 1954 | resched_task(rq->curr); |
| 1953 | } | 1955 | } |
| 1954 | 1956 | ||
| 1955 | enqueue_task_fair(rq, p, 0); | 1957 | spin_unlock_irqrestore(&rq->lock, flags); |
| 1956 | } | 1958 | } |
| 1957 | 1959 | ||
| 1958 | /* | 1960 | /* |
| @@ -2052,7 +2054,7 @@ static const struct sched_class fair_sched_class = { | |||
| 2052 | 2054 | ||
| 2053 | .set_curr_task = set_curr_task_fair, | 2055 | .set_curr_task = set_curr_task_fair, |
| 2054 | .task_tick = task_tick_fair, | 2056 | .task_tick = task_tick_fair, |
| 2055 | .task_new = task_new_fair, | 2057 | .task_fork = task_fork_fair, |
| 2056 | 2058 | ||
| 2057 | .prio_changed = prio_changed_fair, | 2059 | .prio_changed = prio_changed_fair, |
| 2058 | .switched_to = switched_to_fair, | 2060 | .switched_to = switched_to_fair, |
