Merge tag 'io_uring-6.2-2022-12-29' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

- Two fixes for mutex grabbing when the task state is != TASK_RUNNING
(me)

- Check for invalid opcode in io_uring_register() a bit earlier, to
avoid going through the quiesce machinery just to return -EINVAL
later in the process (me)

- Fix for the uapi io_uring header, skipping including time_types.h
when necessary (Stefan)

* tag 'io_uring-6.2-2022-12-29' of git://git.kernel.dk/linux:
uapi:io_uring.h: allow linux/time_types.h to be skipped
io_uring: check for valid register opcode earlier
io_uring/cancel: re-grab ctx mutex after finishing wait
io_uring: finish waiting before flushing overflow entries

+31 -16
+8
include/uapi/linux/io_uring.h
··· 10 10 11 11 #include <linux/fs.h> 12 12 #include <linux/types.h> 13 + /* 14 + * this file is shared with liburing and that has to autodetect 15 + * if linux/time_types.h is available or not, it can 16 + * define UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 17 + * if linux/time_types.h is not available 18 + */ 19 + #ifndef UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 13 20 #include <linux/time_types.h> 21 + #endif 14 22 15 23 #ifdef __cplusplus 16 24 extern "C" {
+4 -5
io_uring/cancel.c
··· 288 288 289 289 ret = __io_sync_cancel(current->io_uring, &cd, sc.fd); 290 290 291 + mutex_unlock(&ctx->uring_lock); 291 292 if (ret != -EALREADY) 292 293 break; 293 294 294 - mutex_unlock(&ctx->uring_lock); 295 295 ret = io_run_task_work_sig(ctx); 296 - if (ret < 0) { 297 - mutex_lock(&ctx->uring_lock); 296 + if (ret < 0) 298 297 break; 299 - } 300 298 ret = schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS); 301 - mutex_lock(&ctx->uring_lock); 302 299 if (!ret) { 303 300 ret = -ETIME; 304 301 break; 305 302 } 303 + mutex_lock(&ctx->uring_lock); 306 304 } while (1); 307 305 308 306 finish_wait(&ctx->cq_wait, &wait); 307 + mutex_lock(&ctx->uring_lock); 309 308 310 309 if (ret == -ENOENT || ret > 0) 311 310 ret = 0;
+19 -11
io_uring/io_uring.c
··· 677 677 io_cq_unlock_post(ctx); 678 678 } 679 679 680 + static void io_cqring_do_overflow_flush(struct io_ring_ctx *ctx) 681 + { 682 + /* iopoll syncs against uring_lock, not completion_lock */ 683 + if (ctx->flags & IORING_SETUP_IOPOLL) 684 + mutex_lock(&ctx->uring_lock); 685 + __io_cqring_overflow_flush(ctx); 686 + if (ctx->flags & IORING_SETUP_IOPOLL) 687 + mutex_unlock(&ctx->uring_lock); 688 + } 689 + 680 690 static void io_cqring_overflow_flush(struct io_ring_ctx *ctx) 681 691 { 682 - if (test_bit(IO_CHECK_CQ_OVERFLOW_BIT, &ctx->check_cq)) { 683 - /* iopoll syncs against uring_lock, not completion_lock */ 684 - if (ctx->flags & IORING_SETUP_IOPOLL) 685 - mutex_lock(&ctx->uring_lock); 686 - __io_cqring_overflow_flush(ctx); 687 - if (ctx->flags & IORING_SETUP_IOPOLL) 688 - mutex_unlock(&ctx->uring_lock); 689 - } 692 + if (test_bit(IO_CHECK_CQ_OVERFLOW_BIT, &ctx->check_cq)) 693 + io_cqring_do_overflow_flush(ctx); 690 694 } 691 695 692 696 void __io_put_task(struct task_struct *task, int nr) ··· 2553 2549 2554 2550 trace_io_uring_cqring_wait(ctx, min_events); 2555 2551 do { 2556 - io_cqring_overflow_flush(ctx); 2552 + if (test_bit(IO_CHECK_CQ_OVERFLOW_BIT, &ctx->check_cq)) { 2553 + finish_wait(&ctx->cq_wait, &iowq.wq); 2554 + io_cqring_do_overflow_flush(ctx); 2555 + } 2557 2556 prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq, 2558 2557 TASK_INTERRUPTIBLE); 2559 2558 ret = io_cqring_wait_schedule(ctx, &iowq, timeout); ··· 4020 4013 return -EEXIST; 4021 4014 4022 4015 if (ctx->restricted) { 4023 - if (opcode >= IORING_REGISTER_LAST) 4024 - return -EINVAL; 4025 4016 opcode = array_index_nospec(opcode, IORING_REGISTER_LAST); 4026 4017 if (!test_bit(opcode, ctx->restrictions.register_op)) 4027 4018 return -EACCES; ··· 4174 4169 struct io_ring_ctx *ctx; 4175 4170 long ret = -EBADF; 4176 4171 struct fd f; 4172 + 4173 + if (opcode >= IORING_REGISTER_LAST) 4174 + return -EINVAL; 4177 4175 4178 4176 f = fdget(fd); 4179 4177 if (!f.file)