]> err.no Git - linux-2.6/blobdiff - fs/proc/task_mmu.c
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[linux-2.6] / fs / proc / task_mmu.c
index bccee7cf9ccd52e80ef5ac8dfd5d2f55d4e71755..0eaad41f4658f3f4eaaf526078dafa24e1ec0094 100644 (file)
 char *task_mem(struct mm_struct *mm, char *buffer)
 {
        unsigned long data, text, lib;
+       unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
+
+       /*
+        * Note: to minimize their overhead, mm maintains hiwater_vm and
+        * hiwater_rss only when about to *lower* total_vm or rss.  Any
+        * collector of these hiwater stats must therefore get total_vm
+        * and rss too, which will usually be the higher.  Barriers? not
+        * worth the effort, such snapshots can always be inconsistent.
+        */
+       hiwater_vm = total_vm = mm->total_vm;
+       if (hiwater_vm < mm->hiwater_vm)
+               hiwater_vm = mm->hiwater_vm;
+       hiwater_rss = total_rss = get_mm_rss(mm);
+       if (hiwater_rss < mm->hiwater_rss)
+               hiwater_rss = mm->hiwater_rss;
 
        data = mm->total_vm - mm->shared_vm - mm->stack_vm;
        text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
        lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
        buffer += sprintf(buffer,
+               "VmPeak:\t%8lu kB\n"
                "VmSize:\t%8lu kB\n"
                "VmLck:\t%8lu kB\n"
+               "VmHWM:\t%8lu kB\n"
                "VmRSS:\t%8lu kB\n"
                "VmData:\t%8lu kB\n"
                "VmStk:\t%8lu kB\n"
                "VmExe:\t%8lu kB\n"
                "VmLib:\t%8lu kB\n"
                "VmPTE:\t%8lu kB\n",
-               (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
+               hiwater_vm << (PAGE_SHIFT-10),
+               (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
                mm->locked_vm << (PAGE_SHIFT-10),
-               get_mm_rss(mm) << (PAGE_SHIFT-10),
+               hiwater_rss << (PAGE_SHIFT-10),
+               total_rss << (PAGE_SHIFT-10),
                data << (PAGE_SHIFT-10),
                mm->stack_vm << (PAGE_SHIFT-10), text, lib,
                (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
@@ -176,7 +195,7 @@ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats
 
 static int show_map(struct seq_file *m, void *v)
 {
-       return show_map_internal(m, v, 0);
+       return show_map_internal(m, v, NULL);
 }
 
 static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
@@ -184,13 +203,14 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
                                struct mem_size_stats *mss)
 {
        pte_t *pte, ptent;
+       spinlock_t *ptl;
        unsigned long pfn;
        struct page *page;
 
-       pte = pte_offset_map(pmd, addr);
+       pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
        do {
                ptent = *pte;
-               if (pte_none(ptent) || !pte_present(ptent))
+               if (!pte_present(ptent))
                        continue;
 
                mss->resident += PAGE_SIZE;
@@ -211,8 +231,8 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
                                mss->private_clean += PAGE_SIZE;
                }
        } while (pte++, addr += PAGE_SIZE, addr != end);
-       pte_unmap(pte - 1);
-       cond_resched_lock(&vma->vm_mm->page_table_lock);
+       pte_unmap_unlock(pte - 1, ptl);
+       cond_resched();
 }
 
 static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud,
@@ -266,17 +286,11 @@ static inline void smaps_pgd_range(struct vm_area_struct *vma,
 static int show_smap(struct seq_file *m, void *v)
 {
        struct vm_area_struct *vma = v;
-       struct mm_struct *mm = vma->vm_mm;
        struct mem_size_stats mss;
 
        memset(&mss, 0, sizeof mss);
-
-       if (mm) {
-               spin_lock(&mm->page_table_lock);
+       if (vma->vm_mm)
                smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss);
-               spin_unlock(&mm->page_table_lock);
-       }
-
        return show_map_internal(m, v, &mss);
 }
 
@@ -376,131 +390,12 @@ struct seq_operations proc_pid_smaps_op = {
 };
 
 #ifdef CONFIG_NUMA
-
-struct numa_maps {
-       unsigned long pages;
-       unsigned long anon;
-       unsigned long mapped;
-       unsigned long mapcount_max;
-       unsigned long node[MAX_NUMNODES];
-};
-
-/*
- * Calculate numa node maps for a vma
- */
-static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
-{
-       struct page *page;
-       unsigned long vaddr;
-       struct mm_struct *mm = vma->vm_mm;
-       int i;
-       struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL);
-
-       if (!md)
-               return NULL;
-       md->pages = 0;
-       md->anon = 0;
-       md->mapped = 0;
-       md->mapcount_max = 0;
-       for_each_node(i)
-               md->node[i] =0;
-
-       spin_lock(&mm->page_table_lock);
-       for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
-               page = follow_page(mm, vaddr, 0);
-               if (page) {
-                       int count = page_mapcount(page);
-
-                       if (count)
-                               md->mapped++;
-                       if (count > md->mapcount_max)
-                               md->mapcount_max = count;
-                       md->pages++;
-                       if (PageAnon(page))
-                               md->anon++;
-                       md->node[page_to_nid(page)]++;
-               }
-       }
-       spin_unlock(&mm->page_table_lock);
-       return md;
-}
-
-static int show_numa_map(struct seq_file *m, void *v)
-{
-       struct task_struct *task = m->private;
-       struct vm_area_struct *vma = v;
-       struct mempolicy *pol;
-       struct numa_maps *md;
-       struct zone **z;
-       int n;
-       int first;
-
-       if (!vma->vm_mm)
-               return 0;
-
-       md = get_numa_maps(vma);
-       if (!md)
-               return 0;
-
-       seq_printf(m, "%08lx", vma->vm_start);
-       pol = get_vma_policy(task, vma, vma->vm_start);
-       /* Print policy */
-       switch (pol->policy) {
-       case MPOL_PREFERRED:
-               seq_printf(m, " prefer=%d", pol->v.preferred_node);
-               break;
-       case MPOL_BIND:
-               seq_printf(m, " bind={");
-               first = 1;
-               for (z = pol->v.zonelist->zones; *z; z++) {
-
-                       if (!first)
-                               seq_putc(m, ',');
-                       else
-                               first = 0;
-                       seq_printf(m, "%d/%s", (*z)->zone_pgdat->node_id,
-                                       (*z)->name);
-               }
-               seq_putc(m, '}');
-               break;
-       case MPOL_INTERLEAVE:
-               seq_printf(m, " interleave={");
-               first = 1;
-               for_each_node(n) {
-                       if (node_isset(n, pol->v.nodes)) {
-                               if (!first)
-                                       seq_putc(m,',');
-                               else
-                                       first = 0;
-                               seq_printf(m, "%d",n);
-                       }
-               }
-               seq_putc(m, '}');
-               break;
-       default:
-               seq_printf(m," default");
-               break;
-       }
-       seq_printf(m, " MaxRef=%lu Pages=%lu Mapped=%lu",
-                       md->mapcount_max, md->pages, md->mapped);
-       if (md->anon)
-               seq_printf(m," Anon=%lu",md->anon);
-
-       for_each_online_node(n) {
-               if (md->node[n])
-                       seq_printf(m, " N%d=%lu", n, md->node[n]);
-       }
-       seq_putc(m, '\n');
-       kfree(md);
-       if (m->count < m->size)  /* vma is copied successfully */
-               m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
-       return 0;
-}
+extern int show_numa_map(struct seq_file *m, void *v);
 
 struct seq_operations proc_pid_numa_maps_op = {
-       .start  = m_start,
-       .next   = m_next,
-       .stop   = m_stop,
-       .show   = show_numa_map
+        .start  = m_start,
+        .next   = m_next,
+        .stop   = m_stop,
+        .show   = show_numa_map
 };
 #endif