Whamcloud - gitweb
LU-13805 llite: Add copy of iovec to sub-dio 40/49940/28
authorPatrick Farrell <pfarrell@whamcloud.com>
Wed, 8 Feb 2023 04:09:17 +0000 (23:09 -0500)
committerOleg Drokin <green@whamcloud.com>
Thu, 24 Aug 2023 04:31:28 +0000 (04:31 +0000)
It's very useful to move some of the direct I/O processing
from the main thread to the ptlrpc threads.  This is done
by associating the processing with each sub DIO, or DIO
'chunk'.  This requires a local copy of the iovec in each
chunk, because we:
A) need the chunk-current state of the iovec (as we move
along the iovec as chunks are created)
B) some operations will modify the iovec, and so to do
them from multiple ptlrpc threads, each needs to work on a
separate copy of the iovec.

This will be used by copy_page_to_iter in completing
unaligned DIO reads.

This has been split out from the main unaligned DIO patch
for simplification.

Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I5645e904b6f9423eafc69cc0f59349cb3dcb9920
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49940
Reviewed-by: Zhenyu Xu <bobijam@hotmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Qian Yingjin <qian@ddn.com>
Tested-by: Maloo <maloo@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
lustre/include/cl_object.h
lustre/llite/rw26.c
lustre/obdclass/cl_io.c

index da23150..845944b 100644 (file)
@@ -2513,7 +2513,8 @@ int cl_sync_io_wait_recycle(const struct lu_env *env, struct cl_sync_io *anchor,
                            long timeout, int ioret);
 struct cl_dio_aio *cl_dio_aio_alloc(struct kiocb *iocb, struct cl_object *obj,
                                    bool is_aio);
-struct cl_sub_dio *cl_sub_dio_alloc(struct cl_dio_aio *ll_aio, bool write,
+struct cl_sub_dio *cl_sub_dio_alloc(struct cl_dio_aio *ll_aio,
+                                   struct iov_iter *iter, bool write,
                                    bool sync);
 void cl_dio_aio_free(const struct lu_env *env, struct cl_dio_aio *aio);
 void cl_sub_dio_free(struct cl_sub_dio *sdio);
@@ -2573,6 +2574,7 @@ struct cl_sub_dio {
        ssize_t                 csd_bytes;
        struct cl_dio_aio       *csd_ll_aio;
        struct ll_dio_pages     csd_dio_pages;
+       struct iov_iter         csd_iter;
        unsigned                csd_creator_free:1,
                                csd_write:1;
 };
index aad6b20..3a5c85d 100644 (file)
@@ -545,7 +545,8 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw)
                 * otherwise it is freed on the final call to cl_sync_io_note
                 * (either in this function or from a ptlrpcd daemon)
                 */
-               sdio = cl_sub_dio_alloc(ll_dio_aio, rw == WRITE, sync_submit);
+               sdio = cl_sub_dio_alloc(ll_dio_aio, iter, rw == WRITE,
+                                       sync_submit);
                if (!sdio)
                        GOTO(out, result = -ENOMEM);
 
index d4d85fa..8d7b6f2 100644 (file)
@@ -1241,7 +1241,8 @@ struct cl_dio_aio *cl_dio_aio_alloc(struct kiocb *iocb, struct cl_object *obj,
 }
 EXPORT_SYMBOL(cl_dio_aio_alloc);
 
-struct cl_sub_dio *cl_sub_dio_alloc(struct cl_dio_aio *ll_aio, bool write,
+struct cl_sub_dio *cl_sub_dio_alloc(struct cl_dio_aio *ll_aio,
+                                   struct iov_iter *iter, bool write,
                                    bool sync)
 {
        struct cl_sub_dio *sdio;
@@ -1260,7 +1261,26 @@ struct cl_sub_dio *cl_sub_dio_alloc(struct cl_dio_aio *ll_aio, bool write,
                atomic_add(1,  &ll_aio->cda_sync.csi_sync_nr);
                sdio->csd_creator_free = sync;
                sdio->csd_write = write;
+
+               /* we need to make a copy of the user iovec at this point in
+                * time so we:
+                * A) have the correct state of the iovec for this chunk of I/O
+                * B) have a chunk-local copy; some of the things we want to
+                * do to the iovec modify it, so to process each chunk from a
+                * separate thread requires a local copy of the iovec
+                */
+               memcpy(&sdio->csd_iter, iter,
+                      sizeof(struct iov_iter));
+               OBD_ALLOC_PTR(sdio->csd_iter.iov);
+               if (sdio->csd_iter.iov == NULL) {
+                       cl_sub_dio_free(sdio);
+                       sdio = NULL;
+                       goto out;
+               }
+               memcpy((void *) sdio->csd_iter.iov, iter->iov,
+                      sizeof(struct iovec));
        }
+out:
        return sdio;
 }
 EXPORT_SYMBOL(cl_sub_dio_alloc);
@@ -1276,8 +1296,13 @@ EXPORT_SYMBOL(cl_dio_aio_free);
 
 void cl_sub_dio_free(struct cl_sub_dio *sdio)
 {
-       if (sdio)
+       if (sdio) {
+               void *tmp = (void *) sdio->csd_iter.iov;
+
+               if (tmp)
+                       OBD_FREE(tmp, sizeof(struct iovec));
                OBD_SLAB_FREE_PTR(sdio, cl_sub_dio_kmem);
+       }
 }
 EXPORT_SYMBOL(cl_sub_dio_free);