aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Whitcroft <apw@canonical.com>2010-07-29 09:46:41 +0100
committerJohn Rigby <john.rigby@linaro.org>2011-08-21 21:29:19 -0600
commit536b8a68d0c51c6b06145106e3883f6f547b552f (patch)
tree4d6300f96da5405da85f5e5f90b82d8077e87892
parent4e73ca87573e65471313890f54b14fe6706b9f2b (diff)
UBUNTU: SAUCE: add tracing for user initiated readahead requests
Track pages which undergo readahead and for each record which were actually consumed, via either read or faulted into a map. This allows userspace readahead applications (such as ureadahead) to track which pages in core at the end of a boot are actually required and generate an optimal readahead pack. It also allows pack adjustment and optimisation in parallel with readahead, allowing the pack to evolve to be accurate as userspace paths change. The status of the pages are reported back via the mincore() call using a newly allocated bit. Signed-off-by: Andy Whitcroft <apw@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
-rw-r--r--include/linux/page-flags.h3
-rw-r--r--mm/filemap.c3
-rw-r--r--mm/memory.c7
-rw-r--r--mm/mincore.c2
-rw-r--r--mm/readahead.c1
5 files changed, 15 insertions, 1 deletions
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 6081493db68..81ce44f708b 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -107,6 +107,7 @@ enum pageflags {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
PG_compound_lock,
#endif
+ PG_readaheadunused, /* user oriented readahead as yet unused*/
__NR_PAGEFLAGS,
/* Filesystems */
@@ -235,6 +236,8 @@ PAGEFLAG(MappedToDisk, mappedtodisk)
PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim)
PAGEFLAG(Readahead, reclaim) /* Reminder to do async read-ahead */
+PAGEFLAG(ReadaheadUnused, readaheadunused)
+
#ifdef CONFIG_HIGHMEM
/*
* Must use a macro here due to header dependency issues. page_zone() is not
diff --git a/mm/filemap.c b/mm/filemap.c
index a8251a8d345..48a1938d5dc 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1306,6 +1306,9 @@ int file_read_actor(read_descriptor_t *desc, struct page *page,
if (size > count)
size = count;
+ if (PageReadaheadUnused(page))
+ ClearPageReadaheadUnused(page);
+
/*
* Faults on the destination of a read are common, so do it before
* taking the kmap.
diff --git a/mm/memory.c b/mm/memory.c
index d961e1914d1..5c17837c38c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3193,10 +3193,15 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
else
VM_BUG_ON(!PageLocked(vmf.page));
+ page = vmf.page;
+
+ /* Mark the page as used on fault. */
+ if (PageReadaheadUnused(page))
+ ClearPageReadaheadUnused(page);
+
/*
* Should we do an early C-O-W break?
*/
- page = vmf.page;
if (flags & FAULT_FLAG_WRITE) {
if (!(vma->vm_flags & VM_SHARED)) {
anon = 1;
diff --git a/mm/mincore.c b/mm/mincore.c
index a4e6b9d75c7..e7b61de86f7 100644
--- a/mm/mincore.c
+++ b/mm/mincore.c
@@ -77,6 +77,8 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff)
page = find_get_page(mapping, pgoff);
if (page) {
present = PageUptodate(page);
+ if (present)
+ present |= (PageReadaheadUnused(page) << 7);
page_cache_release(page);
}
diff --git a/mm/readahead.c b/mm/readahead.c
index 867f9dd82dc..133722cc55f 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -187,6 +187,7 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
list_add(&page->lru, &page_pool);
if (page_idx == nr_to_read - lookahead_size)
SetPageReadahead(page);
+ SetPageReadaheadUnused(page);
ret++;
}