diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-09-21 07:42:49 -0400 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-09-21 07:42:49 -0400 |
commit | 2b1bccf411c97a933796526b0427785a2dafde1d (patch) | |
tree | 52d7cde691596ea8ef6cf842db774bcc4840a1ab /mm/migrate.c | |
parent | 805c547ee3cdc2ef6a5f7556fdf449ced2e48680 (diff) |
9/21/2016wip-percore-lib
Diffstat (limited to 'mm/migrate.c')
-rw-r--r-- | mm/migrate.c | 71 |
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 | ||
683 | int replicate_page(struct address_space *mapping, | 679 | int 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, | |||
757 | EXPORT_SYMBOL(buffer_migrate_page); | 754 | EXPORT_SYMBOL(buffer_migrate_page); |
758 | #endif | 755 | #endif |
759 | 756 | ||
757 | extern struct list_head shared_lib_pages; | ||
758 | |||
760 | int replicate_buffer_page(struct address_space *mapping, | 759 | int 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 | |||
1413 | out: | 1422 | out: |
1414 | if (rc != -EAGAIN) { | 1423 | TRACE_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 | ||
1437 | TRACE_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 |