All of lore.kernel.org
 help / color / mirror / Atom feed
From: Caleb Sander Mateos <csander@purestorage.com>
To: Jens Axboe <axboe@kernel.dk>
Cc: io-uring@vger.kernel.org, linux-kernel@vger.kernel.org,
	Caleb Sander Mateos <csander@purestorage.com>
Subject: [PATCH 1/4] io_uring: split io_uring_alloc_async_data()
Date: Tue,  3 Nov 2026 14:10:28 -0700	[thread overview]
Message-ID: <20261103211031.592745-2-csander@purestorage.com> (raw)
In-Reply-To: <20261103211031.592745-1-csander@purestorage.com>

io_uring_alloc_async_data() accepts an optional struct io_alloc_cache *
argument to use for the allocation in place of kmalloc(). All callers
either always pass NULL or a non-NULL io_alloc_cache. However, the
compiler still emits a NULL check for callers passing a non-NULL
io_alloc_cache. Split out a separate io_uring_alloc_cached_async_data()
for the non-NULL io_alloc_cache cache. This avoids the NULL check at the
cost of duplicating the code to set REQ_F_ASYNC_DATA.

Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
---
 io_uring/io_uring.h  | 23 ++++++++++++++---------
 io_uring/net.c       |  6 +++---
 io_uring/rw.c        |  2 +-
 io_uring/timeout.c   |  2 +-
 io_uring/uring_cmd.c |  2 +-
 io_uring/waitid.c    |  2 +-
 6 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
index 32247529076c..a36a177559f4 100644
--- a/io_uring/io_uring.h
+++ b/io_uring/io_uring.h
@@ -335,21 +335,26 @@ static inline ssize_t io_fixup_restart_res(ssize_t ret)
 	default:
 		return ret;
 	}
 }
 
-static inline void *io_uring_alloc_async_data(struct io_alloc_cache *cache,
-					      struct io_kiocb *req)
+static inline void *
+io_uring_alloc_cached_async_data(struct io_alloc_cache *cache,
+				 struct io_kiocb *req)
 {
-	if (cache) {
-		req->async_data = io_cache_alloc(cache, GFP_KERNEL);
-	} else {
-		const struct io_issue_def *def = &io_issue_defs[req->opcode];
+	req->async_data = io_cache_alloc(cache, GFP_KERNEL);
+	if (req->async_data)
+		req->flags |= REQ_F_ASYNC_DATA;
+	return req->async_data;
+}
 
-		WARN_ON_ONCE(!def->async_size);
-		req->async_data = kmalloc(def->async_size, GFP_KERNEL);
-	}
+static inline void *io_uring_alloc_async_data(struct io_kiocb *req)
+{
+	const struct io_issue_def *def = &io_issue_defs[req->opcode];
+
+	WARN_ON_ONCE(!def->async_size);
+	req->async_data = kmalloc(def->async_size, GFP_KERNEL);
 	if (req->async_data)
 		req->flags |= REQ_F_ASYNC_DATA;
 	return req->async_data;
 }
 
diff --git a/io_uring/net.c b/io_uring/net.c
index 533afd335627..e5f7c13519fb 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -187,11 +187,11 @@ static void io_netmsg_recycle(struct io_kiocb *req, unsigned int issue_flags)
 static struct io_async_msghdr *io_msg_alloc_async(struct io_kiocb *req)
 {
 	struct io_ring_ctx *ctx = req->ctx;
 	struct io_async_msghdr *hdr;
 
-	hdr = io_uring_alloc_async_data(&ctx->netmsg_cache, req);
+	hdr = io_uring_alloc_cached_async_data(&ctx->netmsg_cache, req);
 	if (!hdr)
 		return NULL;
 
 	/* If the async data was cached, we might have an iov cached inside. */
 	if (hdr->vec.iovec)
@@ -1846,11 +1846,11 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 
 	conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
 	conn->addr_len =  READ_ONCE(sqe->addr2);
 	conn->in_progress = conn->seen_econnaborted = false;
 
-	addr = io_uring_alloc_async_data(NULL, req);
+	addr = io_uring_alloc_async_data(req);
 	if (unlikely(!addr))
 		return -ENOMEM;
 
 	return move_addr_to_kernel(conn->addr, conn->addr_len, addr);
 }
@@ -1944,11 +1944,11 @@ int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 		return -EINVAL;
 
 	uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr));
 	bind->addr_len =  READ_ONCE(sqe->addr2);
 
