Skip to content

Instantly share code, notes, and snippets.

@cs-qyzhang
Last active February 27, 2024 10:03
Show Gist options
  • Save cs-qyzhang/27c6e0821670fe02ddaede1046135eba to your computer and use it in GitHub Desktop.
Save cs-qyzhang/27c6e0821670fe02ddaede1046135eba to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/nvme_ioctl.h>
#include <liburing.h>
int iouring_setup(unsigned entries, struct io_uring *ring)
{
return io_uring_queue_init(entries, ring, IORING_SETUP_SQE128 |
IORING_SETUP_CQE32);
}
void iouring_exit(struct io_uring *ring)
{
io_uring_queue_exit(ring);
}
int iouring_passthru_enqueue(struct io_uring *ring, int fd,
const struct nvme_uring_cmd *cmd)
{
// https://github.com/joshkan/fio/blob/big-cqe-pt.v4/engines/io_uring.c
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
if (!sqe) {
printf("Failed to get io_uring sqe\n");
return -1;
}
// fd = open('/dev/ng0n1')
// see https://lpc.events/event/11/contributions/989/attachments/747/1723/lpc-2021-building-a-fast-passthru.pdf
sqe->fd = fd;
sqe->opcode = IORING_OP_URING_CMD;
sqe->cmd_op = NVME_URING_CMD_IO; // see linux/nvme_ioctl.h
memcpy(sqe->cmd, cmd, sizeof(struct nvme_uring_cmd));
return 0;
}
int iouring_submit(struct io_uring *ring)
{
int nr = io_uring_submit(ring);
if (nr < 0) {
perror("io_uring_submit");
return -1;
}
return nr;
}
int iouring_wait_nr(struct io_uring *ring, int nr)
{
struct io_uring_cqe *cqes = NULL;
if (io_uring_wait_cqe_nr(ring, &cqes, nr) < 0) {
perror("io_uring_wait_cqes");
return -1;
}
for (int i = 0; i < nr; i++) {
struct io_uring_cqe *cqe = &cqes[i];
int err = cqe->big_cqe[0] || cqe->res;
if (err) {
fprintf(stderr, "io_uring_wait_cqe_nr: %d, %s\n", err, strerror(-err));
return -1;
}
}
return nr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment