--- 9e0826ea7bbe759dfb2356d13bdfb038cc3e0869 +++ c4a5bfef1848b97ca2668d09d58d4e42ff22831c @@ -454,8 +454,8 @@ out: } EXPORT_SYMBOL(add_to_page_cache_locked); -int add_to_page_cache_lru(struct page *page, struct address_space *mapping, - pgoff_t offset, gfp_t gfp_mask) +int __add_to_page_cache_lru(struct page *page, struct address_space *mapping, + pgoff_t offset, gfp_t gfp_mask, int tail) { int ret; @@ -471,12 +471,19 @@ int add_to_page_cache_lru(struct page *p ret = add_to_page_cache(page, mapping, offset, gfp_mask); if (ret == 0) { if (page_is_file_cache(page)) - lru_cache_add_file(page); + lru_cache_add_file(page, tail); else lru_cache_add_anon(page); } return ret; } + +int add_to_page_cache_lru(struct page *page, struct address_space *mapping, + pgoff_t offset, gfp_t gfp_mask) +{ + return __add_to_page_cache_lru(page, mapping, offset, gfp_mask, 0); +} + EXPORT_SYMBOL_GPL(add_to_page_cache_lru); #ifdef CONFIG_NUMA @@ -970,6 +977,28 @@ static void shrink_readahead_size_eio(st ra->ra_pages /= 4; } +static inline int nr_mapped(void) +{ + return global_page_state(NR_FILE_MAPPED) + + global_page_state(NR_ANON_PAGES); +} + +/* + * This examines how large in pages a file size is and returns 1 if it is + * more than half the unmapped ram. Avoid doing read_page_state which is + * expensive unless we already know it is likely to be large enough. + */ +static int large_isize(unsigned long nr_pages) +{ + if (nr_pages * 6 > vm_total_pages) { + unsigned long unmapped_ram = vm_total_pages - nr_mapped(); + + if (nr_pages * 2 > unmapped_ram) + return 1; + } + return 0; +} + /** * do_generic_file_read - generic file read routine * @filp: the file to read @@ -994,7 +1023,7 @@ static void do_generic_file_read(struct pgoff_t prev_index; unsigned long offset; /* offset into pagecache page */ unsigned int prev_offset; - int error; + int error, tail = 0; index = *ppos >> PAGE_CACHE_SHIFT; prev_index = ra->prev_pos >> PAGE_CACHE_SHIFT; @@ -1005,7 +1034,7 @@ static void do_generic_file_read(struct for (;;) { struct page *page; pgoff_t end_index; - loff_t isize; + loff_t isize = 0; unsigned long nr, ret; cond_resched(); @@ -1179,8 +1208,16 @@ no_cached_page: desc->error = -ENOMEM; goto out; } - error = add_to_page_cache_lru(page, mapping, - index, GFP_KERNEL); + /* + * If we know the file is large we add the pages read to the + * end of the lru as we're unlikely to be able to cache the + * whole file in ram so make those pages the first to be + * dropped if not referenced soon. + */ + if (large_isize(end_index)) + tail = 1; + error = __add_to_page_cache_lru(page, mapping, + index, GFP_KERNEL, tail); if (error) { page_cache_release(page); if (error == -EEXIST)