Whamcloud - gitweb
LU-13802 llite: tag switched hybrid IOs 03/52703/6
authorPatrick Farrell <pfarrell@whamcloud.com>
Tue, 24 Oct 2023 18:36:17 +0000 (14:36 -0400)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Feb 2024 07:01:19 +0000 (07:01 +0000)
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 <pfarrell@whamcloud.com>
Change-Id: I347ef059eadcd9fd3767d7defc2e3da0eeb5573b
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52703
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/cl_object.h
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/rw26.c

index 2af6dde..5634944 100644 (file)
@@ -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.
index e2cf516..844d03a 100644 (file)
@@ -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));
index 624c11e..275c2c8 100644 (file)
@@ -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,
index d554f66..780acf0 100644 (file)
@@ -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
         */