aboutsummaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2012-01-12 20:19:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-12 23:13:09 -0500
commitb969c4ab9f182a6e1b2a0848be349f99714947b0 (patch)
treedc1c6e4375cfec7b15f13a37307eba8a9e07f40f /mm/migrate.c
parent7335084d446b83cbcb15da80497d03f0c1dc9e21 (diff)
mm: compaction: determine if dirty pages can be migrated without blocking within ->migratepage
Asynchronous compaction is used when allocating transparent hugepages to avoid blocking for long periods of time. Due to reports of stalling, there was a debate on disabling synchronous compaction but this severely impacted allocation success rates. Part of the reason was that many dirty pages are skipped in asynchronous compaction by the following check; if (PageDirty(page) && !sync && mapping->a_ops->migratepage != migrate_page) rc = -EBUSY; This skips over all mapping aops using buffer_migrate_page() even though it is possible to migrate some of these pages without blocking. This patch updates the ->migratepage callback with a "sync" parameter. It is the responsibility of the callback to fail gracefully if migration would block. Signed-off-by: Mel Gorman <mgorman@suse.de> Reviewed-by: Rik van Riel <riel@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: Dave Jones <davej@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Andy Isaacson <adi@hexapodia.org> Cc: Nai Xia <nai.xia@gmail.com> Cc: Johannes Weiner <jweiner@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c129
1 files changed, 92 insertions, 37 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index fc391985899f..4e86f3bacb85 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -216,6 +216,55 @@ out:
216 pte_unmap_unlock(ptep, ptl); 216 pte_unmap_unlock(ptep, ptl);
217} 217}
218 218
219#ifdef CONFIG_BLOCK
220/* Returns true if all buffers are successfully locked */
221static bool buffer_migrate_lock_buffers(struct buffer_head *head, bool sync)
222{
223 struct buffer_head *bh = head;
224
225 /* Simple case, sync compaction */
226 if (sync) {
227 do {
228 get_bh(bh);
229 lock_buffer(bh);
230 bh = bh->b_this_page;
231
232 } while (bh != head);
233
234 return true;
235 }
236
237 /* async case, we cannot block on lock_buffer so use trylock_buffer */
238 do {
239 get_bh(bh);
240 if (!trylock_buffer(bh)) {
241 /*
242 * We failed to lock the buffer and cannot stall in
243 * async migration. Release the taken locks
244 */
245 struct buffer_head *failed_bh = bh;
246 put_bh(failed_bh);
247 bh = head;
248 while (bh != failed_bh) {
249 unlock_buffer(bh);
250 put_bh(bh);
251 bh = bh->b_this_page;
252 }
253 return false;
254 }
255
256 bh = bh->b_this_page;
257 } while (bh != head);
258 return true;
259}
260#else
261static inline bool buffer_migrate_lock_buffers(struct buffer_head *head,
262 bool sync)
263{
264 return true;
265}
266#endif /* CONFIG_BLOCK */
267
219/* 268/*
220 * Replace the page in the mapping. 269 * Replace the page in the mapping.
221 * 270 *
@@ -225,7 +274,8 @@ out:
225 * 3 for pages with a mapping and PagePrivate/PagePrivate2 set. 274 * 3 for pages with a mapping and PagePrivate/PagePrivate2 set.
226 */ 275 */
227static int migrate_page_move_mapping(struct address_space *mapping, 276static int migrate_page_move_mapping(struct address_space *mapping,
228 struct page *newpage, struct page *page) 277 struct page *newpage, struct page *page,
278 struct buffer_head *head, bool sync)
229{ 279{
230 int expected_count; 280 int expected_count;
231 void **pslot; 281 void **pslot;
@@ -255,6 +305,19 @@ static int migrate_page_move_mapping(struct address_space *mapping,
255 } 305 }
256 306
257 /* 307 /*
308 * In the async migration case of moving a page with buffers, lock the
309 * buffers using trylock before the mapping is moved. If the mapping
310 * was moved, we later failed to lock the buffers and could not move
311 * the mapping back due to an elevated page count, we would have to
312 * block waiting on other references to be dropped.
313 */
314 if (!sync && head && !buffer_migrate_lock_buffers(head, sync)) {
315 page_unfreeze_refs(page, expected_count);
316 spin_unlock_irq(&mapping->tree_lock);
317 return -EAGAIN;
318 }
319
320 /*
258 * Now we know that no one else is looking at the page. 321 * Now we know that no one else is looking at the page.
259 */ 322 */
260 get_page(newpage); /* add cache reference */ 323 get_page(newpage); /* add cache reference */
@@ -409,13 +472,13 @@ EXPORT_SYMBOL(fail_migrate_page);
409 * Pages are locked upon entry and exit. 472 * Pages are locked upon entry and exit.
410 */ 473 */
411int migrate_page(struct address_space *mapping, 474int migrate_page(struct address_space *mapping,
412 struct page *newpage, struct page *page) 475 struct page *newpage, struct page *page, bool sync)
413{ 476{
414 int rc; 477 int rc;
415 478
416 BUG_ON(PageWriteback(page)); /* Writeback must be complete */ 479 BUG_ON(PageWriteback(page)); /* Writeback must be complete */
417 480
418 rc = migrate_page_move_mapping(mapping, newpage, page); 481 rc = migrate_page_move_mapping(mapping, newpage, page, NULL, sync);
419 482
420 if (rc) 483 if (rc)
421 return rc; 484 return rc;
@@ -432,28 +495,28 @@ EXPORT_SYMBOL(migrate_page);
432 * exist. 495 * exist.
433 */ 496 */
434int buffer_migrate_page(struct address_space *mapping, 497int buffer_migrate_page(struct address_space *mapping,
435 struct page *newpage, struct page *page) 498 struct page *newpage, struct page *page, bool sync)
436{ 499{
437 struct buffer_head *bh, *head; 500 struct buffer_head *bh, *head;
438 int rc; 501 int rc;
439 502
440 if (!page_has_buffers(page)) 503 if (!page_has_buffers(page))
441 return migrate_page(mapping, newpage, page); 504 return migrate_page(mapping, newpage, page, sync);
442 505
443 head = page_buffers(page); 506 head = page_buffers(page);
444 507
445 rc = migrate_page_move_mapping(mapping, newpage, page); 508 rc = migrate_page_move_mapping(mapping, newpage, page, head, sync);
446 509
447 if (rc) 510 if (rc)
448 return rc; 511 return rc;
449 512
450 bh = head; 513 /*
451 do { 514 * In the async case, migrate_page_move_mapping locked the buffers
452 get_bh(bh); 515 * with an IRQ-safe spinlock held. In the sync case, the buffers
453 lock_buffer(bh); 516 * need to be locked now
454 bh = bh->b_this_page; 517 */
455 518 if (sync)
456 } while (bh != head); 519 BUG_ON(!buffer_migrate_lock_buffers(head, sync));
457 520
458 ClearPagePrivate(page); 521 ClearPagePrivate(page);
459 set_page_private(newpage, page_private(page)); 522 set_page_private(newpage, page_private(page));
@@ -530,10 +593,13 @@ static int writeout(struct address_space *mapping, struct page *page)
530 * Default handling if a filesystem does not provide a migration function. 593 * Default handling if a filesystem does not provide a migration function.
531 */ 594 */
532static int fallback_migrate_page(struct address_space *mapping, 595static int fallback_migrate_page(struct address_space *mapping,
533 struct page *newpage, struct page *page) 596 struct page *newpage, struct page *page, bool sync)
534{ 597{
535 if (PageDirty(page)) 598 if (PageDirty(page)) {
599 if (!sync)
600 return -EBUSY;
536 return writeout(mapping, page); 601 return writeout(mapping, page);
602 }
537 603
538 /* 604 /*
539 * Buffers may be managed in a filesystem specific way. 605 * Buffers may be managed in a filesystem specific way.
@@ -543,7 +609,7 @@ static int fallback_migrate_page(struct address_space *mapping,
543 !try_to_release_page(page, GFP_KERNEL)) 609 !try_to_release_page(page, GFP_KERNEL))
544 return -EAGAIN; 610 return -EAGAIN;
545 611
546 return migrate_page(mapping, newpage, page); 612 return migrate_page(mapping, newpage, page, sync);
547} 613}
548 614
549/* 615/*
@@ -579,29 +645,18 @@ static int move_to_new_page(struct page *newpage, struct page *page,
579 645
580 mapping = page_mapping(page); 646 mapping = page_mapping(page);
581 if (!mapping) 647 if (!mapping)
582 rc = migrate_page(mapping, newpage, page); 648 rc = migrate_page(mapping, newpage, page, sync);
583 else { 649 else if (mapping->a_ops->migratepage)
584 /* 650 /*
585 * Do not writeback pages if !sync and migratepage is 651 * Most pages have a mapping and most filesystems provide a
586 * not pointing to migrate_page() which is nonblocking 652 * migratepage callback. Anonymous pages are part of swap
587 * (swapcache/tmpfs uses migratepage = migrate_page). 653 * space which also has its own migratepage callback. This
654 * is the most common path for page migration.
588 */ 655 */
589 if (PageDirty(page) && !sync && 656 rc = mapping->a_ops->migratepage(mapping,
590 mapping->a_ops->migratepage != migrate_page) 657 newpage, page, sync);
591 rc = -EBUSY; 658 else
592 else if (mapping->a_ops->migratepage) 659 rc = fallback_migrate_page(mapping, newpage, page, sync);
593 /*
594 * Most pages have a mapping and most filesystems
595 * should provide a migration function. Anonymous
596 * pages are part of swap space which also has its
597 * own migration function. This is the most common
598 * path for page migration.
599 */
600 rc = mapping->a_ops->migratepage(mapping,
601 newpage, page);
602 else
603 rc = fallback_migrate_page(mapping, newpage, page);
604 }
605 660
606 if (rc) { 661 if (rc) {
607 newpage->mapping = NULL; 662 newpage->mapping = NULL;