Re: [PATCH 17/22] AIO wait on writeback

From: Suparna Bhattacharya
Date: Fri Jul 02 2004 - 11:26:02 EST


On Fri, Jul 02, 2004 at 06:30:30PM +0530, Suparna Bhattacharya wrote:
> The patchset contains modifications and fixes to the AIO core
> to support the full retry model, an implementation of AIO
> support for buffered filesystem AIO reads and O_SYNC writes
> (the latter courtesy O_SYNC speedup changes from Andrew Morton),
> an implementation of AIO reads and writes to pipes (from
> Chris Mason) and AIO poll (again from Chris Mason).
>
> Full retry infrastructure and fixes
> [1] aio-retry.patch
> [2] 4g4g-aio-hang-fix.patch
> [3] aio-retry-elevated-refcount.patch
> [4] aio-splice-runlist.patch
>
> FS AIO read
> [5] aio-wait-page.patch
> [6] aio-fs_read.patch
> [7] aio-upfront-readahead.patch
>
> AIO for pipes
> [8] aio-cancel-fix.patch
> [9] aio-read-immediate.patch
> [10] aio-pipe.patch
> [11] aio-context-switch.patch
>
> Concurrent O_SYNC write speedups using radix-tree walks
> [12] writepages-range.patch
> [13] fix-writeback-range.patch
> [14] fix-writepages-range.patch
> [15] fdatawrite-range.patch
> [16] O_SYNC-speedup.patch
>
> AIO O_SYNC write
> [17] aio-wait_on_page_writeback_range.patch

Todo: merge with the fix in [19]
--
Suparna Bhattacharya (suparna@xxxxxxxxxx)
Linux Technology Center
IBM Software Lab, India

-----------------------------------------------------------

From: Suparna Bhattacharya

Implements async support for wait_on_page_writeback_range.
Accepts a wait queue entry as an additional parameter,
invokes the async version wait_on_page_writeback and takes care
of propagating how much of writeback in the range completed so
far (in terms of number of pages), on an -EIOCBRETRY, so that
subqueuent retries can accordingly check/wait only on the
remaining part of the range.


filemap.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 109 insertions(+), 28 deletions(-)

--- aio/mm/filemap.c 2004-06-18 14:11:49.144076472 -0700
+++ aio-wait_on_page_writeback_range/mm/filemap.c 2004-06-18 14:16:38.620069432 -0700
@@ -194,24 +194,29 @@ EXPORT_SYMBOL(filemap_flush);

/*
* Wait for writeback to complete against pages indexed by start->end
- * inclusive
+ * inclusive.
+ * This could be a synchronous wait or could just queue an async
+ * notification callback depending on the wait queue entry parameter
+ * Returns the size of the range for which writeback has been completed
+ * in terms of number of pages. This value is used in the AIO case
+ * to retry the wait for the remaining part of the range through on
+ * async notification.
*/
-static int wait_on_page_writeback_range(struct address_space *mapping,
- pgoff_t start, pgoff_t end)
+static ssize_t wait_on_page_writeback_range_wq(struct address_space *mapping,
+ pgoff_t start, pgoff_t end, wait_queue_t *wait)
{
struct pagevec pvec;
int nr_pages;
- int ret = 0;
- pgoff_t index;
+ int ret = 0, done = 0;
+ pgoff_t index, curr = start;

if (end < start)
return 0;

pagevec_init(&pvec, 0);
index = start;
- while ((index <= end) &&
- (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_WRITEBACK,
+ while (!done && (index <= end) && (nr_pages = pagevec_lookup_tag(&pvec,
+ mapping, &index, PAGECACHE_TAG_WRITEBACK,
min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
unsigned i;

@@ -222,7 +227,20 @@ static int wait_on_page_writeback_range(
if (page->index > end) {
continue;
}
- wait_on_page_writeback(page);
+ lock_page(page);
+ if (unlikely(page->mapping != mapping)) {
+ unlock_page(page);
+ continue;
+ }
+ curr = page->index;
+ unlock_page(page);
+ ret = wait_on_page_writeback_wq(page, wait);
+ if (ret == -EIOCBRETRY) {
+ if (curr > start)
+ ret = curr - start;
+ done = 1;
+ break;
+ }
if (PageError(page))
ret = -EIO;
}
@@ -236,9 +254,17 @@ static int wait_on_page_writeback_range(
if (test_and_clear_bit(AS_EIO, &mapping->flags))
ret = -EIO;

+ if (ret == 0)
+ ret = end - start + 1;
+
return ret;
}

+static inline ssize_t wait_on_page_writeback_range(struct address_space
+ *mapping, pgoff_t start, pgoff_t end)
+{
+ return wait_on_page_writeback_range_wq(mapping, start, end, NULL);
+}

/*
* Write and wait upon all the pages in the passed range. This is a "data
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/