Skip to content

Commit 415ce0e

Browse files
committed
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: 8d0c12a ("io-uring: add napi busy poll support") Reported-by: Lewis Baker <lewissbaker@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 5fc16fa commit 415ce0e

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

io_uring/napi.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -261,29 +261,31 @@ int io_unregister_napi(struct io_ring_ctx *ctx, void __user *arg)
261261
}
262262

263263
/*
264-
* __io_napi_adjust_timeout() - Add napi id to the busy poll list
264+
* __io_napi_adjust_timeout() - adjust busy loop timeout
265265
* @ctx: pointer to io-uring context structure
266266
* @iowq: pointer to io wait queue
267267
* @ts: pointer to timespec or NULL
268268
*
269269
* Adjust the busy loop timeout according to timespec and busy poll timeout.
270+
* If the specified NAPI timeout is bigger than the wait timeout, then adjust
271+
* the NAPI timeout accordingly.
270272
*/
271273
void __io_napi_adjust_timeout(struct io_ring_ctx *ctx, struct io_wait_queue *iowq,
272274
struct timespec64 *ts)
273275
{
274276
unsigned int poll_to = READ_ONCE(ctx->napi_busy_poll_to);
275277

276278
if (ts) {
277-
struct timespec64 poll_to_ts = ns_to_timespec64(1000 * (s64)poll_to);
278-
279-
if (timespec64_compare(ts, &poll_to_ts) > 0) {
280-
*ts = timespec64_sub(*ts, poll_to_ts);
281-
} else {
282-
u64 to = timespec64_to_ns(ts);
283-
284-
do_div(to, 1000);
285-
ts->tv_sec = 0;
286-
ts->tv_nsec = 0;
279+
struct timespec64 poll_to_ts;
280+
281+
poll_to_ts = ns_to_timespec64(1000 * (s64)poll_to);
282+
if (timespec64_compare(ts, &poll_to_ts) < 0) {
283+
s64 poll_to_ns = timespec64_to_ns(ts);
284+
if (poll_to_ns > 0) {
285+
u64 val = poll_to_ns + 999;
286+
do_div(val, (s64) 1000);
287+
poll_to = val;
288+
}
287289
}
288290
}
289291

0 commit comments

Comments
 (0)