From 3fc4243da7efd4426b6493ae212240a2e4d88747 Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Tue, 24 Oct 2023 14:36:17 -0400 Subject: [PATCH] LU-13802 llite: tag switched hybrid IOs If we switched IO type with hybrid IO, tag the IO in the cl_io. This will be used to make various choices later. Also add a more verbose debug message for DIO, printing various aspects of the IO. Test-Parameters: trivial Signed-off-by: Patrick Farrell Change-Id: I347ef059eadcd9fd3767d7defc2e3da0eeb5573b Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52703 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Shaun Tancheff Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/include/cl_object.h | 4 +++- lustre/llite/file.c | 25 +++++++++++++++++-------- lustre/llite/llite_internal.h | 2 ++ lustre/llite/rw26.c | 28 ++++++++++++++++------------ 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 2af6dde..5634944 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -1946,7 +1946,9 @@ struct cl_io { * to block races between page cache invalidation and page cache * filling functions (fault, read, ...) */ - ci_invalidate_page_cache:1; + ci_invalidate_page_cache:1, + /* was this IO switched from BIO to DIO for hybrid IO? */ + ci_hybrid_switched:1; /** * How many times the read has retried before this one. diff --git a/lustre/llite/file.c b/lustre/llite/file.c index e2cf516..844d03a 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1668,6 +1668,8 @@ void ll_io_init(struct cl_io *io, struct file *file, enum cl_io_type iot, * out allowed */ io->ci_allow_unaligned_dio = true; + if (args) + io->ci_hybrid_switched = args->via_hybrid_switched; ll_io_set_mirror(io, file); } @@ -1768,7 +1770,9 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, if (iocb_ki_flags_check(flags, DIRECT)) { if (iocb_ki_flags_check(flags, APPEND)) dio_lock = true; - if (!is_sync_kiocb(args->u.normal.via_iocb)) + if (!is_sync_kiocb(args->u.normal.via_iocb) && + /* hybrid IO is also potentially async */ + !args->via_hybrid_switched) is_aio = true; /* the kernel does not support AIO on pipes, and parallel DIO @@ -2175,18 +2179,19 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to) ll_ras_enter(file, iocb->ki_pos, iov_iter_count(to)); + args = ll_env_args(env); + args->u.normal.via_iter = to; + args->u.normal.via_iocb = iocb; + if (ll_hybrid_bio_dio_switch_check(file, iocb, CIT_READ, iov_iter_count(to))) { #ifdef IOCB_DIRECT iocb->ki_flags |= IOCB_DIRECT; CDEBUG(D_VFSTRACE, "switching to DIO\n"); + args->via_hybrid_switched = 1; #endif } - args = ll_env_args(env); - args->u.normal.via_iter = to; - args->u.normal.via_iocb = iocb; - result = ll_do_fast_read(iocb, to); if (result < 0 || iov_iter_count(to) == 0) GOTO(out, result); @@ -2289,14 +2294,16 @@ static ssize_t ll_do_tiny_write(struct kiocb *iocb, struct iov_iter *iter) */ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { + struct file *file = iocb->ki_filp; struct vvp_io_args *args; struct lu_env *env; - ssize_t rc_tiny = 0, rc_normal; - struct file *file = iocb->ki_filp; int flags = iocb_ki_flags_get(file, iocb); + ktime_t kstart = ktime_get(); + bool hybrid_switched = false; + ssize_t rc_tiny = 0; + ssize_t rc_normal; __u16 refcheck; bool cached; - ktime_t kstart = ktime_get(); int result; ENTRY; @@ -2329,6 +2336,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from) #ifdef IOCB_DIRECT iocb->ki_flags |= IOCB_DIRECT; CDEBUG(D_VFSTRACE, "switching to DIO\n"); + hybrid_switched = true; #endif } @@ -2355,6 +2363,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from) args = ll_env_args(env); args->u.normal.via_iter = from; args->u.normal.via_iocb = iocb; + args->via_hybrid_switched = hybrid_switched; rc_normal = ll_file_io_generic(env, args, file, CIT_WRITE, &iocb->ki_pos, iov_iter_count(from)); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 624c11e..275c2c8 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1523,6 +1523,8 @@ struct vvp_io_args { struct iov_iter *via_iter; } normal; } u; + /* did we switch this IO from BIO to DIO using hybrid IO? */ + int via_hybrid_switched:1; }; static inline unsigned int iocb_ki_flags_get(const struct file *file, diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index d554f66..780acf0 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -504,12 +504,26 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw) if (ll_iov_iter_alignment(iter) & ~PAGE_MASK) unaligned = true; + lcc = ll_cl_find(inode); + if (lcc == NULL) + RETURN(-EIO); + + env = lcc->lcc_env; + LASSERT(!IS_ERR(env)); + vio = vvp_env_io(env); + io = lcc->lcc_io; + LASSERT(io != NULL); + CDEBUG(D_VFSTRACE, - "VFS Op:inode="DFID"(%p), size=%zd (max %lu), offset=%lld=%llx, pages %zd (max %lu)%s\n", + "VFS Op:inode="DFID"(%p), size=%zd (max %lu), offset=%lld=%llx, pages %zd (max %lu)%s%s%s%s\n", PFID(ll_inode2fid(inode)), inode, count, MAX_DIO_SIZE, file_offset, file_offset, (count >> PAGE_SHIFT) + !!(count & ~PAGE_MASK), - MAX_DIO_SIZE >> PAGE_SHIFT, unaligned ? ", unaligned" : ""); + MAX_DIO_SIZE >> PAGE_SHIFT, + io->ci_dio_lock ? ", locked" : ", lockless", + io->ci_parallel_dio ? ", parallel" : "", + unaligned ? ", unaligned" : "", + io->ci_hybrid_switched ? ", hybrid" : ""); /* Check EOF by ourselves */ if (rw == READ && file_offset >= i_size_read(inode)) @@ -526,16 +540,6 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw) if (unaligned && iov_iter_is_pipe(iter)) RETURN(0); - lcc = ll_cl_find(inode); - if (lcc == NULL) - RETURN(-EIO); - - env = lcc->lcc_env; - LASSERT(!IS_ERR(env)); - vio = vvp_env_io(env); - io = lcc->lcc_io; - LASSERT(io != NULL); - /* this means we encountered an old server which can't safely support * unaligned DIO, so we have to disable it */ -- 1.8.3.1