diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index b7d868cbca09..1b85217b528c 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -70,6 +70,13 @@ struct scan_control { | |||
70 | 70 | ||
71 | int order; | 71 | int order; |
72 | 72 | ||
73 | /* | ||
74 | * Pages that have (or should have) IO pending. If we run into | ||
75 | * a lot of these, we're better off waiting a little for IO to | ||
76 | * finish rather than scanning more pages in the VM. | ||
77 | */ | ||
78 | int nr_io_pages; | ||
79 | |||
73 | /* Which cgroup do we reclaim from */ | 80 | /* Which cgroup do we reclaim from */ |
74 | struct mem_cgroup *mem_cgroup; | 81 | struct mem_cgroup *mem_cgroup; |
75 | 82 | ||
@@ -499,8 +506,10 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
499 | */ | 506 | */ |
500 | if (sync_writeback == PAGEOUT_IO_SYNC && may_enter_fs) | 507 | if (sync_writeback == PAGEOUT_IO_SYNC && may_enter_fs) |
501 | wait_on_page_writeback(page); | 508 | wait_on_page_writeback(page); |
502 | else | 509 | else { |
510 | sc->nr_io_pages++; | ||
503 | goto keep_locked; | 511 | goto keep_locked; |
512 | } | ||
504 | } | 513 | } |
505 | 514 | ||
506 | referenced = page_referenced(page, 1, sc->mem_cgroup); | 515 | referenced = page_referenced(page, 1, sc->mem_cgroup); |
@@ -539,8 +548,10 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
539 | if (PageDirty(page)) { | 548 | if (PageDirty(page)) { |
540 | if (sc->order <= PAGE_ALLOC_COSTLY_ORDER && referenced) | 549 | if (sc->order <= PAGE_ALLOC_COSTLY_ORDER && referenced) |
541 | goto keep_locked; | 550 | goto keep_locked; |
542 | if (!may_enter_fs) | 551 | if (!may_enter_fs) { |
552 | sc->nr_io_pages++; | ||
543 | goto keep_locked; | 553 | goto keep_locked; |
554 | } | ||
544 | if (!sc->may_writepage) | 555 | if (!sc->may_writepage) |
545 | goto keep_locked; | 556 | goto keep_locked; |
546 | 557 | ||
@@ -551,8 +562,10 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
551 | case PAGE_ACTIVATE: | 562 | case PAGE_ACTIVATE: |
552 | goto activate_locked; | 563 | goto activate_locked; |
553 | case PAGE_SUCCESS: | 564 | case PAGE_SUCCESS: |
554 | if (PageWriteback(page) || PageDirty(page)) | 565 | if (PageWriteback(page) || PageDirty(page)) { |
566 | sc->nr_io_pages++; | ||
555 | goto keep; | 567 | goto keep; |
568 | } | ||
556 | /* | 569 | /* |
557 | * A synchronous write - probably a ramdisk. Go | 570 | * A synchronous write - probably a ramdisk. Go |
558 | * ahead and try to reclaim the page. | 571 | * ahead and try to reclaim the page. |
@@ -1259,6 +1272,7 @@ static unsigned long do_try_to_free_pages(struct zone **zones, gfp_t gfp_mask, | |||
1259 | 1272 | ||
1260 | for (priority = DEF_PRIORITY; priority >= 0; priority--) { | 1273 | for (priority = DEF_PRIORITY; priority >= 0; priority--) { |
1261 | sc->nr_scanned = 0; | 1274 | sc->nr_scanned = 0; |
1275 | sc->nr_io_pages = 0; | ||
1262 | if (!priority) | 1276 | if (!priority) |
1263 | disable_swap_token(); | 1277 | disable_swap_token(); |
1264 | nr_reclaimed += shrink_zones(priority, zones, sc); | 1278 | nr_reclaimed += shrink_zones(priority, zones, sc); |
@@ -1292,7 +1306,8 @@ static unsigned long do_try_to_free_pages(struct zone **zones, gfp_t gfp_mask, | |||
1292 | } | 1306 | } |
1293 | 1307 | ||
1294 | /* Take a nap, wait for some writeback to complete */ | 1308 | /* Take a nap, wait for some writeback to complete */ |
1295 | if (sc->nr_scanned && priority < DEF_PRIORITY - 2) | 1309 | if (sc->nr_scanned && priority < DEF_PRIORITY - 2 && |
1310 | sc->nr_io_pages > sc->swap_cluster_max) | ||
1296 | congestion_wait(WRITE, HZ/10); | 1311 | congestion_wait(WRITE, HZ/10); |
1297 | } | 1312 | } |
1298 | /* top priority shrink_caches still had more to do? don't OOM, then */ | 1313 | /* top priority shrink_caches still had more to do? don't OOM, then */ |
@@ -1424,6 +1439,7 @@ loop_again: | |||
1424 | if (!priority) | 1439 | if (!priority) |
1425 | disable_swap_token(); | 1440 | disable_swap_token(); |
1426 | 1441 | ||
1442 | sc.nr_io_pages = 0; | ||
1427 | all_zones_ok = 1; | 1443 | all_zones_ok = 1; |
1428 | 1444 | ||
1429 | /* | 1445 | /* |
@@ -1516,7 +1532,8 @@ loop_again: | |||
1516 | * OK, kswapd is getting into trouble. Take a nap, then take | 1532 | * OK, kswapd is getting into trouble. Take a nap, then take |
1517 | * another pass across the zones. | 1533 | * another pass across the zones. |
1518 | */ | 1534 | */ |
1519 | if (total_scanned && priority < DEF_PRIORITY - 2) | 1535 | if (total_scanned && priority < DEF_PRIORITY - 2 && |
1536 | sc.nr_io_pages > sc.swap_cluster_max) | ||
1520 | congestion_wait(WRITE, HZ/10); | 1537 | congestion_wait(WRITE, HZ/10); |
1521 | 1538 | ||
1522 | /* | 1539 | /* |