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 268a45ea238c..0a7251678982 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2192,7 +2192,7 @@ static inline void post_schedule(struct rq *rq)   * schedule_tail - first thing a freshly forked thread must call.   * @prev: the thread we just switched away from.   */ -asmlinkage void schedule_tail(struct task_struct *prev) +asmlinkage __visible void schedule_tail(struct task_struct *prev)  	__releases(rq->lock)  {  	struct rq *rq = this_rq(); @@ -2592,8 +2592,14 @@ pick_next_task(struct rq *rq, struct task_struct *prev)  	if (likely(prev->sched_class == class &&  		   rq->nr_running == rq->cfs.h_nr_running)) {  		p = fair_sched_class.pick_next_task(rq, prev); -		if (likely(p && p != RETRY_TASK)) -			return p; +		if (unlikely(p == RETRY_TASK)) +			goto again; + +		/* assumes fair_sched_class->next == idle_sched_class */ +		if (unlikely(!p)) +			p = idle_sched_class.pick_next_task(rq, prev); + +		return p;  	}  again: @@ -2741,7 +2747,7 @@ static inline void sched_submit_work(struct task_struct *tsk)  		blk_schedule_flush_plug(tsk);  } -asmlinkage void __sched schedule(void) +asmlinkage __visible void __sched schedule(void)  {  	struct task_struct *tsk = current; @@ -2751,7 +2757,7 @@ asmlinkage void __sched schedule(void)  EXPORT_SYMBOL(schedule);  #ifdef CONFIG_CONTEXT_TRACKING -asmlinkage void __sched schedule_user(void) +asmlinkage __visible void __sched schedule_user(void)  {  	/*  	 * If we come here after a random call to set_need_resched(), @@ -2783,7 +2789,7 @@ void __sched schedule_preempt_disabled(void)   * off of preempt_enable. Kernel preemptions off return from interrupt   * occur there and call schedule directly.   */ -asmlinkage void __sched notrace preempt_schedule(void) +asmlinkage __visible void __sched notrace preempt_schedule(void)  {  	/*  	 * If there is a non-zero preempt_count or interrupts are disabled, @@ -2813,7 +2819,7 @@ EXPORT_SYMBOL(preempt_schedule);   * Note, that this is called and return with irqs disabled. This will   * protect us against recursive calling from irq.   */ -asmlinkage void __sched preempt_schedule_irq(void) +asmlinkage __visible void __sched preempt_schedule_irq(void)  {  	enum ctx_state prev_state; @@ -3124,6 +3130,7 @@ __setparam_dl(struct task_struct *p, const struct sched_attr *attr)  	dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime);  	dl_se->dl_throttled = 0;  	dl_se->dl_new = 1; +	dl_se->dl_yielded = 0;  }  static void __setscheduler_params(struct task_struct *p, @@ -3188,17 +3195,40 @@ __getparam_dl(struct task_struct *p, struct sched_attr *attr)   * We ask for the deadline not being zero, and greater or equal   * than the runtime, as well as the period of being zero or   * greater than deadline. Furthermore, we have to be sure that - * user parameters are above the internal resolution (1us); we - * check sched_runtime only since it is always the smaller one. + * user parameters are above the internal resolution of 1us (we + * check sched_runtime only since it is always the smaller one) and + * below 2^63 ns (we have to check both sched_deadline and + * sched_period, as the latter can be zero).   */  static bool  __checkparam_dl(const struct sched_attr *attr)  { -	return attr && attr->sched_deadline != 0 && -		(attr->sched_period == 0 || -		(s64)(attr->sched_period   - attr->sched_deadline) >= 0) && -		(s64)(attr->sched_deadline - attr->sched_runtime ) >= 0  && -		attr->sched_runtime >= (2 << (DL_SCALE - 1)); +	/* deadline != 0 */ +	if (attr->sched_deadline == 0) +		return false; + +	/* +	 * Since we truncate DL_SCALE bits, make sure we're at least +	 * that big. +	 */ +	if (attr->sched_runtime < (1ULL << DL_SCALE)) +		return false; + +	/* +	 * Since we use the MSB for wrap-around and sign issues, make +	 * sure it's not set (mind that period can be equal to zero). +	 */ +	if (attr->sched_deadline & (1ULL << 63) || +	    attr->sched_period & (1ULL << 63)) +		return false; + +	/* runtime <= deadline <= period (if period != 0) */ +	if ((attr->sched_period != 0 && +	     attr->sched_period < attr->sched_deadline) || +	    attr->sched_deadline < attr->sched_runtime) +		return false; + +	return true;  }  /* @@ -3639,6 +3669,7 @@ SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param)   * sys_sched_setattr - same as above, but with extended sched_attr   * @pid: the pid in question.   * @uattr: structure containing the extended parameters. + * @flags: for future extension.   */  SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr,  			       unsigned int, flags) @@ -3650,8 +3681,12 @@ SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr,  	if (!uattr || pid < 0 || flags)  		return -EINVAL; -	if (sched_copy_attr(uattr, &attr)) -		return -EFAULT; +	retval = sched_copy_attr(uattr, &attr); +	if (retval) +		return retval; + +	if (attr.sched_policy < 0) +		return -EINVAL;  	rcu_read_lock();  	retval = -ESRCH; @@ -3701,7 +3736,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid)   */  SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)  { -	struct sched_param lp; +	struct sched_param lp = { .sched_priority = 0 };  	struct task_struct *p;  	int retval; @@ -3718,11 +3753,8 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)  	if (retval)  		goto out_unlock; -	if (task_has_dl_policy(p)) { -		retval = -EINVAL; -		goto out_unlock; -	} -	lp.sched_priority = p->rt_priority; +	if (task_has_rt_policy(p)) +		lp.sched_priority = p->rt_priority;  	rcu_read_unlock();  	/* @@ -3783,6 +3815,7 @@ err_size:   * @pid: the pid in question.   * @uattr: structure containing the extended parameters.   * @size: sizeof(attr) for fwd/bwd comp. + * @flags: for future extension.   */  SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,  		unsigned int, size, unsigned int, flags) @@ -5043,7 +5076,6 @@ static int sched_cpu_active(struct notifier_block *nfb,  				      unsigned long action, void *hcpu)  {  	switch (action & ~CPU_TASKS_FROZEN) { -	case CPU_STARTING:  	case CPU_DOWN_FAILED:  		set_cpu_active((long)hcpu, true);  		return NOTIFY_OK; @@ -6017,6 +6049,8 @@ sd_numa_init(struct sched_domain_topology_level *tl, int cpu)  					,  		.last_balance		= jiffies,  		.balance_interval	= sd_weight, +		.max_newidle_lb_cost	= 0, +		.next_decay_max_lb_cost	= jiffies,  	};  	SD_INIT_NAME(sd, NUMA);  	sd->private = &tl->data; | 

