diff options
author | Hugh Dickins <hugh.dickins@tiscali.co.uk> | 2009-09-21 20:02:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-22 10:17:31 -0400 |
commit | 9a840895147b12de5cdd633c600b38686840ee53 (patch) | |
tree | a266a69a39decb4ec0364ac331f0ab19b6f09f06 /include | |
parent | 21333b2b66b805a360641568588e5a0bb06d9d1f (diff) |
ksm: identify PageKsm pages
KSM will need to identify its kernel merged pages unambiguously, and
/proc/kpageflags will probably like to do so too.
Since KSM will only be substituting anonymous pages, statistics are best
preserved by making a PageKsm page a special PageAnon page: one with no
anon_vma.
But KSM then needs its own page_add_ksm_rmap() - keep it in ksm.h near
PageKsm; and do_wp_page() must COW them, unlike singly mapped PageAnons.
Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk>
Signed-off-by: Chris Wright <chrisw@redhat.com>
Signed-off-by: Izik Eidus <ieidus@redhat.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Hugh Dickins <hugh.dickins@tiscali.co.uk>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/ksm.h | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/include/linux/ksm.h b/include/linux/ksm.h index eb2a448981ee..a485c14ecd5d 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/vmstat.h> | ||
13 | 14 | ||
14 | #ifdef CONFIG_KSM | 15 | #ifdef CONFIG_KSM |
15 | int ksm_madvise(struct vm_area_struct *vma, unsigned long start, | 16 | int ksm_madvise(struct vm_area_struct *vma, unsigned long start, |
@@ -29,6 +30,27 @@ static inline void ksm_exit(struct mm_struct *mm) | |||
29 | if (test_bit(MMF_VM_MERGEABLE, &mm->flags)) | 30 | if (test_bit(MMF_VM_MERGEABLE, &mm->flags)) |
30 | __ksm_exit(mm); | 31 | __ksm_exit(mm); |
31 | } | 32 | } |
33 | |||
34 | /* | ||
35 | * A KSM page is one of those write-protected "shared pages" or "merged pages" | ||
36 | * which KSM maps into multiple mms, wherever identical anonymous page content | ||
37 | * is found in VM_MERGEABLE vmas. It's a PageAnon page, with NULL anon_vma. | ||
38 | */ | ||
39 | static inline int PageKsm(struct page *page) | ||
40 | { | ||
41 | return ((unsigned long)page->mapping == PAGE_MAPPING_ANON); | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * But we have to avoid the checking which page_add_anon_rmap() performs. | ||
46 | */ | ||
47 | static inline void page_add_ksm_rmap(struct page *page) | ||
48 | { | ||
49 | if (atomic_inc_and_test(&page->_mapcount)) { | ||
50 | page->mapping = (void *) PAGE_MAPPING_ANON; | ||
51 | __inc_zone_page_state(page, NR_ANON_PAGES); | ||
52 | } | ||
53 | } | ||
32 | #else /* !CONFIG_KSM */ | 54 | #else /* !CONFIG_KSM */ |
33 | 55 | ||
34 | static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start, | 56 | static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start, |
@@ -45,6 +67,13 @@ static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) | |||
45 | static inline void ksm_exit(struct mm_struct *mm) | 67 | static inline void ksm_exit(struct mm_struct *mm) |
46 | { | 68 | { |
47 | } | 69 | } |
70 | |||
71 | static inline int PageKsm(struct page *page) | ||
72 | { | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | /* No stub required for page_add_ksm_rmap(page) */ | ||
48 | #endif /* !CONFIG_KSM */ | 77 | #endif /* !CONFIG_KSM */ |
49 | 78 | ||
50 | #endif | 79 | #endif |