-	addr = io_uring_alloc_async_data(NULL, req);
+	addr = io_uring_alloc_async_data(req);
 	if (unlikely(!addr))
 		return -ENOMEM;
 	ret = move_addr_to_kernel(uaddr, bind->addr_len, addr);
 	if (unlikely(ret))
 		return ret;
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 61bd0641dd77..4a9538157d94 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -191,11 +191,11 @@ static void io_req_rw_cleanup(struct io_kiocb *req, unsigned int issue_flags)
 static int io_rw_alloc_async(struct io_kiocb *req)
 {
 	struct io_ring_ctx *ctx = req->ctx;
 	struct io_async_rw *rw;
 
-	rw = io_uring_alloc_async_data(&ctx->rw_cache, req);
+	rw = io_uring_alloc_cached_async_data(&ctx->rw_cache, req);
 	if (!rw)
 		return -ENOMEM;
 	if (rw->vec.iovec)
 		req->flags |= REQ_F_NEED_CLEANUP;
 	rw->bytes_done = 0;
diff --git a/io_uring/timeout.c b/io_uring/timeout.c
index fa7b0d9a81d6..fa54846ed4ce 100644
--- a/io_uring/timeout.c
+++ b/io_uring/timeout.c
@@ -638,11 +638,11 @@ static int __io_timeout_prep(struct io_kiocb *req,
 	if ((flags & IORING_TIMEOUT_MULTISHOT) && off > 0)
 		timeout->repeats = off;
 
 	if (WARN_ON_ONCE(req_has_async_data(req)))
 		return -EFAULT;
-	data = io_uring_alloc_async_data(NULL, req);
+	data = io_uring_alloc_async_data(req);
 	if (!data)
 		return -ENOMEM;
 	data->req = req;
 	data->flags = flags;
 
diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c
index b5486b56ee0c..6f417bda52ea 100644
--- a/io_uring/uring_cmd.c
+++ b/io_uring/uring_cmd.c
@@ -188,11 +188,11 @@ int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 	    !!(req->flags & REQ_F_BUFFER_SELECT))
 		return -EINVAL;
 
 	ioucmd->cmd_op = READ_ONCE(sqe->cmd_op);
 
-	ac = io_uring_alloc_async_data(&req->ctx->cmd_cache, req);
+	ac = io_uring_alloc_cached_async_data(&req->ctx->cmd_cache, req);
 	if (!ac)
 		return -ENOMEM;
 	if (ac->vec.iovec)
 		req->flags |= REQ_F_NEED_CLEANUP;
 	ioucmd->sqe = sqe;
diff --git a/io_uring/waitid.c b/io_uring/waitid.c
index 986fb46639e8..0d3c248f375c 100644
--- a/io_uring/waitid.c
+++ b/io_uring/waitid.c
@@ -292,11 +292,11 @@ int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 	struct io_waitid_async *iwa;
 
 	if (sqe->addr || sqe->buf_index || sqe->addr3 || sqe->waitid_flags)
 		return -EINVAL;
 
-	iwa = io_uring_alloc_async_data(NULL, req);
+	iwa = io_uring_alloc_async_data(req);
 	if (unlikely(!iwa))
 		return -ENOMEM;
 	iwa->req = req;
 
 	iw->which = READ_ONCE(sqe->len);
-- 
2.56.0


  reply	other threads:[~2026-11-03 21:10 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03 21:10 [PATCH 0/4] io_uring: improve alloc_cache branch prediction Caleb Sander Mateos
2026-11-03 21:10 ` Caleb Sander Mateos [this message]
2026-11-03 21:10 ` [PATCH 2/4] io_uring/alloc_cache: mark cache success paths as likely Caleb Sander Mateos
2026-11-03 21:10 ` [PATCH 3/4] io_uring/alloc_cache: assume io_alloc_cache_get() doesn't return NULL Caleb Sander Mateos
2026-11-03 21:10 ` [PATCH 4/4] io_uring/futex: avoid ifd NULL check in io_futex_wait() Caleb Sander Mateos
2026-11-09 21:37 ` [PATCH 0/4] io_uring: improve alloc_cache branch prediction Jens Axboe
2026-11-09 23:14   ` Caleb Sander Mateos
2026-11-09 21:38 ` Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261103211031.592745-2-csander@purestorage.com \
    --to=csander@purestorage.com \
    --cc=axboe@kernel.dk \
    --cc=io-uring@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.