Skip to content

Commit e339158

Browse files
committed
Merge tag 'io_uring-6.10-20240607' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe: - Fix a locking order issue with setting max async thread workers (Hagar) - Fix for a NULL pointer dereference for failed async flagged requests using ring provided buffers. This doesn't affect the current kernel, but it does affect older kernels, and is being queued up for 6.10 just to make the stable process easier (me) - Fix for NAPI timeout calculations for how long to busy poll, and subsequently how much to sleep post that if a wait timeout is passed in (me) - Fix for a regression in this release cycle, where we could end up using a partially unitialized match value for io-wq (Su) * tag 'io_uring-6.10-20240607' of git://git.kernel.dk/linux: io_uring: fix possible deadlock in io_register_iowq_max_workers() io_uring/io-wq: avoid garbage value of 'match' in io_wq_enqueue() io_uring/napi: fix timeout calculation io_uring: check for non-NULL file pointer in io_file_can_poll()
2 parents 0797833 + 73254a2 commit e339158

File tree

4 files changed

+23
-17
lines changed

4 files changed

+23
-17
lines changed

io_uring/io-wq.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,11 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work)
927927
{
928928
struct io_wq_acct *acct = io_work_get_acct(wq, work);
929929
unsigned long work_flags = work->flags;
930-
struct io_cb_cancel_data match;
930+
struct io_cb_cancel_data match = {
931+
.fn = io_wq_work_match_item,
932+
.data = work,
933+
.cancel_all = false,
934+
};
931935
bool do_create;
932936

933937
/*
@@ -965,10 +969,6 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work)
965969
raw_spin_unlock(&wq->lock);
966970

967971
/* fatal condition, failed to create the first worker */
968-
match.fn = io_wq_work_match_item,
969-
match.data = work,
970-
match.cancel_all = false,
971-
972972
io_acct_cancel_pending_work(wq, acct, &match);
973973
}
974974
}

io_uring/io_uring.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ static inline bool io_file_can_poll(struct io_kiocb *req)
433433
{
434434
if (req->flags & REQ_F_CAN_POLL)
435435
return true;
436-
if (file_can_poll(req->file)) {
436+
if (req->file && file_can_poll(req->file)) {
437437
req->flags |= REQ_F_CAN_POLL;
438438
return true;
439439
}

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

io_uring/register.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,10 @@ static __cold int io_register_iowq_max_workers(struct io_ring_ctx *ctx,
355355
}
356356

357357
if (sqd) {
358+
mutex_unlock(&ctx->uring_lock);
358359
mutex_unlock(&sqd->lock);
359360
io_put_sq_data(sqd);
361+
mutex_lock(&ctx->uring_lock);
360362
}
361363

362364
if (copy_to_user(arg, new_count, sizeof(new_count)))
@@ -380,8 +382,10 @@ static __cold int io_register_iowq_max_workers(struct io_ring_ctx *ctx,
380382
return 0;
381383
err:
382384
if (sqd) {
385+
mutex_unlock(&ctx->uring_lock);
383386
mutex_unlock(&sqd->lock);
384387
io_put_sq_data(sqd);
388+
mutex_lock(&ctx->uring_lock);
385389
}
386390
return ret;
387391
}

0 commit comments

Comments
 (0)