]> err.no Git - linux-2.6/blobdiff - kernel/sched.c
Merge /spare/repo/linux-2.6/
[linux-2.6] / kernel / sched.c
index 9bb7489ee64509eca180fe3cfe755db49b153702..deca041fc3645670055502888171811404d249f9 100644 (file)
@@ -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) &&
@@ -3741,19 +3755,22 @@ EXPORT_SYMBOL(cond_resched);
  */
 int cond_resched_lock(spinlock_t * lock)
 {
+       int ret = 0;
+
        if (need_lockbreak(lock)) {
                spin_unlock(lock);
                cpu_relax();
+               ret = 1;
                spin_lock(lock);
        }
        if (need_resched()) {
                _raw_spin_unlock(lock);
                preempt_enable_no_resched();
                __cond_resched();
+               ret = 1;
                spin_lock(lock);
-               return 1;
        }
-       return 0;
+       return ret;
 }
 
 EXPORT_SYMBOL(cond_resched_lock);
@@ -3797,7 +3814,7 @@ EXPORT_SYMBOL(yield);
  */
 void __sched io_schedule(void)
 {
-       struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id());
+       struct runqueue *rq = &per_cpu(runqueues, raw_smp_processor_id());
 
        atomic_inc(&rq->nr_iowait);
        schedule();
@@ -3808,7 +3825,7 @@ EXPORT_SYMBOL(io_schedule);
 
 long __sched io_schedule_timeout(long timeout)
 {
-       struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id());
+       struct runqueue *rq = &per_cpu(runqueues, raw_smp_processor_id());
        long ret;
 
        atomic_inc(&rq->nr_iowait);
@@ -4229,7 +4246,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *tsk)
 
        /* No more Mr. Nice Guy. */
        if (dest_cpu == NR_CPUS) {
-               tsk->cpus_allowed = cpuset_cpus_allowed(tsk);
+               cpus_setall(tsk->cpus_allowed);
                dest_cpu = any_online_cpu(tsk->cpus_allowed);
 
                /*