Commit 4ad976b0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.17-20250815' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

 - Tweak for the fairly recent changes of minimizing io-wq worker
   creations when it's pointless to create them.

 - Fix for an issue with ring provided buffers, which could cause issues
   with reuse or corrupt application data.

* tag 'io_uring-6.17-20250815' of git://git.kernel.dk/linux:
  io_uring/io-wq: add check free worker before create new worker
  io_uring/net: commit partial buffers on retry
parents 8d084337 9d83e1f0
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -357,6 +357,13 @@ static void create_worker_cb(struct callback_head *cb)
	worker = container_of(cb, struct io_worker, create_work);
	wq = worker->wq;
	acct = worker->acct;

	rcu_read_lock();
	do_create = !io_acct_activate_free_worker(acct);
	rcu_read_unlock();
	if (!do_create)
		goto no_need_create;

	raw_spin_lock(&acct->workers_lock);

	if (acct->nr_workers < acct->max_workers) {
@@ -367,6 +374,7 @@ static void create_worker_cb(struct callback_head *cb)
	if (do_create) {
		create_io_worker(wq, acct);
	} else {
no_need_create:
		atomic_dec(&acct->nr_running);
		io_worker_ref_put(wq);
	}
+15 −12
Original line number Diff line number Diff line
@@ -494,6 +494,15 @@ static int io_bundle_nbufs(struct io_async_msghdr *kmsg, int ret)
	return nbufs;
}

static int io_net_kbuf_recyle(struct io_kiocb *req,
			      struct io_async_msghdr *kmsg, int len)
{
	req->flags |= REQ_F_BL_NO_RECYCLE;
	if (req->flags & REQ_F_BUFFERS_COMMIT)
		io_kbuf_commit(req, req->buf_list, len, io_bundle_nbufs(kmsg, len));
	return IOU_RETRY;
}

static inline bool io_send_finish(struct io_kiocb *req, int *ret,
				  struct io_async_msghdr *kmsg,
				  unsigned issue_flags)
@@ -562,8 +571,7 @@ int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
			kmsg->msg.msg_controllen = 0;
			kmsg->msg.msg_control = NULL;
			sr->done_io += ret;
			req->flags |= REQ_F_BL_NO_RECYCLE;
			return -EAGAIN;
			return io_net_kbuf_recyle(req, kmsg, ret);
		}
		if (ret == -ERESTARTSYS)
			ret = -EINTR;
@@ -674,8 +682,7 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
			sr->len -= ret;
			sr->buf += ret;
			sr->done_io += ret;
			req->flags |= REQ_F_BL_NO_RECYCLE;
			return -EAGAIN;
			return io_net_kbuf_recyle(req, kmsg, ret);
		}
		if (ret == -ERESTARTSYS)
			ret = -EINTR;
@@ -1071,8 +1078,7 @@ int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
		}
		if (ret > 0 && io_net_retry(sock, flags)) {
			sr->done_io += ret;
			req->flags |= REQ_F_BL_NO_RECYCLE;
			return IOU_RETRY;
			return io_net_kbuf_recyle(req, kmsg, ret);
		}
		if (ret == -ERESTARTSYS)
			ret = -EINTR;
@@ -1218,8 +1224,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
			sr->len -= ret;
			sr->buf += ret;
			sr->done_io += ret;
			req->flags |= REQ_F_BL_NO_RECYCLE;
			return -EAGAIN;
			return io_net_kbuf_recyle(req, kmsg, ret);
		}
		if (ret == -ERESTARTSYS)
			ret = -EINTR;
@@ -1500,8 +1505,7 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
			zc->len -= ret;
			zc->buf += ret;
			zc->done_io += ret;
			req->flags |= REQ_F_BL_NO_RECYCLE;
			return -EAGAIN;
			return io_net_kbuf_recyle(req, kmsg, ret);
		}
		if (ret == -ERESTARTSYS)
			ret = -EINTR;
@@ -1571,8 +1575,7 @@ int io_sendmsg_zc(struct io_kiocb *req, unsigned int issue_flags)

		if (ret > 0 && io_net_retry(sock, flags)) {
			sr->done_io += ret;
			req->flags |= REQ_F_BL_NO_RECYCLE;
			return -EAGAIN;
			return io_net_kbuf_recyle(req, kmsg, ret);
		}
		if (ret == -ERESTARTSYS)
			ret = -EINTR;