lkml.org 
[lkml]   [2011]   [Apr]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v2 1/6] signal: sys_rt_sigtimedwait: simplify the timeout logic
    No functional changes, cleanup compat_sys_rt_sigtimedwait() and
    sys_rt_sigtimedwait().

    Calculate the timeout before we take ->siglock, this simplifies and
    lessens the code. Use timespec_valid() to check the timespec.

    Signed-off-by: Oleg Nesterov <oleg@redhat.com>
    Acked-by: Tejun Heo <tj@kernel.org>
    Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com>
    ---

    kernel/signal.c | 46 ++++++++++++++++++++--------------------------
    kernel/compat.c | 38 ++++++++++++++++----------------------
    2 files changed, 36 insertions(+), 48 deletions(-)

    --- sigprocmask/kernel/signal.c~1_sigtimedwait_to 2011-04-26 19:52:30.000000000 +0200
    +++ sigprocmask/kernel/signal.c 2011-04-26 19:53:19.000000000 +0200
    @@ -2327,7 +2327,7 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const s
    sigset_t these;
    struct timespec ts;
    siginfo_t info;
    - long timeout = 0;
    + long timeout;

    /* XXX: Don't preclude handling different sized sigset_t's. */
    if (sigsetsize != sizeof(sigset_t))
    @@ -2343,41 +2343,35 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const s
    sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
    signotset(&these);

    + timeout = MAX_SCHEDULE_TIMEOUT;
    if (uts) {
    if (copy_from_user(&ts, uts, sizeof(ts)))
    return -EFAULT;
    - if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
    - || ts.tv_sec < 0)
    + if (!timespec_valid(&ts))
    return -EINVAL;
    + timeout = timespec_to_jiffies(&ts) + (ts.tv_sec || ts.tv_nsec);
    }

    spin_lock_irq(&current->sighand->siglock);
    sig = dequeue_signal(current, &these, &info);
    - if (!sig) {
    - timeout = MAX_SCHEDULE_TIMEOUT;
    - if (uts)
    - timeout = (timespec_to_jiffies(&ts)
    - + (ts.tv_sec || ts.tv_nsec));
    -
    - if (timeout) {
    - /*
    - * None ready -- temporarily unblock those we're
    - * interested while we are sleeping in so that we'll
    - * be awakened when they arrive.
    - */
    - current->real_blocked = current->blocked;
    - sigandsets(&current->blocked, &current->blocked, &these);
    - recalc_sigpending();
    - spin_unlock_irq(&current->sighand->siglock);
    + if (!sig && timeout) {
    + /*
    + * None ready -- temporarily unblock those we're
    + * interested while we are sleeping in so that we'll
    + * be awakened when they arrive.
    + */
    + current->real_blocked = current->blocked;
    + sigandsets(&current->blocked, &current->blocked, &these);
    + recalc_sigpending();
    + spin_unlock_irq(&current->sighand->siglock);

    - timeout = schedule_timeout_interruptible(timeout);
    + timeout = schedule_timeout_interruptible(timeout);

    - spin_lock_irq(&current->sighand->siglock);
    - sig = dequeue_signal(current, &these, &info);
    - current->blocked = current->real_blocked;
    - siginitset(&current->real_blocked, 0);
    - recalc_sigpending();
    - }
    + spin_lock_irq(&current->sighand->siglock);
    + sig = dequeue_signal(current, &these, &info);
    + current->blocked = current->real_blocked;
    + siginitset(&current->real_blocked, 0);
    + recalc_sigpending();
    }
    spin_unlock_irq(&current->sighand->siglock);

    --- sigprocmask/kernel/compat.c~1_sigtimedwait_to 2011-04-26 19:52:30.000000000 +0200
    +++ sigprocmask/kernel/compat.c 2011-04-26 19:53:19.000000000 +0200
    @@ -893,7 +893,7 @@ compat_sys_rt_sigtimedwait (compat_sigse
    int sig;
    struct timespec t;
    siginfo_t info;
    - long ret, timeout = 0;
    + long ret, timeout;

    if (sigsetsize != sizeof(sigset_t))
    return -EINVAL;
    @@ -904,36 +904,30 @@ compat_sys_rt_sigtimedwait (compat_sigse
    sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP));
    signotset(&s);

    + timeout = MAX_SCHEDULE_TIMEOUT;
    if (uts) {
    if (get_compat_timespec (&t, uts))
    return -EFAULT;
    - if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0
    - || t.tv_sec < 0)
    + if (!timespec_valid(&t))
    return -EINVAL;
    + timeout = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
    }

    spin_lock_irq(&current->sighand->siglock);
    sig = dequeue_signal(current, &s, &info);
    - if (!sig) {
    - timeout = MAX_SCHEDULE_TIMEOUT;
    - if (uts)
    - timeout = timespec_to_jiffies(&t)
    - +(t.tv_sec || t.tv_nsec);
    - if (timeout) {
    - current->real_blocked = current->blocked;
    - sigandsets(&current->blocked, &current->blocked, &s);
    -
    - recalc_sigpending();
    - spin_unlock_irq(&current->sighand->siglock);
    + if (!sig && timeout) {
    + current->real_blocked = current->blocked;
    + sigandsets(&current->blocked, &current->blocked, &s);
    + recalc_sigpending();
    + spin_unlock_irq(&current->sighand->siglock);

    - timeout = schedule_timeout_interruptible(timeout);
    + timeout = schedule_timeout_interruptible(timeout);

    - spin_lock_irq(&current->sighand->siglock);
    - sig = dequeue_signal(current, &s, &info);
    - current->blocked = current->real_blocked;
    - siginitset(&current->real_blocked, 0);
    - recalc_sigpending();
    - }
    + spin_lock_irq(&current->sighand->siglock);
    + sig = dequeue_signal(current, &s, &info);
    + current->blocked = current->real_blocked;
    + siginitset(&current->real_blocked, 0);
    + recalc_sigpending();
    }
    spin_unlock_irq(&current->sighand->siglock);

    @@ -943,7 +937,7 @@ compat_sys_rt_sigtimedwait (compat_sigse
    if (copy_siginfo_to_user32(uinfo, &info))
    ret = -EFAULT;
    }
    - }else {
    + } else {
    ret = timeout?-EINTR:-EAGAIN;
    }
    return ret;


    \
     
     \ /
      Last update: 2011-04-26 21:53    [W:0.037 / U:0.120 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site