Commit 794a5492 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.16-20250606' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

 - Fix for a regression introduced in this merge window, where the 'id'
   passed to xa_find() for ifq lookup is uninitialized

 - Fix for zcrx release on registration failure. From 6.15, going to
   stable

 - Tweak for recv bundles, where msg_inq should be > 1 before being used
   to gate a retry event

 - Pavel doesnt want to be a maintainer anymore, remove him from the
   MAINTAINERS entry

 - Limit legacy kbuf registrations to 64k, which is the size of the
   buffer ID field anyway. Hence it's nonsensical to support more than
   that, and the only purpose that serves is to have syzbot trigger long
   exit delays for heavily configured debug kernels

 - Fix for the io_uring futex handling, which got broken for
   FUTEX2_PRIVATE by a generic futex commit adding private hashes

* tag 'io_uring-6.16-20250606' of git://git.kernel.dk/linux:
  io_uring/futex: mark wait requests as inflight
  io_uring/futex: get rid of struct io_futex addr union
  io_uring/kbuf: limit legacy provided buffer lists to USHRT_MAX
  MAINTAINERS: remove myself from io_uring
  io_uring/net: only consider msg_inq if larger than 1
  io_uring/zcrx: fix area release on registration failure
  io_uring/zcrx: init id for xa_find
parents c0c9379f 079afb08
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -12670,7 +12670,6 @@ F: include/linux/iosys-map.h
IO_URING
M:	Jens Axboe <axboe@kernel.dk>
M:	Pavel Begunkov <asml.silence@gmail.com>
L:	io-uring@vger.kernel.org
S:	Maintained
T:	git git://git.kernel.dk/linux-block
+6 −5
Original line number Diff line number Diff line
@@ -14,10 +14,7 @@

struct io_futex {
	struct file	*file;
	union {
		u32 __user			*uaddr;
		struct futex_waitv __user	*uwaitv;
	};
	void __user	*uaddr;
	unsigned long	futex_val;
	unsigned long	futex_mask;
	unsigned long	futexv_owned;
@@ -148,6 +145,8 @@ int io_futex_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
	    !futex_validate_input(iof->futex_flags, iof->futex_mask))
		return -EINVAL;

	/* Mark as inflight, so file exit cancelation will find it */
	io_req_track_inflight(req);
	return 0;
}

@@ -186,13 +185,15 @@ int io_futexv_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
	if (!futexv)
		return -ENOMEM;

	ret = futex_parse_waitv(futexv, iof->uwaitv, iof->futex_nr,
	ret = futex_parse_waitv(futexv, iof->uaddr, iof->futex_nr,
				io_futex_wakev_fn, req);
	if (ret) {
		kfree(futexv);
		return ret;
	}

	/* Mark as inflight, so file exit cancelation will find it */
	io_req_track_inflight(req);
	iof->futexv_owned = 0;
	iof->futexv_unqueued = 0;
	req->flags |= REQ_F_ASYNC_DATA;
+6 −1
Original line number Diff line number Diff line
@@ -408,7 +408,12 @@ static void io_clean_op(struct io_kiocb *req)
	req->flags &= ~IO_REQ_CLEAN_FLAGS;
}

static inline void io_req_track_inflight(struct io_kiocb *req)
/*
 * Mark the request as inflight, so that file cancelation will find it.
 * Can be used if the file is an io_uring instance, or if the request itself
 * relies on ->mm being alive for the duration of the request.
 */
inline void io_req_track_inflight(struct io_kiocb *req)
{
	if (!(req->flags & REQ_F_INFLIGHT)) {
		req->flags |= REQ_F_INFLIGHT;
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ void io_add_aux_cqe(struct io_ring_ctx *ctx, u64 user_data, s32 res, u32 cflags)
bool io_req_post_cqe(struct io_kiocb *req, s32 res, u32 cflags);
void __io_commit_cqring_flush(struct io_ring_ctx *ctx);

void io_req_track_inflight(struct io_kiocb *req);
struct file *io_file_get_normal(struct io_kiocb *req, int fd);
struct file *io_file_get_fixed(struct io_kiocb *req, int fd,
			       unsigned issue_flags);
+15 −2
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ bool io_kbuf_recycle_legacy(struct io_kiocb *req, unsigned issue_flags)
	buf = req->kbuf;
	bl = io_buffer_get_list(ctx, buf->bgid);
	list_add(&buf->list, &bl->buf_list);
	bl->nbufs++;
	req->flags &= ~REQ_F_BUFFER_SELECTED;

	io_ring_submit_unlock(ctx, issue_flags);
@@ -122,6 +123,7 @@ static void __user *io_provided_buffer_select(struct io_kiocb *req, size_t *len,

		kbuf = list_first_entry(&bl->buf_list, struct io_buffer, list);
		list_del(&kbuf->list);
		bl->nbufs--;
		if (*len == 0 || *len > kbuf->len)
			*len = kbuf->len;
		if (list_empty(&bl->buf_list))
@@ -390,6 +392,7 @@ static int io_remove_buffers_legacy(struct io_ring_ctx *ctx,
	for (i = 0; i < nbufs && !list_empty(&bl->buf_list); i++) {
		nxt = list_first_entry(&bl->buf_list, struct io_buffer, list);
		list_del(&nxt->list);
		bl->nbufs--;
		kfree(nxt);
		cond_resched();
	}
@@ -491,14 +494,24 @@ static int io_add_buffers(struct io_ring_ctx *ctx, struct io_provide_buf *pbuf,
{
	struct io_buffer *buf;
	u64 addr = pbuf->addr;
	int i, bid = pbuf->bid;
	int ret = -ENOMEM, i, bid = pbuf->bid;

	for (i = 0; i < pbuf->nbufs; i++) {
		/*
		 * Nonsensical to have more than sizeof(bid) buffers in a
		 * buffer list, as the application then has no way of knowing
		 * which duplicate bid refers to what buffer.
		 */
		if (bl->nbufs == USHRT_MAX) {
			ret = -EOVERFLOW;
			break;
		}
		buf = kmalloc(sizeof(*buf), GFP_KERNEL_ACCOUNT);
		if (!buf)
			break;

		list_add_tail(&buf->list, &bl->buf_list);
		bl->nbufs++;
		buf->addr = addr;
		buf->len = min_t(__u32, pbuf->len, MAX_RW_COUNT);
		buf->bid = bid;
@@ -508,7 +521,7 @@ static int io_add_buffers(struct io_ring_ctx *ctx, struct io_provide_buf *pbuf,
		cond_resched();
	}

	return i ? 0 : -ENOMEM;
	return i ? 0 : ret;
}

static int __io_manage_buffers_legacy(struct io_kiocb *req,
Loading