Skip to content

Commit 2b1ecc3

Browse files
KAGA-KOKOIngo Molnar
authored andcommitted
signals: Use hrtimer for sigtimedwait()
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]>
1 parent 177ec0a commit 2b1ecc3

File tree

1 file changed

+10
-14
lines changed

1 file changed

+10
-14
lines changed

kernel/signal.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,23 +2751,18 @@ int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from)
27512751
* @ts: upper bound on process time suspension
27522752
*/
27532753
int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
2754-
const struct timespec *ts)
2754+
const struct timespec *ts)
27552755
{
2756+
ktime_t *to = NULL, timeout = { .tv64 = KTIME_MAX };
27562757
struct task_struct *tsk = current;
2757-
long timeout = MAX_SCHEDULE_TIMEOUT;
27582758
sigset_t mask = *which;
2759-
int sig;
2759+
int sig, ret = 0;
27602760

27612761
if (ts) {
27622762
if (!timespec_valid(ts))
27632763
return -EINVAL;
2764-
timeout = timespec_to_jiffies(ts);
2765-
/*
2766-
* We can be close to the next tick, add another one
2767-
* to ensure we will wait at least the time asked for.
2768-
*/
2769-
if (ts->tv_sec || ts->tv_nsec)
2770-
timeout++;
2764+
timeout = timespec_to_ktime(*ts);
2765+
to = &timeout;
27712766
}
27722767

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

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

2793-
timeout = freezable_schedule_timeout_interruptible(timeout);
2794-
2788+
__set_current_state(TASK_INTERRUPTIBLE);
2789+
ret = freezable_schedule_hrtimeout_range(to, tsk->timer_slack_ns,
2790+
HRTIMER_MODE_REL);
27952791
spin_lock_irq(&tsk->sighand->siglock);
27962792
__set_task_blocked(tsk, &tsk->real_blocked);
27972793
sigemptyset(&tsk->real_blocked);
@@ -2801,7 +2797,7 @@ int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
28012797

28022798
if (sig)
28032799
return sig;
2804-
return timeout ? -EINTR : -EAGAIN;
2800+
return ret ? -EINTR : -EAGAIN;
28052801
}
28062802

28072803
/**

0 commit comments

Comments
 (0)