aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c120
1 files changed, 95 insertions, 25 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 1a210088ad80..d80fa7d8f720 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -197,7 +197,7 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
197 return policy; 197 return policy;
198} 198}
199 199
200static void gather_stats(struct page *, void *); 200static void gather_stats(struct page *, void *, int pte_dirty);
201static void migrate_page_add(struct page *page, struct list_head *pagelist, 201static void migrate_page_add(struct page *page, struct list_head *pagelist,
202 unsigned long flags); 202 unsigned long flags);
203 203
@@ -239,7 +239,7 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
239 continue; 239 continue;
240 240
241 if (flags & MPOL_MF_STATS) 241 if (flags & MPOL_MF_STATS)
242 gather_stats(page, private); 242 gather_stats(page, private, pte_dirty(*pte));
243 else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) 243 else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))
244 migrate_page_add(page, private, flags); 244 migrate_page_add(page, private, flags);
245 else 245 else
@@ -1753,67 +1753,137 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
1753struct numa_maps { 1753struct numa_maps {
1754 unsigned long pages; 1754 unsigned long pages;
1755 unsigned long anon; 1755 unsigned long anon;
1756 unsigned long mapped; 1756 unsigned long active;
1757 unsigned long writeback;
1757 unsigned long mapcount_max; 1758 unsigned long mapcount_max;
1759 unsigned long dirty;
1760 unsigned long swapcache;
1758 unsigned long node[MAX_NUMNODES]; 1761 unsigned long node[MAX_NUMNODES];
1759}; 1762};
1760 1763
1761static void gather_stats(struct page *page, void *private) 1764static void gather_stats(struct page *page, void *private, int pte_dirty)
1762{ 1765{
1763 struct numa_maps *md = private; 1766 struct numa_maps *md = private;
1764 int count = page_mapcount(page); 1767 int count = page_mapcount(page);
1765 1768
1766 if (count) 1769 md->pages++;
1767 md->mapped++; 1770 if (pte_dirty || PageDirty(page))
1771 md->dirty++;
1768 1772
1769 if (count > md->mapcount_max) 1773 if (PageSwapCache(page))
1770 md->mapcount_max = count; 1774 md->swapcache++;
1771 1775
1772 md->pages++; 1776 if (PageActive(page))
1777 md->active++;
1778
1779 if (PageWriteback(page))
1780 md->writeback++;
1773 1781
1774 if (PageAnon(page)) 1782 if (PageAnon(page))
1775 md->anon++; 1783 md->anon++;
1776 1784
1785 if (count > md->mapcount_max)
1786 md->mapcount_max = count;
1787
1777 md->node[page_to_nid(page)]++; 1788 md->node[page_to_nid(page)]++;
1778 cond_resched(); 1789 cond_resched();
1779} 1790}
1780 1791
1792static void check_huge_range(struct vm_area_struct *vma,
1793 unsigned long start, unsigned long end,
1794 struct numa_maps *md)
1795{
1796 unsigned long addr;
1797 struct page *page;
1798
1799 for (addr = start; addr < end; addr += HPAGE_SIZE) {
1800 pte_t *ptep = huge_pte_offset(vma->vm_mm, addr & HPAGE_MASK);
1801 pte_t pte;
1802
1803 if (!ptep)
1804 continue;
1805
1806 pte = *ptep;
1807 if (pte_none(pte))
1808 continue;
1809
1810 page = pte_page(pte);
1811 if (!page)
1812 continue;
1813
1814 gather_stats(page, md, pte_dirty(*ptep));
1815 }
1816}
1817
1781int show_numa_map(struct seq_file *m, void *v) 1818int show_numa_map(struct seq_file *m, void *v)
1782{ 1819{
1783 struct task_struct *task = m->private; 1820 struct task_struct *task = m->private;
1784 struct vm_area_struct *vma = v; 1821 struct vm_area_struct *vma = v;
1785 struct numa_maps *md; 1822 struct numa_maps *md;
1823 struct file *file = vma->vm_file;
1824 struct mm_struct *mm = vma->vm_mm;
1786 int n; 1825 int n;
1787 char buffer[50]; 1826 char buffer[50];
1788 1827
1789 if (!vma->vm_mm) 1828 if (!mm)
1790 return 0; 1829 return 0;
1791 1830
1792 md = kzalloc(sizeof(struct numa_maps), GFP_KERNEL); 1831 md = kzalloc(sizeof(struct numa_maps), GFP_KERNEL);
1793 if (!md) 1832 if (!md)
1794 return 0; 1833 return 0;
1795 1834
1796 if (!is_vm_hugetlb_page(vma)) 1835 mpol_to_str(buffer, sizeof(buffer),
1836 get_vma_policy(task, vma, vma->vm_start));
1837
1838 seq_printf(m, "%08lx %s", vma->vm_start, buffer);
1839
1840 if (file) {
1841 seq_printf(m, " file=");
1842 seq_path(m, file->f_vfsmnt, file->f_dentry, "\n\t= ");
1843 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
1844 seq_printf(m, " heap");
1845 } else if (vma->vm_start <= mm->start_stack &&
1846 vma->vm_end >= mm->start_stack) {
1847 seq_printf(m, " stack");
1848 }
1849
1850 if (is_vm_hugetlb_page(vma)) {
1851 check_huge_range(vma, vma->vm_start, vma->vm_end, md);
1852 seq_printf(m, " huge");
1853 } else {
1797 check_pgd_range(vma, vma->vm_start, vma->vm_end, 1854 check_pgd_range(vma, vma->vm_start, vma->vm_end,
1798 &node_online_map, MPOL_MF_STATS, md); 1855 &node_online_map, MPOL_MF_STATS, md);
1856 }
1857
1858 if (!md->pages)
1859 goto out;
1799 1860
1800 if (md->pages) { 1861 if (md->anon)
1801 mpol_to_str(buffer, sizeof(buffer), 1862 seq_printf(m," anon=%lu",md->anon);
1802 get_vma_policy(task, vma, vma->vm_start));
1803 1863
1804 seq_printf(m, "%08lx %s pages=%lu mapped=%lu maxref=%lu", 1864 if (md->dirty)
1805 vma->vm_start, buffer, md->pages, 1865 seq_printf(m," dirty=%lu",md->dirty);
1806 md->mapped, md->mapcount_max);
1807 1866
1808 if (md->anon) 1867 if (md->pages != md->anon && md->pages != md->dirty)
1809 seq_printf(m," anon=%lu",md->anon); 1868 seq_printf(m, " mapped=%lu", md->pages);
1810 1869
1811 for_each_online_node(n) 1870 if (md->mapcount_max > 1)
1812 if (md->node[n]) 1871 seq_printf(m, " mapmax=%lu", md->mapcount_max);
1813 seq_printf(m, " N%d=%lu", n, md->node[n]);
1814 1872
1815 seq_putc(m, '\n'); 1873 if (md->swapcache)
1816 } 1874 seq_printf(m," swapcache=%lu", md->swapcache);
1875
1876 if (md->active < md->pages && !is_vm_hugetlb_page(vma))
1877 seq_printf(m," active=%lu", md->active);
1878
1879 if (md->writeback)
1880 seq_printf(m," writeback=%lu", md->writeback);
1881
1882 for_each_online_node(n)
1883 if (md->node[n])
1884 seq_printf(m, " N%d=%lu", n, md->node[n]);
1885out:
1886 seq_putc(m, '\n');
1817 kfree(md); 1887 kfree(md);
1818 1888
1819 if (m->count < m->size) 1889 if (m->count < m->size)