aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2011-04-27 15:24:19 -0400
committerOleg Nesterov <oleg@redhat.com>2011-04-28 07:01:38 -0400
commitfe0faa005d43bc44c357631d51c273806086caa4 (patch)
tree7977c5ec7c452ed3a0036747b8d8861b742c30b3 /kernel
parentbb7efee2ca63b08795ffb3cda96fc89d2e641b79 (diff)
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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/compat.c42
-rw-r--r--kernel/signal.c48
2 files changed, 39 insertions, 51 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 38b1d2c1cbe8..06cbb0619531 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -893,7 +893,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
893 int sig; 893 int sig;
894 struct timespec t; 894 struct timespec t;
895 siginfo_t info; 895 siginfo_t info;
896 long ret, timeout = 0; 896 long ret, timeout;
897 897
898 if (sigsetsize != sizeof(sigset_t)) 898 if (sigsetsize != sizeof(sigset_t))
899 return -EINVAL; 899 return -EINVAL;
@@ -904,36 +904,30 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
904 sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP)); 904 sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP));
905 signotset(&s); 905 signotset(&s);
906 906
907 timeout = MAX_SCHEDULE_TIMEOUT;
907 if (uts) { 908 if (uts) {
908 if (get_compat_timespec (&t, uts)) 909 if (get_compat_timespec (&t, uts))
909 return -EFAULT; 910 return -EFAULT;
910 if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 911 if (!timespec_valid(&t))
911 || t.tv_sec < 0)
912 return -EINVAL; 912 return -EINVAL;
913 timeout = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
913 } 914 }
914 915
915 spin_lock_irq(&current->sighand->siglock); 916 spin_lock_irq(&current->sighand->siglock);
916 sig = dequeue_signal(current, &s, &info); 917 sig = dequeue_signal(current, &s, &info);
917 if (!sig) { 918 if (!sig && timeout) {
918 timeout = MAX_SCHEDULE_TIMEOUT; 919 current->real_blocked = current->blocked;
919 if (uts) 920 sigandsets(&current->blocked, &current->blocked, &s);
920 timeout = timespec_to_jiffies(&t) 921 recalc_sigpending();
921 +(t.tv_sec || t.tv_nsec); 922 spin_unlock_irq(&current->sighand->siglock);
922 if (timeout) { 923
923 current->real_blocked = current->blocked; 924 timeout = schedule_timeout_interruptible(timeout);
924 sigandsets(&current->blocked, &current->blocked, &s); 925
925 926 spin_lock_irq(&current->sighand->siglock);
926 recalc_sigpending(); 927 sig = dequeue_signal(current, &s, &info);
927 spin_unlock_irq(&current->sighand->siglock); 928 current->blocked = current->real_blocked;
928 929 siginitset(&current->real_blocked, 0);
929 timeout = schedule_timeout_interruptible(timeout); 930 recalc_sigpending();
930
931 spin_lock_irq(&current->sighand->siglock);
932 sig = dequeue_signal(current, &s, &info);
933 current->blocked = current->real_blocked;
934 siginitset(&current->real_blocked, 0);
935 recalc_sigpending();
936 }
937 } 931 }
938 spin_unlock_irq(&current->sighand->siglock); 932 spin_unlock_irq(&current->sighand->siglock);
939 933
@@ -943,7 +937,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
943 if (copy_siginfo_to_user32(uinfo, &info)) 937 if (copy_siginfo_to_user32(uinfo, &info))
944 ret = -EFAULT; 938 ret = -EFAULT;
945 } 939 }
946 }else { 940 } else {
947 ret = timeout?-EINTR:-EAGAIN; 941 ret = timeout?-EINTR:-EAGAIN;
948 } 942 }
949 return ret; 943 return ret;
diff --git a/kernel/signal.c b/kernel/signal.c
index bb9200070ea0..c734619554f6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2519,7 +2519,7 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese,
2519 sigset_t these; 2519 sigset_t these;
2520 struct timespec ts; 2520 struct timespec ts;
2521 siginfo_t info; 2521 siginfo_t info;
2522 long timeout = 0; 2522 long timeout;
2523 2523
2524 /* XXX: Don't preclude handling different sized sigset_t's. */ 2524 /* XXX: Don't preclude handling different sized sigset_t's. */
2525 if (sigsetsize != sizeof(sigset_t)) 2525 if (sigsetsize != sizeof(sigset_t))
@@ -2535,41 +2535,35 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese,
2535 sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP)); 2535 sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
2536 signotset(&these); 2536 signotset(&these);
2537 2537
2538 timeout = MAX_SCHEDULE_TIMEOUT;
2538 if (uts) { 2539 if (uts) {
2539 if (copy_from_user(&ts, uts, sizeof(ts))) 2540 if (copy_from_user(&ts, uts, sizeof(ts)))
2540 return -EFAULT; 2541 return -EFAULT;
2541 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0 2542 if (!timespec_valid(&ts))
2542 || ts.tv_sec < 0)
2543 return -EINVAL; 2543 return -EINVAL;
2544 timeout = timespec_to_jiffies(&ts) + (ts.tv_sec || ts.tv_nsec);
2544 } 2545 }
2545 2546
2546 spin_lock_irq(&current->sighand->siglock); 2547 spin_lock_irq(&current->sighand->siglock);
2547 sig = dequeue_signal(current, &these, &info); 2548 sig = dequeue_signal(current, &these, &info);
2548 if (!sig) { 2549 if (!sig && timeout) {
2549 timeout = MAX_SCHEDULE_TIMEOUT; 2550 /*
2550 if (uts) 2551 * None ready -- temporarily unblock those we're
2551 timeout = (timespec_to_jiffies(&ts) 2552 * interested while we are sleeping in so that we'll
2552 + (ts.tv_sec || ts.tv_nsec)); 2553 * be awakened when they arrive.
2554 */
2555 current->real_blocked = current->blocked;
2556 sigandsets(&current->blocked, &current->blocked, &these);
2557 recalc_sigpending();
2558 spin_unlock_irq(&current->sighand->siglock);
2553 2559
2554 if (timeout) { 2560 timeout = schedule_timeout_interruptible(timeout);
2555 /* 2561
2556 * None ready -- temporarily unblock those we're 2562 spin_lock_irq(&current->sighand->siglock);
2557 * interested while we are sleeping in so that we'll 2563 sig = dequeue_signal(current, &these, &info);
2558 * be awakened when they arrive. 2564 current->blocked = current->real_blocked;
2559 */ 2565 siginitset(&current->real_blocked, 0);
2560 current->real_blocked = current->blocked; 2566 recalc_sigpending();
2561 sigandsets(&current->blocked, &current->blocked, &these);
2562 recalc_sigpending();
2563 spin_unlock_irq(&current->sighand->siglock);
2564
2565 timeout = schedule_timeout_interruptible(timeout);
2566
2567 spin_lock_irq(&current->sighand->siglock);
2568 sig = dequeue_signal(current, &these, &info);
2569 current->blocked = current->real_blocked;
2570 siginitset(&current->real_blocked, 0);
2571 recalc_sigpending();
2572 }
2573 } 2567 }
2574 spin_unlock_irq(&current->sighand->siglock); 2568 spin_unlock_irq(&current->sighand->siglock);
2575 2569