xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/libdruntime/core/sys/linux/io_uring.d (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 /**
2  * D header file for the io_uring interface.
3  * Available since Linux 5.1
4  *
5  * Copyright: Copyright Jens Axboe 2019,
6  *            Copyright Christoph Hellwig 2019.
7  * License : $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Authors : Luís Ferreira
9  */
10 module core.sys.linux.io_uring;
11 
12 version (linux):
13 
14 import core.sys.linux.fs : __kernel_rwf_t;
15 
16 extern (C):
17 @system:
18 @nogc:
19 nothrow:
20 @system:
21 
22 /**
23  * IO submission data structure (Submission Queue Entry)
24  */
25 struct io_uring_sqe
26 {
27     /// type of operation for this sqe
28     ubyte opcode;
29     /// IOSQE_* flags
30     ubyte flags;
31     /// ioprio for the request
32     ushort ioprio;
33     /// file descriptor to do IO on
34     int fd;
35     union
36     {
37         /// offset into file
38         ulong off;
39         ulong addr2;
40     }
41 
42     union
43     {
44         /// pointer to buffer or iovecs
45         ulong addr;
46         ulong splice_off_in;
47     }
48 
49     /// buffer size or number of iovecs
50     uint len;
51     union
52     {
53         __kernel_rwf_t rw_flags;
54         uint fsync_flags;
55 
56         /// compatibility
57         ushort poll_events;
58         /// word-reversed for BE
59         uint poll32_events;
60 
61         uint sync_range_flags;
62         uint msg_flags;
63         uint timeout_flags;
64         uint accept_flags;
65         uint cancel_flags;
66         uint open_flags;
67         uint statx_flags;
68         uint fadvise_advice;
69         uint splice_flags;
70         uint rename_flags;
71         uint unlink_flags;
72     }
73 
74     /// data to be passed back at completion time
75     ulong user_data;
76     union
77     {
78         struct
79         {
80             /**
81              * pack this to avoid bogus arm OABI complaints
82              */
83             union
84             {
85                 align (1):
86 
87                 /// index into fixed buffers, if used
88                 ushort buf_index;
89                 /// for grouped buffer selection
90                 ushort buf_group;
91             }
92 
93             /// personality to use, if used
94             ushort personality;
95             int splice_fd_in;
96         }
97 
98         ulong[3] __pad2;
99     }
100 }
101 
102 enum
103 {
104     IOSQE_FIXED_FILE_BIT = 0,
105     IOSQE_IO_DRAIN_BIT = 1,
106     IOSQE_IO_LINK_BIT = 2,
107     IOSQE_IO_HARDLINK_BIT = 3,
108     IOSQE_ASYNC_BIT = 4,
109     IOSQE_BUFFER_SELECT_BIT = 5
110 }
111 
112 enum
113 {
114     /// use fixed fileset
115     IOSQE_FIXED_FILE = 1U << IOSQE_FIXED_FILE_BIT,
116     /// issue after inflight IO
117     IOSQE_IO_DRAIN = 1U << IOSQE_IO_DRAIN_BIT,
118     /// links next sqe
119     IOSQE_IO_LINK = 1U << IOSQE_IO_LINK_BIT,
120     /// like LINK, but stronger
121     IOSQE_IO_HARDLINK = 1U << IOSQE_IO_HARDLINK_BIT,
122     /// always go async
123     IOSQE_ASYNC = 1U << IOSQE_ASYNC_BIT,
124     /// select buffer from sqe.buf_group
125     IOSQE_BUFFER_SELECT = 1U << IOSQE_BUFFER_SELECT_BIT,
126 }
127 
128 /**
129  * io_uring_setup() flags
130  */
131 enum
132 {
133     /// io_context is polled
134     IORING_SETUP_IOPOLL = 1U << 0,
135     /// SQ poll thread
136     IORING_SETUP_SQPOLL = 1U << 1,
137     /// sq_thread_cpu is valid
138     IORING_SETUP_SQ_AFF = 1U << 2,
139     /// app defines CQ size
140     IORING_SETUP_CQSIZE = 1U << 3,
141     /// clamp SQ/CQ ring sizes
142     IORING_SETUP_CLAMP = 1U << 4,
143     /// attach to existing wq
144     IORING_SETUP_ATTACH_WQ = 1U << 5,
145     /// start with ring disabled
146     IORING_SETUP_R_DISABLED = 1U << 6,
147 }
148 
149 enum
150 {
151     IORING_OP_NOP = 0,
152     IORING_OP_READV = 1,
153     IORING_OP_WRITEV = 2,
154     IORING_OP_FSYNC = 3,
155     IORING_OP_READ_FIXED = 4,
156     IORING_OP_WRITE_FIXED = 5,
157     IORING_OP_POLL_ADD = 6,
158     IORING_OP_POLL_REMOVE = 7,
159     IORING_OP_SYNC_FILE_RANGE = 8,
160     IORING_OP_SENDMSG = 9,
161     IORING_OP_RECVMSG = 10,
162     IORING_OP_TIMEOUT = 11,
163     IORING_OP_TIMEOUT_REMOVE = 12,
164     IORING_OP_ACCEPT = 13,
165     IORING_OP_ASYNC_CANCEL = 14,
166     IORING_OP_LINK_TIMEOUT = 15,
167     IORING_OP_CONNECT = 16,
168     IORING_OP_FALLOCATE = 17,
169     IORING_OP_OPENAT = 18,
170     IORING_OP_CLOSE = 19,
171     IORING_OP_FILES_UPDATE = 20,
172     IORING_OP_STATX = 21,
173     IORING_OP_READ = 22,
174     IORING_OP_WRITE = 23,
175     IORING_OP_FADVISE = 24,
176     IORING_OP_MADVISE = 25,
177     IORING_OP_SEND = 26,
178     IORING_OP_RECV = 27,
179     IORING_OP_OPENAT2 = 28,
180     IORING_OP_EPOLL_CTL = 29,
181     IORING_OP_SPLICE = 30,
182     IORING_OP_PROVIDE_BUFFERS = 31,
183     IORING_OP_REMOVE_BUFFERS = 32,
184     IORING_OP_TEE = 33,
185     IORING_OP_SHUTDOWN = 34,
186     IORING_OP_RENAMEAT = 35,
187     IORING_OP_UNLINKAT = 36,
188 
189     IORING_OP_LAST = 37
190 }
191 
192 enum
193 {
194     IORING_FSYNC_DATASYNC = 1U << 0,
195 }
196 
197 enum
198 {
199     IORING_TIMEOUT_ABS = 1U << 0,
200     IORING_TIMEOUT_UPDATE = 1U << 1,
201 }
202 
203 enum SPLICE_F_FD_IN_FIXED = 1U << 31;
204 
205 /**
206  * IO completion data structure (Completion Queue Entry)
207  */
208 struct io_uring_cqe
209 {
210     /// submission passed back
211     ulong user_data;
212     /// result code for this event
213     int res;
214 
215     uint flags;
216 }
217 
218 /**
219  * If set, the upper 16 bits are the buffer ID
220  */
221 enum IORING_CQE_F_BUFFER = 1U << 0;
222 
223 enum
224 {
225     IORING_CQE_BUFFER_SHIFT = 16,
226 }
227 
228 /**
229  * Magic offsets for the application to mmap the data it needs
230  */
231 enum
232 {
233     IORING_OFF_SQ_RING = 0UL,
234     IORING_OFF_CQ_RING = 0x8000000UL,
235     IORING_OFF_SQES = 0x10000000UL,
236 }
237 
238 /**
239  * Filled with the offset for mmap(2)
240  */
241 struct io_sqring_offsets
242 {
243     uint head;
244     uint tail;
245     uint ring_mask;
246     uint ring_entries;
247     uint flags;
248     uint dropped;
249     uint array;
250     uint resv1;
251     ulong resv2;
252 }
253 
254 enum
255 {
256     /// needs io_uring_enter wakeup
257     IORING_SQ_NEED_WAKEUP = 1U << 0,
258     /// CQ ring is overflown
259     IORING_SQ_CQ_OVERFLOW = 1U << 1,
260 }
261 
262 struct io_cqring_offsets
263 {
264     uint head;
265     uint tail;
266     uint ring_mask;
267     uint ring_entries;
268     uint overflow;
269     uint cqes;
270     uint flags;
271     uint resv1;
272     ulong resv2;
273 }
274 
275 enum
276 {
277     /// disable eventfd notifications
278     IORING_CQ_EVENTFD_DISABLED = 1U << 0,
279 }
280 
281 /**
282  * io_uring_enter(2) flags
283  */
284 enum
285 {
286     IORING_ENTER_GETEVENTS = 1U << 0,
287     IORING_ENTER_SQ_WAKEUP = 1U << 1,
288     IORING_ENTER_SQ_WAIT = 1U << 2,
289     IORING_ENTER_EXT_ARG = 1U << 3,
290 }
291 
292 /**
293  * Passed in for io_uring_setup(2)
294  */
295 struct io_uring_params
296 {
297     uint sq_entries;
298     uint cq_entries;
299     uint flags;
300     uint sq_thread_cpu;
301     uint sq_thread_idle;
302     uint features;
303     uint wq_fd;
304     uint[3] resv;
305     io_sqring_offsets sq_off;
306     io_cqring_offsets cq_off;
307 }
308 
309 enum
310 {
311     IORING_FEAT_SINGLE_MMAP = 1U << 0,
312     IORING_FEAT_NODROP = 1U << 1,
313     IORING_FEAT_SUBMIT_STABLE = 1U << 2,
314     IORING_FEAT_RW_CUR_POS = 1U << 3,
315     IORING_FEAT_CUR_PERSONALITY = 1U << 4,
316     IORING_FEAT_FAST_POLL = 1U << 5,
317     IORING_FEAT_POLL_32BITS = 1U << 6,
318     IORING_FEAT_SQPOLL_NONFIXED = 1U << 7,
319     IORING_FEAT_EXT_ARG = 1U << 8,
320 }
321 
322 /**
323  * io_uring_register(2) opcodes and arguments
324  */
325 enum
326 {
327     IORING_REGISTER_BUFFERS = 0,
328     IORING_UNREGISTER_BUFFERS = 1,
329     IORING_REGISTER_FILES = 2,
330     IORING_UNREGISTER_FILES = 3,
331     IORING_REGISTER_EVENTFD = 4,
332     IORING_UNREGISTER_EVENTFD = 5,
333     IORING_REGISTER_FILES_UPDATE = 6,
334     IORING_REGISTER_EVENTFD_ASYNC = 7,
335     IORING_REGISTER_PROBE = 8,
336     IORING_REGISTER_PERSONALITY = 9,
337     IORING_UNREGISTER_PERSONALITY = 10,
338     IORING_REGISTER_RESTRICTIONS = 11,
339     IORING_REGISTER_ENABLE_RINGS = 12,
340 
341     IORING_REGISTER_LAST = 13
342 }
343 
344 struct io_uring_files_update
345 {
346     uint offset;
347     uint resv;
348     ulong fds;
349 }
350 
351 enum IO_URING_OP_SUPPORTED = 1U << 0;
352 
353 struct io_uring_probe_op
354 {
355     ubyte op;
356     ubyte resv;
357 
358     /// IO_URING_OP_* flags
359     ushort flags;
360     uint resv2;
361 }
362 
363 struct io_uring_probe
364 {
365     /// last opcode supported
366     ubyte last_op;
367 
368     /// length of ops[] array below
369     ubyte ops_len;
370 
371     ushort resv;
372     uint[3] resv2;
373     io_uring_probe_op[0] ops;
374 }
375 
376 struct io_uring_restriction
377 {
378     ushort opcode;
379 
380     union
381     {
382         ubyte register_op;
383         ubyte sqe_op;
384         ubyte sqe_flags;
385     }
386 
387     ubyte resv;
388     uint[3] resv2;
389 }
390 
391 enum
392 {
393     /// Allow an io_uring_register(2) opcode
394     IORING_RESTRICTION_REGISTER_OP = 0,
395 
396     /// Allow an sqe opcode
397     IORING_RESTRICTION_SQE_OP = 1,
398 
399     /// Allow sqe flags
400     IORING_RESTRICTION_SQE_FLAGS_ALLOWED = 2,
401 
402     /// Require sqe flags (these flags must be set on each submission)
403     IORING_RESTRICTION_SQE_FLAGS_REQUIRED = 3,
404 
405     IORING_RESTRICTION_LAST = 4
406 }
407 
408 struct io_uring_getevents_arg
409 {
410     ulong sigmask;
411     uint sigmask_sz;
412     uint pad;
413     ulong ts;
414 }
415