[RHEL7,COMMIT] ploop: Teach kaio_sync_io() work with many pages

Submitted by Konstantin Khorenko on Feb. 5, 2020, 9:55 a.m.

Details

Message ID 202002050955.0159tHHn028682@finist-ce7.sw.ru
State New
Series "Possibility to batch page reads and batch on holes_bitmap population"
Headers show

Commit Message

Konstantin Khorenko Feb. 5, 2020, 9:55 a.m.
The commit is pushed to "branch-rh7-3.10.0-1062.7.1.vz7.130.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1062.7.1.vz7.130.15
------>
commit 8ce48b11f6cfb662ca8a9b01c15dcadf69fee54e
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Wed Feb 5 12:55:17 2020 +0300

    ploop: Teach kaio_sync_io() work with many pages
    
    This will be used to submit bunch of pages in next patches.
    
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    
    Patchset description:
    Possibility to batch page reads and batch on holes_bitmap population
    
    Submit batch request up to 10 clusters (10Mb, 2560 pages)
    during holes_bitmap population to speed up ploop mount
    of big images.
    
    https://jira.sw.ru/browse/PSBM-101246
    
    Kirill Tkhai (4):
          ploop: Teach dio_sync_io() work with many pages
          ploop: Teach kaio_sync_io() work with many pages
          ploop: Introduce .sync_read_many method
          ploop: Read 10 BAT clusters on holes_bitmap population
---
 drivers/block/ploop/io_kaio.c | 44 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index 3632f8376fbef..c48b80b9785f1 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -776,16 +776,22 @@  static void kaio_sync_io_complete(u64 data, long err)
 		complete(&comp->comp);
 }
 
+/*
+ * @off is offset within first page in bytes.
+ * @len is sum length in bytes.
+ */
 static int
-kaio_sync_io(struct ploop_io * io, int op, struct page * page,
-	     unsigned int len, unsigned int off, sector_t sec)
+kaio_sync_io(struct ploop_io * io, int op, struct page **pages,
+	     unsigned int nr_pages, unsigned int len,
+	     unsigned int off, sector_t sec)
 {
 	struct kiocb *iocb;
 	struct iov_iter iter;
-	struct bio_vec bvec;
+	struct bio_vec bvec_on_stack, *bvec;
 	loff_t pos = (loff_t) sec << 9;
 	struct file *file = io->files.file;
 	struct kaio_comp comp;
+	unsigned int i, count;
 	int err;
 
 	kaio_comp_init(&comp);
@@ -793,12 +799,27 @@  kaio_sync_io(struct ploop_io * io, int op, struct page * page,
 	iocb = aio_kernel_alloc(GFP_NOIO);
 	if (!iocb)
 		return -ENOMEM;
+	if (nr_pages == 1)
+		bvec = &bvec_on_stack;
+	else
+		bvec = kmalloc(sizeof(*bvec) * nr_pages, GFP_NOIO);
+	if (!bvec) {
+		kfree(iocb);
+		return -ENOMEM;
+	}
 
-	bvec.bv_page = page;
-	bvec.bv_len = len;
-	bvec.bv_offset = off;
+	for (i = 0; i < nr_pages; i++) {
+		bvec->bv_page = pages[i];
+		count = PAGE_SIZE - off;
+		if (count > len)
+			count = len;
+		bvec->bv_len = count;
+		bvec->bv_offset = off;
+		off = 0;
+		len -= count;
+	}
 
-	iov_iter_init_bvec(&iter, &bvec, 1, bvec_length(&bvec, 1), 0);
+	iov_iter_init_bvec(&iter, bvec, nr_pages, bvec_length(bvec, nr_pages), 0);
 	aio_kernel_init_iter(iocb, file, op, &iter, pos);
 	aio_kernel_init_callback(iocb, kaio_sync_io_complete, (u64)&comp);
 
@@ -827,6 +848,9 @@  kaio_sync_io(struct ploop_io * io, int op, struct page * page,
 		       (op == IOCB_CMD_WRITE_ITER) ? "WRITE" : "READ",
 		       pos, len, off);
 
+	if (bvec != &bvec_on_stack)
+		kfree(bvec);
+	/* Not needed to free iocb */
 	return comp.error;
 }
 
@@ -834,16 +858,18 @@  static int
 kaio_sync_read(struct ploop_io * io, struct page * page, unsigned int len,
 		unsigned int off, sector_t sec)
 {
-	return kaio_sync_io(io, IOCB_CMD_READ_ITER, page, len, off, sec);
+	struct page *pages[] = { page };
+	return kaio_sync_io(io, IOCB_CMD_READ_ITER, pages, 1, len, off, sec);
 }
 
 static int
 kaio_sync_write(struct ploop_io * io, struct page * page, unsigned int len,
 		 unsigned int off, sector_t sec)
 {
+	struct page *pages[] = { page };
 	int ret;
 
-	ret = kaio_sync_io(io, IOCB_CMD_WRITE_ITER, page, len, off, sec);
+	ret = kaio_sync_io(io, IOCB_CMD_WRITE_ITER, pages, 1, len, off, sec);
 
 	if (sec < io->plo->track_end)
 		ploop_tracker_notify(io->plo, sec);