UBUNTU: SAUCE: (no-up) add tracing for user initiated readahead requests
authorAndy Whitcroft <apw@canonical.com>
Thu, 29 Jul 2010 08:46:41 +0000 (09:46 +0100)
committerLeann Ogasawara <leann.ogasawara@canonical.com>
Mon, 2 Apr 2012 20:10:06 +0000 (13:10 -0700)
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>

include/linux/page-flags.h
mm/filemap.c
mm/memory.c
mm/mincore.c
mm/readahead.c

index e90a673..db2fb39 100644 (file)
@@ -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 */
@@ -230,6 +231,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
index 03c5b0e..7fe956c 100644 (file)
@@ -1313,6 +1313,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.
index 1b1ca17..15dec6a 100644 (file)
@@ -3211,10 +3211,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)) {
                        page = cow_page;
index 936b4ce..7c2874a 100644 (file)
@@ -80,6 +80,8 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff)
 #endif
        if (page) {
                present = PageUptodate(page);
+               if (present)
+                       present |= (PageReadaheadUnused(page) << 7);
                page_cache_release(page);
        }
 
index cbcbb02..2acb815 100644 (file)
@@ -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++;
        }