mm: change isolate mode from #define to bitwise type

Change ISOLATE_XXX macro with bitwise isolate_mode_t type.  Normally,
macro isn't recommended as it's type-unsafe and making debugging harder as
symbol cannot be passed throught to the debugger.

Quote from Johannes
" Hmm, it would probably be cleaner to fully convert the isolation mode
into independent flags.  INACTIVE, ACTIVE, BOTH is currently a
tri-state among flags, which is a bit ugly."

This patch moves isolate mode from swap.h to mmzone.h by memcontrol.h

Signed-off-by: Minchan Kim <minchan.kim@gmail.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Rik van Riel <riel@redhat.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Minchan Kim 2011-10-31 17:06:47 -07:00 committed by Linus Torvalds
parent b9e84ac153
commit 4356f21d09
8 changed files with 43 additions and 34 deletions

View File

@ -379,10 +379,10 @@ EVENT_PROCESS:
# To closer match vmstat scanning statistics, only count isolate_both # To closer match vmstat scanning statistics, only count isolate_both
# and isolate_inactive as scanning. isolate_active is rotation # and isolate_inactive as scanning. isolate_active is rotation
# isolate_inactive == 0 # isolate_inactive == 1
# isolate_active == 1 # isolate_active == 2
# isolate_both == 2 # isolate_both == 3
if ($isolate_mode != 1) { if ($isolate_mode != 2) {
$perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
} }
$perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty; $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;

View File

@ -35,7 +35,8 @@ enum mem_cgroup_page_stat_item {
extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
struct list_head *dst, struct list_head *dst,
unsigned long *scanned, int order, unsigned long *scanned, int order,
int mode, struct zone *z, isolate_mode_t mode,
struct zone *z,
struct mem_cgroup *mem_cont, struct mem_cgroup *mem_cont,
int active, int file); int active, int file);

View File

@ -164,6 +164,14 @@ static inline int is_unevictable_lru(enum lru_list l)
#define LRU_ALL_EVICTABLE (LRU_ALL_FILE | LRU_ALL_ANON) #define LRU_ALL_EVICTABLE (LRU_ALL_FILE | LRU_ALL_ANON)
#define LRU_ALL ((1 << NR_LRU_LISTS) - 1) #define LRU_ALL ((1 << NR_LRU_LISTS) - 1)
/* Isolate inactive pages */
#define ISOLATE_INACTIVE ((__force isolate_mode_t)0x1)
/* Isolate active pages */
#define ISOLATE_ACTIVE ((__force isolate_mode_t)0x2)
/* LRU Isolation modes. */
typedef unsigned __bitwise__ isolate_mode_t;
enum zone_watermarks { enum zone_watermarks {
WMARK_MIN, WMARK_MIN,
WMARK_LOW, WMARK_LOW,

View File

@ -243,15 +243,10 @@ static inline void lru_cache_add_file(struct page *page)
__lru_cache_add(page, LRU_INACTIVE_FILE); __lru_cache_add(page, LRU_INACTIVE_FILE);
} }
/* LRU Isolation modes. */
#define ISOLATE_INACTIVE 0 /* Isolate inactive pages. */
#define ISOLATE_ACTIVE 1 /* Isolate active pages. */
#define ISOLATE_BOTH 2 /* Isolate both active and inactive pages. */
/* linux/mm/vmscan.c */ /* linux/mm/vmscan.c */
extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
gfp_t gfp_mask, nodemask_t *mask); gfp_t gfp_mask, nodemask_t *mask);
extern int __isolate_lru_page(struct page *page, int mode, int file); extern int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file);
extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem,
gfp_t gfp_mask, bool noswap); gfp_t gfp_mask, bool noswap);
extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem,

View File

@ -266,7 +266,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
unsigned long nr_lumpy_taken, unsigned long nr_lumpy_taken,
unsigned long nr_lumpy_dirty, unsigned long nr_lumpy_dirty,
unsigned long nr_lumpy_failed, unsigned long nr_lumpy_failed,
int isolate_mode), isolate_mode_t isolate_mode),
TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode),
@ -278,7 +278,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
__field(unsigned long, nr_lumpy_taken) __field(unsigned long, nr_lumpy_taken)
__field(unsigned long, nr_lumpy_dirty) __field(unsigned long, nr_lumpy_dirty)
__field(unsigned long, nr_lumpy_failed) __field(unsigned long, nr_lumpy_failed)
__field(int, isolate_mode) __field(isolate_mode_t, isolate_mode)
), ),
TP_fast_assign( TP_fast_assign(
@ -312,7 +312,7 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate,
unsigned long nr_lumpy_taken, unsigned long nr_lumpy_taken,
unsigned long nr_lumpy_dirty, unsigned long nr_lumpy_dirty,
unsigned long nr_lumpy_failed, unsigned long nr_lumpy_failed,
int isolate_mode), isolate_mode_t isolate_mode),
TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode)
@ -327,7 +327,7 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate,
unsigned long nr_lumpy_taken, unsigned long nr_lumpy_taken,
unsigned long nr_lumpy_dirty, unsigned long nr_lumpy_dirty,
unsigned long nr_lumpy_failed, unsigned long nr_lumpy_failed,
int isolate_mode), isolate_mode_t isolate_mode),
TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode)

View File

@ -349,7 +349,8 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
} }
/* Try isolate the page */ /* Try isolate the page */
if (__isolate_lru_page(page, ISOLATE_BOTH, 0) != 0) if (__isolate_lru_page(page,
ISOLATE_ACTIVE|ISOLATE_INACTIVE, 0) != 0)
continue; continue;
VM_BUG_ON(PageTransCompound(page)); VM_BUG_ON(PageTransCompound(page));

