io_uring.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #include <unistd.h>
  2. #include <sys/syscall.h>
  3. #include <sys/uio.h>
  4. #include <signal.h>
  5. #define __SWIFT_IORING_SQE_FALLBACK_STRUCT { \
  6. __u8 opcode; \
  7. __u8 flags; \
  8. __u16 ioprio; \
  9. __s32 fd; \
  10. union { \
  11. __u64 off; \
  12. __u64 addr2; \
  13. struct { \
  14. __u32 cmd_op; \
  15. __u32 __pad1; \
  16. }; \
  17. }; \
  18. union { \
  19. __u64 addr; \
  20. __u64 splice_off_in; \
  21. struct { \
  22. __u32 level; \
  23. __u32 optname; \
  24. }; \
  25. }; \
  26. __u32 len; \
  27. union { \
  28. __kernel_rwf_t rw_flags; \
  29. __u32 fsync_flags; \
  30. __u16 poll_events; \
  31. __u32 poll32_events; \
  32. __u32 sync_range_flags; \
  33. __u32 msg_flags; \
  34. __u32 timeout_flags; \
  35. __u32 accept_flags; \
  36. __u32 cancel_flags; \
  37. __u32 open_flags; \
  38. __u32 statx_flags; \
  39. __u32 fadvise_advice; \
  40. __u32 splice_flags; \
  41. __u32 rename_flags; \
  42. __u32 unlink_flags; \
  43. __u32 hardlink_flags; \
  44. __u32 xattr_flags; \
  45. __u32 msg_ring_flags; \
  46. __u32 uring_cmd_flags; \
  47. __u32 waitid_flags; \
  48. __u32 futex_flags; \
  49. __u32 install_fd_flags; \
  50. __u32 nop_flags; \
  51. }; \
  52. __u64 user_data; \
  53. union { \
  54. __u16 buf_index; \
  55. __u16 buf_group; \
  56. } __attribute__((packed)); \
  57. __u16 personality; \
  58. union { \
  59. __s32 splice_fd_in; \
  60. __u32 file_index; \
  61. __u32 optlen; \
  62. struct { \
  63. __u16 addr_len; \
  64. __u16 __pad3[1]; \
  65. }; \
  66. }; \
  67. union { \
  68. struct { \
  69. __u64 addr3; \
  70. __u64 __pad2[1]; \
  71. }; \
  72. __u64 optval; \
  73. __u8 cmd[0]; \
  74. }; \
  75. }
  76. #if __has_include(<linux/io_uring.h>)
  77. #include <linux/io_uring.h>
  78. #ifdef IORING_TIMEOUT_BOOTTIME
  79. // Kernel version >= 5.15, io_uring_sqe has file_index
  80. // and all current Swift operations are supported.
  81. #define __SWIFT_IORING_SUPPORTED 1
  82. typedef struct io_uring_sqe swift_io_uring_sqe;
  83. #else
  84. // io_uring_sqe is missing properties that IORequest expects.
  85. // This configuration is not supported for now.
  86. //
  87. // Define a fallback struct to avoid build errors, but IORing
  88. // will throw ENOTSUP on initialization.
  89. #define __SWIFT_IORING_SUPPORTED 0
  90. typedef struct __SWIFT_IORING_SQE_FALLBACK_STRUCT swift_io_uring_sqe;
  91. #endif
  92. // We can define more specific availability later
  93. #ifdef IORING_FEAT_RW_CUR_POS
  94. // Kernel version >= 5.6, io_uring_sqe has open_flags
  95. #endif
  96. #ifdef IORING_FEAT_NODROP
  97. // Kernel version >= 5.5, io_uring_sqe has cancel_flags
  98. #endif
  99. #else
  100. // Minimal fallback definitions when linux/io_uring.h is not available (e.g. static SDK)
  101. #include <stdint.h>
  102. #define __SWIFT_IORING_SUPPORTED 0
  103. #define IORING_OFF_SQ_RING 0ULL
  104. #define IORING_OFF_CQ_RING 0x8000000ULL
  105. #define IORING_OFF_SQES 0x10000000ULL
  106. #define IORING_ENTER_GETEVENTS (1U << 0)
  107. #define IORING_ENTER_EXT_ARG (1U << 3)
  108. #define IORING_FEAT_SINGLE_MMAP (1U << 0)
  109. #define IORING_FEAT_NODROP (1U << 1)
  110. #define IORING_FEAT_SUBMIT_STABLE (1U << 2)
  111. #define IORING_FEAT_RW_CUR_POS (1U << 3)
  112. #define IORING_FEAT_CUR_PERSONALITY (1U << 4)
  113. #define IORING_FEAT_FAST_POLL (1U << 5)
  114. #define IORING_FEAT_POLL_32BITS (1U << 6)
  115. #define IORING_FEAT_SQPOLL_NONFIXED (1U << 7)
  116. #define IORING_FEAT_EXT_ARG (1U << 8)
  117. #define IORING_FEAT_NATIVE_WORKERS (1U << 9)
  118. #define IORING_FEAT_RSRC_TAGS (1U << 10)
  119. #define IORING_FEAT_CQE_SKIP (1U << 11)
  120. #define IORING_FEAT_LINKED_FILE (1U << 12)
  121. #define IORING_FEAT_REG_REG_RING (1U << 13)
  122. #define IORING_FEAT_RECVSEND_BUNDLE (1U << 14)
  123. #define IORING_FEAT_MIN_TIMEOUT (1U << 15)
  124. #define IORING_FEAT_RW_ATTR (1U << 16)
  125. #define IORING_FEAT_NO_IOWAIT (1U << 17)
  126. #if !defined(_ASM_GENERIC_INT_LL64_H) && !defined(_ASM_GENERIC_INT_L64_H) && !defined(_UAPI_ASM_GENERIC_INT_LL64_H) && !defined(_UAPI_ASM_GENERIC_INT_L64_H)
  127. typedef uint8_t __u8;
  128. typedef uint16_t __u16;
  129. typedef uint32_t __u32;
  130. typedef uint64_t __u64;
  131. typedef int32_t __s32;
  132. #endif
  133. #ifndef __kernel_rwf_t
  134. typedef int __kernel_rwf_t;
  135. #endif
  136. typedef struct __SWIFT_IORING_SQE_FALLBACK_STRUCT swift_io_uring_sqe;
  137. struct io_uring_cqe {
  138. __u64 user_data;
  139. __s32 res;
  140. __u32 flags;
  141. };
  142. struct io_sqring_offsets {
  143. __u32 head;
  144. __u32 tail;
  145. __u32 ring_mask;
  146. __u32 ring_entries;
  147. __u32 flags;
  148. __u32 dropped;
  149. __u32 array;
  150. __u32 resv1;
  151. __u64 user_addr;
  152. };
  153. struct io_cqring_offsets {
  154. __u32 head;
  155. __u32 tail;
  156. __u32 ring_mask;
  157. __u32 ring_entries;
  158. __u32 overflow;
  159. __u32 cqes;
  160. __u32 flags;
  161. __u32 resv1;
  162. __u64 user_addr;
  163. };
  164. struct io_uring_params {
  165. __u32 sq_entries;
  166. __u32 cq_entries;
  167. __u32 flags;
  168. __u32 sq_thread_cpu;
  169. __u32 sq_thread_idle;
  170. __u32 features;
  171. __u32 wq_fd;
  172. __u32 resv[3];
  173. struct io_sqring_offsets sq_off;
  174. struct io_cqring_offsets cq_off;
  175. };
  176. #endif // __has_include(<linux/io_uring.h>)
  177. #ifndef SWIFT_IORING_C_WRAPPER
  178. #define SWIFT_IORING_C_WRAPPER
  179. # ifndef __NR_io_uring_setup
  180. # define __NR_io_uring_setup 425
  181. # endif
  182. # ifndef __NR_io_uring_enter
  183. # define __NR_io_uring_enter 426
  184. # endif
  185. # ifndef __NR_io_uring_register
  186. # define __NR_io_uring_register 427
  187. # endif
  188. /*
  189. struct io_uring_getevents_arg {
  190. __u64 sigmask;
  191. __u32 sigmask_sz;
  192. __u32 min_wait_usec; //used to be called `pad`. This compatibility wrapper avoids dealing with that.
  193. __u64 ts;
  194. };
  195. */
  196. struct swift_io_uring_getevents_arg {
  197. __u64 sigmask;
  198. __u32 sigmask_sz;
  199. __u32 min_wait_usec;
  200. __u64 ts;
  201. };
  202. static inline int io_uring_register(int fd, unsigned int opcode, void *arg,
  203. unsigned int nr_args)
  204. {
  205. return syscall(__NR_io_uring_register, fd, opcode, arg, nr_args);
  206. }
  207. static inline int io_uring_setup(unsigned int entries, struct io_uring_params *p)
  208. {
  209. return syscall(__NR_io_uring_setup, entries, p);
  210. }
  211. static inline int io_uring_enter2(int fd, unsigned int to_submit, unsigned int min_complete,
  212. unsigned int flags, void *args, size_t sz)
  213. {
  214. return syscall(__NR_io_uring_enter, fd, to_submit, min_complete,
  215. flags, args, sz);
  216. }
  217. static inline int io_uring_enter(int fd, unsigned int to_submit, unsigned int min_complete,
  218. unsigned int flags, sigset_t *sig)
  219. {
  220. return io_uring_enter2(fd, to_submit, min_complete, flags, sig, _NSIG / 8);
  221. }
  222. #endif