Most page cache allocation happens via readahead (sync or async), so if
we want to have significant number of huge pages in page cache we need
to find a ways to allocate them from readahead.

Unfortunately, huge pages doesn't fit into current readahead design:
128 max readahead window, assumption on page size, PageReadahead() to
track hit/miss.

I haven't found a ways to get it right yet.

This patch just allocates huge page if allowed, but doesn't really
provide any readahead if huge page is allocated. We read out 2M a time
and I would expect spikes in latancy without readahead.

Therefore HACK.

Any suggestions are welcome.

Signed-off-by: Kirill A. Shutemov <[email protected]>
---
 mm/readahead.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/mm/readahead.c b/mm/readahead.c
index 65ec288dc057..3d7742a687f2 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -173,6 +173,20 @@ int __do_page_cache_readahead(struct address_space 
*mapping, struct file *filp,
                if (page_offset > end_index)
                        break;
 
+               if ((!page_idx || page_offset % HPAGE_PMD_NR == 0) &&
+                               page_cache_allow_huge(mapping, page_offset)) {
+                       page = __page_cache_alloc_order(gfp_mask | __GFP_COMP,
+                                       HPAGE_PMD_ORDER);
+                       if (page) {
+                               prep_transhuge_page(page);
+                               page->index = round_down(page_offset,
+                                               HPAGE_PMD_NR);
+                               list_add(&page->lru, &page_pool);
+                               ret++;
+                               goto start_io;
+                       }
+               }
+
                rcu_read_lock();
                page = radix_tree_lookup(&mapping->page_tree, page_offset);
                rcu_read_unlock();
@@ -188,7 +202,7 @@ int __do_page_cache_readahead(struct address_space 
*mapping, struct file *filp,
                        SetPageReadahead(page);
                ret++;
        }
-
+start_io:
        /*
         * Now start the IO.  We ignore I/O errors - if the page is not
         * uptodate then the caller will launch readpage again, and
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to