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 <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Arjan van de Ven <[email protected]>
Cc: Chris Mason <[email protected]>
Cc: Cyril Hrubis <[email protected]>
Cc: George Spelvin <[email protected]>
Cc: Josh Triplett <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Paul McKenney <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Rik van Riel <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • 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.