aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <khlebnikov@yandex-team.ru>2015-09-08 18:00:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-08 18:35:28 -0400
commit77bb499bb60f4b79cca7d139c8041662860fcf87 (patch)
tree6a1565ab551fcf8c04b4f38c37b085bbf0829da5 /fs/proc
parent1c90308e7a77af6742a97d1021cca923b23b7f0d (diff)
pagemap: add mmap-exclusive bit for marking pages mapped only here
This patch sets bit 56 in pagemap if this page is mapped only once. It allows to detect exclusively used pages without exposing PFN: present file exclusive state 0 0 0 non-present 1 1 0 file page mapped somewhere else 1 1 1 file page mapped only here 1 0 0 anon non-CoWed page (shared with parent/child) 1 0 1 anon CoWed page (or never forked) CoWed pages in (MAP_FILE | MAP_PRIVATE) areas are anon in this context. MMap-exclusive bit doesn't reflect potential page-sharing via swapcache: page could be mapped once but has several swap-ptes which point to it. Application could detect that by swap bit in pagemap entry and touch that pte via /proc/pid/mem to get real information. See http://lkml.kernel.org/r/CAEVpBa+_RyACkhODZrRvQLs80iy0sqpdrd0AaP_-tgnX3Y9yNQ@mail.gmail.com Requested by Mark Williamson. [akpm@linux-foundation.org: fix spello] Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Reviewed-by: Mark Williamson <mwilliamson@undo-software.com> Tested-by: Mark Williamson <mwilliamson@undo-software.com> Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/task_mmu.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index bc651644b1b2..67c76468a7be 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -949,6 +949,7 @@ struct pagemapread {
949#define PM_PFRAME_BITS 55 949#define PM_PFRAME_BITS 55
950#define PM_PFRAME_MASK GENMASK_ULL(PM_PFRAME_BITS - 1, 0) 950#define PM_PFRAME_MASK GENMASK_ULL(PM_PFRAME_BITS - 1, 0)
951#define PM_SOFT_DIRTY BIT_ULL(55) 951#define PM_SOFT_DIRTY BIT_ULL(55)
952#define PM_MMAP_EXCLUSIVE BIT_ULL(56)
952#define PM_FILE BIT_ULL(61) 953#define PM_FILE BIT_ULL(61)
953#define PM_SWAP BIT_ULL(62) 954#define PM_SWAP BIT_ULL(62)
954#define PM_PRESENT BIT_ULL(63) 955#define PM_PRESENT BIT_ULL(63)
@@ -1036,6 +1037,8 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
1036 1037
1037 if (page && !PageAnon(page)) 1038 if (page && !PageAnon(page))
1038 flags |= PM_FILE; 1039 flags |= PM_FILE;
1040 if (page && page_mapcount(page) == 1)
1041 flags |= PM_MMAP_EXCLUSIVE;
1039 if (vma->vm_flags & VM_SOFTDIRTY) 1042 if (vma->vm_flags & VM_SOFTDIRTY)
1040 flags |= PM_SOFT_DIRTY; 1043 flags |= PM_SOFT_DIRTY;
1041 1044
@@ -1066,6 +1069,11 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
1066 * This if-check is just to prepare for future implementation. 1069 * This if-check is just to prepare for future implementation.
1067 */ 1070 */
1068 if (pmd_present(pmd)) { 1071 if (pmd_present(pmd)) {
1072 struct page *page = pmd_page(pmd);
1073
1074 if (page_mapcount(page) == 1)
1075 flags |= PM_MMAP_EXCLUSIVE;
1076
1069 flags |= PM_PRESENT; 1077 flags |= PM_PRESENT;
1070 if (pm->show_pfn) 1078 if (pm->show_pfn)
1071 frame = pmd_pfn(pmd) + 1079 frame = pmd_pfn(pmd) +
@@ -1131,6 +1139,9 @@ static int pagemap_hugetlb_range(pte_t *ptep, unsigned long hmask,
1131 if (!PageAnon(page)) 1139 if (!PageAnon(page))
1132 flags |= PM_FILE; 1140 flags |= PM_FILE;
1133 1141
1142 if (page_mapcount(page) == 1)
1143 flags |= PM_MMAP_EXCLUSIVE;
1144
1134 flags |= PM_PRESENT; 1145 flags |= PM_PRESENT;
1135 if (pm->show_pfn) 1146 if (pm->show_pfn)
1136 frame = pte_pfn(pte) + 1147 frame = pte_pfn(pte) +
@@ -1163,7 +1174,8 @@ static int pagemap_hugetlb_range(pte_t *ptep, unsigned long hmask,
1163 * Bits 0-4 swap type if swapped 1174 * Bits 0-4 swap type if swapped
1164 * Bits 5-54 swap offset if swapped 1175 * Bits 5-54 swap offset if swapped
1165 * Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt) 1176 * Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
1166 * Bits 56-60 zero 1177 * Bit 56 page exclusively mapped
1178 * Bits 57-60 zero
1167 * Bit 61 page is file-page or shared-anon 1179 * Bit 61 page is file-page or shared-anon
1168 * Bit 62 page swapped 1180 * Bit 62 page swapped
1169 * Bit 63 page present 1181 * Bit 63 page present