All of lore.kernel.org
 help / color / mirror / Atom feed
From: frezidok1@gmail.com
To: openembedded-core@lists.openembedded.org
Cc: martin.jansa@gmail.com, Dmitry Sakhonchik <frezidok1@gmail.com>
Subject: [PATCH] io_uring-writev: open output file through io_uring
Date: Mon, 31 Aug 2026 11:02:23 +0300	[thread overview]
Message-ID: <20260831080223.124050-1-frezidok1@gmail.com> (raw)

From: Dmitry Sakhonchik <frezidok1@gmail.com>

The existing test creates the output file with open(), which ends up
using openat() and is therefore intercepted by pseudo before the actual
io_uring write operation happens.

Use IORING_OP_OPENAT to create the output file through io_uring as well.
This makes the test successfully bypass pseudo

io-uring-writev.bb: wrynose doesn't support "S = ${WORKDIR}" anymore, fix it

[YOCTO #15244]

Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
---
 .../recipes-test/io-uring/io-uring-writev.bb  |  2 +-
 .../io-uring-writev/io-uring-writev.c         | 98 ++++++++++++++++---
 2 files changed, 88 insertions(+), 12 deletions(-)

diff --git a/meta-selftest/recipes-test/io-uring/io-uring-writev.bb b/meta-selftest/recipes-test/io-uring/io-uring-writev.bb
index 8b2ca6005b..f5de317429 100644
--- a/meta-selftest/recipes-test/io-uring/io-uring-writev.bb
+++ b/meta-selftest/recipes-test/io-uring/io-uring-writev.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda
 
 SRC_URI = "file://io-uring-writev.c"
 
-S = "${WORKDIR}"
+S = "${UNPACKDIR}"
 
 do_compile() {
 	${BUILD_CC} io-uring-writev.c -o io-uring-writev
diff --git a/meta-selftest/recipes-test/io-uring/io-uring-writev/io-uring-writev.c b/meta-selftest/recipes-test/io-uring/io-uring-writev/io-uring-writev.c
index a5e4253b7a..54f49fa481 100644
--- a/meta-selftest/recipes-test/io-uring/io-uring-writev/io-uring-writev.c
+++ b/meta-selftest/recipes-test/io-uring/io-uring-writev/io-uring-writev.c
@@ -20,10 +20,13 @@
 /* If your compilation fails because the header file below is missing,
  * your kernel is probably too old to support io_uring.
  * */
+#include <errno.h>
+#include <stdbool.h>
 #include <linux/io_uring.h>
 
 #define QUEUE_DEPTH 1
 #define BLOCK_SZ    1024
+#define OPEN_TAG    1
 
 /* This is x86 specific */
 #define read_barrier()  __asm__ __volatile__("":::"memory")
@@ -101,6 +104,79 @@ off_t get_file_size(int fd) {
     return -1;
 }
 
+int open_with_uring(const char* path, struct submitter *s) {
+    struct app_io_sq_ring *sring = &s->sq_ring;
+    struct app_io_cq_ring *cring = &s->cq_ring;
+
+    // Get position of the next SQE
+    unsigned tail = *sring->tail;
+    read_barrier();
+    unsigned index = tail & *sring->ring_mask;
+    unsigned next_tail = tail + 1;
+    struct io_uring_sqe *sqe = &s->sqes[index];
+
+    // Prepare SQE
+    memset(sqe, 0, sizeof(*sqe));
+    sqe->opcode = IORING_OP_OPENAT;
+    sqe->fd = AT_FDCWD;
+    sqe->addr = (unsigned long)path;
+    sqe->open_flags = O_WRONLY | O_CREAT;
+    sqe->len = 0666;
+    sqe->user_data = OPEN_TAG;
+
+    // Add prepared sqe to the submission queue
+    sring->array[index] = index;
+
+    // Update the tail so the kernel can see it
+    tail = next_tail;
+    if(*sring->tail != tail) {
+        write_barrier();
+        *sring->tail = tail;
+    }
+
+    //Tell the kernel to process events in SQ
+    int ret =  io_uring_enter(s->ring_fd, 1,1,
+            IORING_ENTER_GETEVENTS);
+    if(ret < 0) {
+        perror("io_uring_enter");
+        return -1;
+    }
+
+    //Now we need to read the output from kernel from the CQ
+    while (true) {
+        unsigned head = *cring->head;
+        tail = *cring->tail;
+        read_barrier();
+
+        if (head == tail) {
+            /*  It means the buffer is empty.
+             *  If we are here, then something went wrong and
+             *  kernel didn't return CQE with user_data == OPEN_TAG for some reason
+             */
+            fprintf(stderr, "open_with_uring error: kernel didn't return fd");
+            return -1;
+        }
+
+        index = head & *cring->ring_mask;
+        struct io_uring_cqe *cqe = &cring->cqes[index];
+
+        unsigned long long tag = cqe->user_data;
+        int res = cqe->res;
+
+        write_barrier();
+        *cring->head = head + 1;
+
+        if (tag == OPEN_TAG) {
+            if (res < 0) {
+                errno = -res;
+                perror("IORING_OP_OPENAT");
+                return -1;
+            }
+            return res;
+        }
+    }
+}
+
 /*
  * io_uring requires a lot of setup which looks pretty hairy, but isn't all
  * that difficult to understand. Because of all this boilerplate code,
@@ -155,7 +231,7 @@ int app_setup_uring(struct submitter *s) {
     /* Map in the submission and completion queue ring buffers.
      * Older kernels only map in the submission queue, though.
      * */
-    sq_ptr = mmap(0, sring_sz, PROT_READ | PROT_WRITE, 
+    sq_ptr = mmap(0, sring_sz, PROT_READ | PROT_WRITE,
             MAP_SHARED | MAP_POPULATE,
             s->ring_fd, IORING_OFF_SQ_RING);
     if (sq_ptr == MAP_FAILED) {
@@ -167,7 +243,7 @@ int app_setup_uring(struct submitter *s) {
         cq_ptr = sq_ptr;
     } else {
         /* Map in the completion queue ring buffer in older kernels separately */
-        cq_ptr = mmap(0, cring_sz, PROT_READ | PROT_WRITE, 
+        cq_ptr = mmap(0, cring_sz, PROT_READ | PROT_WRITE,
                 MAP_SHARED | MAP_POPULATE,
                 s->ring_fd, IORING_OFF_CQ_RING);
         if (cq_ptr == MAP_FAILED) {
@@ -266,8 +342,8 @@ void read_from_cq(struct submitter *s) {
 int submit_to_sq(char *file_path, struct submitter *s) {
     struct file_info *fi;
 
-    int file_fd = open(file_path, O_WRONLY|O_CREAT, 0666);
-    if (file_fd < 0 ) {
+    int file_fd = open_with_uring(file_path, s);
+    if (file_fd < 0) {
         perror("open");
         return 1;
     }
@@ -317,7 +393,7 @@ int submit_to_sq(char *file_path, struct submitter *s) {
     */
     fi->iovecs[current_block].iov_len = bytes_remaining;
     fi->iovecs[current_block].iov_base = bark;
-    
+
 
     /* Add our submission queue entry to the tail of the SQE ring buffer */
     next_tail = tail = *sring->tail;
@@ -336,7 +412,7 @@ int submit_to_sq(char *file_path, struct submitter *s) {
     tail = next_tail;
 
     /* Update the tail so the kernel can see it. */
-    if(*sring->tail != tail) {
+    if (*sring->tail != tail) {
         *sring->tail = tail;
         write_barrier();
     }
@@ -347,9 +423,9 @@ int submit_to_sq(char *file_path, struct submitter *s) {
      * io_uring_enter() call to wait until min_complete events (the 3rd param)
      * complete.
      * */
-    int ret =  io_uring_enter(s->ring_fd, 1,1,
-            IORING_ENTER_GETEVENTS);
-    if(ret < 0) {
+    int ret = io_uring_enter(s->ring_fd, 1, 1,
+                             IORING_ENTER_GETEVENTS);
+    if (ret < 0) {
         perror("io_uring_enter");
         return 1;
     }
@@ -372,13 +448,13 @@ int main(int argc, char *argv[]) {
     }
     memset(s, 0, sizeof(*s));
 
-    if(app_setup_uring(s)) {
+    if (app_setup_uring(s)) {
         fprintf(stderr, "Unable to setup uring!\n");
         return 1;
     }
 
     for (int i = 1; i < argc; i++) {
-        if(submit_to_sq(argv[i], s)) {
+        if (submit_to_sq(argv[i], s)) {
             fprintf(stderr, "Error writting file\n");
             return 1;
         }


             reply	other threads:[~2026-08-31  8:03 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31  8:02 frezidok1 [this message]
2026-09-01  5:34 ` [OE-core] [PATCH] io_uring-writev: open output file through io_uring Mathieu Dubois-Briand
2026-09-01  5:48   ` Dmitry Sakhonchik

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=20260831080223.124050-1-frezidok1@gmail.com \
    --to=frezidok1@gmail.com \
    --cc=martin.jansa@gmail.com \
    --cc=openembedded-core@lists.openembedded.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.