diff options
author | Konstantin Khlebnikov <khlebnikov@openvz.org> | 2012-05-29 18:06:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-29 19:22:25 -0400 |
commit | 3cb9945179bd04e9282f31a1173ac11b1300c462 (patch) | |
tree | 06c7cb3dfc969f347b16eaca515e2b3ca9058f8f /mm/vmscan.c | |
parent | 89abfab133ef1f5902abafb744df72793213ac19 (diff) |
mm: push lru index into shrink_[in]active_list()
Let's toss lru index through call stack to isolate_lru_pages(), this is
better than its reconstructing from individual bits.
[akpm@linux-foundation.org: fix kerneldoc, per Minchan]
Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Hugh Dickins <hughd@google.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 41 |
1 files changed, 17 insertions, 24 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index e234ada18747..987be819fad6 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1044,27 +1044,22 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file) | |||
1044 | * @nr_scanned: The number of pages that were scanned. | 1044 | * @nr_scanned: The number of pages that were scanned. |
1045 | * @sc: The scan_control struct for this reclaim session | 1045 | * @sc: The scan_control struct for this reclaim session |
1046 | * @mode: One of the LRU isolation modes | 1046 | * @mode: One of the LRU isolation modes |
1047 | * @active: True [1] if isolating active pages | 1047 | * @lru: LRU list id for isolating |
1048 | * @file: True [1] if isolating file [!anon] pages | ||
1049 | * | 1048 | * |
1050 | * returns how many pages were moved onto *@dst. | 1049 | * returns how many pages were moved onto *@dst. |
1051 | */ | 1050 | */ |
1052 | static unsigned long isolate_lru_pages(unsigned long nr_to_scan, | 1051 | static unsigned long isolate_lru_pages(unsigned long nr_to_scan, |
1053 | struct mem_cgroup_zone *mz, struct list_head *dst, | 1052 | struct mem_cgroup_zone *mz, struct list_head *dst, |
1054 | unsigned long *nr_scanned, struct scan_control *sc, | 1053 | unsigned long *nr_scanned, struct scan_control *sc, |
1055 | isolate_mode_t mode, int active, int file) | 1054 | isolate_mode_t mode, enum lru_list lru) |
1056 | { | 1055 | { |
1057 | struct lruvec *lruvec; | 1056 | struct lruvec *lruvec; |
1058 | struct list_head *src; | 1057 | struct list_head *src; |
1059 | unsigned long nr_taken = 0; | 1058 | unsigned long nr_taken = 0; |
1060 | unsigned long scan; | 1059 | unsigned long scan; |
1061 | int lru = LRU_BASE; | 1060 | int file = is_file_lru(lru); |
1062 | 1061 | ||
1063 | lruvec = mem_cgroup_zone_lruvec(mz->zone, mz->mem_cgroup); | 1062 | lruvec = mem_cgroup_zone_lruvec(mz->zone, mz->mem_cgroup); |
1064 | if (active) | ||
1065 | lru += LRU_ACTIVE; | ||
1066 | if (file) | ||
1067 | lru += LRU_FILE; | ||
1068 | src = &lruvec->lists[lru]; | 1063 | src = &lruvec->lists[lru]; |
1069 | 1064 | ||
1070 | for (scan = 0; scan < nr_to_scan && !list_empty(src); scan++) { | 1065 | for (scan = 0; scan < nr_to_scan && !list_empty(src); scan++) { |
@@ -1277,7 +1272,7 @@ update_isolated_counts(struct mem_cgroup_zone *mz, | |||
1277 | */ | 1272 | */ |
1278 | static noinline_for_stack unsigned long | 1273 | static noinline_for_stack unsigned long |
1279 | shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz, | 1274 | shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz, |
1280 | struct scan_control *sc, int priority, int file) | 1275 | struct scan_control *sc, int priority, enum lru_list lru) |
1281 | { | 1276 | { |
1282 | LIST_HEAD(page_list); | 1277 | LIST_HEAD(page_list); |
1283 | unsigned long nr_scanned; | 1278 | unsigned long nr_scanned; |
@@ -1288,6 +1283,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz, | |||
1288 | unsigned long nr_dirty = 0; | 1283 | unsigned long nr_dirty = 0; |
1289 | unsigned long nr_writeback = 0; | 1284 | unsigned long nr_writeback = 0; |
1290 | isolate_mode_t isolate_mode = ISOLATE_INACTIVE; | 1285 | isolate_mode_t isolate_mode = ISOLATE_INACTIVE; |
1286 | int file = is_file_lru(lru); | ||
1291 | struct zone *zone = mz->zone; | 1287 | struct zone *zone = mz->zone; |
1292 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz); | 1288 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz); |
1293 | 1289 | ||
@@ -1309,7 +1305,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz, | |||
1309 | spin_lock_irq(&zone->lru_lock); | 1305 | spin_lock_irq(&zone->lru_lock); |
1310 | 1306 | ||
1311 | nr_taken = isolate_lru_pages(nr_to_scan, mz, &page_list, &nr_scanned, | 1307 | nr_taken = isolate_lru_pages(nr_to_scan, mz, &page_list, &nr_scanned, |
1312 | sc, isolate_mode, 0, file); | 1308 | sc, isolate_mode, lru); |
1313 | if (global_reclaim(sc)) { | 1309 | if (global_reclaim(sc)) { |
1314 | zone->pages_scanned += nr_scanned; | 1310 | zone->pages_scanned += nr_scanned; |
1315 | if (current_is_kswapd()) | 1311 | if (current_is_kswapd()) |
@@ -1445,7 +1441,7 @@ static void move_active_pages_to_lru(struct zone *zone, | |||
1445 | static void shrink_active_list(unsigned long nr_to_scan, | 1441 | static void shrink_active_list(unsigned long nr_to_scan, |
1446 | struct mem_cgroup_zone *mz, | 1442 | struct mem_cgroup_zone *mz, |
1447 | struct scan_control *sc, | 1443 | struct scan_control *sc, |
1448 | int priority, int file) | 1444 | int priority, enum lru_list lru) |
1449 | { | 1445 | { |
1450 | unsigned long nr_taken; | 1446 | unsigned long nr_taken; |
1451 | unsigned long nr_scanned; | 1447 | unsigned long nr_scanned; |
@@ -1457,6 +1453,7 @@ static void shrink_active_list(unsigned long nr_to_scan, | |||
1457 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz); | 1453 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz); |
1458 | unsigned long nr_rotated = 0; | 1454 | unsigned long nr_rotated = 0; |
1459 | isolate_mode_t isolate_mode = ISOLATE_ACTIVE; | 1455 | isolate_mode_t isolate_mode = ISOLATE_ACTIVE; |
1456 | int file = is_file_lru(lru); | ||
1460 | struct zone *zone = mz->zone; | 1457 | struct zone *zone = mz->zone; |
1461 | 1458 | ||
1462 | lru_add_drain(); | 1459 | lru_add_drain(); |
@@ -1469,17 +1466,14 @@ static void shrink_active_list(unsigned long nr_to_scan, | |||
1469 | spin_lock_irq(&zone->lru_lock); | 1466 | spin_lock_irq(&zone->lru_lock); |
1470 | 1467 | ||
1471 | nr_taken = isolate_lru_pages(nr_to_scan, mz, &l_hold, &nr_scanned, sc, | 1468 | nr_taken = isolate_lru_pages(nr_to_scan, mz, &l_hold, &nr_scanned, sc, |
1472 | isolate_mode, 1, file); | 1469 | isolate_mode, lru); |
1473 | if (global_reclaim(sc)) | 1470 | if (global_reclaim(sc)) |
1474 | zone->pages_scanned += nr_scanned; | 1471 | zone->pages_scanned += nr_scanned; |
1475 | 1472 | ||
1476 | reclaim_stat->recent_scanned[file] += nr_taken; | 1473 | reclaim_stat->recent_scanned[file] += nr_taken; |
1477 | 1474 | ||
1478 | __count_zone_vm_events(PGREFILL, zone, nr_scanned); | 1475 | __count_zone_vm_events(PGREFILL, zone, nr_scanned); |
1479 | if (file) | 1476 | __mod_zone_page_state(zone, NR_LRU_BASE + lru, -nr_taken); |
1480 | __mod_zone_page_state(zone, NR_ACTIVE_FILE, -nr_taken); | ||
1481 | else | ||
1482 | __mod_zone_page_state(zone, NR_ACTIVE_ANON, -nr_taken); | ||
1483 | __mod_zone_page_state(zone, NR_ISOLATED_ANON + file, nr_taken); | 1477 | __mod_zone_page_state(zone, NR_ISOLATED_ANON + file, nr_taken); |
1484 | spin_unlock_irq(&zone->lru_lock); | 1478 | spin_unlock_irq(&zone->lru_lock); |
1485 | 1479 | ||
@@ -1535,10 +1529,8 @@ static void shrink_active_list(unsigned long nr_to_scan, | |||
1535 | */ | 1529 | */ |
1536 | reclaim_stat->recent_rotated[file] += nr_rotated; | 1530 | reclaim_stat->recent_rotated[file] += nr_rotated; |
1537 | 1531 | ||
1538 | move_active_pages_to_lru(zone, &l_active, &l_hold, | 1532 | move_active_pages_to_lru(zone, &l_active, &l_hold, lru); |
1539 | LRU_ACTIVE + file * LRU_FILE); | 1533 | move_active_pages_to_lru(zone, &l_inactive, &l_hold, lru - LRU_ACTIVE); |
1540 | move_active_pages_to_lru(zone, &l_inactive, &l_hold, | ||
1541 | LRU_BASE + file * LRU_FILE); | ||
1542 | __mod_zone_page_state(zone, NR_ISOLATED_ANON + file, -nr_taken); | 1534 | __mod_zone_page_state(zone, NR_ISOLATED_ANON + file, -nr_taken); |
1543 | spin_unlock_irq(&zone->lru_lock); | 1535 | spin_unlock_irq(&zone->lru_lock); |
1544 | 1536 | ||
@@ -1638,11 +1630,11 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, | |||
1638 | 1630 | ||
1639 | if (is_active_lru(lru)) { | 1631 | if (is_active_lru(lru)) { |
1640 | if (inactive_list_is_low(mz, file)) | 1632 | if (inactive_list_is_low(mz, file)) |
1641 | shrink_active_list(nr_to_scan, mz, sc, priority, file); | 1633 | shrink_active_list(nr_to_scan, mz, sc, priority, lru); |
1642 | return 0; | 1634 | return 0; |
1643 | } | 1635 | } |
1644 | 1636 | ||
1645 | return shrink_inactive_list(nr_to_scan, mz, sc, priority, file); | 1637 | return shrink_inactive_list(nr_to_scan, mz, sc, priority, lru); |
1646 | } | 1638 | } |
1647 | 1639 | ||
1648 | static int vmscan_swappiness(struct mem_cgroup_zone *mz, | 1640 | static int vmscan_swappiness(struct mem_cgroup_zone *mz, |
@@ -1900,7 +1892,8 @@ restart: | |||
1900 | * rebalance the anon lru active/inactive ratio. | 1892 | * rebalance the anon lru active/inactive ratio. |
1901 | */ | 1893 | */ |
1902 | if (inactive_anon_is_low(mz)) | 1894 | if (inactive_anon_is_low(mz)) |
1903 | shrink_active_list(SWAP_CLUSTER_MAX, mz, sc, priority, 0); | 1895 | shrink_active_list(SWAP_CLUSTER_MAX, mz, |
1896 | sc, priority, LRU_ACTIVE_ANON); | ||
1904 | 1897 | ||
1905 | /* reclaim/compaction might need reclaim to continue */ | 1898 | /* reclaim/compaction might need reclaim to continue */ |
1906 | if (should_continue_reclaim(mz, nr_reclaimed, | 1899 | if (should_continue_reclaim(mz, nr_reclaimed, |
@@ -2339,7 +2332,7 @@ static void age_active_anon(struct zone *zone, struct scan_control *sc, | |||
2339 | 2332 | ||
2340 | if (inactive_anon_is_low(&mz)) | 2333 | if (inactive_anon_is_low(&mz)) |
2341 | shrink_active_list(SWAP_CLUSTER_MAX, &mz, | 2334 | shrink_active_list(SWAP_CLUSTER_MAX, &mz, |
2342 | sc, priority, 0); | 2335 | sc, priority, LRU_ACTIVE_ANON); |
2343 | 2336 | ||
2344 | memcg = mem_cgroup_iter(NULL, memcg, NULL); | 2337 | memcg = mem_cgroup_iter(NULL, memcg, NULL); |
2345 | } while (memcg); | 2338 | } while (memcg); |