On 12/22/21 7:48 PM, David Butler wrote: > Hello, > > I'm trying to learn the basics of io_uring. I have this code `hello_uring.cpp': > > // clang-13 -O0 -glldb -fsanitize=address -fno-exceptions -Wall > -Werror -luring hello_uring.cpp -o build/hello_uring.exec > #include <fcntl.h> > #include <stdio.h> > #include <assert.h> > #include <liburing.h> > > #define error_check(v) if ((u_int64_t)v == -1) {perror(#v); > assert((u_int64_t)v != -1);} > static int const queue_depth = 4; > static int const buf_size = 1<<10; > > char buffers[queue_depth][buf_size]; > > int main () { int r; > > { > // setup test > auto f = fopen("build/testfile2", "w"); > for (unsigned long i = 0; i< 1024; i++) { > fwrite(&i, sizeof i, 1, f); > } > fclose(f); > } > > auto file_fd = open("build/testfile2", O_RDONLY); > > io_uring ring; > r = io_uring_queue_init(queue_depth, &ring, 0); > error_check(r); > > { > struct iovec vecs[queue_depth]; > for (int veci = 0; veci < queue_depth; veci++) { > auto sqe = io_uring_get_sqe(&ring); > assert(sqe); > sqe->user_data = veci; > printf("submit: %d\n", veci); > vecs[veci] = { .iov_base = buffers[veci], .iov_len = buf_size}; > io_uring_prep_readv(sqe, file_fd, &vecs[veci], 1, veci * buf_size); > } > r = io_uring_submit(&ring); > error_check(r); > assert(r == queue_depth); > } > > for (int done_count = 0; done_count < queue_depth; done_count++) { > > struct io_uring_cqe *cqe; > r = io_uring_wait_cqe(&ring, &cqe); > error_check(r); > > printf("got_completion: %lld, %d, %d\n", cqe->user_data, > cqe->res, cqe->flags); > io_uring_cqe_seen(&ring, cqe); > } > > { > unsigned long next_value = 0; > for (int buf_i = 0; buf_i < queue_depth; buf_i++) { > for (auto buf_values = (unsigned long *)buffers[buf_i]; > (char*)buf_values < buffers[buf_i] + buf_size; buf_values++) { > assert(*buf_values == next_value++); > } > } > assert(next_value == (1024/8) * 4); > } > } > > On execution, I get all zeros for user_data on the `got_completion' > lines... I was expecting those to be 0, 1, 2, 3.... What am I missing > here? You're doing a prep command after filling in the user_data, the former clears the sqe. Move the user_data assignment after io_uring_prep_readv(). -- Jens Axboe