aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Schermerhorn <Lee.Schermerhorn@hp.com>2008-10-18 23:26:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 11:50:26 -0400
commitba9ddf49391645e6bb93219131a40446538a5e76 (patch)
tree2202525ca36c6f629685f5fea60b5b3ba335f546
parent7b854121eb3e5ba0241882ff939e2c485228c9c5 (diff)
Ramfs and Ram Disk pages are unevictable
Christoph Lameter pointed out that ram disk pages also clutter the LRU lists. When vmscan finds them dirty and tries to clean them, the ram disk writeback function just redirties the page so that it goes back onto the active list. Round and round she goes... With the ram disk driver [rd.c] replaced by the newer 'brd.c', this is no longer the case, as ram disk pages are no longer maintained on the lru. [This makes them unmigratable for defrag or memory hot remove, but that can be addressed by a separate patch series.] However, the ramfs pages behave like ram disk pages used to, so: Define new address_space flag [shares address_space flags member with mapping's gfp mask] to indicate that the address space contains all unevictable pages. This will provide for efficient testing of ramfs pages in page_evictable(). Also provide wrapper functions to set/test the unevictable state to minimize #ifdefs in ramfs driver and any other users of this facility. Set the unevictable state on address_space structures for new ramfs inodes. Test the unevictable state in page_evictable() to cull unevictable pages. These changes depend on [CONFIG_]UNEVICTABLE_LRU. [riel@redhat.com: undo the brd.c part] Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com> Signed-off-by: Rik van Riel <riel@redhat.com> Debugged-by: Nick Piggin <nickpiggin@yahoo.com.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ramfs/inode.c1
-rw-r--r--include/linux/pagemap.h22
-rw-r--r--mm/vmscan.c5
3 files changed, 28 insertions, 0 deletions
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index b13123424e49..f031d1c925f0 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -61,6 +61,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
61 inode->i_mapping->a_ops = &ramfs_aops; 61 inode->i_mapping->a_ops = &ramfs_aops;
62 inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; 62 inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
63 mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); 63 mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
64 mapping_set_unevictable(inode->i_mapping);
64 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 65 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
65 switch (mode & S_IFMT) { 66 switch (mode & S_IFMT) {
66 default: 67 default:
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 5da31c12101c..09164d2c5c27 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -32,6 +32,28 @@ static inline void mapping_set_error(struct address_space *mapping, int error)
32 } 32 }
33} 33}
34 34
35#ifdef CONFIG_UNEVICTABLE_LRU
36#define AS_UNEVICTABLE (__GFP_BITS_SHIFT + 2) /* e.g., ramdisk, SHM_LOCK */
37
38static inline void mapping_set_unevictable(struct address_space *mapping)
39{
40 set_bit(AS_UNEVICTABLE, &mapping->flags);
41}
42
43static inline int mapping_unevictable(struct address_space *mapping)
44{
45 if (mapping && (mapping->flags & AS_UNEVICTABLE))
46 return 1;
47 return 0;
48}
49#else
50static inline void mapping_set_unevictable(struct address_space *mapping) { }
51static inline int mapping_unevictable(struct address_space *mapping)
52{
53 return 0;
54}
55#endif
56
35static inline gfp_t mapping_gfp_mask(struct address_space * mapping) 57static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
36{ 58{
37 return (__force gfp_t)mapping->flags & __GFP_BITS_MASK; 59 return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2804d23e2da7..9babfbc1ddc8 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2332,11 +2332,16 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
2332 * lists vs unevictable list. 2332 * lists vs unevictable list.
2333 * 2333 *
2334 * Reasons page might not be evictable: 2334 * Reasons page might not be evictable:
2335 * (1) page's mapping marked unevictable
2336 *
2335 * TODO - later patches 2337 * TODO - later patches
2336 */ 2338 */
2337int page_evictable(struct page *page, struct vm_area_struct *vma) 2339int page_evictable(struct page *page, struct vm_area_struct *vma)
2338{ 2340{
2339 2341
2342 if (mapping_unevictable(page_mapping(page)))
2343 return 0;
2344
2340 /* TODO: test page [!]evictable conditions */ 2345 /* TODO: test page [!]evictable conditions */
2341 2346
2342 return 1; 2347 return 1;