diff options
Diffstat (limited to 'kernel/sched.c')
| -rw-r--r-- | kernel/sched.c | 28 | 
1 files changed, 21 insertions, 7 deletions
| diff --git a/kernel/sched.c b/kernel/sched.c index 9bb7489ee645..0dc3158667a2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2906,6 +2906,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,   * @q: the waitqueue   * @mode: which threads   * @nr_exclusive: how many wake-one or wake-many threads to wake up + * @key: is directly passed to the wakeup function   */  void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode,  				int nr_exclusive, void *key) @@ -2928,7 +2929,7 @@ void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode)  }  /** - * __wake_up - sync- wake up threads blocked on a waitqueue. + * __wake_up_sync - wake up threads blocked on a waitqueue.   * @q: the waitqueue   * @mode: which threads   * @nr_exclusive: how many wake-one or wake-many threads to wake up @@ -3223,6 +3224,19 @@ out_unlock:  EXPORT_SYMBOL(set_user_nice); +/* + * can_nice - check if a task can reduce its nice value + * @p: task + * @nice: nice value + */ +int can_nice(const task_t *p, const int nice) +{ +	/* convert nice value [19,-20] to rlimit style value [0,39] */ +	int nice_rlim = 19 - nice; +	return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || +		capable(CAP_SYS_NICE)); +} +  #ifdef __ARCH_WANT_SYS_NICE  /* @@ -3242,12 +3256,8 @@ asmlinkage long sys_nice(int increment)  	 * We don't have to worry. Conceptually one call occurs first  	 * and we have a single winner.  	 */ -	if (increment < 0) { -		if (!capable(CAP_SYS_NICE)) -			return -EPERM; -		if (increment < -40) -			increment = -40; -	} +	if (increment < -40) +		increment = -40;  	if (increment > 40)  		increment = 40; @@ -3257,6 +3267,9 @@ asmlinkage long sys_nice(int increment)  	if (nice > 19)  		nice = 19; +	if (increment < 0 && !can_nice(current, nice)) +		return -EPERM; +  	retval = security_task_setnice(current, nice);  	if (retval)  		return retval; @@ -3372,6 +3385,7 @@ recheck:  		return -EINVAL;  	if ((policy == SCHED_FIFO || policy == SCHED_RR) && +	    param->sched_priority > p->signal->rlim[RLIMIT_RTPRIO].rlim_cur &&  	    !capable(CAP_SYS_NICE))  		return -EPERM;  	if ((current->euid != p->euid) && (current->euid != p->uid) && | 
