aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>2009-01-06 17:40:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:06 -0500
commit01dbe5c9b1004dab045cb7f38428258ca9cddc02 (patch)
tree526bba2afd30a7a58e47597f0ab9255a37a21d55 /mm/vmscan.c
parenta79311c14eae4bb946a97af25f3e1b17d625985d (diff)
vmscan: improve reclaim throughput to bail out patch
The vmscan bail out patch move nr_reclaimed variable to struct scan_control. Unfortunately, indirect access can easily happen cache miss. if heavy memory pressure happend, that's ok. cache miss already plenty. it is not observable. but, if memory pressure is lite, performance degression is obserbable. I compared following three pattern (it was mesured 10 times each) hackbench 125 process 3000 hackbench 130 process 3000 hackbench 135 process 3000 2.6.28-rc6 bail-out 125 130 135 125 130 135 ============================================================== 71.866 75.86 81.274 93.414 73.254 193.382 74.145 78.295 77.27 74.897 75.021 80.17 70.305 77.643 75.855 70.134 77.571 79.896 74.288 73.986 75.955 77.222 78.48 80.619 72.029 79.947 78.312 75.128 82.172 79.708 71.499 77.615 77.042 74.177 76.532 77.306 76.188 74.471 83.562 73.839 72.43 79.833 73.236 75.606 78.743 76.001 76.557 82.726 69.427 77.271 76.691 76.236 79.371 103.189 72.473 76.978 80.643 69.128 78.932 75.736 avg 72.545 76.767 78.534 76.017 77.03 93.256 std 1.89 1.71 2.41 6.29 2.79 34.16 min 69.427 73.986 75.855 69.128 72.43 75.736 max 76.188 79.947 83.562 93.414 82.172 193.382 about 4-5% degression. Then, this patch introduces a temporary local variable. result: 2.6.28-rc6 this patch num 125 130 135 125 130 135 ============================================================== 71.866 75.86 81.274 67.302 68.269 77.161 74.145 78.295 77.27 72.616 72.712 79.06 70.305 77.643 75.855 72.475 75.712 77.735 74.288 73.986 75.955 69.229 73.062 78.814 72.029 79.947 78.312 71.551 74.392 78.564 71.499 77.615 77.042 69.227 74.31 78.837 76.188 74.471 83.562 70.759 75.256 76.6 73.236 75.606 78.743 69.966 76.001 78.464 69.427 77.271 76.691 69.068 75.218 80.321 72.473 76.978 80.643 72.057 77.151 79.068 avg 72.545 76.767 78.534 70.425 74.2083 78.462 std 1.89 1.71 2.41 1.66 2.34 1.00 min 69.427 73.986 75.855 67.302 68.269 76.6 max 76.188 79.947 83.562 72.616 77.151 80.321 OK. the degression is disappeared. Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Acked-by: Rik van Riel <riel@redhat.com> Cc: Mel Gorman <mel@csn.ul.ie> 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.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5faa7739487f..13f050d667e9 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1410,6 +1410,8 @@ static void shrink_zone(int priority, struct zone *zone,
1410 unsigned long nr_to_scan; 1410 unsigned long nr_to_scan;
1411 unsigned long percent[2]; /* anon @ 0; file @ 1 */ 1411 unsigned long percent[2]; /* anon @ 0; file @ 1 */
1412 enum lru_list l; 1412 enum lru_list l;
1413 unsigned long nr_reclaimed = sc->nr_reclaimed;
1414 unsigned long swap_cluster_max = sc->swap_cluster_max;
1413 1415
1414 get_scan_ratio(zone, sc, percent); 1416 get_scan_ratio(zone, sc, percent);
1415 1417
@@ -1425,7 +1427,7 @@ static void shrink_zone(int priority, struct zone *zone,
1425 } 1427 }
1426 zone->lru[l].nr_scan += scan; 1428 zone->lru[l].nr_scan += scan;
1427 nr[l] = zone->lru[l].nr_scan; 1429 nr[l] = zone->lru[l].nr_scan;
1428 if (nr[l] >= sc->swap_cluster_max) 1430 if (nr[l] >= swap_cluster_max)
1429 zone->lru[l].nr_scan = 0; 1431 zone->lru[l].nr_scan = 0;
1430 else 1432 else
1431 nr[l] = 0; 1433 nr[l] = 0;
@@ -1444,12 +1446,11 @@ static void shrink_zone(int priority, struct zone *zone,
1444 nr[LRU_INACTIVE_FILE]) { 1446 nr[LRU_INACTIVE_FILE]) {
1445 for_each_evictable_lru(l) { 1447 for_each_evictable_lru(l) {
1446 if (nr[l]) { 1448 if (nr[l]) {
1447 nr_to_scan = min(nr[l], 1449 nr_to_scan = min(nr[l], swap_cluster_max);
1448 (unsigned long)sc->swap_cluster_max);
1449 nr[l] -= nr_to_scan; 1450 nr[l] -= nr_to_scan;
1450 1451
1451 sc->nr_reclaimed += shrink_list(l, nr_to_scan, 1452 nr_reclaimed += shrink_list(l, nr_to_scan,
1452 zone, sc, priority); 1453 zone, sc, priority);
1453 } 1454 }
1454 } 1455 }
1455 /* 1456 /*
@@ -1460,11 +1461,13 @@ static void shrink_zone(int priority, struct zone *zone,
1460 * with multiple processes reclaiming pages, the total 1461 * with multiple processes reclaiming pages, the total
1461 * freeing target can get unreasonably large. 1462 * freeing target can get unreasonably large.
1462 */ 1463 */
1463 if (sc->nr_reclaimed > sc->swap_cluster_max && 1464 if (nr_reclaimed > swap_cluster_max &&
1464 priority < DEF_PRIORITY && !current_is_kswapd()) 1465 priority < DEF_PRIORITY && !current_is_kswapd())
1465 break; 1466 break;
1466 } 1467 }
1467 1468
1469 sc->nr_reclaimed = nr_reclaimed;
1470
1468 /* 1471 /*
1469 * Even if we did not try to evict anon pages at all, we want to 1472 * Even if we did not try to evict anon pages at all, we want to
1470 * rebalance the anon lru active/inactive ratio. 1473 * rebalance the anon lru active/inactive ratio.