@@ -1578,8 +1578,12 @@ static void io_clean_op(struct io_kiocb *req)
if (req->flags & REQ_F_CREDS)
put_cred(req->creds);
if (req->flags & REQ_F_ASYNC_DATA) {
- kfree(req->async_data);
- req->async_data = NULL;
+ const struct io_op_def *def = &io_op_defs[req->opcode];
+
+ if (!(def->recycle_async && def->recycle_async(req))) {
+ kfree(req->async_data);
+ req->async_data = NULL;
+ }
}
req->flags &= ~IO_REQ_CLEAN_FLAGS;
}
@@ -34,6 +34,7 @@ struct io_op_def {
int (*issue)(struct io_kiocb *, unsigned int);
int (*prep_async)(struct io_kiocb *);
void (*cleanup)(struct io_kiocb *);
+ bool (*recycle_async)(struct io_kiocb *);
};
extern const struct io_op_def io_op_defs[];
Some ops recycle or cache async data when they are done. Build this into the framework for async data so that we can rely on io_uring to know when a request is done (rather than doing it inline in a handler). Signed-off-by: Dylan Yudaken <dylany@fb.com> --- io_uring/io_uring.c | 8 ++++++-- io_uring/opdef.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)