diff options
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r-- | fs/proc/task_mmu.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c7ef3e48e35b..d2fa42006d8f 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -14,22 +14,41 @@ | |||
14 | char *task_mem(struct mm_struct *mm, char *buffer) | 14 | char *task_mem(struct mm_struct *mm, char *buffer) |
15 | { | 15 | { |
16 | unsigned long data, text, lib; | 16 | unsigned long data, text, lib; |
17 | unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; | ||
18 | |||
19 | /* | ||
20 | * Note: to minimize their overhead, mm maintains hiwater_vm and | ||
21 | * hiwater_rss only when about to *lower* total_vm or rss. Any | ||
22 | * collector of these hiwater stats must therefore get total_vm | ||
23 | * and rss too, which will usually be the higher. Barriers? not | ||
24 | * worth the effort, such snapshots can always be inconsistent. | ||
25 | */ | ||
26 | hiwater_vm = total_vm = mm->total_vm; | ||
27 | if (hiwater_vm < mm->hiwater_vm) | ||
28 | hiwater_vm = mm->hiwater_vm; | ||
29 | hiwater_rss = total_rss = get_mm_rss(mm); | ||
30 | if (hiwater_rss < mm->hiwater_rss) | ||
31 | hiwater_rss = mm->hiwater_rss; | ||
17 | 32 | ||
18 | data = mm->total_vm - mm->shared_vm - mm->stack_vm; | 33 | data = mm->total_vm - mm->shared_vm - mm->stack_vm; |
19 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; | 34 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; |
20 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; | 35 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; |
21 | buffer += sprintf(buffer, | 36 | buffer += sprintf(buffer, |
37 | "VmPeak:\t%8lu kB\n" | ||
22 | "VmSize:\t%8lu kB\n" | 38 | "VmSize:\t%8lu kB\n" |
23 | "VmLck:\t%8lu kB\n" | 39 | "VmLck:\t%8lu kB\n" |
40 | "VmHWM:\t%8lu kB\n" | ||
24 | "VmRSS:\t%8lu kB\n" | 41 | "VmRSS:\t%8lu kB\n" |
25 | "VmData:\t%8lu kB\n" | 42 | "VmData:\t%8lu kB\n" |
26 | "VmStk:\t%8lu kB\n" | 43 | "VmStk:\t%8lu kB\n" |
27 | "VmExe:\t%8lu kB\n" | 44 | "VmExe:\t%8lu kB\n" |
28 | "VmLib:\t%8lu kB\n" | 45 | "VmLib:\t%8lu kB\n" |
29 | "VmPTE:\t%8lu kB\n", | 46 | "VmPTE:\t%8lu kB\n", |
30 | (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), | 47 | hiwater_vm << (PAGE_SHIFT-10), |
48 | (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), | ||
31 | mm->locked_vm << (PAGE_SHIFT-10), | 49 | mm->locked_vm << (PAGE_SHIFT-10), |
32 | get_mm_counter(mm, rss) << (PAGE_SHIFT-10), | 50 | hiwater_rss << (PAGE_SHIFT-10), |
51 | total_rss << (PAGE_SHIFT-10), | ||
33 | data << (PAGE_SHIFT-10), | 52 | data << (PAGE_SHIFT-10), |
34 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, | 53 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, |
35 | (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); | 54 | (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); |
@@ -44,13 +63,11 @@ unsigned long task_vsize(struct mm_struct *mm) | |||
44 | int task_statm(struct mm_struct *mm, int *shared, int *text, | 63 | int task_statm(struct mm_struct *mm, int *shared, int *text, |
45 | int *data, int *resident) | 64 | int *data, int *resident) |
46 | { | 65 | { |
47 | int rss = get_mm_counter(mm, rss); | 66 | *shared = get_mm_counter(mm, file_rss); |
48 | |||
49 | *shared = rss - get_mm_counter(mm, anon_rss); | ||
50 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) | 67 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) |
51 | >> PAGE_SHIFT; | 68 | >> PAGE_SHIFT; |
52 | *data = mm->total_vm - mm->shared_vm; | 69 | *data = mm->total_vm - mm->shared_vm; |
53 | *resident = rss; | 70 | *resident = *shared + get_mm_counter(mm, anon_rss); |
54 | return mm->total_vm; | 71 | return mm->total_vm; |
55 | } | 72 | } |
56 | 73 | ||
@@ -186,13 +203,14 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
186 | struct mem_size_stats *mss) | 203 | struct mem_size_stats *mss) |
187 | { | 204 | { |
188 | pte_t *pte, ptent; | 205 | pte_t *pte, ptent; |
206 | spinlock_t *ptl; | ||
189 | unsigned long pfn; | 207 | unsigned long pfn; |
190 | struct page *page; | 208 | struct page *page; |
191 | 209 | ||
192 | pte = pte_offset_map(pmd, addr); | 210 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
193 | do { | 211 | do { |
194 | ptent = *pte; | 212 | ptent = *pte; |
195 | if (pte_none(ptent) || !pte_present(ptent)) | 213 | if (!pte_present(ptent)) |
196 | continue; | 214 | continue; |
197 | 215 | ||
198 | mss->resident += PAGE_SIZE; | 216 | mss->resident += PAGE_SIZE; |
@@ -213,8 +231,8 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
213 | mss->private_clean += PAGE_SIZE; | 231 | mss->private_clean += PAGE_SIZE; |
214 | } | 232 | } |
215 | } while (pte++, addr += PAGE_SIZE, addr != end); | 233 | } while (pte++, addr += PAGE_SIZE, addr != end); |
216 | pte_unmap(pte - 1); | 234 | pte_unmap_unlock(pte - 1, ptl); |
217 | cond_resched_lock(&vma->vm_mm->page_table_lock); | 235 | cond_resched(); |
218 | } | 236 | } |
219 | 237 | ||
220 | static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud, | 238 | static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud, |
@@ -268,17 +286,11 @@ static inline void smaps_pgd_range(struct vm_area_struct *vma, | |||
268 | static int show_smap(struct seq_file *m, void *v) | 286 | static int show_smap(struct seq_file *m, void *v) |
269 | { | 287 | { |
270 | struct vm_area_struct *vma = v; | 288 | struct vm_area_struct *vma = v; |
271 | struct mm_struct *mm = vma->vm_mm; | ||
272 | struct mem_size_stats mss; | 289 | struct mem_size_stats mss; |
273 | 290 | ||
274 | memset(&mss, 0, sizeof mss); | 291 | memset(&mss, 0, sizeof mss); |
275 | 292 | if (vma->vm_mm) | |
276 | if (mm) { | ||
277 | spin_lock(&mm->page_table_lock); | ||
278 | smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); | 293 | smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); |
279 | spin_unlock(&mm->page_table_lock); | ||
280 | } | ||
281 | |||
282 | return show_map_internal(m, v, &mss); | 294 | return show_map_internal(m, v, &mss); |
283 | } | 295 | } |
284 | 296 | ||
@@ -407,7 +419,6 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma) | |||
407 | for_each_node(i) | 419 | for_each_node(i) |
408 | md->node[i] =0; | 420 | md->node[i] =0; |
409 | 421 | ||
410 | spin_lock(&mm->page_table_lock); | ||
411 | for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) { | 422 | for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) { |
412 | page = follow_page(mm, vaddr, 0); | 423 | page = follow_page(mm, vaddr, 0); |
413 | if (page) { | 424 | if (page) { |
@@ -422,8 +433,8 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma) | |||
422 | md->anon++; | 433 | md->anon++; |
423 | md->node[page_to_nid(page)]++; | 434 | md->node[page_to_nid(page)]++; |
424 | } | 435 | } |
436 | cond_resched(); | ||
425 | } | 437 | } |
426 | spin_unlock(&mm->page_table_lock); | ||
427 | return md; | 438 | return md; |
428 | } | 439 | } |
429 | 440 | ||
@@ -469,7 +480,7 @@ static int show_numa_map(struct seq_file *m, void *v) | |||
469 | seq_printf(m, " interleave={"); | 480 | seq_printf(m, " interleave={"); |
470 | first = 1; | 481 | first = 1; |
471 | for_each_node(n) { | 482 | for_each_node(n) { |
472 | if (test_bit(n, pol->v.nodes)) { | 483 | if (node_isset(n, pol->v.nodes)) { |
473 | if (!first) | 484 | if (!first) |
474 | seq_putc(m,','); | 485 | seq_putc(m,','); |
475 | else | 486 | else |