aboutsummaryrefslogtreecommitdiffstats
path: root/mm/ksm.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/ksm.c')
-rw-r--r--mm/ksm.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/mm/ksm.c b/mm/ksm.c
index 20f46a7b2799..dfdc292d3626 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1656,6 +1656,71 @@ out:
1656 return ret; 1656 return ret;
1657} 1657}
1658 1658
1659#ifdef CONFIG_MIGRATION
1660int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *,
1661 struct vm_area_struct *, unsigned long, void *), void *arg)
1662{
1663 struct stable_node *stable_node;
1664 struct hlist_node *hlist;
1665 struct rmap_item *rmap_item;
1666 int ret = SWAP_AGAIN;
1667 int search_new_forks = 0;
1668
1669 VM_BUG_ON(!PageKsm(page));
1670 VM_BUG_ON(!PageLocked(page));
1671
1672 stable_node = page_stable_node(page);
1673 if (!stable_node)
1674 return ret;
1675again:
1676 hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
1677 struct anon_vma *anon_vma = rmap_item->anon_vma;
1678 struct vm_area_struct *vma;
1679
1680 spin_lock(&anon_vma->lock);
1681 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
1682 if (rmap_item->address < vma->vm_start ||
1683 rmap_item->address >= vma->vm_end)
1684 continue;
1685 /*
1686 * Initially we examine only the vma which covers this
1687 * rmap_item; but later, if there is still work to do,
1688 * we examine covering vmas in other mms: in case they
1689 * were forked from the original since ksmd passed.
1690 */
1691 if ((rmap_item->mm == vma->vm_mm) == search_new_forks)
1692 continue;
1693
1694 ret = rmap_one(page, vma, rmap_item->address, arg);
1695 if (ret != SWAP_AGAIN) {
1696 spin_unlock(&anon_vma->lock);
1697 goto out;
1698 }
1699 }
1700 spin_unlock(&anon_vma->lock);
1701 }
1702 if (!search_new_forks++)
1703 goto again;
1704out:
1705 return ret;
1706}
1707
1708void ksm_migrate_page(struct page *newpage, struct page *oldpage)
1709{
1710 struct stable_node *stable_node;
1711
1712 VM_BUG_ON(!PageLocked(oldpage));
1713 VM_BUG_ON(!PageLocked(newpage));
1714 VM_BUG_ON(newpage->mapping != oldpage->mapping);
1715
1716 stable_node = page_stable_node(newpage);
1717 if (stable_node) {
1718 VM_BUG_ON(stable_node->page != oldpage);
1719 stable_node->page = newpage;
1720 }
1721}
1722#endif /* CONFIG_MIGRATION */
1723
1659#ifdef CONFIG_SYSFS 1724#ifdef CONFIG_SYSFS
1660/* 1725/*
1661 * This all compiles without CONFIG_SYSFS, but is a waste of space. 1726 * This all compiles without CONFIG_SYSFS, but is a waste of space.