Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe0faa00 authored by Oleg Nesterov's avatar Oleg Nesterov
Browse files

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: default avatarOleg Nesterov <oleg@redhat.com>
Acked-by: default avatarTejun Heo <tj@kernel.org>
Reviewed-by: default avatarMatt Fleming <matt.fleming@linux.intel.com>
parent bb7efee2
Loading
Loading
Loading
Loading
+18 −24
Original line number Diff line number Diff line
@@ -893,7 +893,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
	int sig;
	struct timespec t;
	siginfo_t info;
	long ret, timeout = 0;
	long ret, timeout;

	if (sigsetsize != sizeof(sigset_t))
		return -EINVAL;
@@ -904,25 +904,20 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
	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) {
	if (!sig && timeout) {
		current->real_blocked = current->blocked;
		sigandsets(&current->blocked, &current->blocked, &s);

		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);

@@ -934,7 +929,6 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
		siginitset(&current->real_blocked, 0);
		recalc_sigpending();
	}
	}
	spin_unlock_irq(&current->sighand->siglock);

	if (sig) {
+21 −27
Original line number Diff line number Diff line
@@ -2519,7 +2519,7 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese,
	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))
@@ -2535,23 +2535,18 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese,
	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) {
	if (!sig && timeout) {
		/*
		 * None ready -- temporarily unblock those we're
		 * interested while we are sleeping in so that we'll
@@ -2570,7 +2565,6 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese,
		siginitset(&current->real_blocked, 0);
		recalc_sigpending();
	}
	}
	spin_unlock_irq(&current->sighand->siglock);

	if (sig) {