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.c370
1 files changed, 269 insertions, 101 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7dcd2a25049..1030a716d15 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -209,16 +209,20 @@ static int do_maps_open(struct inode *inode, struct file *file,
209 return ret; 209 return ret;
210} 210}
211 211
212static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) 212static void
213show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
213{ 214{
214 struct mm_struct *mm = vma->vm_mm; 215 struct mm_struct *mm = vma->vm_mm;
215 struct file *file = vma->vm_file; 216 struct file *file = vma->vm_file;
217 struct proc_maps_private *priv = m->private;
218 struct task_struct *task = priv->task;
216 vm_flags_t flags = vma->vm_flags; 219 vm_flags_t flags = vma->vm_flags;
217 unsigned long ino = 0; 220 unsigned long ino = 0;
218 unsigned long long pgoff = 0; 221 unsigned long long pgoff = 0;
219 unsigned long start, end; 222 unsigned long start, end;
220 dev_t dev = 0; 223 dev_t dev = 0;
221 int len; 224 int len;
225 const char *name = NULL;
222 226
223 if (file) { 227 if (file) {
224 struct inode *inode = vma->vm_file->f_path.dentry->d_inode; 228 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
@@ -252,36 +256,57 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
252 if (file) { 256 if (file) {
253 pad_len_spaces(m, len); 257 pad_len_spaces(m, len);
254 seq_path(m, &file->f_path, "\n"); 258 seq_path(m, &file->f_path, "\n");
255 } else { 259 goto done;
256 const char *name = arch_vma_name(vma); 260 }
257 if (!name) { 261
258 if (mm) { 262 name = arch_vma_name(vma);
259 if (vma->vm_start <= mm->brk && 263 if (!name) {
260 vma->vm_end >= mm->start_brk) { 264 pid_t tid;
261 name = "[heap]"; 265
262 } else if (vma->vm_start <= mm->start_stack && 266 if (!mm) {
263 vma->vm_end >= mm->start_stack) { 267 name = "[vdso]";
264 name = "[stack]"; 268 goto done;
265 } 269 }
270
271 if (vma->vm_start <= mm->brk &&
272 vma->vm_end >= mm->start_brk) {
273 name = "[heap]";
274 goto done;
275 }
276
277 tid = vm_is_stack(task, vma, is_pid);
278
279 if (tid != 0) {
280 /*
281 * Thread stack in /proc/PID/task/TID/maps or
282 * the main process stack.
283 */
284 if (!is_pid || (vma->vm_start <= mm->start_stack &&
285 vma->vm_end >= mm->start_stack)) {
286 name = "[stack]";
266 } else { 287 } else {
267 name = "[vdso]"; 288 /* Thread stack in /proc/PID/maps */
289 pad_len_spaces(m, len);
290 seq_printf(m, "[stack:%d]", tid);
268 } 291 }
269 } 292 }
270 if (name) { 293 }
271 pad_len_spaces(m, len); 294
272 seq_puts(m, name); 295done:
273 } 296 if (name) {
297 pad_len_spaces(m, len);
298 seq_puts(m, name);
274 } 299 }
275 seq_putc(m, '\n'); 300 seq_putc(m, '\n');
276} 301}
277 302
278static int show_map(struct seq_file *m, void *v) 303static int show_map(struct seq_file *m, void *v, int is_pid)
279{ 304{
280 struct vm_area_struct *vma = v; 305 struct vm_area_struct *vma = v;
281 struct proc_maps_private *priv = m->private; 306 struct proc_maps_private *priv = m->private;
282 struct task_struct *task = priv->task; 307 struct task_struct *task = priv->task;
283 308
284 show_map_vma(m, vma); 309 show_map_vma(m, vma, is_pid);
285 310
286 if (m->count < m->size) /* vma is copied successfully */ 311 if (m->count < m->size) /* vma is copied successfully */
287 m->version = (vma != get_gate_vma(task->mm)) 312 m->version = (vma != get_gate_vma(task->mm))
@@ -289,20 +314,49 @@ static int show_map(struct seq_file *m, void *v)
289 return 0; 314 return 0;
290} 315}
291 316
317static int show_pid_map(struct seq_file *m, void *v)
318{
319 return show_map(m, v, 1);
320}
321
322static int show_tid_map(struct seq_file *m, void *v)
323{
324 return show_map(m, v, 0);
325}
326
292static const struct seq_operations proc_pid_maps_op = { 327static const struct seq_operations proc_pid_maps_op = {
293 .start = m_start, 328 .start = m_start,
294 .next = m_next, 329 .next = m_next,
295 .stop = m_stop, 330 .stop = m_stop,
296 .show = show_map 331 .show = show_pid_map
297}; 332};
298 333
299static int maps_open(struct inode *inode, struct file *file) 334static const struct seq_operations proc_tid_maps_op = {
335 .start = m_start,
336 .next = m_next,
337 .stop = m_stop,
338 .show = show_tid_map
339};
340
341static int pid_maps_open(struct inode *inode, struct file *file)
300{ 342{
301 return do_maps_open(inode, file, &proc_pid_maps_op); 343 return do_maps_open(inode, file, &proc_pid_maps_op);
302} 344}
303 345
304const struct file_operations proc_maps_operations = { 346static int tid_maps_open(struct inode *inode, struct file *file)
305 .open = maps_open, 347{
348 return do_maps_open(inode, file, &proc_tid_maps_op);
349}
350
351const struct file_operations proc_pid_maps_operations = {
352 .open = pid_maps_open,
353 .read = seq_read,
354 .llseek = seq_lseek,
355 .release = seq_release_private,
356};
357
358const struct file_operations proc_tid_maps_operations = {
359 .open = tid_maps_open,
306 .read = seq_read, 360 .read = seq_read,
307 .llseek = seq_lseek, 361 .llseek = seq_lseek,
308 .release = seq_release_private, 362 .release = seq_release_private,
@@ -394,21 +448,15 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
394 pte_t *pte; 448 pte_t *pte;
395 spinlock_t *ptl; 449 spinlock_t *ptl;
396 450
397 spin_lock(&walk->mm->page_table_lock); 451 if (pmd_trans_huge_lock(pmd, vma) == 1) {
398 if (pmd_trans_huge(*pmd)) { 452 smaps_pte_entry(*(pte_t *)pmd, addr, HPAGE_PMD_SIZE, walk);
399 if (pmd_trans_splitting(*pmd)) {
400 spin_unlock(&walk->mm->page_table_lock);
401 wait_split_huge_page(vma->anon_vma, pmd);
402 } else {
403 smaps_pte_entry(*(pte_t *)pmd, addr,
404 HPAGE_PMD_SIZE, walk);
405 spin_unlock(&walk->mm->page_table_lock);
406 mss->anonymous_thp += HPAGE_PMD_SIZE;
407 return 0;
408 }
409 } else {
410 spin_unlock(&walk->mm->page_table_lock); 453 spin_unlock(&walk->mm->page_table_lock);
454 mss->anonymous_thp += HPAGE_PMD_SIZE;
455 return 0;
411 } 456 }
457
458 if (pmd_trans_unstable(pmd))
459 return 0;
412 /* 460 /*
413 * The mmap_sem held all the way back in m_start() is what 461 * The mmap_sem held all the way back in m_start() is what
414 * keeps khugepaged out of here and from collapsing things 462 * keeps khugepaged out of here and from collapsing things
@@ -422,7 +470,7 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
422 return 0; 470 return 0;
423} 471}
424 472
425static int show_smap(struct seq_file *m, void *v) 473static int show_smap(struct seq_file *m, void *v, int is_pid)
426{ 474{
427 struct proc_maps_private *priv = m->private; 475 struct proc_maps_private *priv = m->private;
428 struct task_struct *task = priv->task; 476 struct task_struct *task = priv->task;
@@ -440,7 +488,7 @@ static int show_smap(struct seq_file *m, void *v)
440 if (vma->vm_mm && !is_vm_hugetlb_page(vma)) 488 if (vma->vm_mm && !is_vm_hugetlb_page(vma))
441 walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk); 489 walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
442 490
443 show_map_vma(m, vma); 491 show_map_vma(m, vma, is_pid);
444 492
445 seq_printf(m, 493 seq_printf(m,
446 "Size: %8lu kB\n" 494 "Size: %8lu kB\n"
@@ -479,20 +527,49 @@ static int show_smap(struct seq_file *m, void *v)
479 return 0; 527 return 0;
480} 528}
481 529
530static int show_pid_smap(struct seq_file *m, void *v)
531{
532 return show_smap(m, v, 1);
533}
534
535static int show_tid_smap(struct seq_file *m, void *v)
536{
537 return show_smap(m, v, 0);
538}
539
482static const struct seq_operations proc_pid_smaps_op = { 540static const struct seq_operations proc_pid_smaps_op = {
483 .start = m_start, 541 .start = m_start,
484 .next = m_next, 542 .next = m_next,
485 .stop = m_stop, 543 .stop = m_stop,
486 .show = show_smap 544 .show = show_pid_smap
545};
546
547static const struct seq_operations proc_tid_smaps_op = {
548 .start = m_start,
549 .next = m_next,
550 .stop = m_stop,
551 .show = show_tid_smap
487}; 552};
488 553
489static int smaps_open(struct inode *inode, struct file *file) 554static int pid_smaps_open(struct inode *inode, struct file *file)
490{ 555{
491 return do_maps_open(inode, file, &proc_pid_smaps_op); 556 return do_maps_open(inode, file, &proc_pid_smaps_op);
492} 557}
493 558
494const struct file_operations proc_smaps_operations = { 559static int tid_smaps_open(struct inode *inode, struct file *file)
495 .open = smaps_open, 560{
561 return do_maps_open(inode, file, &proc_tid_smaps_op);
562}
563
564const struct file_operations proc_pid_smaps_operations = {
565 .open = pid_smaps_open,
566 .read = seq_read,
567 .llseek = seq_lseek,
568 .release = seq_release_private,
569};
570
571const struct file_operations proc_tid_smaps_operations = {
572 .open = tid_smaps_open,
496 .read = seq_read, 573 .read = seq_read,
497 .llseek = seq_lseek, 574 .llseek = seq_lseek,
498 .release = seq_release_private, 575 .release = seq_release_private,
@@ -507,6 +584,8 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
507 struct page *page; 584 struct page *page;
508 585
509 split_huge_page_pmd(walk->mm, pmd); 586 split_huge_page_pmd(walk->mm, pmd);
587 if (pmd_trans_unstable(pmd))
588 return 0;
510 589
511 pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); 590 pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
512 for (; addr != end; pte++, addr += PAGE_SIZE) { 591 for (; addr != end; pte++, addr += PAGE_SIZE) {
@@ -518,9 +597,6 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
518 if (!page) 597 if (!page)
519 continue; 598 continue;
520 599
521 if (PageReserved(page))
522 continue;
523
524 /* Clear accessed and referenced bits. */ 600 /* Clear accessed and referenced bits. */
525 ptep_test_and_clear_young(vma, addr, pte); 601 ptep_test_and_clear_young(vma, addr, pte);
526 ClearPageReferenced(page); 602 ClearPageReferenced(page);
@@ -598,11 +674,18 @@ const struct file_operations proc_clear_refs_operations = {
598 .llseek = noop_llseek, 674 .llseek = noop_llseek,
599}; 675};
600 676
677typedef struct {
678 u64 pme;
679} pagemap_entry_t;
680
601struct pagemapread { 681struct pagemapread {
602 int pos, len; 682 int pos, len;
603 u64 *buffer; 683 pagemap_entry_t *buffer;
604}; 684};
605 685
686#define PAGEMAP_WALK_SIZE (PMD_SIZE)
687#define PAGEMAP_WALK_MASK (PMD_MASK)
688
606#define PM_ENTRY_BYTES sizeof(u64) 689#define PM_ENTRY_BYTES sizeof(u64)
607#define PM_STATUS_BITS 3 690#define PM_STATUS_BITS 3
608#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS) 691#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS)
@@ -620,10 +703,15 @@ struct pagemapread {
620#define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT) 703#define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT)
621#define PM_END_OF_BUFFER 1 704#define PM_END_OF_BUFFER 1
622 705
623static int add_to_pagemap(unsigned long addr, u64 pfn, 706static inline pagemap_entry_t make_pme(u64 val)
707{
708 return (pagemap_entry_t) { .pme = val };
709}
710
711static int add_to_pagemap(unsigned long addr, pagemap_entry_t *pme,
624 struct pagemapread *pm) 712 struct pagemapread *pm)
625{ 713{
626 pm->buffer[pm->pos++] = pfn; 714 pm->buffer[pm->pos++] = *pme;
627 if (pm->pos >= pm->len) 715 if (pm->pos >= pm->len)
628 return PM_END_OF_BUFFER; 716 return PM_END_OF_BUFFER;
629 return 0; 717 return 0;
@@ -635,8 +723,10 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
635 struct pagemapread *pm = walk->private; 723 struct pagemapread *pm = walk->private;
636 unsigned long addr; 724 unsigned long addr;
637 int err = 0; 725 int err = 0;
726 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT);
727
638 for (addr = start; addr < end; addr += PAGE_SIZE) { 728 for (addr = start; addr < end; addr += PAGE_SIZE) {
639 err = add_to_pagemap(addr, PM_NOT_PRESENT, pm); 729 err = add_to_pagemap(addr, &pme, pm);
640 if (err) 730 if (err)
641 break; 731 break;
642 } 732 }
@@ -649,18 +739,40 @@ static u64 swap_pte_to_pagemap_entry(pte_t pte)
649 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); 739 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
650} 740}
651 741
652static u64 pte_to_pagemap_entry(pte_t pte) 742static void pte_to_pagemap_entry(pagemap_entry_t *pme, pte_t pte)
653{ 743{
654 u64 pme = 0;
655 if (is_swap_pte(pte)) 744 if (is_swap_pte(pte))
656 pme = PM_PFRAME(swap_pte_to_pagemap_entry(pte)) 745 *pme = make_pme(PM_PFRAME(swap_pte_to_pagemap_entry(pte))
657 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; 746 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP);
658 else if (pte_present(pte)) 747 else if (pte_present(pte))
659 pme = PM_PFRAME(pte_pfn(pte)) 748 *pme = make_pme(PM_PFRAME(pte_pfn(pte))
660 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; 749 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
661 return pme; 750 else
751 *pme = make_pme(PM_NOT_PRESENT);
662} 752}
663 753
754#ifdef CONFIG_TRANSPARENT_HUGEPAGE
755static void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme,
756 pmd_t pmd, int offset)
757{
758 /*
759 * Currently pmd for thp is always present because thp can not be
760 * swapped-out, migrated, or HWPOISONed (split in such cases instead.)
761 * This if-check is just to prepare for future implementation.
762 */
763 if (pmd_present(pmd))
764 *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset)
765 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
766 else
767 *pme = make_pme(PM_NOT_PRESENT);
768}
769#else
770static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme,
771 pmd_t pmd, int offset)
772{
773}
774#endif
775
664static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 776static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
665 struct mm_walk *walk) 777 struct mm_walk *walk)
666{ 778{
@@ -668,29 +780,46 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
668 struct pagemapread *pm = walk->private; 780 struct pagemapread *pm = walk->private;
669 pte_t *pte; 781 pte_t *pte;
670 int err = 0; 782 int err = 0;
671 783 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT);
672 split_huge_page_pmd(walk->mm, pmd);
673 784
674 /* find the first VMA at or above 'addr' */ 785 /* find the first VMA at or above 'addr' */
675 vma = find_vma(walk->mm, addr); 786 vma = find_vma(walk->mm, addr);
787 if (pmd_trans_huge_lock(pmd, vma) == 1) {
788 for (; addr != end; addr += PAGE_SIZE) {
789 unsigned long offset;
790
791 offset = (addr & ~PAGEMAP_WALK_MASK) >>
792 PAGE_SHIFT;
793 thp_pmd_to_pagemap_entry(&pme, *pmd, offset);
794 err = add_to_pagemap(addr, &pme, pm);
795 if (err)
796 break;
797 }
798 spin_unlock(&walk->mm->page_table_lock);
799 return err;
800 }
801
802 if (pmd_trans_unstable(pmd))
803 return 0;
676 for (; addr != end; addr += PAGE_SIZE) { 804 for (; addr != end; addr += PAGE_SIZE) {
677 u64 pfn = PM_NOT_PRESENT;
678 805
679 /* check to see if we've left 'vma' behind 806 /* check to see if we've left 'vma' behind
680 * and need a new, higher one */ 807 * and need a new, higher one */
681 if (vma && (addr >= vma->vm_end)) 808 if (vma && (addr >= vma->vm_end)) {
682 vma = find_vma(walk->mm, addr); 809 vma = find_vma(walk->mm, addr);
810 pme = make_pme(PM_NOT_PRESENT);
811 }
683 812
684 /* check that 'vma' actually covers this address, 813 /* check that 'vma' actually covers this address,
685 * and that it isn't a huge page vma */ 814 * and that it isn't a huge page vma */
686 if (vma && (vma->vm_start <= addr) && 815 if (vma && (vma->vm_start <= addr) &&
687 !is_vm_hugetlb_page(vma)) { 816 !is_vm_hugetlb_page(vma)) {
688 pte = pte_offset_map(pmd, addr); 817 pte = pte_offset_map(pmd, addr);
689 pfn = pte_to_pagemap_entry(*pte); 818 pte_to_pagemap_entry(&pme, *pte);
690 /* unmap before userspace copy */ 819 /* unmap before userspace copy */
691 pte_unmap(pte); 820 pte_unmap(pte);
692 } 821 }
693 err = add_to_pagemap(addr, pfn, pm); 822 err = add_to_pagemap(addr, &pme, pm);
694 if (err) 823 if (err)
695 return err; 824 return err;
696 } 825 }
@@ -701,13 +830,14 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
701} 830}
702 831
703#ifdef CONFIG_HUGETLB_PAGE 832#ifdef CONFIG_HUGETLB_PAGE
704static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset) 833static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme,
834 pte_t pte, int offset)
705{ 835{
706 u64 pme = 0;
707 if (pte_present(pte)) 836 if (pte_present(pte))
708 pme = PM_PFRAME(pte_pfn(pte) + offset) 837 *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset)
709 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; 838 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
710 return pme; 839 else
840 *pme = make_pme(PM_NOT_PRESENT);
711} 841}
712 842
713/* This function walks within one hugetlb entry in the single call */ 843/* This function walks within one hugetlb entry in the single call */
@@ -717,12 +847,12 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
717{ 847{
718 struct pagemapread *pm = walk->private; 848 struct pagemapread *pm = walk->private;
719 int err = 0; 849 int err = 0;
720 u64 pfn; 850 pagemap_entry_t pme;
721 851
722 for (; addr != end; addr += PAGE_SIZE) { 852 for (; addr != end; addr += PAGE_SIZE) {
723 int offset = (addr & ~hmask) >> PAGE_SHIFT; 853 int offset = (addr & ~hmask) >> PAGE_SHIFT;
724 pfn = huge_pte_to_pagemap_entry(*pte, offset); 854 huge_pte_to_pagemap_entry(&pme, *pte, offset);
725 err = add_to_pagemap(addr, pfn, pm); 855 err = add_to_pagemap(addr, &pme, pm);
726 if (err) 856 if (err)
727 return err; 857 return err;
728 } 858 }
@@ -757,8 +887,6 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
757 * determine which areas of memory are actually mapped and llseek to 887 * determine which areas of memory are actually mapped and llseek to
758 * skip over unmapped regions. 888 * skip over unmapped regions.
759 */ 889 */
760#define PAGEMAP_WALK_SIZE (PMD_SIZE)
761#define PAGEMAP_WALK_MASK (PMD_MASK)
762static ssize_t pagemap_read(struct file *file, char __user *buf, 890static ssize_t pagemap_read(struct file *file, char __user *buf,
763 size_t count, loff_t *ppos) 891 size_t count, loff_t *ppos)
764{ 892{
@@ -941,26 +1069,21 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
941 pte_t *pte; 1069 pte_t *pte;
942 1070
943 md = walk->private; 1071 md = walk->private;
944 spin_lock(&walk->mm->page_table_lock); 1072
945 if (pmd_trans_huge(*pmd)) { 1073 if (pmd_trans_huge_lock(pmd, md->vma) == 1) {
946 if (pmd_trans_splitting(*pmd)) { 1074 pte_t huge_pte = *(pte_t *)pmd;
947 spin_unlock(&walk->mm->page_table_lock); 1075 struct page *page;
948 wait_split_huge_page(md->vma->anon_vma, pmd); 1076
949 } else { 1077 page = can_gather_numa_stats(huge_pte, md->vma, addr);
950 pte_t huge_pte = *(pte_t *)pmd; 1078 if (page)
951 struct page *page; 1079 gather_stats(page, md, pte_dirty(huge_pte),
952 1080 HPAGE_PMD_SIZE/PAGE_SIZE);
953 page = can_gather_numa_stats(huge_pte, md->vma, addr);
954 if (page)
955 gather_stats(page, md, pte_dirty(huge_pte),
956 HPAGE_PMD_SIZE/PAGE_SIZE);
957 spin_unlock(&walk->mm->page_table_lock);
958 return 0;
959 }
960 } else {
961 spin_unlock(&walk->mm->page_table_lock); 1081 spin_unlock(&walk->mm->page_table_lock);
1082 return 0;
962 } 1083 }
963 1084
1085 if (pmd_trans_unstable(pmd))
1086 return 0;
964 orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); 1087 orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
965 do { 1088 do {
966 struct page *page = can_gather_numa_stats(*pte, md->vma, addr); 1089 struct page *page = can_gather_numa_stats(*pte, md->vma, addr);
@@ -1002,7 +1125,7 @@ static int gather_hugetbl_stats(pte_t *pte, unsigned long hmask,
1002/* 1125/*
1003 * Display pages allocated per node and memory policy via /proc. 1126 * Display pages allocated per node and memory policy via /proc.
1004 */ 1127 */
1005static int show_numa_map(struct seq_file *m, void *v) 1128static int show_numa_map(struct seq_file *m, void *v, int is_pid)
1006{ 1129{
1007 struct numa_maps_private *numa_priv = m->private; 1130 struct numa_maps_private *numa_priv = m->private;
1008 struct proc_maps_private *proc_priv = &numa_priv->proc_maps; 1131 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
@@ -1039,9 +1162,19 @@ static int show_numa_map(struct seq_file *m, void *v)
1039 seq_path(m, &file->f_path, "\n\t= "); 1162 seq_path(m, &file->f_path, "\n\t= ");
1040 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { 1163 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
1041 seq_printf(m, " heap"); 1164 seq_printf(m, " heap");
1042 } else if (vma->vm_start <= mm->start_stack && 1165 } else {
1043 vma->vm_end >= mm->start_stack) { 1166 pid_t tid = vm_is_stack(proc_priv->task, vma, is_pid);
1044 seq_printf(m, " stack"); 1167 if (tid != 0) {
1168 /*
1169 * Thread stack in /proc/PID/task/TID/maps or
1170 * the main process stack.
1171 */
1172 if (!is_pid || (vma->vm_start <= mm->start_stack &&
1173 vma->vm_end >= mm->start_stack))
1174 seq_printf(m, " stack");
1175 else
1176 seq_printf(m, " stack:%d", tid);
1177 }
1045 } 1178 }
1046 1179
1047 if (is_vm_hugetlb_page(vma)) 1180 if (is_vm_hugetlb_page(vma))
@@ -1084,21 +1217,39 @@ out:
1084 return 0; 1217 return 0;
1085} 1218}
1086 1219
1220static int show_pid_numa_map(struct seq_file *m, void *v)
1221{
1222 return show_numa_map(m, v, 1);
1223}
1224
1225static int show_tid_numa_map(struct seq_file *m, void *v)
1226{
1227 return show_numa_map(m, v, 0);
1228}
1229
1087static const struct seq_operations proc_pid_numa_maps_op = { 1230static const struct seq_operations proc_pid_numa_maps_op = {
1088 .start = m_start, 1231 .start = m_start,
1089 .next = m_next, 1232 .next = m_next,
1090 .stop = m_stop, 1233 .stop = m_stop,
1091 .show = show_numa_map, 1234 .show = show_pid_numa_map,
1235};
1236
1237static const struct seq_operations proc_tid_numa_maps_op = {
1238 .start = m_start,
1239 .next = m_next,
1240 .stop = m_stop,
1241 .show = show_tid_numa_map,
1092}; 1242};
1093 1243
1094static int numa_maps_open(struct inode *inode, struct file *file) 1244static int numa_maps_open(struct inode *inode, struct file *file,
1245 const struct seq_operations *ops)
1095{ 1246{
1096 struct numa_maps_private *priv; 1247 struct numa_maps_private *priv;
1097 int ret = -ENOMEM; 1248 int ret = -ENOMEM;
1098 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1249 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1099 if (priv) { 1250 if (priv) {
1100 priv->proc_maps.pid = proc_pid(inode); 1251 priv->proc_maps.pid = proc_pid(inode);
1101 ret = seq_open(file, &proc_pid_numa_maps_op); 1252 ret = seq_open(file, ops);
1102 if (!ret) { 1253 if (!ret) {
1103 struct seq_file *m = file->private_data; 1254 struct seq_file *m = file->private_data;
1104 m->private = priv; 1255 m->private = priv;
@@ -1109,8 +1260,25 @@ static int numa_maps_open(struct inode *inode, struct file *file)
1109 return ret; 1260 return ret;
1110} 1261}
1111 1262
1112const struct file_operations proc_numa_maps_operations = { 1263static int pid_numa_maps_open(struct inode *inode, struct file *file)
1113 .open = numa_maps_open, 1264{
1265 return numa_maps_open(inode, file, &proc_pid_numa_maps_op);
1266}
1267
1268static int tid_numa_maps_open(struct inode *inode, struct file *file)
1269{
1270 return numa_maps_open(inode, file, &proc_tid_numa_maps_op);
1271}
1272
1273const struct file_operations proc_pid_numa_maps_operations = {
1274 .open = pid_numa_maps_open,
1275 .read = seq_read,
1276 .llseek = seq_lseek,
1277 .release = seq_release_private,
1278};
1279
1280const struct file_operations proc_tid_numa_maps_operations = {
1281 .open = tid_numa_maps_open,
1114 .read = seq_read, 1282 .read = seq_read,
1115 .llseek = seq_lseek, 1283 .llseek = seq_lseek,
1116 .release = seq_release_private, 1284 .release = seq_release_private,