Instead of converting the time on the first loop, the same if (end_time) can be shared. Simplify the loop by taking time conversion out. Also prepare the ground for converting poll() restart_block timeout into ktime_t - that's the only user that leaves it in timespec. The conversion is needed to introduce an API for ptrace() to get a timeout from restart_block. Signed-off-by: Dmitry Safonov <dima@xxxxxxxxxx> --- fs/eventpoll.c | 4 ++-- fs/select.c | 38 ++++++++++++-------------------------- include/linux/poll.h | 2 +- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index d7f1f5011fac..d5120fc49a39 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1836,9 +1836,9 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, if (timeout > 0) { struct timespec64 end_time = ep_set_mstimeout(timeout); - slack = select_estimate_accuracy(&end_time); + expires = timespec64_to_ktime(end_time); to = &expires; - *to = timespec64_to_ktime(end_time); + slack = select_estimate_accuracy(expires); } else if (timeout == 0) { /* * Avoid the unnecessary trip to the wait queue loop, if the diff --git a/fs/select.c b/fs/select.c index 2477c202631e..458f2a944318 100644 --- a/fs/select.c +++ b/fs/select.c @@ -66,7 +66,7 @@ static long __estimate_accuracy(ktime_t slack) return slack; } -u64 select_estimate_accuracy(struct timespec64 *timeout) +u64 select_estimate_accuracy(ktime_t timeout) { ktime_t now, slack; @@ -77,7 +77,7 @@ u64 select_estimate_accuracy(struct timespec64 *timeout) return 0; now = ktime_get(); - slack = now - timespec64_to_ktime(*timeout); + slack = now - timeout; slack = __estimate_accuracy(slack); if (slack < current->timer_slack_ns) @@ -490,8 +490,11 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) timed_out = 1; } - if (end_time && !timed_out) - slack = select_estimate_accuracy(end_time); + if (end_time && !timed_out) { + expire = timespec64_to_ktime(*end_time); + to = &expire; + slack = select_estimate_accuracy(expire); + } retval = 0; for (;;) { @@ -582,16 +585,6 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) } busy_flag = 0; - /* - * If this is the first loop and we have a timeout - * given, then we convert to ktime_t and set the to - * pointer to the expiry value. - */ - if (end_time && !to) { - expire = timespec64_to_ktime(*end_time); - to = &expire; - } - if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE, to, slack)) timed_out = 1; @@ -876,8 +869,11 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait, timed_out = 1; } - if (end_time && !timed_out) - slack = select_estimate_accuracy(end_time); + if (end_time && !timed_out) { + expire = timespec64_to_ktime(*end_time); + to = &expire; + slack = select_estimate_accuracy(expire); + } for (;;) { struct poll_list *walk; @@ -930,16 +926,6 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait, } busy_flag = 0; - /* - * If this is the first loop and we have a timeout - * given, then we convert to ktime_t and set the to - * pointer to the expiry value. - */ - if (end_time && !to) { - expire = timespec64_to_ktime(*end_time); - to = &expire; - } - if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack)) timed_out = 1; } diff --git a/include/linux/poll.h b/include/linux/poll.h index 1cdc32b1f1b0..d0f21eb19257 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -112,7 +112,7 @@ struct poll_wqueues { extern void poll_initwait(struct poll_wqueues *pwq); extern void poll_freewait(struct poll_wqueues *pwq); -extern u64 select_estimate_accuracy(struct timespec64 *tv); +extern u64 select_estimate_accuracy(ktime_t timeout); #define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1) -- 2.23.0