aboutsummaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2016-09-21 07:42:49 -0400
committerNamhoon Kim <namhoonk@cs.unc.edu>2016-09-21 07:42:49 -0400
commit2b1bccf411c97a933796526b0427785a2dafde1d (patch)
tree52d7cde691596ea8ef6cf842db774bcc4840a1ab /mm/migrate.c
parent805c547ee3cdc2ef6a5f7556fdf449ced2e48680 (diff)
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index c88f881f2daa..a5ff157cfe00 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -408,23 +408,17 @@ int replicate_page_move_mapping(struct address_space *mapping,
408 int expected_count = 1 + extra_count; 408 int expected_count = 1 + extra_count;
409 void **pslot; 409 void **pslot;
410 410
411// if (!mapping) { 411 BUG_ON(!mapping);
412 /* Anonymous page without mapping */
413// if (page_count(page) != expected_count)
414// return -EAGAIN;
415// return MIGRATEPAGE_SUCCESS;
416// }
417
418 TRACE_TASK(current, "page has mapping.\n"); 412 TRACE_TASK(current, "page has mapping.\n");
419 spin_lock_irq(&mapping->tree_lock); 413 spin_lock_irq(&mapping->tree_lock);
420 414
421 pslot = radix_tree_lookup_slot(&mapping->page_tree, 415 pslot = radix_tree_lookup_slot(&mapping->page_tree, page_index(page));
422 page_index(page));
423 416
424 expected_count += 1 + page_has_private(page); 417 expected_count += 1 + page_has_private(page);
425 418
426 TRACE_TASK(current, "page_count(page) = %d, expected_count = %d, page_has_private? %d\n", page_count(page), expected_count, page_has_private(page)); 419 TRACE_TASK(current, "page_count(page) = %d, expected_count = %d, page_has_private? %d\n", page_count(page), expected_count, page_has_private(page));
427 420
421 expected_count++;
428 if (page_count(page) != expected_count || 422 if (page_count(page) != expected_count ||
429 radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) { 423 radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) {
430 spin_unlock_irq(&mapping->tree_lock); 424 spin_unlock_irq(&mapping->tree_lock);
@@ -463,13 +457,15 @@ int replicate_page_move_mapping(struct address_space *mapping,
463 } 457 }
464 458
465 radix_tree_replace_slot(pslot, newpage); 459 radix_tree_replace_slot(pslot, newpage);
460 //radix_tree_replace_slot(pslot, page);
466 461
467 /* 462 /*
468 * Drop cache reference from old page by unfreezing 463 * Drop cache reference from old page by unfreezing
469 * to one less reference. 464 * to one less reference.
470 * We know this isn't the last reference. 465 * We know this isn't the last reference.
471 */ 466 */
472 page_unfreeze_refs(page, expected_count - 1); 467 //page_unfreeze_refs(page, expected_count - 1);
468 page_unfreeze_refs(page, expected_count - 2);
473 469
474 /* 470 /*
475 * If moved to a different zone then also account 471 * If moved to a different zone then also account
@@ -682,7 +678,7 @@ EXPORT_SYMBOL(migrate_page);
682 678
683int replicate_page(struct address_space *mapping, 679int replicate_page(struct address_space *mapping,
684 struct page *newpage, struct page *page, 680 struct page *newpage, struct page *page,
685 enum migrate_mode mode) 681 enum migrate_mode mode, int has_replica)
686{ 682{
687 int rc, extra_count = 0; 683 int rc, extra_count = 0;
688 684
@@ -693,7 +689,8 @@ int replicate_page(struct address_space *mapping,
693 if (rc != MIGRATEPAGE_SUCCESS) 689 if (rc != MIGRATEPAGE_SUCCESS)
694 return rc; 690 return rc;
695 691
696 migrate_page_copy(newpage, page); 692 if (has_replica == 0)
693 migrate_page_copy(newpage, page);
697 return MIGRATEPAGE_SUCCESS; 694 return MIGRATEPAGE_SUCCESS;
698} 695}
699 696
@@ -757,20 +754,23 @@ int buffer_migrate_page(struct address_space *mapping,
757EXPORT_SYMBOL(buffer_migrate_page); 754EXPORT_SYMBOL(buffer_migrate_page);
758#endif 755#endif
759 756
757extern struct list_head shared_lib_pages;
758
760int replicate_buffer_page(struct address_space *mapping, 759int replicate_buffer_page(struct address_space *mapping,
761 struct page *newpage, struct page *page, enum migrate_mode mode) 760 struct page *newpage, struct page *page, enum migrate_mode mode,
761 int has_replica)
762{ 762{
763 struct buffer_head *bh, *head; 763 struct buffer_head *bh, *head;
764 int rc; 764 int rc;
765 765
766 if (!page_has_buffers(page)) { 766 if (!page_has_buffers(page)) {
767 TRACE_TASK(current, "page does not have buffers\n"); 767 TRACE_TASK(current, "page does not have buffers\n");
768 return replicate_page(mapping, newpage, page, mode); 768 return replicate_page(mapping, newpage, page, mode, has_replica);
769 } 769 }
770 770
771 head = page_buffers(page); 771 head = page_buffers(page);
772 772
773 rc = migrate_page_move_mapping(mapping, newpage, page, head, mode, 0); 773 rc = replicate_page_move_mapping(mapping, newpage, page, head, mode, 0);
774 774
775 if (rc != MIGRATEPAGE_SUCCESS) 775 if (rc != MIGRATEPAGE_SUCCESS)
776 return rc; 776 return rc;
@@ -798,7 +798,8 @@ int replicate_buffer_page(struct address_space *mapping,
798 798
799 SetPagePrivate(newpage); 799 SetPagePrivate(newpage);
800 800
801 migrate_page_copy(newpage, page); 801 if (has_replica == 0)
802 migrate_page_copy(newpage, page);
802 803
803 bh = head; 804 bh = head;
804 do { 805 do {
@@ -982,7 +983,7 @@ static int copy_to_new_page(struct page *newpage, struct page *page,
982 */ 983 */
983 //rc = mapping->a_ops->migratepage(mapping, 984 //rc = mapping->a_ops->migratepage(mapping,
984 // newpage, page, mode); 985 // newpage, page, mode);
985 rc = replicate_buffer_page(mapping, newpage, page, mode); 986 rc = replicate_buffer_page(mapping, newpage, page, mode, has_replica);
986 } 987 }
987 else { 988 else {
988 TRACE_TASK(current, "fallback function\n"); 989 TRACE_TASK(current, "fallback function\n");
@@ -992,9 +993,13 @@ static int copy_to_new_page(struct page *newpage, struct page *page,
992 if (rc != MIGRATEPAGE_SUCCESS) { 993 if (rc != MIGRATEPAGE_SUCCESS) {
993 newpage->mapping = NULL; 994 newpage->mapping = NULL;
994 } else { 995 } else {
996 if (mem_cgroup_disabled())
997 TRACE_TASK(current, "mem_cgroup_disabled()\n");
995 mem_cgroup_migrate(page, newpage, false); 998 mem_cgroup_migrate(page, newpage, false);
996 if (page_was_mapped) 999 if (page_was_mapped) {
1000 TRACE_TASK(current, "PAGE_WAS_MAPPED = 1\n");
997 remove_migration_ptes(page, newpage); 1001 remove_migration_ptes(page, newpage);
1002 }
998 page->mapping = NULL; 1003 page->mapping = NULL;
999 } 1004 }
1000 1005
@@ -1378,7 +1383,7 @@ static ICE_noinline int unmap_and_copy(new_page_t get_new_page,
1378 rcu_read_lock(); 1383 rcu_read_lock();
1379 list_for_each_entry(lib_page, &shared_lib_pages, list) 1384 list_for_each_entry(lib_page, &shared_lib_pages, list)
1380 { 1385 {
1381 if (page_to_pfn(page) == lib_page->p_pfn) { 1386 if (page_to_pfn(page) == lib_page->master_pfn) {
1382 is_exist_in_psl = 1; 1387 is_exist_in_psl = 1;
1383 break; 1388 break;
1384 } 1389 }
@@ -1386,14 +1391,13 @@ static ICE_noinline int unmap_and_copy(new_page_t get_new_page,
1386 rcu_read_unlock(); 1391 rcu_read_unlock();
1387 1392
1388 if (is_exist_in_psl) 1393 if (is_exist_in_psl)
1389 TRACE_TASK(current, "Page %ld exists in PSL list\n", lib_page->p_pfn); 1394 TRACE_TASK(current, "Page %ld exists in PSL list\n", lib_page->master_pfn);
1390 1395
1391 if (lib_page->r_page == NULL) { 1396 if (lib_page->r_page == NULL) {
1392 newpage = get_new_page(page, private, &result); 1397 newpage = get_new_page(page, private, &result);
1393 if (!newpage) 1398 if (!newpage)
1394 return -ENOMEM; 1399 return -ENOMEM;
1395 } 1400 } else {
1396 else {
1397 newpage = lib_page->r_page; 1401 newpage = lib_page->r_page;
1398 has_replica = 1; 1402 has_replica = 1;
1399 } 1403 }
@@ -1409,21 +1413,28 @@ static ICE_noinline int unmap_and_copy(new_page_t get_new_page,
1409 goto out; 1413 goto out;
1410 1414
1411 rc = __unmap_and_copy(page, newpage, force, mode, has_replica); 1415 rc = __unmap_and_copy(page, newpage, force, mode, has_replica);
1412 1416
1417 if (has_replica == 0) {
1418 lib_page->r_page = newpage;
1419 lib_page->r_pfn = page_to_pfn(newpage);
1420 }
1421
1413out: 1422out:
1414 if (rc != -EAGAIN) { 1423TRACE_TASK(current, "__unmap_and_copy returned %d\n", rc);
1424// if (rc != -EAGAIN) {
1415 /* 1425 /*
1416 * A page that has been migrated has all references 1426 * A page that has been migrated has all references
1417 * removed and will be freed. A page that has not been 1427 * removed and will be freed. A page that has not been
1418 * migrated will have kepts its references and be 1428 * migrated will have kepts its references and be
1419 * restored. 1429 * restored.
1420 */ 1430 */
1421 list_del(&page->lru); 1431// list_del(&page->lru);
1422 dec_zone_page_state(page, NR_ISOLATED_ANON + 1432// dec_zone_page_state(page, NR_ISOLATED_ANON +
1423 page_is_file_cache(page)); 1433// page_is_file_cache(page));
1424 putback_lru_page(page); 1434// putback_lru_page(page);
1425 } 1435// }
1426 1436
1437TRACE_TASK(current, "old page freed\n");
1427 /* 1438 /*
1428 * If migration was not successful and there's a freeing callback, use 1439 * If migration was not successful and there's a freeing callback, use
1429 * it. Otherwise, putback_lru_page() will drop the reference grabbed 1440 * it. Otherwise, putback_lru_page() will drop the reference grabbed