Merge tag 'io_uring-7.2-20260710' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux

Pull io_uring fixes from Jens Axboe:

 - Restore full RCU read section in io_req_local_work_add(), which was
   mistakenly dropped with the DEFER_TASKRUN rework in this merge
   window. Revert the commit that grabbed the RCU read lock in
   io_ctx_mark_taskrun(), as that's no longer required with the previous
   fix.

 - Fix a dangling iovec after a provided-buffer bundle grow failure,
   also an issue introduced in this merge window.

 - Reject IORING_CQE_F_32 flag pass-through in MSG_RING to rings that
   weren't setup with CQE32 or CQE_MIXED.

 - Return -EINVAL rather than -ENOMEM from get_unmapped_area() when mmap
   validation fails, matching io_uring_mmap().

* tag 'io_uring-7.2-20260710' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
  Revert "io_uring: grab RCU read lock marking task run"
  io_uring: restore RCU read section in io_req_local_work_add()
  io_uring: fix dangling iovec after provided-buffer bundle grow failure
  io_uring/uring_cmd: fix uring_cmd.c comments
  io_uring/msg_ring: reject CQE32 flag pass-through to normal rings
  io_uring/memmap: return -EINVAL from get_unmapped_area() on bad mmap
This commit is contained in:
Linus Torvalds
2026-07-11 09:24:38 -07:00
5 changed files with 40 additions and 16 deletions

View File

@@ -287,8 +287,6 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg,
iov = kmalloc_objs(struct iovec, nr_avail);
if (unlikely(!iov))
return -ENOMEM;
if (arg->mode & KBUF_MODE_FREE)
kfree(arg->iovs);
arg->iovs = iov;
nr_iovs = nr_avail;
} else if (nr_avail < nr_iovs) {
@@ -330,6 +328,9 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg,
buf = io_ring_head_to_buf(br, ++head, bl->mask);
} while (--nr_iovs);
if (arg->mode & KBUF_MODE_FREE)
kfree(arg->iovs);
if (head == tail)
req->flags |= REQ_F_BL_EMPTY;

View File

@@ -337,7 +337,7 @@ unsigned long io_uring_get_unmapped_area(struct file *filp, unsigned long addr,
ptr = io_uring_validate_mmap_request(filp, pgoff);
if (IS_ERR(ptr))
return -ENOMEM;
return PTR_ERR(ptr);
/*
* Some architectures have strong cache aliasing requirements.

View File

@@ -93,19 +93,38 @@ static void io_msg_remote_post(struct io_ring_ctx *ctx, struct io_kiocb *req,
io_req_task_work_add_remote(req, IOU_F_TWQ_LAZY_WAKE);
}
static int io_msg_ring_cqe_flags(struct io_ring_ctx *target_ctx,
const struct io_msg *msg, u32 *flags)
{
*flags = 0;
if (!(msg->flags & IORING_MSG_RING_FLAGS_PASS))
return 0;
*flags = msg->cqe_flags;
if ((*flags & IORING_CQE_F_32) &&
!(target_ctx->flags & (IORING_SETUP_CQE32 |
IORING_SETUP_CQE_MIXED)))
return -EINVAL;
return 0;
}
static int io_msg_data_remote(struct io_ring_ctx *target_ctx,
struct io_msg *msg)
{
struct io_kiocb *target;
u32 flags = 0;
u32 flags;
int ret;
target = kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO) ;
ret = io_msg_ring_cqe_flags(target_ctx, msg, &flags);
if (ret)
return ret;
target = kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
if (unlikely(!target))
return -ENOMEM;
if (msg->flags & IORING_MSG_RING_FLAGS_PASS)
flags = msg->cqe_flags;
io_msg_remote_post(target_ctx, target, msg->len, flags, msg->user_data);
return 0;
}
@@ -130,8 +149,9 @@ static int __io_msg_ring_data(struct io_ring_ctx *target_ctx,
if (io_msg_need_remote(target_ctx))
return io_msg_data_remote(target_ctx, msg);
if (msg->flags & IORING_MSG_RING_FLAGS_PASS)
flags = msg->cqe_flags;
ret = io_msg_ring_cqe_flags(target_ctx, msg, &flags);
if (ret)
return ret;
ret = -EOVERFLOW;
if (target_ctx->flags & IORING_SETUP_IOPOLL) {

View File

@@ -139,11 +139,11 @@ void tctx_task_work(struct callback_head *cb)
*/
static void io_ctx_mark_taskrun(struct io_ring_ctx *ctx)
{
if (ctx->flags & IORING_SETUP_TASKRUN_FLAG) {
struct io_rings *rings;
lockdep_assert_in_rcu_read_lock();
if (ctx->flags & IORING_SETUP_TASKRUN_FLAG) {
struct io_rings *rings = rcu_dereference(ctx->rings_rcu);
guard(rcu)();
rings = rcu_dereference(ctx->rings_rcu);
atomic_or(IORING_SQ_TASKRUN, &rings->sq_flags);
}
}
@@ -153,6 +153,9 @@ void io_req_local_work_add(struct io_kiocb *req, unsigned flags)
struct io_ring_ctx *ctx = req->ctx;
int nr_wait;
/* pairs with synchronize_rcu() in io_ring_exit_work() */
guard(rcu)();
/*
* We don't know how many requests there are in the link and whether
* they can even be queued lazily, fall back to non-lazy.

View File

@@ -90,7 +90,7 @@ static void io_uring_cmd_del_cancelable(struct io_uring_cmd *cmd,
}
/*
* Mark this command as concelable, then io_uring_try_cancel_uring_cmd()
* Mark this command as cancelable, then io_uring_try_cancel_uring_cmd()
* will try to cancel this issued command by sending ->uring_cmd() with
* issue_flags of IO_URING_F_CANCEL.
*
@@ -168,7 +168,7 @@ void __io_uring_cmd_done(struct io_uring_cmd *ioucmd, s32 ret, u64 res2,
}
io_req_uring_cleanup(req, issue_flags);
if (req->flags & REQ_F_IOPOLL) {
/* order with io_iopoll_req_issued() checking ->iopoll_complete */
/* order with io_do_iopoll() checking ->iopoll_completed */
smp_store_release(&req->iopoll_completed, 1);
} else if (issue_flags & IO_URING_F_COMPLETE_DEFER) {
if (WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED))