Linux io-uring development
 help / color / mirror / Atom feed
From: Pavel Begunkov <asml.silence@gmail.com>
To: io-uring@vger.kernel.org
Cc: asml.silence@gmail.com, axboe@kernel.dk
Subject: [PATCH liburing 1/1] tests: don't assume tail/head layout in bpf
Date: Sun, 12 Apr 2026 15:30:04 +0100	[thread overview]
Message-ID: <6fdc76568f2066bf0d7f0349088883ab29e6cb63.1776004188.git.asml.silence@gmail.com> (raw)

Keep separate tail and head offsets and don't assume they're placed next
to each other.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 test/bpf-progs/cp.bpf.c   | 19 ++++++++++---------
 test/bpf-progs/nops.bpf.c | 19 ++++++++++---------
 test/bpf_cp.c             |  4 ++--
 test/bpf_defs.h           |  5 -----
 test/bpf_nops.c           |  5 +++--
 5 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/test/bpf-progs/cp.bpf.c b/test/bpf-progs/cp.bpf.c
index 67a9f825..3987d9e3 100644
--- a/test/bpf-progs/cp.bpf.c
+++ b/test/bpf-progs/cp.bpf.c
@@ -9,8 +9,8 @@ enum {
 	REQ_TOKEN_WRITE
 };
 
-const volatile unsigned cq_hdr_offset;
-const volatile unsigned sq_hdr_offset;
+const volatile unsigned cq_tail_offset;
+const volatile unsigned cq_head_offset;
 const volatile unsigned cqes_offset;
 const volatile unsigned sq_entries;
 const volatile unsigned cq_entries;
@@ -68,7 +68,7 @@ int BPF_PROG(cp_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *ls)
 {
 	struct io_uring_sqe *sqes;
 	struct io_uring_cqe *cqes;
-	struct io_uring *cq_hdr;
+	__u32 *cq_tail, *cq_head;
 	void *rings;
 	int ret;
 
@@ -78,7 +78,8 @@ int BPF_PROG(cp_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *ls)
 				cqes_offset + cq_entries * sizeof(struct io_uring_cqe));
 	if (!rings || !sqes)
 		return IOU_LOOP_STOP;
-	cq_hdr = rings + cq_hdr_offset;
+	cq_tail = rings + cq_tail_offset;
+	cq_head = rings + cq_head_offset;
 	cqes = rings + cqes_offset;
 
 	if (!nr_infligt) {
@@ -89,15 +90,15 @@ int BPF_PROG(cp_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *ls)
 			return IOU_LOOP_STOP;
 	}
 
