sched: fix mysql+oltp regression
[safe/jmp/linux-2.6] / kernel / posix-timers.c
index 36d563f..9a21681 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/mutex.h>
 
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
 #include <linux/list.h>
 #include <linux/init.h>
 #include <linux/compiler.h>
@@ -256,8 +255,9 @@ static void schedule_next_timer(struct k_itimer *timr)
        if (timr->it.real.interval.tv64 == 0)
                return;
 
-       timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(),
-                                           timr->it.real.interval);
+       timr->it_overrun += (unsigned int) hrtimer_forward(timer,
+                                               timer->base->get_time(),
+                                               timr->it.real.interval);
 
        timr->it_overrun_last = timr->it_overrun;
        timr->it_overrun = -1;
@@ -310,8 +310,7 @@ int posix_timer_event(struct k_itimer *timr,int si_private)
 
        if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
                struct task_struct *leader;
-               int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
-                                       timr->it_process);
+               int ret = send_sigqueue(timr->sigq, timr->it_process, 0);
 
                if (likely(ret >= 0))
                        return ret;
@@ -322,8 +321,7 @@ int posix_timer_event(struct k_itimer *timr,int si_private)
                timr->it_process = leader;
        }
 
-       return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
-                                  timr->it_process);
+       return send_sigqueue(timr->sigq, timr->it_process, 1);
 }
 EXPORT_SYMBOL_GPL(posix_timer_event);
 
@@ -386,7 +384,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
                                        now = ktime_add(now, kj);
                        }
 #endif
-                       timr->it_overrun +=
+                       timr->it_overrun += (unsigned int)
                                hrtimer_forward(timer, now,
                                                timr->it.real.interval);
                        ret = HRTIMER_RESTART;
@@ -403,7 +401,7 @@ static struct task_struct * good_sigevent(sigevent_t * event)
        struct task_struct *rtn = current->group_leader;
 
        if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
-               (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
+               (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) ||
                 !same_thread_group(rtn, current) ||
                 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
                return NULL;
@@ -451,9 +449,6 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
                spin_unlock_irqrestore(&idr_lock, flags);
        }
        sigqueue_free(tmr->sigq);
-       if (unlikely(tmr->it_process) &&
-           tmr->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
-               put_task_struct(tmr->it_process);
        kmem_cache_free(posix_timers_cache, tmr);
 }
 
@@ -662,7 +657,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
         */
        if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
            (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
-               timr->it_overrun += hrtimer_forward(timer, now, iv);
+               timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
 
        remaining = ktime_sub(timer->expires, now);
        /* Return 0 only, when the timer is expired and not pending */
@@ -766,9 +761,11 @@ common_timer_set(struct k_itimer *timr, int flags,
        /* SIGEV_NONE timers are not queued ! See common_timer_get */
        if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
                /* Setup correct expiry time for relative timers */
-               if (mode == HRTIMER_MODE_REL)
-                       timer->expires = ktime_add(timer->expires,
-                                                  timer->base->get_time());
+               if (mode == HRTIMER_MODE_REL) {
+                       timer->expires =
+                               ktime_add_safe(timer->expires,
+                                              timer->base->get_time());
+               }
                return 0;
        }
 
@@ -856,11 +853,10 @@ retry_delete:
         * This keeps any tasks waiting on the spin lock from thinking
         * they got something (see the lock code above).
         */
-       if (timer->it_process) {
-               if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
-                       put_task_struct(timer->it_process);
-               timer->it_process = NULL;
-       }
+       if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
+               put_task_struct(timer->it_process);
+       timer->it_process = NULL;
+
        unlock_timer(timer, flags);
        release_posix_timer(timer, IT_ID_SET);
        return 0;
@@ -885,11 +881,10 @@ retry_delete:
         * This keeps any tasks waiting on the spin lock from thinking
         * they got something (see the lock code above).
         */
-       if (timer->it_process) {
-               if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
-                       put_task_struct(timer->it_process);
-               timer->it_process = NULL;
-       }
+       if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
+               put_task_struct(timer->it_process);
+       timer->it_process = NULL;
+
        unlock_timer(timer, flags);
        release_posix_timer(timer, IT_ID_SET);
 }
@@ -981,20 +976,9 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp)
 static int common_nsleep(const clockid_t which_clock, int flags,
                         struct timespec *tsave, struct timespec __user *rmtp)
 {
-       struct timespec rmt;
-       int ret;
-
-       ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
-                               flags & TIMER_ABSTIME ?
-                               HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
-                               which_clock);
-
-       if (ret && rmtp) {
-               if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
-                       return -EFAULT;
-       }
-
-       return ret;
+       return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
+                                HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
+                                which_clock);
 }
 
 asmlinkage long