|
@@ -1012,23 +1012,27 @@ keep_lumpy:
|
|
|
*
|
|
|
* 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;
|
|
|
|
|
|
/* Only take pages on the LRU. */
|
|
|
if (!PageLRU(page))
|
|
|
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
|
|
|
* dealing with comparible boolean values. Take the logical not
|
|
|
* of each.
|
|
|
*/
|
|
|
- if (mode != ISOLATE_BOTH && (!PageActive(page) != !mode))
|
|
|
+ if (!all_lru_mode && !PageActive(page) != !(mode & ISOLATE_ACTIVE))
|
|
|
return ret;
|
|
|
|
|
|
- if (mode != ISOLATE_BOTH && page_is_file_cache(page) != file)
|
|
|
+ if (!all_lru_mode && !!page_is_file_cache(page) != file)
|
|
|
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,
|
|
|
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_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,
|
|
|
struct list_head *dst,
|
|
|
unsigned long *scanned, int order,
|
|
|
- int mode, struct zone *z,
|
|
|
- int active, int file)
|
|
|
+ isolate_mode_t mode,
|
|
|
+ struct zone *z, int active, int file)
|
|
|
{
|
|
|
int lru = LRU_BASE;
|
|
|
if (active)
|
|
@@ -1448,6 +1453,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone,
|
|
|
unsigned long nr_taken;
|
|
|
unsigned long nr_anon;
|
|
|
unsigned long nr_file;
|
|
|
+ isolate_mode_t reclaim_mode = ISOLATE_INACTIVE;
|
|
|
|
|
|
while (unlikely(too_many_isolated(zone, file, sc))) {
|
|
|
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);
|
|
|
+ if (sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM)
|
|
|
+ reclaim_mode |= ISOLATE_ACTIVE;
|
|
|
+
|
|
|
lru_add_drain();
|
|
|
spin_lock_irq(&zone->lru_lock);
|
|
|
|
|
|
if (scanning_global_lru(sc)) {
|
|
|
- nr_taken = isolate_pages_global(nr_to_scan,
|
|
|
- &page_list, &nr_scanned, sc->order,
|
|
|
- sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM ?
|
|
|
- ISOLATE_BOTH : ISOLATE_INACTIVE,
|
|
|
- zone, 0, file);
|
|
|
+ nr_taken = isolate_pages_global(nr_to_scan, &page_list,
|
|
|
+ &nr_scanned, sc->order, reclaim_mode, zone, 0, file);
|
|
|
zone->pages_scanned += nr_scanned;
|
|
|
if (current_is_kswapd())
|
|
|
__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,
|
|
|
nr_scanned);
|
|
|
} else {
|
|
|
- nr_taken = mem_cgroup_isolate_pages(nr_to_scan,
|
|
|
- &page_list, &nr_scanned, sc->order,
|
|
|
- sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM ?
|
|
|
- ISOLATE_BOTH : ISOLATE_INACTIVE,
|
|
|
- zone, sc->mem_cgroup,
|
|
|
- 0, file);
|
|
|
+ nr_taken = mem_cgroup_isolate_pages(nr_to_scan, &page_list,
|
|
|
+ &nr_scanned, sc->order, reclaim_mode, zone,
|
|
|
+ sc->mem_cgroup, 0, file);
|
|
|
/*
|
|
|
* mem_cgroup_isolate_pages() keeps track of
|
|
|
* scanned pages on its own.
|