View File

@ -1185,7 +1185,8 @@ mem_cgroup_get_reclaim_stat_from_page(struct page *page)
unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
struct list_head *dst, struct list_head *dst,
unsigned long *scanned, int order, unsigned long *scanned, int order,
int mode, struct zone *z, isolate_mode_t mode,
struct zone *z,
struct mem_cgroup *mem_cont, struct mem_cgroup *mem_cont,
int active, int file) int active, int file)
{ {

View File

@ -1012,23 +1012,27 @@ keep_lumpy:
* *
* returns 0 on success, -ve errno on failure. * returns 0 on success, -ve errno on failure.
*/ */
int __isolate_lru_page(struct page *page, int mode, int file) int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file)
{ {
bool all_lru_mode;
int ret = -EINVAL; int ret = -EINVAL;
/* Only take pages on the LRU. */ /* Only take pages on the LRU. */
if (!PageLRU(page)) if (!PageLRU(page))
return ret; return ret;
all_lru_mode = (mode & (ISOLATE_ACTIVE|ISOLATE_INACTIVE)) ==
(ISOLATE_ACTIVE|ISOLATE_INACTIVE);
/* /*
* When checking the active state, we need to be sure we are * When checking the active state, we need to be sure we are
* dealing with comparible boolean values. Take the logical not * dealing with comparible boolean values. Take the logical not
* of each. * of each.
*/ */
if (mode != ISOLATE_BOTH && (!PageActive(page) != !mode)) if (!all_lru_mode && !PageActive(page) != !(mode & ISOLATE_ACTIVE))
return ret; return ret;
if (mode != ISOLATE_BOTH && page_is_file_cache(page) != file) if (!all_lru_mode && !!page_is_file_cache(page) != file)
return ret; return ret;
/* /*
@ -1076,7 +1080,8 @@ int __isolate_lru_page(struct page *page, int mode, int file)
*/ */
static unsigned long isolate_lru_pages(unsigned long nr_to_scan, static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
struct list_head *src, struct list_head *dst, struct list_head *src, struct list_head *dst,
unsigned long *scanned, int order, int mode, int file) unsigned long *scanned, int order, isolate_mode_t mode,
int file)
{ {
unsigned long nr_taken = 0; unsigned long nr_taken = 0;
unsigned long nr_lumpy_taken = 0; unsigned long nr_lumpy_taken = 0;
@ -1201,8 +1206,8 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
static unsigned long isolate_pages_global(unsigned long nr, static unsigned long isolate_pages_global(unsigned long nr,
struct list_head *dst, struct list_head *dst,
unsigned long *scanned, int order, unsigned long *scanned, int order,
int mode, struct zone *z, isolate_mode_t mode,
int active, int file) struct zone *z, int active, int file)
{ {
int lru = LRU_BASE; int lru = LRU_BASE;
if (active) if (active)
@ -1448,6 +1453,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone,
unsigned long nr_taken; unsigned long nr_taken;
unsigned long nr_anon; unsigned long nr_anon;
unsigned long nr_file; unsigned long nr_file;
isolate_mode_t reclaim_mode = ISOLATE_INACTIVE;
while (unlikely(too_many_isolated(zone, file, sc))) { while (unlikely(too_many_isolated(zone, file, sc))) {
congestion_wait(BLK_RW_ASYNC, HZ/10); congestion_wait(BLK_RW_ASYNC, HZ/10);
@ -1458,15 +1464,15 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone,
} }
set_reclaim_mode(priority, sc, false); set_reclaim_mode(priority, sc, false);
if (sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM)
reclaim_mode |= ISOLATE_ACTIVE;
lru_add_drain(); lru_add_drain();
spin_lock_irq(&zone->lru_lock); spin_lock_irq(&zone->lru_lock);
if (scanning_global_lru(sc)) { if (scanning_global_lru(sc)) {
nr_taken = isolate_pages_global(nr_to_scan, nr_taken = isolate_pages_global(nr_to_scan, &page_list,
&page_list, &nr_scanned, sc->order, &nr_scanned, sc->order, reclaim_mode, zone, 0, file);
sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM ?
ISOLATE_BOTH : ISOLATE_INACTIVE,
zone, 0, file);
zone->pages_scanned += nr_scanned; zone->pages_scanned += nr_scanned;
if (current_is_kswapd()) if (current_is_kswapd())
__count_zone_vm_events(PGSCAN_KSWAPD, zone, __count_zone_vm_events(PGSCAN_KSWAPD, zone,
@ -1475,12 +1481,9 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone,
__count_zone_vm_events(PGSCAN_DIRECT, zone, __count_zone_vm_events(PGSCAN_DIRECT, zone,
nr_scanned); nr_scanned);
} else { } else {
nr_taken = mem_cgroup_isolate_pages(nr_to_scan, nr_taken = mem_cgroup_isolate_pages(nr_to_scan, &page_list,
&page_list, &nr_scanned, sc->order, &nr_scanned, sc->order, reclaim_mode, zone,
sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM ? sc->mem_cgroup, 0, file);
ISOLATE_BOTH : ISOLATE_INACTIVE,
zone, sc->mem_cgroup,
0, file);
/* /*
* mem_cgroup_isolate_pages() keeps track of * mem_cgroup_isolate_pages() keeps track of
* scanned pages on its own. * scanned pages on its own.