blob: ce5d23704baefb93bbbdbd66f935fa2754dfeb39 [file] [log] [blame]
Jens Axboee5024352020-02-11 20:34:12 -07001/* SPDX-License-Identifier: MIT */
Simon Zenidf6b9a92020-10-28 21:19:59 -04002#define _POSIX_C_SOURCE 200112L
3
Jens Axboe213d6f32019-01-17 21:40:30 -07004#include <sys/types.h>
5#include <sys/stat.h>
6#include <sys/mman.h>
7#include <unistd.h>
8#include <errno.h>
9#include <string.h>
Jens Axboe043ea222019-06-17 11:41:15 -060010#include <stdbool.h>
Jens Axboe213d6f32019-01-17 21:40:30 -070011
Stefan Hajnoczic31c7ec2019-07-24 09:24:50 +010012#include "liburing/compat.h"
13#include "liburing/io_uring.h"
Jens Axboe213d6f32019-01-17 21:40:30 -070014#include "liburing.h"
Stefan Hajnoczic31c7ec2019-07-24 09:24:50 +010015#include "liburing/barrier.h"
Jens Axboe213d6f32019-01-17 21:40:30 -070016
Jens Axboe96144ea2019-12-01 11:21:39 -070017#include "syscall.h"
18
Jens Axboe98455102019-11-27 17:21:38 -070019/*
20 * Returns true if we're not using SQ thread (thus nobody submits but us)
21 * or if IORING_SQ_NEED_WAKEUP is set, so submit thread must be explicitly
22 * awakened. For the latter case, we set the thread wakeup flag.
23 */
Jens Axboe1bafb3c2020-08-20 21:40:16 -060024static inline bool sq_ring_needs_enter(struct io_uring *ring, unsigned *flags)
Jens Axboe98455102019-11-27 17:21:38 -070025{
Jens Axboe1bafb3c2020-08-20 21:40:16 -060026 if (!(ring->flags & IORING_SETUP_SQPOLL))
Jens Axboe98455102019-11-27 17:21:38 -070027 return true;
Nuno Sac0b15122021-01-14 22:14:04 +010028
29 if (uring_unlikely(IO_URING_READ_ONCE(*ring->sq.kflags) &
30 IORING_SQ_NEED_WAKEUP)) {
31 *flags |= IORING_ENTER_SQ_WAKEUP;
32 return true;
33 }
Jens Axboe98455102019-11-27 17:21:38 -070034
35 return false;
36}
37
Xiaoguang Wang122eca62020-07-09 09:16:20 +080038static inline bool cq_ring_needs_flush(struct io_uring *ring)
39{
40 return IO_URING_READ_ONCE(*ring->sq.kflags) & IORING_SQ_CQ_OVERFLOW;
41}
42
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070043static int __io_uring_peek_cqe(struct io_uring *ring,
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050044 struct io_uring_cqe **cqe_ptr,
45 unsigned *nr_available)
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070046{
47 struct io_uring_cqe *cqe;
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070048 int err = 0;
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050049 unsigned available;
50 unsigned mask = *ring->cq.kring_mask;
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070051
52 do {
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050053 unsigned tail = io_uring_smp_load_acquire(ring->cq.ktail);
54 unsigned head = *ring->cq.khead;
55
56 cqe = NULL;
57 available = tail - head;
58 if (!available)
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070059 break;
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050060
61 cqe = &ring->cq.cqes[head & mask];
李通洲51be5d32021-02-08 10:28:07 +080062 if (!(ring->features & IORING_FEAT_EXT_ARG) &&
63 cqe->user_data == LIBURING_UDATA_TIMEOUT) {
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050064 if (cqe->res < 0)
65 err = cqe->res;
66 io_uring_cq_advance(ring, 1);
67 if (!err)
68 continue;
69 cqe = NULL;
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070070 }
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050071
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070072 break;
73 } while (1);
74
75 *cqe_ptr = cqe;
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050076 *nr_available = available;
Bijan Mottahedeh36c05ec2020-05-19 14:52:21 -070077 return err;
78}
79
Jens Axboe898294d2020-11-04 11:44:48 -070080struct get_data {
81 unsigned submit;
82 unsigned wait_nr;
83 unsigned get_flags;
84 int sz;
85 void *arg;
86};
87
88static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
89 struct get_data *data)
Jens Axboe213d6f32019-01-17 21:40:30 -070090{
Jens Axboe8ce3a072019-12-16 12:10:07 -070091 struct io_uring_cqe *cqe = NULL;
Pavel Begunkovbe648cf2021-02-07 23:32:17 +000092 int err;
Jens Axboe213d6f32019-01-17 21:40:30 -070093
Jens Axboe213d6f32019-01-17 21:40:30 -070094 do {
Pavel Begunkov516e9132021-02-11 23:08:13 +000095 bool need_enter = false;
Xiaoguang Wang122eca62020-07-09 09:16:20 +080096 bool cq_overflow_flush = false;
李通洲38c82de2019-12-02 22:36:04 +080097 unsigned flags = 0;
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -050098 unsigned nr_available;
Pavel Begunkovbe648cf2021-02-07 23:32:17 +000099 int ret;
Jens Axboe98455102019-11-27 17:21:38 -0700100
Marcelo Diop-Gonzalez3bdd9832020-12-03 11:07:06 -0500101 err = __io_uring_peek_cqe(ring, &cqe, &nr_available);
Jens Axboe7ad0e4b2019-12-01 09:11:31 -0700102 if (err)
Jens Axboe213d6f32019-01-17 21:40:30 -0700103 break;
Jens Axboe10a9ff82021-02-11 16:44:16 -0700104 if (!cqe && !data->wait_nr && !data->submit) {
Xiaoguang Wang122eca62020-07-09 09:16:20 +0800105 if (!cq_ring_needs_flush(ring)) {
106 err = -EAGAIN;
107 break;
108 }
109 cq_overflow_flush = true;
Jens Axboe76e92322019-09-20 22:15:38 -0600110 }
Pavel Begunkov516e9132021-02-11 23:08:13 +0000111 if (data->wait_nr > nr_available || cq_overflow_flush) {
Jens Axboe898294d2020-11-04 11:44:48 -0700112 flags = IORING_ENTER_GETEVENTS | data->get_flags;
Pavel Begunkov516e9132021-02-11 23:08:13 +0000113 need_enter = true;
114 }
115 if (data->submit) {
Jens Axboe1bafb3c2020-08-20 21:40:16 -0600116 sq_ring_needs_enter(ring, &flags);
Pavel Begunkov516e9132021-02-11 23:08:13 +0000117 need_enter = true;
118 }
119 if (!need_enter)
Pavel Begunkovbe648cf2021-02-07 23:32:17 +0000120 break;
121
122 ret = __sys_io_uring_enter2(ring->ring_fd, data->submit,
123 data->wait_nr, flags, data->arg,
124 data->sz);
Jens Axboedc14e302020-03-02 08:33:17 -0700125 if (ret < 0) {
Jens Axboe20c92932019-09-28 05:35:02 -0600126 err = -errno;
Pavel Begunkovb4fea6b2021-02-07 23:32:16 +0000127 break;
128 }
129
130 data->submit -= ret;
Jens Axboe8ce3a072019-12-16 12:10:07 -0700131 if (cqe)
Jens Axboe7ad0e4b2019-12-01 09:11:31 -0700132 break;
Pavel Begunkovb4fea6b2021-02-07 23:32:16 +0000133 } while (1);
Jens Axboe213d6f32019-01-17 21:40:30 -0700134
Jens Axboe8ce3a072019-12-16 12:10:07 -0700135 *cqe_ptr = cqe;
Jens Axboe76e92322019-09-20 22:15:38 -0600136 return err;
Jens Axboe213d6f32019-01-17 21:40:30 -0700137}
138
Jens Axboe898294d2020-11-04 11:44:48 -0700139int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
140 unsigned submit, unsigned wait_nr, sigset_t *sigmask)
141{
142 struct get_data data = {
143 .submit = submit,
144 .wait_nr = wait_nr,
Jens Axboe5a7c8ac2020-11-04 13:57:17 -0700145 .get_flags = 0,
Jens Axboe898294d2020-11-04 11:44:48 -0700146 .sz = _NSIG / 8,
147 .arg = sigmask,
148 };
149
150 return _io_uring_get_cqe(ring, cqe_ptr, &data);
151}
152
Jens Axboe213d6f32019-01-17 21:40:30 -0700153/*
James Rouzier0b88d722019-09-25 15:35:06 -0400154 * Fill in an array of IO completions up to count, if any are available.
155 * Returns the amount of IO completions filled.
156 */
Jens Axboe6d338022019-09-26 00:41:24 -0600157unsigned io_uring_peek_batch_cqe(struct io_uring *ring,
158 struct io_uring_cqe **cqes, unsigned count)
James Rouzier0b88d722019-09-25 15:35:06 -0400159{
Jens Axboe6d338022019-09-26 00:41:24 -0600160 unsigned ready;
Xiaoguang Wang20a7c012020-07-09 15:33:49 +0800161 bool overflow_checked = false;
Jens Axboe6d338022019-09-26 00:41:24 -0600162
Xiaoguang Wang20a7c012020-07-09 15:33:49 +0800163again:
Jens Axboe6d338022019-09-26 00:41:24 -0600164 ready = io_uring_cq_ready(ring);
James Rouzier0b88d722019-09-25 15:35:06 -0400165 if (ready) {
James Rouzier0b88d722019-09-25 15:35:06 -0400166 unsigned head = *ring->cq.khead;
James Rouzier0b88d722019-09-25 15:35:06 -0400167 unsigned mask = *ring->cq.kring_mask;
Jens Axboe6d338022019-09-26 00:41:24 -0600168 unsigned last;
James Rouzier0b88d722019-09-25 15:35:06 -0400169 int i = 0;
Jens Axboe6d338022019-09-26 00:41:24 -0600170
171 count = count > ready ? ready : count;
172 last = head + count;
173 for (;head != last; head++, i++)
James Rouzier0b88d722019-09-25 15:35:06 -0400174 cqes[i] = &ring->cq.cqes[head & mask];
James Rouzier0b88d722019-09-25 15:35:06 -0400175
176 return count;
177 }
178
Xiaoguang Wang20a7c012020-07-09 15:33:49 +0800179 if (overflow_checked)
180 goto done;
181
182 if (cq_ring_needs_flush(ring)) {
183 __sys_io_uring_enter(ring->ring_fd, 0, 0,
184 IORING_ENTER_GETEVENTS, NULL);
185 overflow_checked = true;
186 goto again;
187 }
188
189done:
James Rouzier0b88d722019-09-25 15:35:06 -0400190 return 0;
191}
192
193/*
Jens Axboec39a0582019-12-19 10:06:28 -0700194 * Sync internal state with kernel ring state on the SQ side. Returns the
195 * number of pending items in the SQ ring, for the shared ring.
Jens Axboe8578f0d2019-09-27 04:13:42 -0600196 */
Glauber Costa59641342020-08-21 09:25:07 -0400197int __io_uring_flush_sq(struct io_uring *ring)
Jens Axboe8578f0d2019-09-27 04:13:42 -0600198{
199 struct io_uring_sq *sq = &ring->sq;
200 const unsigned mask = *sq->kring_mask;
Jens Axboe1781f0e2019-12-11 09:00:43 -0700201 unsigned ktail, to_submit;
Jens Axboe8578f0d2019-09-27 04:13:42 -0600202
Jens Axboec39a0582019-12-19 10:06:28 -0700203 if (sq->sqe_head == sq->sqe_tail) {
204 ktail = *sq->ktail;
205 goto out;
206 }
Jens Axboe8578f0d2019-09-27 04:13:42 -0600207
208 /*
209 * Fill in sqes that we have queued up, adding them to the kernel ring
210 */
Jens Axboe8578f0d2019-09-27 04:13:42 -0600211 ktail = *sq->ktail;
212 to_submit = sq->sqe_tail - sq->sqe_head;
213 while (to_submit--) {
214 sq->array[ktail & mask] = sq->sqe_head & mask;
215 ktail++;
216 sq->sqe_head++;
Jens Axboe8578f0d2019-09-27 04:13:42 -0600217 }
218
219 /*
220 * Ensure that the kernel sees the SQE updates before it sees the tail
221 * update.
222 */
Kornilios Kourtisf3897452019-10-30 13:25:13 +0100223 io_uring_smp_store_release(sq->ktail, ktail);
Jens Axboec39a0582019-12-19 10:06:28 -0700224out:
Jens Axboe88b845d2020-12-17 17:10:18 -0700225 /*
226 * This _may_ look problematic, as we're not supposed to be reading
227 * SQ->head without acquire semantics. When we're in SQPOLL mode, the
228 * kernel submitter could be updating this right now. For non-SQPOLL,
Nuno Sa2ebc85b2021-01-14 22:18:51 +0100229 * task itself does it, and there's no potential race. But even for
Jens Axboe88b845d2020-12-17 17:10:18 -0700230 * SQPOLL, the load is going to be potentially out-of-date the very
231 * instant it's done, regardless or whether or not it's done
232 * atomically. Worst case, we're going to be over-estimating what
233 * we can submit. The point is, we need to be able to deal with this
234 * situation regardless of any perceived atomicity.
235 */
Jens Axboec39a0582019-12-19 10:06:28 -0700236 return ktail - *sq->khead;
Jens Axboe8578f0d2019-09-27 04:13:42 -0600237}
238
239/*
Jens Axboeba0a2e42020-11-04 14:34:03 -0700240 * If we have kernel support for IORING_ENTER_EXT_ARG, then we can use that
241 * more efficiently than queueing an internal timeout command.
Jens Axboe0de9d8c2020-11-04 12:02:28 -0700242 */
243static int io_uring_wait_cqes_new(struct io_uring *ring,
244 struct io_uring_cqe **cqe_ptr,
245 unsigned wait_nr, struct __kernel_timespec *ts,
246 sigset_t *sigmask)
247{
248 struct io_uring_getevents_arg arg = {
249 .sigmask = (unsigned long) sigmask,
250 .sigmask_sz = _NSIG / 8,
251 .ts = (unsigned long) ts
252 };
253 struct get_data data = {
254 .submit = __io_uring_flush_sq(ring),
255 .wait_nr = wait_nr,
Jens Axboeba0a2e42020-11-04 14:34:03 -0700256 .get_flags = IORING_ENTER_EXT_ARG,
Jens Axboe0de9d8c2020-11-04 12:02:28 -0700257 .sz = sizeof(arg),
258 .arg = &arg
259 };
260
261 return _io_uring_get_cqe(ring, cqe_ptr, &data);
262}
263
264/*
Jens Axboe76e92322019-09-20 22:15:38 -0600265 * Like io_uring_wait_cqe(), except it accepts a timeout value as well. Note
李通洲51be5d32021-02-08 10:28:07 +0800266 * that an sqe is used internally to handle the timeout. For kernel doesn't
267 * support IORING_FEAT_EXT_ARG, applications using this function must never
268 * set sqe->user_data to LIBURING_UDATA_TIMEOUT!
Jens Axboe8b93cca2019-09-21 14:44:57 -0600269 *
Jens Axboec9620252021-02-02 09:30:44 -0700270 * For kernels without IORING_FEAT_EXT_ARG (5.10 and older), if 'ts' is
271 * specified, the application need not call io_uring_submit() before
Jens Axboe4f48c042020-03-06 07:03:24 -0700272 * calling this function, as we will do that on its behalf. From this it also
273 * follows that this function isn't safe to use for applications that split SQ
274 * and CQ handling between two threads and expect that to work without
275 * synchronization, as this function manipulates both the SQ and CQ side.
Jens Axboec9620252021-02-02 09:30:44 -0700276 *
277 * For kernels with IORING_FEAT_EXT_ARG, no implicit submission is done and
278 * hence this function is safe to use for applications that split SQ and CQ
279 * handling between two threads.
Jens Axboe76e92322019-09-20 22:15:38 -0600280 */
Jens Axboeac726402019-09-27 07:26:45 -0600281int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
Jens Axboee2934e12019-10-01 10:05:16 -0600282 unsigned wait_nr, struct __kernel_timespec *ts,
283 sigset_t *sigmask)
Jens Axboe76e92322019-09-20 22:15:38 -0600284{
Jens Axboee80a08c2019-12-01 17:19:16 -0700285 unsigned to_submit = 0;
Jens Axboe76e92322019-09-20 22:15:38 -0600286
Jens Axboe7ad0e4b2019-12-01 09:11:31 -0700287 if (ts) {
Jens Axboe11e18b32019-09-21 15:04:52 -0600288 struct io_uring_sqe *sqe;
Jens Axboe217756d2019-11-22 21:43:24 -0700289 int ret;
Jens Axboe11e18b32019-09-21 15:04:52 -0600290
Jens Axboeba0a2e42020-11-04 14:34:03 -0700291 if (ring->features & IORING_FEAT_EXT_ARG)
292 return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr,
293 ts, sigmask);
294
Jens Axboe11e18b32019-09-21 15:04:52 -0600295 /*
296 * If the SQ ring is full, we may need to submit IO first
297 */
Jens Axboe76e92322019-09-20 22:15:38 -0600298 sqe = io_uring_get_sqe(ring);
Jens Axboe11e18b32019-09-21 15:04:52 -0600299 if (!sqe) {
300 ret = io_uring_submit(ring);
301 if (ret < 0)
302 return ret;
303 sqe = io_uring_get_sqe(ring);
Jens Axboee80a08c2019-12-01 17:19:16 -0700304 if (!sqe)
305 return -EAGAIN;
Jens Axboe11e18b32019-09-21 15:04:52 -0600306 }
Jens Axboe11a8f2b2019-10-15 17:31:17 -0600307 io_uring_prep_timeout(sqe, ts, wait_nr, 0);
Jens Axboe11e18b32019-09-21 15:04:52 -0600308 sqe->user_data = LIBURING_UDATA_TIMEOUT;
Jens Axboec39a0582019-12-19 10:06:28 -0700309 to_submit = __io_uring_flush_sq(ring);
Jens Axboe76e92322019-09-20 22:15:38 -0600310 }
Jens Axboe11e18b32019-09-21 15:04:52 -0600311
Jens Axboee80a08c2019-12-01 17:19:16 -0700312 return __io_uring_get_cqe(ring, cqe_ptr, to_submit, wait_nr, sigmask);
Jens Axboe213d6f32019-01-17 21:40:30 -0700313}
314
315/*
Jens Axboe217756d2019-11-22 21:43:24 -0700316 * See io_uring_wait_cqes() - this function is the same, it just always uses
317 * '1' as the wait_nr.
Jens Axboe11e18b32019-09-21 15:04:52 -0600318 */
319int io_uring_wait_cqe_timeout(struct io_uring *ring,
320 struct io_uring_cqe **cqe_ptr,
Jens Axboee2934e12019-10-01 10:05:16 -0600321 struct __kernel_timespec *ts)
Jens Axboe11e18b32019-09-21 15:04:52 -0600322{
Jens Axboeac726402019-09-27 07:26:45 -0600323 return io_uring_wait_cqes(ring, cqe_ptr, 1, ts, NULL);
Jens Axboe11e18b32019-09-21 15:04:52 -0600324}
325
326/*
Jens Axboe40b44d22019-09-27 04:10:52 -0600327 * Submit sqes acquired from io_uring_get_sqe() to the kernel.
328 *
329 * Returns number of sqes submitted
330 */
331static int __io_uring_submit(struct io_uring *ring, unsigned submitted,
332 unsigned wait_nr)
333{
334 unsigned flags;
335 int ret;
Jens Axboe213d6f32019-01-17 21:40:30 -0700336
Jens Axboe043ea222019-06-17 11:41:15 -0600337 flags = 0;
Jens Axboe1bafb3c2020-08-20 21:40:16 -0600338 if (sq_ring_needs_enter(ring, &flags) || wait_nr) {
Glauber Costabf3aeb32019-12-19 11:15:48 -0500339 if (wait_nr || (ring->flags & IORING_SETUP_IOPOLL))
Jens Axboe91dde5c2019-06-06 10:46:13 -0600340 flags |= IORING_ENTER_GETEVENTS;
Roman Penyaevdf23d2d2019-05-27 21:05:09 +0200341
Jens Axboe96144ea2019-12-01 11:21:39 -0700342 ret = __sys_io_uring_enter(ring->ring_fd, submitted, wait_nr,
343 flags, NULL);
Roman Penyaevdf23d2d2019-05-27 21:05:09 +0200344 if (ret < 0)
345 return -errno;
346 } else
347 ret = submitted;
Jens Axboe82600292019-03-05 20:12:48 -0700348
Jens Axboea8652212019-03-13 08:48:45 -0600349 return ret;
Jens Axboe213d6f32019-01-17 21:40:30 -0700350}
351
Jens Axboe94c9df32019-09-27 05:35:28 -0600352static int __io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr)
353{
Jens Axboec39a0582019-12-19 10:06:28 -0700354 return __io_uring_submit(ring, __io_uring_flush_sq(ring), wait_nr);
Jens Axboe94c9df32019-09-27 05:35:28 -0600355}
356
Jens Axboe213d6f32019-01-17 21:40:30 -0700357/*
Jens Axboe91dde5c2019-06-06 10:46:13 -0600358 * Submit sqes acquired from io_uring_get_sqe() to the kernel.
359 *
360 * Returns number of sqes submitted
361 */
362int io_uring_submit(struct io_uring *ring)
363{
Jens Axboe94c9df32019-09-27 05:35:28 -0600364 return __io_uring_submit_and_wait(ring, 0);
Jens Axboe91dde5c2019-06-06 10:46:13 -0600365}
366
367/*
368 * Like io_uring_submit(), but allows waiting for events as well.
369 *
370 * Returns number of sqes submitted
371 */
372int io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr)
373{
Jens Axboe94c9df32019-09-27 05:35:28 -0600374 return __io_uring_submit_and_wait(ring, wait_nr);
Jens Axboe91dde5c2019-06-06 10:46:13 -0600375}
376
377/*
Jens Axboe213d6f32019-01-17 21:40:30 -0700378 * Return an sqe to fill. Application must later call io_uring_submit()
379 * when it's ready to tell the kernel about it. The caller may call this
380 * function multiple times before calling io_uring_submit().
381 *
382 * Returns a vacant sqe, or NULL if we're full.
383 */
384struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring)
385{
386 struct io_uring_sq *sq = &ring->sq;
Pavel Begunkov865fe282021-01-07 23:00:27 +0000387 unsigned int head = io_uring_smp_load_acquire(sq->khead);
388 unsigned int next = sq->sqe_tail + 1;
389 struct io_uring_sqe *sqe = NULL;
Jens Axboe213d6f32019-01-17 21:40:30 -0700390
Pavel Begunkov865fe282021-01-07 23:00:27 +0000391 if (next - head <= *sq->kring_entries) {
392 sqe = &sq->sqes[sq->sqe_tail & *sq->kring_mask];
393 sq->sqe_tail = next;
394 }
395 return sqe;
Jens Axboe213d6f32019-01-17 21:40:30 -0700396}
Jens Axboe29768112020-09-05 15:25:52 -0600397
398int __io_uring_sqring_wait(struct io_uring *ring)
399{
400 int ret;
401
402 ret = __sys_io_uring_enter(ring->ring_fd, 0, 0, IORING_ENTER_SQ_WAIT,
403 NULL);
404 if (ret < 0)
405 ret = -errno;
406 return ret;
407}