aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ksm.h54
-rw-r--r--include/linux/rmap.h5
2 files changed, 53 insertions, 6 deletions
diff --git a/include/linux/ksm.h b/include/linux/ksm.h
index ef55ce14a2ce..157d83dbaef8 100644
--- a/include/linux/ksm.h
+++ b/include/linux/ksm.h
@@ -9,10 +9,12 @@
9 9
10#include <linux/bitops.h> 10#include <linux/bitops.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/pagemap.h>
13#include <linux/rmap.h>
12#include <linux/sched.h> 14#include <linux/sched.h>
13#include <linux/vmstat.h>
14 15
15struct stable_node; 16struct stable_node;
17struct mem_cgroup;
16 18
17#ifdef CONFIG_KSM 19#ifdef CONFIG_KSM
18int ksm_madvise(struct vm_area_struct *vma, unsigned long start, 20int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
@@ -57,11 +59,36 @@ static inline void set_page_stable_node(struct page *page,
57 (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM); 59 (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM);
58} 60}
59 61
60static inline void page_add_ksm_rmap(struct page *page) 62/*
63 * When do_swap_page() first faults in from swap what used to be a KSM page,
64 * no problem, it will be assigned to this vma's anon_vma; but thereafter,
65 * it might be faulted into a different anon_vma (or perhaps to a different
66 * offset in the same anon_vma). do_swap_page() cannot do all the locking
67 * needed to reconstitute a cross-anon_vma KSM page: for now it has to make
68 * a copy, and leave remerging the pages to a later pass of ksmd.
69 *
70 * We'd like to make this conditional on vma->vm_flags & VM_MERGEABLE,
71 * but what if the vma was unmerged while the page was swapped out?
72 */
73struct page *ksm_does_need_to_copy(struct page *page,
74 struct vm_area_struct *vma, unsigned long address);
75static inline struct page *ksm_might_need_to_copy(struct page *page,
76 struct vm_area_struct *vma, unsigned long address)
61{ 77{
62 if (atomic_inc_and_test(&page->_mapcount)) 78 struct anon_vma *anon_vma = page_anon_vma(page);
63 __inc_zone_page_state(page, NR_ANON_PAGES); 79
80 if (!anon_vma ||
81 (anon_vma == vma->anon_vma &&
82 page->index == linear_page_index(vma, address)))
83 return page;
84
85 return ksm_does_need_to_copy(page, vma, address);
64} 86}
87
88int page_referenced_ksm(struct page *page,
89 struct mem_cgroup *memcg, unsigned long *vm_flags);
90int try_to_unmap_ksm(struct page *page, enum ttu_flags flags);
91
65#else /* !CONFIG_KSM */ 92#else /* !CONFIG_KSM */
66 93
67static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start, 94static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
@@ -84,7 +111,22 @@ static inline int PageKsm(struct page *page)
84 return 0; 111 return 0;
85} 112}
86 113
87/* No stub required for page_add_ksm_rmap(page) */ 114static inline struct page *ksm_might_need_to_copy(struct page *page,
115 struct vm_area_struct *vma, unsigned long address)
116{
117 return page;
118}
119
120static inline int page_referenced_ksm(struct page *page,
121 struct mem_cgroup *memcg, unsigned long *vm_flags)
122{
123 return 0;
124}
125
126static inline int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
127{
128 return 0;
129}
88#endif /* !CONFIG_KSM */ 130#endif /* !CONFIG_KSM */
89 131
90#endif 132#endif /* __LINUX_KSM_H */
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 1f65af44c6d2..0b4913a4a344 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -89,6 +89,9 @@ static inline void page_dup_rmap(struct page *page)
89 */ 89 */
90int page_referenced(struct page *, int is_locked, 90int page_referenced(struct page *, int is_locked,
91 struct mem_cgroup *cnt, unsigned long *vm_flags); 91 struct mem_cgroup *cnt, unsigned long *vm_flags);
92int page_referenced_one(struct page *, struct vm_area_struct *,
93 unsigned long address, unsigned int *mapcount, unsigned long *vm_flags);
94
92enum ttu_flags { 95enum ttu_flags {
93 TTU_UNMAP = 0, /* unmap mode */ 96 TTU_UNMAP = 0, /* unmap mode */
94 TTU_MIGRATION = 1, /* migration mode */ 97 TTU_MIGRATION = 1, /* migration mode */
@@ -102,6 +105,8 @@ enum ttu_flags {
102#define TTU_ACTION(x) ((x) & TTU_ACTION_MASK) 105#define TTU_ACTION(x) ((x) & TTU_ACTION_MASK)
103 106
104int try_to_unmap(struct page *, enum ttu_flags flags); 107int try_to_unmap(struct page *, enum ttu_flags flags);
108int try_to_unmap_one(struct page *, struct vm_area_struct *,
109 unsigned long address, enum ttu_flags flags);
105 110
106/* 111/*
107 * Called from mm/filemap_xip.c to unmap empty zero page 112 * Called from mm/filemap_xip.c to unmap empty zero page