aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/task_mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r--fs/proc/task_mmu.c97
1 files changed, 61 insertions, 36 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 107d026f5d6e..fb52b548080d 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -62,7 +62,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
62 total_rss << (PAGE_SHIFT-10), 62 total_rss << (PAGE_SHIFT-10),
63 data << (PAGE_SHIFT-10), 63 data << (PAGE_SHIFT-10),
64 mm->stack_vm << (PAGE_SHIFT-10), text, lib, 64 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
65 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10, 65 (PTRS_PER_PTE * sizeof(pte_t) *
66 atomic_long_read(&mm->nr_ptes)) >> 10,
66 swap << (PAGE_SHIFT-10)); 67 swap << (PAGE_SHIFT-10));
67} 68}
68 69
@@ -83,14 +84,6 @@ unsigned long task_statm(struct mm_struct *mm,
83 return mm->total_vm; 84 return mm->total_vm;
84} 85}
85 86
86static void pad_len_spaces(struct seq_file *m, int len)
87{
88 len = 25 + sizeof(void*) * 6 - len;
89 if (len < 1)
90 len = 1;
91 seq_printf(m, "%*c", len, ' ');
92}
93
94#ifdef CONFIG_NUMA 87#ifdef CONFIG_NUMA
95/* 88/*
96 * These functions are for numa_maps but called in generic **maps seq_file 89 * These functions are for numa_maps but called in generic **maps seq_file
@@ -268,7 +261,6 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
268 unsigned long long pgoff = 0; 261 unsigned long long pgoff = 0;
269 unsigned long start, end; 262 unsigned long start, end;
270 dev_t dev = 0; 263 dev_t dev = 0;
271 int len;
272 const char *name = NULL; 264 const char *name = NULL;
273 265
274 if (file) { 266 if (file) {
@@ -286,7 +278,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
286 if (stack_guard_page_end(vma, end)) 278 if (stack_guard_page_end(vma, end))
287 end -= PAGE_SIZE; 279 end -= PAGE_SIZE;
288 280
289 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", 281 seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
282 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
290 start, 283 start,
291 end, 284 end,
292 flags & VM_READ ? 'r' : '-', 285 flags & VM_READ ? 'r' : '-',
@@ -294,14 +287,14 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
294 flags & VM_EXEC ? 'x' : '-', 287 flags & VM_EXEC ? 'x' : '-',
295 flags & VM_MAYSHARE ? 's' : 'p', 288 flags & VM_MAYSHARE ? 's' : 'p',
296 pgoff, 289 pgoff,
297 MAJOR(dev), MINOR(dev), ino, &len); 290 MAJOR(dev), MINOR(dev), ino);
298 291
299 /* 292 /*
300 * Print the dentry name for named mappings, and a 293 * Print the dentry name for named mappings, and a
301 * special [heap] marker for the heap: 294 * special [heap] marker for the heap:
302 */ 295 */
303 if (file) { 296 if (file) {
304 pad_len_spaces(m, len); 297 seq_pad(m, ' ');
305 seq_path(m, &file->f_path, "\n"); 298 seq_path(m, &file->f_path, "\n");
306 goto done; 299 goto done;
307 } 300 }
@@ -333,7 +326,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
333 name = "[stack]"; 326 name = "[stack]";
334 } else { 327 } else {
335 /* Thread stack in /proc/PID/maps */ 328 /* Thread stack in /proc/PID/maps */
336 pad_len_spaces(m, len); 329 seq_pad(m, ' ');
337 seq_printf(m, "[stack:%d]", tid); 330 seq_printf(m, "[stack:%d]", tid);
338 } 331 }
339 } 332 }
@@ -341,7 +334,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
341 334
342done: 335done:
343 if (name) { 336 if (name) {
344 pad_len_spaces(m, len); 337 seq_pad(m, ' ');
345 seq_puts(m, name); 338 seq_puts(m, name);
346 } 339 }
347 seq_putc(m, '\n'); 340 seq_putc(m, '\n');
@@ -505,9 +498,9 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
505 pte_t *pte; 498 pte_t *pte;
506 spinlock_t *ptl; 499 spinlock_t *ptl;
507 500
508 if (pmd_trans_huge_lock(pmd, vma) == 1) { 501 if (pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
509 smaps_pte_entry(*(pte_t *)pmd, addr, HPAGE_PMD_SIZE, walk); 502 smaps_pte_entry(*(pte_t *)pmd, addr, HPAGE_PMD_SIZE, walk);
510 spin_unlock(&walk->mm->page_table_lock); 503 spin_unlock(ptl);
511 mss->anonymous_thp += HPAGE_PMD_SIZE; 504 mss->anonymous_thp += HPAGE_PMD_SIZE;
512 return 0; 505 return 0;
513 } 506 }
@@ -561,6 +554,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
561 [ilog2(VM_NONLINEAR)] = "nl", 554 [ilog2(VM_NONLINEAR)] = "nl",
562 [ilog2(VM_ARCH_1)] = "ar", 555 [ilog2(VM_ARCH_1)] = "ar",
563 [ilog2(VM_DONTDUMP)] = "dd", 556 [ilog2(VM_DONTDUMP)] = "dd",
557#ifdef CONFIG_MEM_SOFT_DIRTY
558 [ilog2(VM_SOFTDIRTY)] = "sd",
559#endif
564 [ilog2(VM_MIXEDMAP)] = "mm", 560 [ilog2(VM_MIXEDMAP)] = "mm",
565 [ilog2(VM_HUGEPAGE)] = "hg", 561 [ilog2(VM_HUGEPAGE)] = "hg",
566 [ilog2(VM_NOHUGEPAGE)] = "nh", 562 [ilog2(VM_NOHUGEPAGE)] = "nh",
@@ -740,6 +736,9 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma,
740 ptent = pte_file_clear_soft_dirty(ptent); 736 ptent = pte_file_clear_soft_dirty(ptent);
741 } 737 }
742 738
739 if (vma->vm_flags & VM_SOFTDIRTY)
740 vma->vm_flags &= ~VM_SOFTDIRTY;
741
743 set_pte_at(vma->vm_mm, addr, pte, ptent); 742 set_pte_at(vma->vm_mm, addr, pte, ptent);
744#endif 743#endif
745} 744}
@@ -938,6 +937,8 @@ static void pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
938 frame = pte_pfn(pte); 937 frame = pte_pfn(pte);
939 flags = PM_PRESENT; 938 flags = PM_PRESENT;
940 page = vm_normal_page(vma, addr, pte); 939 page = vm_normal_page(vma, addr, pte);
940 if (pte_soft_dirty(pte))
941 flags2 |= __PM_SOFT_DIRTY;
941 } else if (is_swap_pte(pte)) { 942 } else if (is_swap_pte(pte)) {
942 swp_entry_t entry; 943 swp_entry_t entry;
943 if (pte_swp_soft_dirty(pte)) 944 if (pte_swp_soft_dirty(pte))
@@ -949,13 +950,15 @@ static void pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
949 if (is_migration_entry(entry)) 950 if (is_migration_entry(entry))
950 page = migration_entry_to_page(entry); 951 page = migration_entry_to_page(entry);
951 } else { 952 } else {
952 *pme = make_pme(PM_NOT_PRESENT(pm->v2)); 953 if (vma->vm_flags & VM_SOFTDIRTY)
954 flags2 |= __PM_SOFT_DIRTY;
955 *pme = make_pme(PM_NOT_PRESENT(pm->v2) | PM_STATUS2(pm->v2, flags2));
953 return; 956 return;
954 } 957 }
955 958
956 if (page && !PageAnon(page)) 959 if (page && !PageAnon(page))
957 flags |= PM_FILE; 960 flags |= PM_FILE;
958 if (pte_soft_dirty(pte)) 961 if ((vma->vm_flags & VM_SOFTDIRTY))
959 flags2 |= __PM_SOFT_DIRTY; 962 flags2 |= __PM_SOFT_DIRTY;
960 963
961 *pme = make_pme(PM_PFRAME(frame) | PM_STATUS2(pm->v2, flags2) | flags); 964 *pme = make_pme(PM_PFRAME(frame) | PM_STATUS2(pm->v2, flags2) | flags);
@@ -974,7 +977,7 @@ static void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *p
974 *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset) 977 *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset)
975 | PM_STATUS2(pm->v2, pmd_flags2) | PM_PRESENT); 978 | PM_STATUS2(pm->v2, pmd_flags2) | PM_PRESENT);
976 else 979 else
977 *pme = make_pme(PM_NOT_PRESENT(pm->v2)); 980 *pme = make_pme(PM_NOT_PRESENT(pm->v2) | PM_STATUS2(pm->v2, pmd_flags2));
978} 981}
979#else 982#else
980static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm, 983static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
@@ -988,16 +991,21 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
988{ 991{
989 struct vm_area_struct *vma; 992 struct vm_area_struct *vma;
990 struct pagemapread *pm = walk->private; 993 struct pagemapread *pm = walk->private;
994 spinlock_t *ptl;
991 pte_t *pte; 995 pte_t *pte;
992 int err = 0; 996 int err = 0;
993 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2)); 997 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2));
994 998
995 /* find the first VMA at or above 'addr' */ 999 /* find the first VMA at or above 'addr' */
996 vma = find_vma(walk->mm, addr); 1000 vma = find_vma(walk->mm, addr);
997 if (vma && pmd_trans_huge_lock(pmd, vma) == 1) { 1001 if (vma && pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
998 int pmd_flags2; 1002 int pmd_flags2;
999 1003
1000 pmd_flags2 = (pmd_soft_dirty(*pmd) ? __PM_SOFT_DIRTY : 0); 1004 if ((vma->vm_flags & VM_SOFTDIRTY) || pmd_soft_dirty(*pmd))
1005 pmd_flags2 = __PM_SOFT_DIRTY;
1006 else
1007 pmd_flags2 = 0;
1008
1001 for (; addr != end; addr += PAGE_SIZE) { 1009 for (; addr != end; addr += PAGE_SIZE) {
1002 unsigned long offset; 1010 unsigned long offset;
1003 1011
@@ -1008,19 +1016,24 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
1008 if (err) 1016 if (err)
1009 break; 1017 break;
1010 } 1018 }
1011 spin_unlock(&walk->mm->page_table_lock); 1019 spin_unlock(ptl);
1012 return err; 1020 return err;
1013 } 1021 }
1014 1022
1015 if (pmd_trans_unstable(pmd)) 1023 if (pmd_trans_unstable(pmd))
1016 return 0; 1024 return 0;
1017 for (; addr != end; addr += PAGE_SIZE) { 1025 for (; addr != end; addr += PAGE_SIZE) {
1026 int flags2;
1018 1027
1019 /* check to see if we've left 'vma' behind 1028 /* check to see if we've left 'vma' behind
1020 * and need a new, higher one */ 1029 * and need a new, higher one */
1021 if (vma && (addr >= vma->vm_end)) { 1030 if (vma && (addr >= vma->vm_end)) {
1022 vma = find_vma(walk->mm, addr); 1031 vma = find_vma(walk->mm, addr);
1023 pme = make_pme(PM_NOT_PRESENT(pm->v2)); 1032 if (vma && (vma->vm_flags & VM_SOFTDIRTY))
1033 flags2 = __PM_SOFT_DIRTY;
1034 else
1035 flags2 = 0;
1036 pme = make_pme(PM_NOT_PRESENT(pm->v2) | PM_STATUS2(pm->v2, flags2));
1024 } 1037 }
1025 1038
1026 /* check that 'vma' actually covers this address, 1039 /* check that 'vma' actually covers this address,
@@ -1044,13 +1057,15 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
1044 1057
1045#ifdef CONFIG_HUGETLB_PAGE 1058#ifdef CONFIG_HUGETLB_PAGE
1046static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm, 1059static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
1047 pte_t pte, int offset) 1060 pte_t pte, int offset, int flags2)
1048{ 1061{
1049 if (pte_present(pte)) 1062 if (pte_present(pte))
1050 *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset) 1063 *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset) |
1051 | PM_STATUS2(pm->v2, 0) | PM_PRESENT); 1064 PM_STATUS2(pm->v2, flags2) |
1065 PM_PRESENT);
1052 else 1066 else
1053 *pme = make_pme(PM_NOT_PRESENT(pm->v2)); 1067 *pme = make_pme(PM_NOT_PRESENT(pm->v2) |
1068 PM_STATUS2(pm->v2, flags2));
1054} 1069}
1055 1070
1056/* This function walks within one hugetlb entry in the single call */ 1071/* This function walks within one hugetlb entry in the single call */
@@ -1059,12 +1074,22 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
1059 struct mm_walk *walk) 1074 struct mm_walk *walk)
1060{ 1075{
1061 struct pagemapread *pm = walk->private; 1076 struct pagemapread *pm = walk->private;
1077 struct vm_area_struct *vma;
1062 int err = 0; 1078 int err = 0;
1079 int flags2;
1063 pagemap_entry_t pme; 1080 pagemap_entry_t pme;
1064 1081
1082 vma = find_vma(walk->mm, addr);
1083 WARN_ON_ONCE(!vma);
1084
1085 if (vma && (vma->vm_flags & VM_SOFTDIRTY))
1086 flags2 = __PM_SOFT_DIRTY;
1087 else
1088 flags2 = 0;
1089
1065 for (; addr != end; addr += PAGE_SIZE) { 1090 for (; addr != end; addr += PAGE_SIZE) {
1066 int offset = (addr & ~hmask) >> PAGE_SHIFT; 1091 int offset = (addr & ~hmask) >> PAGE_SHIFT;
1067 huge_pte_to_pagemap_entry(&pme, pm, *pte, offset); 1092 huge_pte_to_pagemap_entry(&pme, pm, *pte, offset, flags2);
1068 err = add_to_pagemap(addr, &pme, pm); 1093 err = add_to_pagemap(addr, &pme, pm);
1069 if (err) 1094 if (err)
1070 return err; 1095 return err;
@@ -1293,7 +1318,7 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
1293 1318
1294 md = walk->private; 1319 md = walk->private;
1295 1320
1296 if (pmd_trans_huge_lock(pmd, md->vma) == 1) { 1321 if (pmd_trans_huge_lock(pmd, md->vma, &ptl) == 1) {
1297 pte_t huge_pte = *(pte_t *)pmd; 1322 pte_t huge_pte = *(pte_t *)pmd;
1298 struct page *page; 1323 struct page *page;
1299 1324
@@ -1301,7 +1326,7 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
1301 if (page) 1326 if (page)
1302 gather_stats(page, md, pte_dirty(huge_pte), 1327 gather_stats(page, md, pte_dirty(huge_pte),
1303 HPAGE_PMD_SIZE/PAGE_SIZE); 1328 HPAGE_PMD_SIZE/PAGE_SIZE);
1304 spin_unlock(&walk->mm->page_table_lock); 1329 spin_unlock(ptl);
1305 return 0; 1330 return 0;
1306 } 1331 }
1307 1332
@@ -1359,8 +1384,8 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
1359 struct mm_struct *mm = vma->vm_mm; 1384 struct mm_struct *mm = vma->vm_mm;
1360 struct mm_walk walk = {}; 1385 struct mm_walk walk = {};
1361 struct mempolicy *pol; 1386 struct mempolicy *pol;
1362 int n; 1387 char buffer[64];
1363 char buffer[50]; 1388 int nid;
1364 1389
1365 if (!mm) 1390 if (!mm)
1366 return 0; 1391 return 0;
@@ -1430,9 +1455,9 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
1430 if (md->writeback) 1455 if (md->writeback)
1431 seq_printf(m, " writeback=%lu", md->writeback); 1456 seq_printf(m, " writeback=%lu", md->writeback);
1432 1457
1433 for_each_node_state(n, N_MEMORY) 1458 for_each_node_state(nid, N_MEMORY)
1434 if (md->node[n]) 1459 if (md->node[nid])
1435 seq_printf(m, " N%d=%lu", n, md->node[n]); 1460 seq_printf(m, " N%d=%lu", nid, md->node[nid]);
1436out: 1461out:
1437 seq_putc(m, '\n'); 1462 seq_putc(m, '\n');
1438 1463