From: <ag...@us...> - 2013-07-03 18:34:52
|
Revision: 494 http://sourceforge.net/p/iscsitarget/code/494 Author: agr1 Date: 2013-07-03 18:34:49 +0000 (Wed, 03 Jul 2013) Log Message: ----------- Avoid zero sized bio_add_page (blockio) / vfs_{read,write} (fileio) calls From: Shivaram Upadhyayula <shi...@qu...> Let suppose the total write length for the write same command is 1048576 + 512 (1MB + 512). As per the logic the writes are split into two due to the MAX_IO_SIZE limitation of 1MB tio pg_cnt will be (1MB / 4096)) == 256 while (length > 0) { u32 to_write = (u32)min_t(u64, length, MAX_IO_SIZE); So the first iteration will be to_write == 1M The second iteration will be to_write == 512 target_tio pg_cnt will be 256 as we dont modify that and is required to free up the pages later Now examining block-io.c make_request while (tio_index < tio->pg_cnt) { Notice above that for the second iteration we will iterate from 0 to 256 but we need to write only 512 bytes. With the 512 byte write, for the first iteration in the below loop /* Loop for filling bio */ while (tio_index < tio->pg_cnt) { unsigned int bytes = PAGE_SIZE; if (bytes > size) bytes = size; if (!bio_add_page(bio, tio->pvec[tio_index], bytes, 0)) break; size -= bytes; ppos += bytes; tio_index++; In the above loop, we add the 512 bytes to the bio in the first iteration itself. In the second iteration of the above loops bytes == size == 0 and so on till 256 and in the second iteration we call bio_add_page with size 0. (redlicha: this was part of another patch and split out to a distinct patch) Signed-off-by: Shivaram Upadhyayula <shi...@qu...> Signed-off-by: Arne Redlich <arn...@go...> Modified Paths: -------------- trunk/kernel/block-io.c trunk/kernel/file-io.c Modified: trunk/kernel/block-io.c =================================================================== --- trunk/kernel/block-io.c 2013-07-02 19:33:19 UTC (rev 493) +++ trunk/kernel/block-io.c 2013-07-03 18:34:49 UTC (rev 494) @@ -79,7 +79,7 @@ init_completion(&tio_work->tio_complete); /* Main processing loop, allocate and fill all bios */ - while (tio_index < tio->pg_cnt) { + while (size && tio_index < tio->pg_cnt) { bio = bio_alloc(GFP_KERNEL, min(max_pages, BIO_MAX_PAGES)); if (!bio) { err = -ENOMEM; @@ -100,7 +100,7 @@ atomic_inc(&tio_work->bios_remaining); /* Loop for filling bio */ - while (tio_index < tio->pg_cnt) { + while (size && tio_index < tio->pg_cnt) { unsigned int bytes = PAGE_SIZE; if (bytes > size) Modified: trunk/kernel/file-io.c =================================================================== --- trunk/kernel/file-io.c 2013-07-02 19:33:19 UTC (rev 493) +++ trunk/kernel/file-io.c 2013-07-03 18:34:49 UTC (rev 494) @@ -34,7 +34,7 @@ size = tio->size; ppos = tio->offset; - for (i = 0; i < tio->pg_cnt; i++) { + for (i = 0; i < tio->pg_cnt && size; i++) { page = tio->pvec[i]; assert(page); buf = page_address(page); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |