Whamcloud - gitweb
LU-17422 clio: use page pools for UDIO/hybrid 70/53670/17
authorPatrick Farrell <paf0187@gmail.com>
Wed, 27 Mar 2024 21:45:02 +0000 (17:45 -0400)
committerOleg Drokin <green@whamcloud.com>
Tue, 23 Apr 2024 19:51:05 +0000 (19:51 +0000)
This moves unaligned/hybrid IO to using page pools.  This
reduces the time spent in memory allocation while doing IO
to near zero, at least in simple tests.

This should close most of the performance gap between
udio/hybrid and regular DIO for reads, taking them from
~13 GiB/s to close to 20 GiB/s.  This should also scale as
DIO performance improves.

The improvement for writes is much more limited, because
UDIO writes do not have parallel data copy yet.  This will
improve UDIO write performance by perhaps 10-20%, so from
~2.5 GiB/s to ~3.0 GiB/s, very roughly.

Signed-off-by: Patrick Farrell <patrick.farrell@oracle.com>
Change-Id: I0cb8b5881bf2885a926383291f67fa252b56574f
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53670
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
lustre/obdclass/cl_io.c

index 6d811d5..98c5a02 100644 (file)
@@ -1372,10 +1372,8 @@ EXPORT_SYMBOL(cl_sub_dio_free);
  */
 int ll_allocate_dio_buffer(struct ll_dio_pages *pvec, size_t io_size)
 {
-       struct page *new_page;
        size_t pg_offset;
        int result = 0;
-       ssize_t i;
 
        ENTRY;
 
@@ -1399,18 +1397,11 @@ int ll_allocate_dio_buffer(struct ll_dio_pages *pvec, size_t io_size)
        OBD_ALLOC_PTR_ARRAY_LARGE(pvec->ldp_pages, pvec->ldp_count);
 #endif
        if (pvec->ldp_pages == NULL)
-               RETURN(-ENOMEM);
-
-       for (i = 0; i < pvec->ldp_count; i++) {
-               new_page = alloc_page(GFP_NOFS);
-               if (!new_page) {
-                       result = -ENOMEM;
-                       pvec->ldp_count = i;
-                       goto out;
-               }
-               pvec->ldp_pages[i] = new_page;
-       }
-       WARN_ON(i != pvec->ldp_count);
+               GOTO(out, result = -ENOMEM);
+
+       result = obd_pool_get_pages_array(pvec->ldp_pages, pvec->ldp_count);
+       if (result)
+               GOTO(out, result);
 
 out:
        if (result) {
@@ -1427,13 +1418,10 @@ EXPORT_SYMBOL(ll_allocate_dio_buffer);
 
 void ll_free_dio_buffer(struct ll_dio_pages *pvec)
 {
-       int i;
-
-       for (i = 0; i < pvec->ldp_count; i++)
-               __free_page(pvec->ldp_pages[i]);
+       obd_pool_put_pages_array(pvec->ldp_pages, pvec->ldp_count);
 
 #ifdef HAVE_DIO_ITER
-       kfree(pvec->ldp_pages);
+       kvfree(pvec->ldp_pages);
 #else
        OBD_FREE_PTR_ARRAY_LARGE(pvec->ldp_pages, pvec->ldp_count);
 #endif