-	if (cq_hdr->tail != cq_hdr->head) {
+	if (*cq_tail != *cq_head) {
 		struct io_uring_cqe *cqe;
 
-		if (cq_hdr->tail - cq_hdr->head != 1) {
+		if (*cq_tail - *cq_head != 1) {
 			cp_result = -ERANGE;
 			return IOU_LOOP_STOP;
 		}
 
-		cqe = &cqes[cq_hdr->head & (cq_entries - 1)];
+		cqe = &cqes[*cq_head & (cq_entries - 1)];
 		if (cqe->res < 0) {
 			cp_result = cqe->res;
 			return IOU_LOOP_STOP;
@@ -127,10 +128,10 @@ int BPF_PROG(cp_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *ls)
 			return IOU_LOOP_STOP;
 		};
 
-		cq_hdr->head++;
+		*cq_head += 1;
 	}
 
-	ls->cq_wait_idx = cq_hdr->head + 1;
+	ls->cq_wait_idx = *cq_head + 1;
 	return IOU_LOOP_CONTINUE;
 }
 
diff --git a/test/bpf-progs/nops.bpf.c b/test/bpf-progs/nops.bpf.c
index 0aefc76e..dccf8e76 100644
--- a/test/bpf-progs/nops.bpf.c
+++ b/test/bpf-progs/nops.bpf.c
@@ -7,8 +7,8 @@ char LICENSE[] SEC("license") = "Dual BSD/GPL";
 #define REQ_TOKEN 0xabba1741
 
 const unsigned max_inflight = 8;
-const volatile unsigned cq_hdr_offset;
-const volatile unsigned sq_hdr_offset;
+const volatile unsigned cq_tail_offset;
+const volatile unsigned cq_head_offset;
 const volatile unsigned cqes_offset;
 const volatile unsigned cq_entries;
 const volatile unsigned sq_entries;
@@ -35,7 +35,7 @@ int BPF_PROG(nops_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *l
 {
 	struct io_uring_sqe *sqes;
 	struct io_uring_cqe *cqes;
-	struct io_uring *cq_hdr;
+	__u32 *cq_tail, *cq_head;
 	unsigned to_submit;
 	unsigned to_wait;
 	unsigned nr_cqes;
@@ -48,7 +48,8 @@ int BPF_PROG(nops_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *l
 				cqes_offset + cq_entries * sizeof(struct io_uring_cqe));
 	if (!rings || !sqes)
 		return IOU_LOOP_STOP;
-	cq_hdr = rings + cq_hdr_offset;
+	cq_tail = rings + cq_tail_offset;
+	cq_head = rings + cq_head_offset;
 	cqes = rings + cqes_offset;
 
 	to_submit = nr_to_submit();
@@ -67,14 +68,14 @@ int BPF_PROG(nops_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *l
 		reqs_inflight += to_submit;
 	}
 
-	nr_cqes = cq_hdr->tail - cq_hdr->head;
+	nr_cqes = *cq_tail - *cq_head;
 	nr_cqes = t_min(nr_cqes, max_inflight);
 	for (i = 0; i < nr_cqes; i++) {
-		struct io_uring_cqe *cqe = &cqes[cq_hdr->head & (cq_entries - 1)];
+		struct io_uring_cqe *cqe = &cqes[*cq_head & (cq_entries - 1)];
 
 		if (cqe->user_data != REQ_TOKEN)
 			return IOU_LOOP_STOP;
-		cq_hdr->head++;
+		*cq_head += 1;
 	}
 
 	reqs_inflight -= nr_cqes;
@@ -85,9 +86,9 @@ int BPF_PROG(nops_loop_step, struct io_ring_ctx *ring, struct iou_loop_params *l
 
 	to_wait = reqs_inflight;
 	/* Don't sleep if there are still CQEs left */
-	if (cq_hdr->tail != cq_hdr->head)
+	if (*cq_tail != *cq_head)
 		to_wait = 0;
-	ls->cq_wait_idx = cq_hdr->head + to_wait;
+	ls->cq_wait_idx = *cq_head + to_wait;
 	return IOU_LOOP_CONTINUE;
 }
 
diff --git a/test/bpf_cp.c b/test/bpf_cp.c
index b9ff11a3..110135da 100644
--- a/test/bpf_cp.c
+++ b/test/bpf_cp.c
@@ -51,8 +51,8 @@ static int setup_ring_ops(struct io_uring *ring)
 	}
 
 	skel->struct_ops.cp_ops->ring_fd = ring->ring_fd;
-	skel->rodata->sq_hdr_offset = params.sq_off.head;
-	skel->rodata->cq_hdr_offset = params.cq_off.head;
+	skel->rodata->cq_head_offset = params.cq_off.head;
+	skel->rodata->cq_tail_offset = params.cq_off.tail;
 	skel->rodata->cqes_offset = params.cq_off.cqes;
 	skel->rodata->cq_entries = CQ_ENTRIES;
 	skel->rodata->sq_entries = SQ_ENTRIES;
diff --git a/test/bpf_defs.h b/test/bpf_defs.h
index 8e120057..df78bb00 100644
--- a/test/bpf_defs.h
+++ b/test/bpf_defs.h
@@ -14,11 +14,6 @@ struct iou_loop_params {
 	__u32 cq_wait_idx;
 };
 
-struct io_uring {
-	__u32 head;
-	__u32 tail;
-};
-
 enum {
 	IOU_REGION_MEM = 0,
 	IOU_REGION_CQ = 1,
diff --git a/test/bpf_nops.c b/test/bpf_nops.c
index f097434f..1a1068a7 100644
--- a/test/bpf_nops.c
+++ b/test/bpf_nops.c
@@ -45,8 +45,9 @@ static int setup_ring_ops(struct io_uring *ring)
 
 	skel->struct_ops.nops_ops->ring_fd = ring->ring_fd;
 	skel->bss->reqs_to_run = NR_ITERS;
-	skel->rodata->sq_hdr_offset = params.sq_off.head;
-	skel->rodata->cq_hdr_offset = params.cq_off.head;
+	skel->rodata->cq_head_offset = params.cq_off.head;
+	skel->rodata->cq_tail_offset = params.cq_off.tail;
+
 	skel->rodata->cqes_offset = params.cq_off.cqes;
 	skel->rodata->cq_entries = CQ_ENTRIES;
 	skel->rodata->sq_entries = SQ_ENTRIES;
-- 
2.53.0


             reply	other threads:[~2026-04-12 14:29 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-12 14:30 Pavel Begunkov [this message]
2026-04-15 20:12 ` [PATCH liburing 1/1] tests: don't assume tail/head layout in bpf 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=6fdc76568f2066bf0d7f0349088883ab29e6cb63.1776004188.git.asml.silence@gmail.com \
    --to=asml.silence@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=io-uring@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox