xref: /spdk/module/fsdev/aio/aio_mgr.c (revision a29d7fdf9ba2d019916288e092b6be04c4ec2aa3)
1e21c39aaSAnton Nayshtut /*   SPDX-License-Identifier: BSD-3-Clause
2e21c39aaSAnton Nayshtut  *   Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3e21c39aaSAnton Nayshtut  */
4e21c39aaSAnton Nayshtut #include "spdk/stdinc.h"
5e21c39aaSAnton Nayshtut #include "spdk/util.h"
6e21c39aaSAnton Nayshtut #include "spdk/log.h"
7e21c39aaSAnton Nayshtut #include "aio_mgr.h"
8e21c39aaSAnton Nayshtut 
9e21c39aaSAnton Nayshtut #define REQS_PER_AIO 10
10e21c39aaSAnton Nayshtut 
11e21c39aaSAnton Nayshtut struct spdk_aio_mgr_req {
12e21c39aaSAnton Nayshtut 	struct aiocb io;
13e21c39aaSAnton Nayshtut 	TAILQ_ENTRY(spdk_aio_mgr_req) link;
14e21c39aaSAnton Nayshtut };
15e21c39aaSAnton Nayshtut 
16e21c39aaSAnton Nayshtut struct spdk_aio_mgr_io {
17e21c39aaSAnton Nayshtut 	TAILQ_ENTRY(spdk_aio_mgr_io) link;
18e21c39aaSAnton Nayshtut 	TAILQ_HEAD(, spdk_aio_mgr_req) reqs;
19e21c39aaSAnton Nayshtut 	struct spdk_aio_mgr *mgr;
20e21c39aaSAnton Nayshtut 	fsdev_aio_done_cb clb;
21e21c39aaSAnton Nayshtut 	void *ctx;
22e21c39aaSAnton Nayshtut 	uint32_t data_size;
23e21c39aaSAnton Nayshtut 	int err;
24e21c39aaSAnton Nayshtut };
25e21c39aaSAnton Nayshtut 
26e21c39aaSAnton Nayshtut struct spdk_aio_mgr {
27e21c39aaSAnton Nayshtut 	TAILQ_HEAD(, spdk_aio_mgr_io) in_flight;
28e21c39aaSAnton Nayshtut 	struct {
29e21c39aaSAnton Nayshtut 		struct spdk_aio_mgr_req *arr;
30e21c39aaSAnton Nayshtut 		uint32_t size;
31e21c39aaSAnton Nayshtut 		TAILQ_HEAD(, spdk_aio_mgr_req) pool;
32e21c39aaSAnton Nayshtut 	} reqs;
33e21c39aaSAnton Nayshtut 	struct {
34e21c39aaSAnton Nayshtut 		struct spdk_aio_mgr_io *arr;
35e21c39aaSAnton Nayshtut 		uint32_t size;
36e21c39aaSAnton Nayshtut 		TAILQ_HEAD(, spdk_aio_mgr_io) pool;
37e21c39aaSAnton Nayshtut 	} aios;
38e21c39aaSAnton Nayshtut };
39e21c39aaSAnton Nayshtut 
40e21c39aaSAnton Nayshtut static inline struct spdk_aio_mgr_req *
41e21c39aaSAnton Nayshtut aio_mgr_get_aio_req(struct spdk_aio_mgr *mgr)
42e21c39aaSAnton Nayshtut {
43e21c39aaSAnton Nayshtut 	struct spdk_aio_mgr_req *req = TAILQ_FIRST(&mgr->reqs.pool);
44e21c39aaSAnton Nayshtut 
45e21c39aaSAnton Nayshtut 	if (req) {
46e21c39aaSAnton Nayshtut 		TAILQ_REMOVE(&mgr->reqs.pool, req, link);
47e21c39aaSAnton Nayshtut 	}
48e21c39aaSAnton Nayshtut 
49e21c39aaSAnton Nayshtut 	return req;
50e21c39aaSAnton Nayshtut }
51e21c39aaSAnton Nayshtut 
52e21c39aaSAnton Nayshtut static inline void
53e21c39aaSAnton Nayshtut aio_mgr_put_aio_req(struct spdk_aio_mgr *mgr, struct spdk_aio_mgr_req *req)
54e21c39aaSAnton Nayshtut {
55e21c39aaSAnton Nayshtut 	TAILQ_INSERT_TAIL(&mgr->reqs.pool, req, link);
56e21c39aaSAnton Nayshtut }
57e21c39aaSAnton Nayshtut 
58e21c39aaSAnton Nayshtut static uint32_t
59e21c39aaSAnton Nayshtut fsdev_aio_submit(struct spdk_aio_mgr_io *aio, int fd, uint64_t offs, uint32_t size,
60e21c39aaSAnton Nayshtut 		 struct iovec *iovs,
61e21c39aaSAnton Nayshtut 		 uint32_t iovcnt, int (*aio_submit_func)(struct aiocb *), const char *aio_type)
62e21c39aaSAnton Nayshtut {
63e21c39aaSAnton Nayshtut 	uint32_t bytes_handled = 0;
64e21c39aaSAnton Nayshtut 	uint32_t iov_idx = 0;
65e21c39aaSAnton Nayshtut 
66e21c39aaSAnton Nayshtut 	assert(aio->mgr);
67e21c39aaSAnton Nayshtut 	assert(!aio->err);
68e21c39aaSAnton Nayshtut 	assert(iovs != NULL);
69e21c39aaSAnton Nayshtut 	assert(iovcnt != 0);
70e21c39aaSAnton Nayshtut 
71e21c39aaSAnton Nayshtut 	while (size && iov_idx < iovcnt) {
72e21c39aaSAnton Nayshtut 		struct spdk_aio_mgr_req *req;
73e21c39aaSAnton Nayshtut 		struct iovec *iov = &iovs[iov_idx];
74e21c39aaSAnton Nayshtut 		size_t ho_handle = spdk_min(iov->iov_len, size);
75e21c39aaSAnton Nayshtut 
76e21c39aaSAnton Nayshtut 		req = aio_mgr_get_aio_req(aio->mgr);
77e21c39aaSAnton Nayshtut 		if (!req) {
78e21c39aaSAnton Nayshtut 			SPDK_ERRLOG("cannot get aio req\n");
79e21c39aaSAnton Nayshtut 			aio->err = EINVAL;
80e21c39aaSAnton Nayshtut 			break;
81e21c39aaSAnton Nayshtut 		}
82e21c39aaSAnton Nayshtut 
83e21c39aaSAnton Nayshtut 		memset(&req->io, 0, sizeof(req->io));
84e21c39aaSAnton Nayshtut 
85e21c39aaSAnton Nayshtut 		req->io.aio_nbytes = ho_handle;
86e21c39aaSAnton Nayshtut 		req->io.aio_buf = iov->iov_base;
87e21c39aaSAnton Nayshtut 		req->io.aio_offset = offs + bytes_handled;
88e21c39aaSAnton Nayshtut 		req->io.aio_fildes = fd;
89e21c39aaSAnton Nayshtut 
90e21c39aaSAnton Nayshtut 		SPDK_DEBUGLOG(spdk_aio_mgr_io,
91e21c39aaSAnton Nayshtut 			      "aio to %s: aio=%p req=%p aio_nbytes=%zu aio_buf=%p aio_offset=%" PRIu64 " aio_fildes=%d\n",
92e21c39aaSAnton Nayshtut 			      aio_type, aio, req, req->io.aio_nbytes, req->io.aio_buf, (uint64_t)req->io.aio_offset,
93e21c39aaSAnton Nayshtut 			      req->io.aio_fildes);
94e21c39aaSAnton Nayshtut 
95e21c39aaSAnton Nayshtut 		if (aio_submit_func(&req->io)) {
96e21c39aaSAnton Nayshtut 			aio->err = errno;
97e21c39aaSAnton Nayshtut 			SPDK_ERRLOG("aio_%s of io[%" PRIu32 "] at offset %" PRIu64 " failed with err=%d\n",
98e21c39aaSAnton Nayshtut 				    aio_type, iov_idx, offs, aio->err);
99e21c39aaSAnton Nayshtut 			aio_mgr_put_aio_req(aio->mgr, req);
100e21c39aaSAnton Nayshtut 			break;
101e21c39aaSAnton Nayshtut 		}
102e21c39aaSAnton Nayshtut 
103e21c39aaSAnton Nayshtut 		TAILQ_INSERT_TAIL(&aio->reqs, req, link);
104e21c39aaSAnton Nayshtut 
105e21c39aaSAnton Nayshtut 		bytes_handled += ho_handle;
106e21c39aaSAnton Nayshtut 		size -= ho_handle;
107e21c39aaSAnton Nayshtut 
108e21c39aaSAnton Nayshtut 		iov_idx++;
109e21c39aaSAnton Nayshtut 	}
110e21c39aaSAnton Nayshtut 
111e21c39aaSAnton Nayshtut 	return bytes_handled;
112e21c39aaSAnton Nayshtut }
113e21c39aaSAnton Nayshtut 
114e21c39aaSAnton Nayshtut static void
115e21c39aaSAnton Nayshtut fsdev_aio_cancel(struct spdk_aio_mgr_io *aio)
116e21c39aaSAnton Nayshtut {
117e21c39aaSAnton Nayshtut 	struct spdk_aio_mgr_req *req;
118e21c39aaSAnton Nayshtut 	TAILQ_FOREACH(req, &aio->reqs, link) {
119e21c39aaSAnton Nayshtut 		aio_cancel(req->io.aio_fildes, &req->io);
120e21c39aaSAnton Nayshtut 	}
121e21c39aaSAnton Nayshtut }
122e21c39aaSAnton Nayshtut 
123e21c39aaSAnton Nayshtut static struct spdk_aio_mgr_io *
124e21c39aaSAnton Nayshtut aio_mgr_get_aio(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx)
125e21c39aaSAnton Nayshtut {
126e21c39aaSAnton Nayshtut 	struct spdk_aio_mgr_io *aio = TAILQ_FIRST(&mgr->aios.pool);
127e21c39aaSAnton Nayshtut 
128e21c39aaSAnton Nayshtut 	if (aio) {
129e21c39aaSAnton Nayshtut 		aio->mgr = mgr;
130e21c39aaSAnton Nayshtut 		aio->clb = clb;
131e21c39aaSAnton Nayshtut 		aio->ctx = ctx;
132e21c39aaSAnton Nayshtut 		aio->err = 0;
133e21c39aaSAnton Nayshtut 		aio->data_size = 0;
134e21c39aaSAnton Nayshtut 		TAILQ_INIT(&aio->reqs);
135e21c39aaSAnton Nayshtut 		TAILQ_REMOVE(&mgr->aios.pool, aio, link);
136e21c39aaSAnton Nayshtut 	}
137e21c39aaSAnton Nayshtut 
138e21c39aaSAnton Nayshtut 	return aio;
139e21c39aaSAnton Nayshtut }
140e21c39aaSAnton Nayshtut 
141e21c39aaSAnton Nayshtut static inline void
142e21c39aaSAnton Nayshtut aio_mgr_put_aio(struct spdk_aio_mgr *mgr, struct spdk_aio_mgr_io *aio)
143e21c39aaSAnton Nayshtut {
144e21c39aaSAnton Nayshtut 	TAILQ_INSERT_TAIL(&aio->mgr->aios.pool, aio, link);
145e21c39aaSAnton Nayshtut }
146e21c39aaSAnton Nayshtut 
147e21c39aaSAnton Nayshtut static struct spdk_aio_mgr_io *
148e21c39aaSAnton Nayshtut spdk_aio_mgr_submit_io(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx,
149e21c39aaSAnton Nayshtut 		       int fd, uint64_t offs, uint32_t size, struct iovec *iovs, uint32_t iovcnt,
150e21c39aaSAnton Nayshtut 		       int (*aio_submit_func)(struct aiocb *), const char *aio_type)
151e21c39aaSAnton Nayshtut {
152e21c39aaSAnton Nayshtut 	struct spdk_aio_mgr_io *aio;
153e21c39aaSAnton Nayshtut 	uint32_t bytes_handled;
154e21c39aaSAnton Nayshtut 
155e21c39aaSAnton Nayshtut 	SPDK_DEBUGLOG(spdk_aio_mgr_io, "%s: fd=%d offs=%" PRIu64 " size=%" PRIu32 " iovcnt=%" PRIu32 "\n",
156e21c39aaSAnton Nayshtut 		      aio_type, fd, offs, size, iovcnt);
157e21c39aaSAnton Nayshtut 
158e21c39aaSAnton Nayshtut 	aio = aio_mgr_get_aio(mgr, clb, ctx);
159e21c39aaSAnton Nayshtut 	if (!aio) {
160e21c39aaSAnton Nayshtut 		SPDK_ERRLOG("Cannot get aio\n");
161e21c39aaSAnton Nayshtut 		clb(ctx, 0, EFAULT);
162e21c39aaSAnton Nayshtut 		return NULL;
163e21c39aaSAnton Nayshtut 	}
164e21c39aaSAnton Nayshtut 
165e21c39aaSAnton Nayshtut 	bytes_handled = fsdev_aio_submit(aio, fd, offs, size, iovs, iovcnt, aio_submit_func, aio_type);
166e21c39aaSAnton Nayshtut 	SPDK_DEBUGLOG(spdk_aio_mgr_io, "%s: aio=%p: handled %" PRIu32 " bytes\n", aio_type, aio,
167e21c39aaSAnton Nayshtut 		      bytes_handled);
168e21c39aaSAnton Nayshtut 	if (bytes_handled) {
169e21c39aaSAnton Nayshtut 		TAILQ_INSERT_TAIL(&aio->mgr->in_flight, aio, link);
170e21c39aaSAnton Nayshtut 		return aio;
171e21c39aaSAnton Nayshtut 	} else {
172e21c39aaSAnton Nayshtut 		aio->clb(aio->ctx, 0, aio->err);
173e21c39aaSAnton Nayshtut 		aio_mgr_put_aio(mgr, aio);
174e21c39aaSAnton Nayshtut 		return NULL;
175e21c39aaSAnton Nayshtut 	}
176e21c39aaSAnton Nayshtut }
177e21c39aaSAnton Nayshtut 
178e21c39aaSAnton Nayshtut struct spdk_aio_mgr *
179e21c39aaSAnton Nayshtut spdk_aio_mgr_create(uint32_t max_aios)
180e21c39aaSAnton Nayshtut {
181e21c39aaSAnton Nayshtut 	struct spdk_aio_mgr *mgr;
182e21c39aaSAnton Nayshtut 	uint32_t i;
183e21c39aaSAnton Nayshtut 
184e21c39aaSAnton Nayshtut 	mgr = calloc(1, sizeof(*mgr));
185e21c39aaSAnton Nayshtut 	if (!mgr) {
186e21c39aaSAnton Nayshtut 		SPDK_ERRLOG("cannot alloc mgr of %zu bytes\n", sizeof(*mgr));
187e21c39aaSAnton Nayshtut 		return NULL;
188e21c39aaSAnton Nayshtut 	}
189e21c39aaSAnton Nayshtut 
190e21c39aaSAnton Nayshtut 	mgr->reqs.arr = calloc(max_aios * REQS_PER_AIO, sizeof(mgr->reqs.arr[0]));
191e21c39aaSAnton Nayshtut 	if (!mgr->reqs.arr) {
192e21c39aaSAnton Nayshtut 		SPDK_ERRLOG("cannot alloc req pool of %" PRIu32 " * %d\n", max_aios, REQS_PER_AIO);
193e21c39aaSAnton Nayshtut 		free(mgr);
194e21c39aaSAnton Nayshtut 		return NULL;
195e21c39aaSAnton Nayshtut 	}
196e21c39aaSAnton Nayshtut 
197e21c39aaSAnton Nayshtut 	mgr->aios.arr = calloc(max_aios, sizeof(mgr->aios.arr[0]));
198e21c39aaSAnton Nayshtut 	if (!mgr->aios.arr) {
199e21c39aaSAnton Nayshtut 		SPDK_ERRLOG("cannot alloc aios pool of %" PRIu32 "\n", max_aios);
200e21c39aaSAnton Nayshtut 		free(mgr->reqs.arr);
201e21c39aaSAnton Nayshtut 		free(mgr);
202e21c39aaSAnton Nayshtut 		return NULL;
203e21c39aaSAnton Nayshtut 	}
204e21c39aaSAnton Nayshtut 
205e21c39aaSAnton Nayshtut 	TAILQ_INIT(&mgr->in_flight);
206e21c39aaSAnton Nayshtut 	TAILQ_INIT(&mgr->reqs.pool);
207e21c39aaSAnton Nayshtut 	TAILQ_INIT(&mgr->aios.pool);
208e21c39aaSAnton Nayshtut 
209e21c39aaSAnton Nayshtut 	for (i = 0; i < max_aios * REQS_PER_AIO; i++) {
210e21c39aaSAnton Nayshtut 		TAILQ_INSERT_TAIL(&mgr->reqs.pool, &mgr->reqs.arr[i], link);
211e21c39aaSAnton Nayshtut 	}
212e21c39aaSAnton Nayshtut 
213e21c39aaSAnton Nayshtut 	for (i = 0; i < max_aios; i++) {
214e21c39aaSAnton Nayshtut 		TAILQ_INSERT_TAIL(&mgr->aios.pool, &mgr->aios.arr[i], link);
215e21c39aaSAnton Nayshtut 	}
216e21c39aaSAnton Nayshtut 
217e21c39aaSAnton Nayshtut 	return mgr;
218e21c39aaSAnton Nayshtut }
219e21c39aaSAnton Nayshtut 
220e21c39aaSAnton Nayshtut struct spdk_aio_mgr_io *
221e21c39aaSAnton Nayshtut spdk_aio_mgr_read(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx,
222e21c39aaSAnton Nayshtut 		  int fd, uint64_t offs, uint32_t size, struct iovec *iovs, uint32_t iovcnt)
223e21c39aaSAnton Nayshtut {
224e21c39aaSAnton Nayshtut 	return spdk_aio_mgr_submit_io(mgr, clb, ctx, fd, offs, size, iovs, iovcnt, aio_read, "read");
225e21c39aaSAnton Nayshtut }
226e21c39aaSAnton Nayshtut 
227e21c39aaSAnton Nayshtut struct spdk_aio_mgr_io *
228e21c39aaSAnton Nayshtut spdk_aio_mgr_write(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx,
229e21c39aaSAnton Nayshtut 		   int fd, uint64_t offs, uint32_t size, const struct iovec *iovs, uint32_t iovcnt)
230e21c39aaSAnton Nayshtut {
231e21c39aaSAnton Nayshtut 	return spdk_aio_mgr_submit_io(mgr, clb, ctx, fd, offs, size, (struct iovec *)iovs, iovcnt,
232e21c39aaSAnton Nayshtut 				      aio_write, "write");
233e21c39aaSAnton Nayshtut }
234e21c39aaSAnton Nayshtut 
235e21c39aaSAnton Nayshtut 
236e21c39aaSAnton Nayshtut void
237e21c39aaSAnton Nayshtut spdk_aio_mgr_cancel(struct spdk_aio_mgr *mgr, struct spdk_aio_mgr_io *aio)
238e21c39aaSAnton Nayshtut {
239e21c39aaSAnton Nayshtut 	assert(mgr == aio->mgr);
240e21c39aaSAnton Nayshtut 
241e21c39aaSAnton Nayshtut 	SPDK_DEBUGLOG(spdk_aio_mgr_io, "aio=%p cancelled\n", aio);
242e21c39aaSAnton Nayshtut 	fsdev_aio_cancel(aio);
243e21c39aaSAnton Nayshtut }
244e21c39aaSAnton Nayshtut 
245*a29d7fdfSAnton Nayshtut bool
246e21c39aaSAnton Nayshtut spdk_aio_mgr_poll(struct spdk_aio_mgr *mgr)
247e21c39aaSAnton Nayshtut {
248e21c39aaSAnton Nayshtut 	struct spdk_aio_mgr_io *aio, *tmp_aio;
249*a29d7fdfSAnton Nayshtut 	uint32_t num_completions = 0;
250e21c39aaSAnton Nayshtut 	TAILQ_FOREACH_SAFE(aio, &mgr->in_flight, link, tmp_aio) {
251e21c39aaSAnton Nayshtut 		struct spdk_aio_mgr_req *req, *tmp_req;
252e21c39aaSAnton Nayshtut 		TAILQ_FOREACH_SAFE(req, &aio->reqs, link, tmp_req) {
253e21c39aaSAnton Nayshtut 			ssize_t ret;
254e21c39aaSAnton Nayshtut 			int err = aio_error(&req->io);
255e21c39aaSAnton Nayshtut 			if (err == EINPROGRESS) { /* the request has not been completed yet */
256e21c39aaSAnton Nayshtut 				break; /* stop checking completions for this aio */
257e21c39aaSAnton Nayshtut 			}
258e21c39aaSAnton Nayshtut 
259*a29d7fdfSAnton Nayshtut 			if (!err) { /* the request completed successfully */
260e21c39aaSAnton Nayshtut 				;
261e21c39aaSAnton Nayshtut 			} else if (err == ECANCELED) { /* the request was canceled */
262e21c39aaSAnton Nayshtut 				SPDK_WARNLOG("aio processing was cancelled\n");
263e21c39aaSAnton Nayshtut 				aio->err = EAGAIN;
264e21c39aaSAnton Nayshtut 			} else {
265e21c39aaSAnton Nayshtut 				SPDK_ERRLOG("aio processing failed with err=%d\n", err);
266e21c39aaSAnton Nayshtut 				aio->err = err;
267e21c39aaSAnton Nayshtut 			}
268e21c39aaSAnton Nayshtut 
269e21c39aaSAnton Nayshtut 			ret = aio_return(&req->io);
270e21c39aaSAnton Nayshtut 			if (ret > 0) {
271e21c39aaSAnton Nayshtut 				aio->data_size += ret;
272e21c39aaSAnton Nayshtut 			}
273e21c39aaSAnton Nayshtut 
274e21c39aaSAnton Nayshtut 			SPDK_DEBUGLOG(spdk_aio_mgr_io, "aio completed: aio=%p req=%p err=%d ret=%zd\n", aio, req, err, ret);
275e21c39aaSAnton Nayshtut 
276e21c39aaSAnton Nayshtut 			/* the request processing is done */
277e21c39aaSAnton Nayshtut 			TAILQ_REMOVE(&aio->reqs, req, link); /* remove the req from the aio */
278e21c39aaSAnton Nayshtut 			TAILQ_INSERT_TAIL(&mgr->reqs.pool, req, link); /* return the req to the pool */
279*a29d7fdfSAnton Nayshtut 			num_completions++;
280e21c39aaSAnton Nayshtut 			if (TAILQ_EMPTY(&aio->reqs)) { /* all the aio's requests have been processed */
281e21c39aaSAnton Nayshtut 				SPDK_DEBUGLOG(spdk_aio_mgr_io, "aio=%p is done (data_size=%" PRIu32 ")\n", aio, aio->data_size);
282e21c39aaSAnton Nayshtut 				aio->clb(aio->ctx, aio->data_size, aio->err); /* call the user's callback */
283e21c39aaSAnton Nayshtut 				TAILQ_REMOVE(&mgr->in_flight, aio, link); /* remove the aio from the in_flight aios list */
284e21c39aaSAnton Nayshtut 				TAILQ_INSERT_TAIL(&mgr->aios.pool, aio, link); /* return the aio to the pool */
285e21c39aaSAnton Nayshtut 			}
286e21c39aaSAnton Nayshtut 		}
287e21c39aaSAnton Nayshtut 	}
288*a29d7fdfSAnton Nayshtut 
289*a29d7fdfSAnton Nayshtut 	return num_completions ? true : false;
290e21c39aaSAnton Nayshtut }
291e21c39aaSAnton Nayshtut 
292e21c39aaSAnton Nayshtut void
293e21c39aaSAnton Nayshtut spdk_aio_mgr_delete(struct spdk_aio_mgr *mgr)
294e21c39aaSAnton Nayshtut {
295e21c39aaSAnton Nayshtut 	assert(TAILQ_EMPTY(&mgr->in_flight));
296e21c39aaSAnton Nayshtut 	free(mgr->aios.arr);
297e21c39aaSAnton Nayshtut 	free(mgr->reqs.arr);
298e21c39aaSAnton Nayshtut 	free(mgr);
299e21c39aaSAnton Nayshtut }
300e21c39aaSAnton Nayshtut 
301e21c39aaSAnton Nayshtut SPDK_LOG_REGISTER_COMPONENT(spdk_aio_mgr_io)
302