18c2ecf20Sopenharmony_ci#ifndef LIB_URING_H 28c2ecf20Sopenharmony_ci#define LIB_URING_H 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifdef __cplusplus 58c2ecf20Sopenharmony_ciextern "C" { 68c2ecf20Sopenharmony_ci#endif 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <sys/uio.h> 98c2ecf20Sopenharmony_ci#include <signal.h> 108c2ecf20Sopenharmony_ci#include <string.h> 118c2ecf20Sopenharmony_ci#include "../../include/uapi/linux/io_uring.h" 128c2ecf20Sopenharmony_ci#include <inttypes.h> 138c2ecf20Sopenharmony_ci#include <linux/swab.h> 148c2ecf20Sopenharmony_ci#include "barrier.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * Library interface to io_uring 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_cistruct io_uring_sq { 208c2ecf20Sopenharmony_ci unsigned *khead; 218c2ecf20Sopenharmony_ci unsigned *ktail; 228c2ecf20Sopenharmony_ci unsigned *kring_mask; 238c2ecf20Sopenharmony_ci unsigned *kring_entries; 248c2ecf20Sopenharmony_ci unsigned *kflags; 258c2ecf20Sopenharmony_ci unsigned *kdropped; 268c2ecf20Sopenharmony_ci unsigned *array; 278c2ecf20Sopenharmony_ci struct io_uring_sqe *sqes; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci unsigned sqe_head; 308c2ecf20Sopenharmony_ci unsigned sqe_tail; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci size_t ring_sz; 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistruct io_uring_cq { 368c2ecf20Sopenharmony_ci unsigned *khead; 378c2ecf20Sopenharmony_ci unsigned *ktail; 388c2ecf20Sopenharmony_ci unsigned *kring_mask; 398c2ecf20Sopenharmony_ci unsigned *kring_entries; 408c2ecf20Sopenharmony_ci unsigned *koverflow; 418c2ecf20Sopenharmony_ci struct io_uring_cqe *cqes; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci size_t ring_sz; 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistruct io_uring { 478c2ecf20Sopenharmony_ci struct io_uring_sq sq; 488c2ecf20Sopenharmony_ci struct io_uring_cq cq; 498c2ecf20Sopenharmony_ci int ring_fd; 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* 538c2ecf20Sopenharmony_ci * System calls 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_ciextern int io_uring_setup(unsigned entries, struct io_uring_params *p); 568c2ecf20Sopenharmony_ciextern int io_uring_enter(int fd, unsigned to_submit, 578c2ecf20Sopenharmony_ci unsigned min_complete, unsigned flags, sigset_t *sig); 588c2ecf20Sopenharmony_ciextern int io_uring_register(int fd, unsigned int opcode, void *arg, 598c2ecf20Sopenharmony_ci unsigned int nr_args); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* 628c2ecf20Sopenharmony_ci * Library interface 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ciextern int io_uring_queue_init(unsigned entries, struct io_uring *ring, 658c2ecf20Sopenharmony_ci unsigned flags); 668c2ecf20Sopenharmony_ciextern int io_uring_queue_mmap(int fd, struct io_uring_params *p, 678c2ecf20Sopenharmony_ci struct io_uring *ring); 688c2ecf20Sopenharmony_ciextern void io_uring_queue_exit(struct io_uring *ring); 698c2ecf20Sopenharmony_ciextern int io_uring_peek_cqe(struct io_uring *ring, 708c2ecf20Sopenharmony_ci struct io_uring_cqe **cqe_ptr); 718c2ecf20Sopenharmony_ciextern int io_uring_wait_cqe(struct io_uring *ring, 728c2ecf20Sopenharmony_ci struct io_uring_cqe **cqe_ptr); 738c2ecf20Sopenharmony_ciextern int io_uring_submit(struct io_uring *ring); 748c2ecf20Sopenharmony_ciextern struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* 778c2ecf20Sopenharmony_ci * Must be called after io_uring_{peek,wait}_cqe() after the cqe has 788c2ecf20Sopenharmony_ci * been processed by the application. 798c2ecf20Sopenharmony_ci */ 808c2ecf20Sopenharmony_cistatic inline void io_uring_cqe_seen(struct io_uring *ring, 818c2ecf20Sopenharmony_ci struct io_uring_cqe *cqe) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci if (cqe) { 848c2ecf20Sopenharmony_ci struct io_uring_cq *cq = &ring->cq; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci (*cq->khead)++; 878c2ecf20Sopenharmony_ci /* 888c2ecf20Sopenharmony_ci * Ensure that the kernel sees our new head, the kernel has 898c2ecf20Sopenharmony_ci * the matching read barrier. 908c2ecf20Sopenharmony_ci */ 918c2ecf20Sopenharmony_ci write_barrier(); 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* 968c2ecf20Sopenharmony_ci * Command prep helpers 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_cistatic inline void io_uring_sqe_set_data(struct io_uring_sqe *sqe, void *data) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci sqe->user_data = (unsigned long) data; 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic inline void *io_uring_cqe_get_data(struct io_uring_cqe *cqe) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci return (void *) (uintptr_t) cqe->user_data; 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic inline void io_uring_prep_rw(int op, struct io_uring_sqe *sqe, int fd, 1098c2ecf20Sopenharmony_ci const void *addr, unsigned len, 1108c2ecf20Sopenharmony_ci off_t offset) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci memset(sqe, 0, sizeof(*sqe)); 1138c2ecf20Sopenharmony_ci sqe->opcode = op; 1148c2ecf20Sopenharmony_ci sqe->fd = fd; 1158c2ecf20Sopenharmony_ci sqe->off = offset; 1168c2ecf20Sopenharmony_ci sqe->addr = (unsigned long) addr; 1178c2ecf20Sopenharmony_ci sqe->len = len; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic inline void io_uring_prep_readv(struct io_uring_sqe *sqe, int fd, 1218c2ecf20Sopenharmony_ci const struct iovec *iovecs, 1228c2ecf20Sopenharmony_ci unsigned nr_vecs, off_t offset) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci io_uring_prep_rw(IORING_OP_READV, sqe, fd, iovecs, nr_vecs, offset); 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic inline void io_uring_prep_read_fixed(struct io_uring_sqe *sqe, int fd, 1288c2ecf20Sopenharmony_ci void *buf, unsigned nbytes, 1298c2ecf20Sopenharmony_ci off_t offset) 1308c2ecf20Sopenharmony_ci{ 1318c2ecf20Sopenharmony_ci io_uring_prep_rw(IORING_OP_READ_FIXED, sqe, fd, buf, nbytes, offset); 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic inline void io_uring_prep_writev(struct io_uring_sqe *sqe, int fd, 1358c2ecf20Sopenharmony_ci const struct iovec *iovecs, 1368c2ecf20Sopenharmony_ci unsigned nr_vecs, off_t offset) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci io_uring_prep_rw(IORING_OP_WRITEV, sqe, fd, iovecs, nr_vecs, offset); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic inline void io_uring_prep_write_fixed(struct io_uring_sqe *sqe, int fd, 1428c2ecf20Sopenharmony_ci const void *buf, unsigned nbytes, 1438c2ecf20Sopenharmony_ci off_t offset) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci io_uring_prep_rw(IORING_OP_WRITE_FIXED, sqe, fd, buf, nbytes, offset); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic inline void io_uring_prep_poll_add(struct io_uring_sqe *sqe, int fd, 1498c2ecf20Sopenharmony_ci unsigned poll_mask) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci memset(sqe, 0, sizeof(*sqe)); 1528c2ecf20Sopenharmony_ci sqe->opcode = IORING_OP_POLL_ADD; 1538c2ecf20Sopenharmony_ci sqe->fd = fd; 1548c2ecf20Sopenharmony_ci#if __BYTE_ORDER == __BIG_ENDIAN 1558c2ecf20Sopenharmony_ci poll_mask = __swahw32(poll_mask); 1568c2ecf20Sopenharmony_ci#endif 1578c2ecf20Sopenharmony_ci sqe->poll_events = poll_mask; 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cistatic inline void io_uring_prep_poll_remove(struct io_uring_sqe *sqe, 1618c2ecf20Sopenharmony_ci void *user_data) 1628c2ecf20Sopenharmony_ci{ 1638c2ecf20Sopenharmony_ci memset(sqe, 0, sizeof(*sqe)); 1648c2ecf20Sopenharmony_ci sqe->opcode = IORING_OP_POLL_REMOVE; 1658c2ecf20Sopenharmony_ci sqe->addr = (unsigned long) user_data; 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic inline void io_uring_prep_fsync(struct io_uring_sqe *sqe, int fd, 1698c2ecf20Sopenharmony_ci unsigned fsync_flags) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci memset(sqe, 0, sizeof(*sqe)); 1728c2ecf20Sopenharmony_ci sqe->opcode = IORING_OP_FSYNC; 1738c2ecf20Sopenharmony_ci sqe->fd = fd; 1748c2ecf20Sopenharmony_ci sqe->fsync_flags = fsync_flags; 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic inline void io_uring_prep_nop(struct io_uring_sqe *sqe) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci memset(sqe, 0, sizeof(*sqe)); 1808c2ecf20Sopenharmony_ci sqe->opcode = IORING_OP_NOP; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci#ifdef __cplusplus 1848c2ecf20Sopenharmony_ci} 1858c2ecf20Sopenharmony_ci#endif 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci#endif 188