mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 12:10:38 -04:00
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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user