diff options
Diffstat (limited to 'kernel/sched/core.c')
| -rw-r--r-- | kernel/sched/core.c | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 00781cc38047..a8c0fde25e4a 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -2192,7 +2192,7 @@ static inline void post_schedule(struct rq *rq) | |||
| 2192 | * schedule_tail - first thing a freshly forked thread must call. | 2192 | * schedule_tail - first thing a freshly forked thread must call. |
| 2193 | * @prev: the thread we just switched away from. | 2193 | * @prev: the thread we just switched away from. |
| 2194 | */ | 2194 | */ |
| 2195 | asmlinkage void schedule_tail(struct task_struct *prev) | 2195 | asmlinkage __visible void schedule_tail(struct task_struct *prev) |
| 2196 | __releases(rq->lock) | 2196 | __releases(rq->lock) |
| 2197 | { | 2197 | { |
| 2198 | struct rq *rq = this_rq(); | 2198 | struct rq *rq = this_rq(); |
| @@ -2594,8 +2594,14 @@ pick_next_task(struct rq *rq, struct task_struct *prev) | |||
| 2594 | if (likely(prev->sched_class == class && | 2594 | if (likely(prev->sched_class == class && |
| 2595 | rq->nr_running == rq->cfs.h_nr_running)) { | 2595 | rq->nr_running == rq->cfs.h_nr_running)) { |
| 2596 | p = fair_sched_class.pick_next_task(rq, prev); | 2596 | p = fair_sched_class.pick_next_task(rq, prev); |
| 2597 | if (likely(p && p != RETRY_TASK)) | 2597 | if (unlikely(p == RETRY_TASK)) |
| 2598 | return p; | 2598 | goto again; |
| 2599 | |||
| 2600 | /* assumes fair_sched_class->next == idle_sched_class */ | ||
| 2601 | if (unlikely(!p)) | ||
| 2602 | p = idle_sched_class.pick_next_task(rq, prev); | ||
| 2603 | |||
| 2604 | return p; | ||
| 2599 | } | 2605 | } |
| 2600 | 2606 | ||
| 2601 | again: | 2607 | again: |
| @@ -2743,7 +2749,7 @@ static inline void sched_submit_work(struct task_struct *tsk) | |||
| 2743 | blk_schedule_flush_plug(tsk); | 2749 | blk_schedule_flush_plug(tsk); |
| 2744 | } | 2750 | } |
| 2745 | 2751 | ||
| 2746 | asmlinkage void __sched schedule(void) | 2752 | asmlinkage __visible void __sched schedule(void) |
| 2747 | { | 2753 | { |
| 2748 | struct task_struct *tsk = current; | 2754 | struct task_struct *tsk = current; |
| 2749 | 2755 | ||
| @@ -2753,7 +2759,7 @@ asmlinkage void __sched schedule(void) | |||
| 2753 | EXPORT_SYMBOL(schedule); | 2759 | EXPORT_SYMBOL(schedule); |
| 2754 | 2760 | ||
| 2755 | #ifdef CONFIG_CONTEXT_TRACKING | 2761 | #ifdef CONFIG_CONTEXT_TRACKING |
| 2756 | asmlinkage void __sched schedule_user(void) | 2762 | asmlinkage __visible void __sched schedule_user(void) |
| 2757 | { | 2763 | { |
| 2758 | /* | 2764 | /* |
| 2759 | * If we come here after a random call to set_need_resched(), | 2765 | * If we come here after a random call to set_need_resched(), |
| @@ -2785,7 +2791,7 @@ void __sched schedule_preempt_disabled(void) | |||
| 2785 | * off of preempt_enable. Kernel preemptions off return from interrupt | 2791 | * off of preempt_enable. Kernel preemptions off return from interrupt |
| 2786 | * occur there and call schedule directly. | 2792 | * occur there and call schedule directly. |
| 2787 | */ | 2793 | */ |
| 2788 | asmlinkage void __sched notrace preempt_schedule(void) | 2794 | asmlinkage __visible void __sched notrace preempt_schedule(void) |
| 2789 | { | 2795 | { |
| 2790 | /* | 2796 | /* |
| 2791 | * If there is a non-zero preempt_count or interrupts are disabled, | 2797 | * If there is a non-zero preempt_count or interrupts are disabled, |
| @@ -2816,7 +2822,7 @@ EXPORT_SYMBOL(preempt_schedule); | |||
| 2816 | * Note, that this is called and return with irqs disabled. This will | 2822 | * Note, that this is called and return with irqs disabled. This will |
| 2817 | * protect us against recursive calling from irq. | 2823 | * protect us against recursive calling from irq. |
| 2818 | */ | 2824 | */ |
| 2819 | asmlinkage void __sched preempt_schedule_irq(void) | 2825 | asmlinkage __visible void __sched preempt_schedule_irq(void) |
| 2820 | { | 2826 | { |
| 2821 | enum ctx_state prev_state; | 2827 | enum ctx_state prev_state; |
| 2822 | 2828 | ||
| @@ -3127,6 +3133,7 @@ __setparam_dl(struct task_struct *p, const struct sched_attr *attr) | |||
| 3127 | dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime); | 3133 | dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime); |
| 3128 | dl_se->dl_throttled = 0; | 3134 | dl_se->dl_throttled = 0; |
| 3129 | dl_se->dl_new = 1; | 3135 | dl_se->dl_new = 1; |
| 3136 | dl_se->dl_yielded = 0; | ||
| 3130 | } | 3137 | } |
| 3131 | 3138 | ||
| 3132 | static void __setscheduler_params(struct task_struct *p, | 3139 | static void __setscheduler_params(struct task_struct *p, |
| @@ -3191,17 +3198,40 @@ __getparam_dl(struct task_struct *p, struct sched_attr *attr) | |||
| 3191 | * We ask for the deadline not being zero, and greater or equal | 3198 | * We ask for the deadline not being zero, and greater or equal |
| 3192 | * than the runtime, as well as the period of being zero or | 3199 | * than the runtime, as well as the period of being zero or |
| 3193 | * greater than deadline. Furthermore, we have to be sure that | 3200 | * greater than deadline. Furthermore, we have to be sure that |
| 3194 | * user parameters are above the internal resolution (1us); we | 3201 | * user parameters are above the internal resolution of 1us (we |
| 3195 | * check sched_runtime only since it is always the smaller one. | 3202 | * check sched_runtime only since it is always the smaller one) and |
| 3203 | * below 2^63 ns (we have to check both sched_deadline and | ||
| 3204 | * sched_period, as the latter can be zero). | ||
| 3196 | */ | 3205 | */ |
| 3197 | static bool | 3206 | static bool |
| 3198 | __checkparam_dl(const struct sched_attr *attr) | 3207 | __checkparam_dl(const struct sched_attr *attr) |
| 3199 | { | 3208 | { |
| 3200 | return attr && attr->sched_deadline != 0 && | 3209 | /* deadline != 0 */ |
| 3201 | (attr->sched_period == 0 || | 3210 | if (attr->sched_deadline == 0) |
| 3202 | (s64)(attr->sched_period - attr->sched_deadline) >= 0) && | 3211 | return false; |
| 3203 | (s64)(attr->sched_deadline - attr->sched_runtime ) >= 0 && | 3212 | |
| 3204 | attr->sched_runtime >= (2 << (DL_SCALE - 1)); | 3213 | /* |
| 3214 | * Since we truncate DL_SCALE bits, make sure we're at least | ||
| 3215 | * that big. | ||
| 3216 | */ | ||
| 3217 | if (attr->sched_runtime < (1ULL << DL_SCALE)) | ||
| 3218 | return false; | ||
| 3219 | |||
| 3220 | /* | ||
| 3221 | * Since we use the MSB for wrap-around and sign issues, make | ||
| 3222 | * sure it's not set (mind that period can be equal to zero). | ||
| 3223 | */ | ||
| 3224 | if (attr->sched_deadline & (1ULL << 63) || | ||
| 3225 | attr->sched_period & (1ULL << 63)) | ||
| 3226 | return false; | ||
| 3227 | |||
| 3228 | /* runtime <= deadline <= period (if period != 0) */ | ||
| 3229 | if ((attr->sched_period != 0 && | ||
| 3230 | attr->sched_period < attr->sched_deadline) || | ||
| 3231 | attr->sched_deadline < attr->sched_runtime) | ||
| 3232 | return false; | ||
| 3233 | |||
| 3234 | return true; | ||
| 3205 | } | 3235 | } |
| 3206 | 3236 | ||
| 3207 | /* | 3237 | /* |
| @@ -3642,6 +3672,7 @@ SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param) | |||
| 3642 | * sys_sched_setattr - same as above, but with extended sched_attr | 3672 | * sys_sched_setattr - same as above, but with extended sched_attr |
| 3643 | * @pid: the pid in question. | 3673 | * @pid: the pid in question. |
| 3644 | * @uattr: structure containing the extended parameters. | 3674 | * @uattr: structure containing the extended parameters. |
| 3675 | * @flags: for future extension. | ||
| 3645 | */ | 3676 | */ |
| 3646 | SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, | 3677 | SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, |
| 3647 | unsigned int, flags) | 3678 | unsigned int, flags) |
| @@ -3653,8 +3684,12 @@ SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, | |||
| 3653 | if (!uattr || pid < 0 || flags) | 3684 | if (!uattr || pid < 0 || flags) |
| 3654 | return -EINVAL; | 3685 | return -EINVAL; |
| 3655 | 3686 | ||
| 3656 | if (sched_copy_attr(uattr, &attr)) | 3687 | retval = sched_copy_attr(uattr, &attr); |
| 3657 | return -EFAULT; | 3688 | if (retval) |
| 3689 | return retval; | ||
| 3690 | |||
| 3691 | if (attr.sched_policy < 0) | ||
| 3692 | return -EINVAL; | ||
| 3658 | 3693 | ||
| 3659 | rcu_read_lock(); | 3694 | rcu_read_lock(); |
| 3660 | retval = -ESRCH; | 3695 | retval = -ESRCH; |
| @@ -3704,7 +3739,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) | |||
| 3704 | */ | 3739 | */ |
| 3705 | SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) | 3740 | SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) |
| 3706 | { | 3741 | { |
| 3707 | struct sched_param lp; | 3742 | struct sched_param lp = { .sched_priority = 0 }; |
| 3708 | struct task_struct *p; | 3743 | struct task_struct *p; |
| 3709 | int retval; | 3744 | int retval; |
| 3710 | 3745 | ||
| @@ -3721,11 +3756,8 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) | |||
| 3721 | if (retval) | 3756 | if (retval) |
| 3722 | goto out_unlock; | 3757 | goto out_unlock; |
| 3723 | 3758 | ||
| 3724 | if (task_has_dl_policy(p)) { | 3759 | if (task_has_rt_policy(p)) |
| 3725 | retval = -EINVAL; | 3760 | lp.sched_priority = p->rt_priority; |
| 3726 | goto out_unlock; | ||
| 3727 | } | ||
| 3728 | lp.sched_priority = p->rt_priority; | ||
| 3729 | rcu_read_unlock(); | 3761 | rcu_read_unlock(); |
| 3730 | 3762 | ||
| 3731 | /* | 3763 | /* |
| @@ -3786,6 +3818,7 @@ err_size: | |||
| 3786 | * @pid: the pid in question. | 3818 | * @pid: the pid in question. |
| 3787 | * @uattr: structure containing the extended parameters. | 3819 | * @uattr: structure containing the extended parameters. |
| 3788 | * @size: sizeof(attr) for fwd/bwd comp. | 3820 | * @size: sizeof(attr) for fwd/bwd comp. |
| 3821 | * @flags: for future extension. | ||
| 3789 | */ | 3822 | */ |
| 3790 | SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, | 3823 | SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, |
| 3791 | unsigned int, size, unsigned int, flags) | 3824 | unsigned int, size, unsigned int, flags) |
| @@ -5046,7 +5079,6 @@ static int sched_cpu_active(struct notifier_block *nfb, | |||
| 5046 | unsigned long action, void *hcpu) | 5079 | unsigned long action, void *hcpu) |
| 5047 | { | 5080 | { |
| 5048 | switch (action & ~CPU_TASKS_FROZEN) { | 5081 | switch (action & ~CPU_TASKS_FROZEN) { |
| 5049 | case CPU_STARTING: | ||
| 5050 | case CPU_DOWN_FAILED: | 5082 | case CPU_DOWN_FAILED: |
| 5051 | set_cpu_active((long)hcpu, true); | 5083 | set_cpu_active((long)hcpu, true); |
| 5052 | return NOTIFY_OK; | 5084 | return NOTIFY_OK; |
| @@ -6020,6 +6052,8 @@ sd_numa_init(struct sched_domain_topology_level *tl, int cpu) | |||
| 6020 | , | 6052 | , |
| 6021 | .last_balance = jiffies, | 6053 | .last_balance = jiffies, |
| 6022 | .balance_interval = sd_weight, | 6054 | .balance_interval = sd_weight, |
| 6055 | .max_newidle_lb_cost = 0, | ||
| 6056 | .next_decay_max_lb_cost = jiffies, | ||
| 6023 | }; | 6057 | }; |
| 6024 | SD_INIT_NAME(sd, NUMA); | 6058 | SD_INIT_NAME(sd, NUMA); |
| 6025 | sd->private = &tl->data; | 6059 | sd->private = &tl->data; |
