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