aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2008-02-07 03:14:08 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:19 -0500
commitf1a9ee758de7de1e040de849fdef46e6802ea117 (patch)
tree99dfac0c81de111025e12546d97aaebd3d8d576c
parentfef1bdd68c81b71882ccb6f47c70980a03182063 (diff)
kswapd should only wait on IO if there is IO
The current kswapd (and try_to_free_pages) code has an oddity where the code will wait on IO, even if there is no IO in flight. This problem is notable especially when the system scans through many unfreeable pages, causing unnecessary stalls in the VM. Additionally, tasks without __GFP_FS or __GFP_IO in the direct reclaim path will sleep if a significant number of pages are encountered that should be written out. This gives kswapd a chance to write out those pages, while the direct reclaim task sleeps. Signed-off-by: Rik van Riel <riel@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/vmscan.c27
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 /*