Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+22 -16
+5 -5
io_uring/io-wq.c
··· 927 927 { 928 928 struct io_wq_acct *acct = io_work_get_acct(wq, work); 929 929 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 + }; 931 935 bool do_create; 932 936 933 937 /* ··· 969 965 raw_spin_unlock(&wq->lock); 970 966 971 967 /* fatal condition, failed to create the first worker */ 972 - match.fn = io_wq_work_match_item, 973 - match.data = work, 974 - match.cancel_all = false, 975 - 976 968 io_acct_cancel_pending_work(wq, acct, &match); 977 969 } 978 970 }
+1 -1
io_uring/io_uring.h
··· 433 433 { 434 434 if (req->flags & REQ_F_CAN_POLL) 435 435 return true; 436 - if (file_can_poll(req->file)) { 436 + if (req->file && file_can_poll(req->file)) { 437 437 req->flags |= REQ_F_CAN_POLL; 438 438 return true; 439 439 }
+12 -10
io_uring/napi.c
··· 261 261 } 262 262 263 263 /* 264 - * __io_napi_adjust_timeout() - Add napi id to the busy poll list 264 + * __io_napi_adjust_timeout() - adjust busy loop timeout 265 265 * @ctx: pointer to io-uring context structure 266 266 * @iowq: pointer to io wait queue 267 267 * @ts: pointer to timespec or NULL 268 268 * 269 269 * 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. 270 272 */ 271 273 void __io_napi_adjust_timeout(struct io_ring_ctx *ctx, struct io_wait_queue *iowq, 272 274 struct timespec64 *ts) ··· 276 274 unsigned int poll_to = READ_ONCE(ctx->napi_busy_poll_to); 277 275 278 276 if (ts) { 279 - struct timespec64 poll_to_ts = ns_to_timespec64(1000 * (s64)poll_to); 277 + struct timespec64 poll_to_ts; 280 278 281 - if (timespec64_compare(ts, &poll_to_ts) > 0) { 282 - *ts = timespec64_sub(*ts, poll_to_ts); 283 - } else { 284 - u64 to = timespec64_to_ns(ts); 285 - 286 - do_div(to, 1000); 287 - ts->tv_sec = 0; 288 - ts->tv_nsec = 0; 279 + poll_to_ts = ns_to_timespec64(1000 * (s64)poll_to); 280 + if (timespec64_compare(ts, &poll_to_ts) < 0) { 281 + s64 poll_to_ns = timespec64_to_ns(ts); 282 + if (poll_to_ns > 0) { 283 + u64 val = poll_to_ns + 999; 284 + do_div(val, (s64) 1000); 285 + poll_to = val; 286 + } 289 287 } 290 288 } 291 289
+4
io_uring/register.c
··· 355 355 } 356 356 357 357 if (sqd) { 358 + mutex_unlock(&ctx->uring_lock); 358 359 mutex_unlock(&sqd->lock); 359 360 io_put_sq_data(sqd); 361 + mutex_lock(&ctx->uring_lock); 360 362 } 361 363 362 364 if (copy_to_user(arg, new_count, sizeof(new_count))) ··· 382 380 return 0; 383 381 err: 384 382 if (sqd) { 383 + mutex_unlock(&ctx->uring_lock); 385 384 mutex_unlock(&sqd->lock); 386 385 io_put_sq_data(sqd); 386 + mutex_lock(&ctx->uring_lock); 387 387 } 388 388 return ret; 389 389 }