aboutsummaryrefslogtreecommitdiffstats
path: root/mm/ksm.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/ksm.c')
-rw-r--r--mm/ksm.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/mm/ksm.c b/mm/ksm.c
index 70daa35266ef..e02430fb26f6 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -514,15 +514,14 @@ static void remove_node_from_stable_tree(struct stable_node *stable_node)
514 * but this is different - made simpler by ksm_thread_mutex being held, but 514 * but this is different - made simpler by ksm_thread_mutex being held, but
515 * interesting for assuming that no other use of the struct page could ever 515 * interesting for assuming that no other use of the struct page could ever
516 * put our expected_mapping into page->mapping (or a field of the union which 516 * put our expected_mapping into page->mapping (or a field of the union which
517 * coincides with page->mapping). The RCU calls are not for KSM at all, but 517 * coincides with page->mapping).
518 * to keep the page_count protocol described with page_cache_get_speculative.
519 * 518 *
520 * Note: it is possible that get_ksm_page() will return NULL one moment, 519 * Note: it is possible that get_ksm_page() will return NULL one moment,
521 * then page the next, if the page is in between page_freeze_refs() and 520 * then page the next, if the page is in between page_freeze_refs() and
522 * page_unfreeze_refs(): this shouldn't be a problem anywhere, the page 521 * page_unfreeze_refs(): this shouldn't be a problem anywhere, the page
523 * is on its way to being freed; but it is an anomaly to bear in mind. 522 * is on its way to being freed; but it is an anomaly to bear in mind.
524 */ 523 */
525static struct page *get_ksm_page(struct stable_node *stable_node) 524static struct page *get_ksm_page(struct stable_node *stable_node, bool locked)
526{ 525{
527 struct page *page; 526 struct page *page;
528 void *expected_mapping; 527 void *expected_mapping;
@@ -530,7 +529,6 @@ static struct page *get_ksm_page(struct stable_node *stable_node)
530 page = pfn_to_page(stable_node->kpfn); 529 page = pfn_to_page(stable_node->kpfn);
531 expected_mapping = (void *)stable_node + 530 expected_mapping = (void *)stable_node +
532 (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM); 531 (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM);
533 rcu_read_lock();
534 if (page->mapping != expected_mapping) 532 if (page->mapping != expected_mapping)
535 goto stale; 533 goto stale;
536 if (!get_page_unless_zero(page)) 534 if (!get_page_unless_zero(page))
@@ -539,10 +537,16 @@ static struct page *get_ksm_page(struct stable_node *stable_node)
539 put_page(page); 537 put_page(page);
540 goto stale; 538 goto stale;
541 } 539 }
542 rcu_read_unlock(); 540 if (locked) {
541 lock_page(page);
542 if (page->mapping != expected_mapping) {
543 unlock_page(page);
544 put_page(page);
545 goto stale;
546 }
547 }
543 return page; 548 return page;
544stale: 549stale:
545 rcu_read_unlock();
546 remove_node_from_stable_tree(stable_node); 550 remove_node_from_stable_tree(stable_node);
547 return NULL; 551 return NULL;
548} 552}
@@ -558,11 +562,10 @@ static void remove_rmap_item_from_tree(struct rmap_item *rmap_item)
558 struct page *page; 562 struct page *page;
559 563
560 stable_node = rmap_item->head; 564 stable_node = rmap_item->head;
561 page = get_ksm_page(stable_node); 565 page = get_ksm_page(stable_node, true);
562 if (!page) 566 if (!page)
563 goto out; 567 goto out;
564 568
565 lock_page(page);
566 hlist_del(&rmap_item->hlist); 569 hlist_del(&rmap_item->hlist);
567 unlock_page(page); 570 unlock_page(page);
568 put_page(page); 571 put_page(page);
@@ -1042,7 +1045,7 @@ static struct page *stable_tree_search(struct page *page)
1042 1045
1043 cond_resched(); 1046 cond_resched();
1044 stable_node = rb_entry(node, struct stable_node, node); 1047 stable_node = rb_entry(node, struct stable_node, node);
1045 tree_page = get_ksm_page(stable_node); 1048 tree_page = get_ksm_page(stable_node, false);
1046 if (!tree_page) 1049 if (!tree_page)
1047 return NULL; 1050 return NULL;
1048 1051
@@ -1086,7 +1089,7 @@ static struct stable_node *stable_tree_insert(struct page *kpage)
1086 1089
1087 cond_resched(); 1090 cond_resched();
1088 stable_node = rb_entry(*new, struct stable_node, node); 1091 stable_node = rb_entry(*new, struct stable_node, node);
1089 tree_page = get_ksm_page(stable_node); 1092 tree_page = get_ksm_page(stable_node, false);
1090 if (!tree_page) 1093 if (!tree_page)
1091 return NULL; 1094 return NULL;
1092 1095