diff options
Diffstat (limited to 'kernel/sched/core.c')
| -rw-r--r-- | kernel/sched/core.c | 37 | 
1 files changed, 25 insertions, 12 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index b46131ef6aab..f5c6635b806c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1952,7 +1952,7 @@ static int dl_overflow(struct task_struct *p, int policy,  {  	struct dl_bw *dl_b = dl_bw_of(task_cpu(p)); -	u64 period = attr->sched_period; +	u64 period = attr->sched_period ?: attr->sched_deadline;  	u64 runtime = attr->sched_runtime;  	u64 new_bw = dl_policy(policy) ? to_ratio(period, runtime) : 0;  	int cpus, err = -1; @@ -3338,6 +3338,15 @@ recheck:  				return -EPERM;  		} +		 /* +		  * Can't set/change SCHED_DEADLINE policy at all for now +		  * (safest behavior); in the future we would like to allow +		  * unprivileged DL tasks to increase their relative deadline +		  * or reduce their runtime (both ways reducing utilization) +		  */ +		if (dl_policy(policy)) +			return -EPERM; +  		/*  		 * Treat SCHED_IDLE as nice 20. Only allow a switch to  		 * SCHED_NORMAL if the RLIMIT_NICE would normally permit it. @@ -3661,13 +3670,14 @@ SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param)   * @pid: the pid in question.   * @uattr: structure containing the extended parameters.   */ -SYSCALL_DEFINE2(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr) +SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, +			       unsigned int, flags)  {  	struct sched_attr attr;  	struct task_struct *p;  	int retval; -	if (!uattr || pid < 0) +	if (!uattr || pid < 0 || flags)  		return -EINVAL;  	if (sched_copy_attr(uattr, &attr)) @@ -3786,7 +3796,7 @@ static int sched_read_attr(struct sched_attr __user *uattr,  		attr->size = usize;  	} -	ret = copy_to_user(uattr, attr, usize); +	ret = copy_to_user(uattr, attr, attr->size);  	if (ret)  		return -EFAULT; @@ -3804,8 +3814,8 @@ err_size:   * @uattr: structure containing the extended parameters.   * @size: sizeof(attr) for fwd/bwd comp.   */ -SYSCALL_DEFINE3(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, -		unsigned int, size) +SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, +		unsigned int, size, unsigned int, flags)  {  	struct sched_attr attr = {  		.size = sizeof(struct sched_attr), @@ -3814,7 +3824,7 @@ SYSCALL_DEFINE3(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,  	int retval;  	if (!uattr || pid < 0 || size > PAGE_SIZE || -	    size < SCHED_ATTR_SIZE_VER0) +	    size < SCHED_ATTR_SIZE_VER0 || flags)  		return -EINVAL;  	rcu_read_lock(); @@ -7422,6 +7432,7 @@ static int sched_dl_global_constraints(void)  	u64 period = global_rt_period();  	u64 new_bw = to_ratio(period, runtime);  	int cpu, ret = 0; +	unsigned long flags;  	/*  	 * Here we want to check the bandwidth not being set to some @@ -7435,10 +7446,10 @@ static int sched_dl_global_constraints(void)  	for_each_possible_cpu(cpu) {  		struct dl_bw *dl_b = dl_bw_of(cpu); -		raw_spin_lock(&dl_b->lock); +		raw_spin_lock_irqsave(&dl_b->lock, flags);  		if (new_bw < dl_b->total_bw)  			ret = -EBUSY; -		raw_spin_unlock(&dl_b->lock); +		raw_spin_unlock_irqrestore(&dl_b->lock, flags);  		if (ret)  			break; @@ -7451,6 +7462,7 @@ static void sched_dl_do_global(void)  {  	u64 new_bw = -1;  	int cpu; +	unsigned long flags;  	def_dl_bandwidth.dl_period = global_rt_period();  	def_dl_bandwidth.dl_runtime = global_rt_runtime(); @@ -7464,9 +7476,9 @@ static void sched_dl_do_global(void)  	for_each_possible_cpu(cpu) {  		struct dl_bw *dl_b = dl_bw_of(cpu); -		raw_spin_lock(&dl_b->lock); +		raw_spin_lock_irqsave(&dl_b->lock, flags);  		dl_b->bw = new_bw; -		raw_spin_unlock(&dl_b->lock); +		raw_spin_unlock_irqrestore(&dl_b->lock, flags);  	}  } @@ -7475,7 +7487,8 @@ static int sched_rt_global_validate(void)  	if (sysctl_sched_rt_period <= 0)  		return -EINVAL; -	if (sysctl_sched_rt_runtime > sysctl_sched_rt_period) +	if ((sysctl_sched_rt_runtime != RUNTIME_INF) && +		(sysctl_sched_rt_runtime > sysctl_sched_rt_period))  		return -EINVAL;  	return 0;  | 
