From db6f203965d9173c3128c8d1c6188d2f63bc1b3e Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Thu, 30 Jul 2020 23:09:44 +0800 Subject: [PATCH] LU-13835 llite: reuse same cl_dio_aio for one IO IO might be restarted if layout changed, this might cause ki_complete() called several times for one IO. Fixes: d1dded6 ("LU-4198 clio: AIO support for direct IO") Fixes: 84c3e85 ("LU-13697 llite: fix short io for AIO") Signed-off-by: Wang Shilong Change-Id: I791b8f9d82fae6822d38293ba22adf74560c9dce Reviewed-on: https://review.whamcloud.com/39542 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- lustre/llite/file.c | 56 ++++++++++++++++++++++++++++++----------------------- lustre/llite/rw26.c | 5 +++++ 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 0bb845f..2318ab7 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1538,6 +1538,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, int rc = 0; unsigned int retried = 0, ignore_lockless = 0; bool is_aio = false; + struct cl_dio_aio *ci_aio = NULL; ENTRY; @@ -1545,9 +1546,20 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, file_dentry(file)->d_name.name, iot == CIT_READ ? "read" : "write", *ppos, count); + io = vvp_env_thread_io(env); + if (args->via_io_subtype == IO_NORMAL && + file->f_flags & O_DIRECT) { + if (!is_sync_kiocb(args->u.normal.via_iocb)) + is_aio = true; + ci_aio = cl_aio_alloc(args->u.normal.via_iocb); + if (!ci_aio) + GOTO(out, rc = -ENOMEM); + } + restart: io = vvp_env_thread_io(env); ll_io_init(io, file, iot, args); + io->ci_aio = ci_aio; io->ci_ignore_lockless = ignore_lockless; io->ci_ndelay_tried = retried; @@ -1566,13 +1578,6 @@ restart: case IO_NORMAL: vio->vui_iter = args->u.normal.via_iter; vio->vui_iocb = args->u.normal.via_iocb; - if (file->f_flags & O_DIRECT) { - if (!is_sync_kiocb(vio->vui_iocb)) - is_aio = true; - io->ci_aio = cl_aio_alloc(vio->vui_iocb); - if (!io->ci_aio) - GOTO(out, rc = -ENOMEM); - } /* Direct IO reads must also take range lock, * or multiple reads will try to work on the same pages * See LU-6227 for details. */ @@ -1618,29 +1623,18 @@ restart: * EIOCBQUEUED to the caller, So we could only return * number of bytes in non-AIO case. */ - if (io->ci_nob > 0 && !is_aio) { - result += io->ci_nob; - count -= io->ci_nob; - *ppos = io->u.ci_wr.wr.crw_pos; /* for splice */ + if (io->ci_nob > 0) { + if (!is_aio) { + result += io->ci_nob; + *ppos = io->u.ci_wr.wr.crw_pos; /* for splice */ + } + count -= io->ci_nob; /* prepare IO restart */ if (count > 0 && args->via_io_subtype == IO_NORMAL) args->u.normal.via_iter = vio->vui_iter; } out: - if (io->ci_aio) { - /** - * Drop one extra reference so that end_io() could be - * called for this IO context, we could call it after - * we make sure all AIO requests have been proceed. - */ - cl_sync_io_note(env, &io->ci_aio->cda_sync, - rc == -EIOCBQUEUED ? 0 : rc); - if (!is_aio) { - cl_aio_free(io->ci_aio); - io->ci_aio = NULL; - } - } cl_io_fini(env, io); CDEBUG(D_VFSTRACE, @@ -1661,6 +1655,20 @@ out: goto restart; } + if (io->ci_aio) { + /** + * Drop one extra reference so that end_io() could be + * called for this IO context, we could call it after + * we make sure all AIO requests have been proceed. + */ + cl_sync_io_note(env, &io->ci_aio->cda_sync, + rc == -EIOCBQUEUED ? 0 : rc); + if (!is_aio) { + cl_aio_free(io->ci_aio); + io->ci_aio = NULL; + } + } + if (iot == CIT_READ) { if (result > 0) ll_stats_ops_tally(ll_i2sbi(inode), diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index 8fd227e..94b2436 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -346,6 +346,11 @@ ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, size_t size, int iot = rw == READ ? CRT_READ : CRT_WRITE; atomic_add(io_pages, &anchor->csi_sync_nr); + /* + * Avoid out-of-order execution of adding inflight + * modifications count and io submit. + */ + smp_mb(); rc = cl_io_submit_rw(env, io, iot, queue); if (rc == 0) { cl_page_list_splice(&queue->c2_qout, -- 1.8.3.1