Skip to content

Commit

Permalink
signals: Use hrtimer for sigtimedwait()
Browse files Browse the repository at this point in the history
We've converted most timeout related syscalls to hrtimers, but
sigtimedwait() did not get this treatment.

Convert it so we get a reasonable accuracy and remove the
user space exposure to the timer wheel properties.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Chris Mason <clm@fb.com>
Cc: Cyril Hrubis <chrubis@suse.cz>
Cc: George Spelvin <linux@sciencehorizons.net>
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160704094341.787164909@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
KAGA-KOKO authored and Ingo Molnar committed Jul 7, 2016
1 parent 177ec0a commit 2b1ecc3
Showing 1 changed file with 10 additions and 14 deletions.
24 changes: 10 additions & 14 deletions kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2751,23 +2751,18 @@ int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from)
* @ts: upper bound on process time suspension
*/
int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
const struct timespec *ts)
const struct timespec *ts)
{
ktime_t *to = NULL, timeout = { .tv64 = KTIME_MAX };
struct task_struct *tsk = current;
long timeout = MAX_SCHEDULE_TIMEOUT;
sigset_t mask = *which;
int sig;
int sig, ret = 0;

if (ts) {
if (!timespec_valid(ts))
return -EINVAL;
timeout = timespec_to_jiffies(ts);
/*
* We can be close to the next tick, add another one
* to ensure we will wait at least the time asked for.
*/
if (ts->tv_sec || ts->tv_nsec)
timeout++;
timeout = timespec_to_ktime(*ts);
to = &timeout;
}

/*
Expand All @@ -2778,7 +2773,7 @@ int do_sigtimedwait(const sigset_t *which, siginfo_t *info,

spin_lock_irq(&tsk->sighand->siglock);
sig = dequeue_signal(tsk, &mask, info);
if (!sig && timeout) {
if (!sig && timeout.tv64) {
/*
* None ready, temporarily unblock those we're interested
* while we are sleeping in so that we'll be awakened when
Expand All @@ -2790,8 +2785,9 @@ int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
recalc_sigpending();
spin_unlock_irq(&tsk->sighand->siglock);

timeout = freezable_schedule_timeout_interruptible(timeout);

__set_current_state(TASK_INTERRUPTIBLE);
ret = freezable_schedule_hrtimeout_range(to, tsk->timer_slack_ns,
HRTIMER_MODE_REL);
spin_lock_irq(&tsk->sighand->siglock);
__set_task_blocked(tsk, &tsk->real_blocked);
sigemptyset(&tsk->real_blocked);
Expand All @@ -2801,7 +2797,7 @@ int do_sigtimedwait(const sigset_t *which, siginfo_t *info,

if (sig)
return sig;
return timeout ? -EINTR : -EAGAIN;
return ret ? -EINTR : -EAGAIN;
}

/**
Expand Down

0 comments on commit 2b1ecc3

Please sign in to comment.