Commit ad820c5dd47dff9397ef1e94388bc6577983f68b
Committed by
Linus Torvalds
1 parent
5ddfae16bd
Exists in
master
and in
7 other branches
[PATCH] smaps: shared fix
The point of the smaps "shared" is to count the number of pages that are mapped by more than one process, according to Mauricio Lin. However, smaps uses page_count for this, so it will return a false positive for every page that is mapped by just that one process, which is also in pagecache or swapcache. There are false positive situations for anonymous pages not in swapcache as well: - page reclaim, migration - get_user_pages (eg. direct-io, ptrace) Use page_mapcount instead, to count the number of mappings to the page. Use vm_normal_page so that weird things like /dev/mem aren't counted either. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 1 changed file with 4 additions and 5 deletions Side-by-side Diff
fs/proc/task_mmu.c
... | ... | @@ -204,7 +204,6 @@ |
204 | 204 | { |
205 | 205 | pte_t *pte, ptent; |
206 | 206 | spinlock_t *ptl; |
207 | - unsigned long pfn; | |
208 | 207 | struct page *page; |
209 | 208 | |
210 | 209 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
211 | 210 | |
... | ... | @@ -214,12 +213,12 @@ |
214 | 213 | continue; |
215 | 214 | |
216 | 215 | mss->resident += PAGE_SIZE; |
217 | - pfn = pte_pfn(ptent); | |
218 | - if (!pfn_valid(pfn)) | |
216 | + | |
217 | + page = vm_normal_page(vma, addr, ptent); | |
218 | + if (!page) | |
219 | 219 | continue; |
220 | 220 | |
221 | - page = pfn_to_page(pfn); | |
222 | - if (page_count(page) >= 2) { | |
221 | + if (page_mapcount(page) >= 2) { | |
223 | 222 | if (pte_dirty(ptent)) |
224 | 223 | mss->shared_dirty += PAGE_SIZE; |
225 | 224 | else |