Commit 415ce0ea authored by Jens Axboe's avatar Jens Axboe

io_uring/napi: fix timeout calculation

Not quite sure what __io_napi_adjust_timeout() was attemping to do, it's
adjusting both the NAPI timeout and the general overall timeout, and
calculating a value that is never used. The overall timeout is a super
set of the NAPI timeout, and doesn't need adjusting. The only thing we
really need to care about is that the NAPI timeout doesn't exceed the
overall timeout. If a user asked for a timeout of eg 5 usec and NAPI
timeout is 10 usec, then we should not spin for 10 usec.

While in there, sanitize the time checking a bit. If we have a negative
value in the passed in timeout, discard it. Round up the value as well,
so we don't end up with a NAPI timeout for the majority of the wait,
with only a tiny sleep value at the end.

Hence the only case we need to care about is if the NAPI timeout is
larger than the overall timeout. If it is, cap the NAPI timeout at what
the overall timeout is.

Cc: stable@vger.kernel.org
Fixes: 8d0c12a8 ("io-uring: add napi busy poll support")
Reported-by: default avatarLewis Baker <lewissbaker@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 5fc16fa5
...@@ -261,12 +261,14 @@ int io_unregister_napi(struct io_ring_ctx *ctx, void __user *arg) ...@@ -261,12 +261,14 @@ int io_unregister_napi(struct io_ring_ctx *ctx, void __user *arg)
} }
/* /*
* __io_napi_adjust_timeout() - Add napi id to the busy poll list * __io_napi_adjust_timeout() - adjust busy loop timeout
* @ctx: pointer to io-uring context structure * @ctx: pointer to io-uring context structure
* @iowq: pointer to io wait queue * @iowq: pointer to io wait queue
* @ts: pointer to timespec or NULL * @ts: pointer to timespec or NULL
* *
* Adjust the busy loop timeout according to timespec and busy poll timeout. * Adjust the busy loop timeout according to timespec and busy poll timeout.
* If the specified NAPI timeout is bigger than the wait timeout, then adjust
* the NAPI timeout accordingly.
*/ */
void __io_napi_adjust_timeout(struct io_ring_ctx *ctx, struct io_wait_queue *iowq, void __io_napi_adjust_timeout(struct io_ring_ctx *ctx, struct io_wait_queue *iowq,
struct timespec64 *ts) struct timespec64 *ts)
...@@ -274,16 +276,16 @@ void __io_napi_adjust_timeout(struct io_ring_ctx *ctx, struct io_wait_queue *iow ...@@ -274,16 +276,16 @@ void __io_napi_adjust_timeout(struct io_ring_ctx *ctx, struct io_wait_queue *iow
unsigned int poll_to = READ_ONCE(ctx->napi_busy_poll_to); unsigned int poll_to = READ_ONCE(ctx->napi_busy_poll_to);
if (ts) { if (ts) {
struct timespec64 poll_to_ts = ns_to_timespec64(1000 * (s64)poll_to); struct timespec64 poll_to_ts;
if (timespec64_compare(ts, &poll_to_ts) > 0) { poll_to_ts = ns_to_timespec64(1000 * (s64)poll_to);
*ts = timespec64_sub(*ts, poll_to_ts); if (timespec64_compare(ts, &poll_to_ts) < 0) {
} else { s64 poll_to_ns = timespec64_to_ns(ts);
u64 to = timespec64_to_ns(ts); if (poll_to_ns > 0) {
u64 val = poll_to_ns + 999;
do_div(to, 1000); do_div(val, (s64) 1000);
ts->tv_sec = 0; poll_to = val;
ts->tv_nsec = 0; }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment