Skip to content

Commit

Permalink
Ramfs and Ram Disk pages are unevictable
Browse files Browse the repository at this point in the history
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.

[[email protected]: undo the brd.c part]
Signed-off-by: Lee Schermerhorn <[email protected]>
Signed-off-by: Rik van Riel <[email protected]>
Debugged-by: Nick Piggin <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Lee Schermerhorn authored and torvalds committed Oct 20, 2008
1 parent 7b85412 commit ba9ddf4
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
1 change: 1 addition & 0 deletions fs/ramfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
inode->i_mapping->a_ops = &ramfs_aops;
inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
mapping_set_unevictable(inode->i_mapping);
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
default:
Expand Down
22 changes: 22 additions & 0 deletions include/linux/pagemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@ static inline void mapping_set_error(struct address_space *mapping, int error)
}
}

#ifdef CONFIG_UNEVICTABLE_LRU
#define AS_UNEVICTABLE (__GFP_BITS_SHIFT + 2) /* e.g., ramdisk, SHM_LOCK */

static inline void mapping_set_unevictable(struct address_space *mapping)
{
set_bit(AS_UNEVICTABLE, &mapping->flags);
}

static inline int mapping_unevictable(struct address_space *mapping)
{
if (mapping && (mapping->flags & AS_UNEVICTABLE))
return 1;
return 0;
}
#else
static inline void mapping_set_unevictable(struct address_space *mapping) { }
static inline int mapping_unevictable(struct address_space *mapping)
{
return 0;
}
#endif

static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
Expand Down
5 changes: 5 additions & 0 deletions mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -2332,11 +2332,16 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
* lists vs unevictable list.
*
* Reasons page might not be evictable:
* (1) page's mapping marked unevictable
*
* TODO - later patches
*/
int page_evictable(struct page *page, struct vm_area_struct *vma)
{

if (mapping_unevictable(page_mapping(page)))
return 0;

/* TODO: test page [!]evictable conditions */

return 1;
Expand Down

0 comments on commit ba9ddf4

Please sign in to comment.