Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=826fad1b93fdb4ffacfd9cd860f06140e852e377
Commit:     826fad1b93fdb4ffacfd9cd860f06140e852e377
Parent:     0013572b2ae535bfd6314f22d9aef53725ea00d8
Author:     David Rientjes <[EMAIL PROTECTED]>
AuthorDate: Sun May 6 14:49:21 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Mon May 7 12:12:52 2007 -0700

    smaps: extract pmd walker from smaps code
    
    Extracts the pmd walker from smaps-specific code in fs/proc/task_mmu.c.
    
    The new struct pmd_walker includes the struct vm_area_struct of the memory 
to
    walk over.  Iteration begins at the vma->vm_start and completes at
    vma->vm_end.  A pointer to another data structure may be stored in the 
private
    field such as struct mem_size_stats, which acts as the smaps accumulator.  
For
    each pmd in the VMA, the action function is called with a pointer to its
    struct vm_area_struct, a pointer to the pmd_t, its start and end addresses,
    and the private field.
    
    The interface for walking pmd's in a VMA for fs/proc/task_mmu.c is now:
    
        void for_each_pmd(struct vm_area_struct *vma,
                          void (*action)(struct vm_area_struct *vma,
                                         pmd_t *pmd, unsigned long addr,
                                         unsigned long end,
                                         void *private),
                          void *private);
    
    Since the pmd walker is now extracted from the smaps code, smaps_one_pmd() 
is
    invoked for each pmd in the VMA.  Its behavior and efficiency is identical 
to
    the existing implementation.
    
    Cc: Hugh Dickins <[EMAIL PROTECTED]>
    Cc: Paul Mundt <[EMAIL PROTECTED]>
    Cc: Christoph Lameter <[EMAIL PROTECTED]>
    Signed-off-by: David Rientjes <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/proc/task_mmu.c |   69 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7445980..9d22c1c 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -122,6 +122,13 @@ struct mem_size_stats
        unsigned long private_dirty;
 };
 
+struct pmd_walker {
+       struct vm_area_struct *vma;
+       void *private;
+       void (*action)(struct vm_area_struct *, pmd_t *, unsigned long,
+                      unsigned long, void *);
+};
+
 static int show_map_internal(struct seq_file *m, void *v, struct 
mem_size_stats *mss)
 {
        struct proc_maps_private *priv = m->private;
@@ -204,16 +211,17 @@ static int show_map(struct seq_file *m, void *v)
        return show_map_internal(m, v, NULL);
 }
 
-static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
-                               unsigned long addr, unsigned long end,
-                               struct mem_size_stats *mss)
+static void smaps_one_pmd(struct vm_area_struct *vma, pmd_t *pmd,
+                         unsigned long addr, unsigned long end,
+                         void *private)
 {
+       struct mem_size_stats *mss = private;
        pte_t *pte, ptent;
        spinlock_t *ptl;
        struct page *page;
 
        pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
-       do {
+       for (; addr != end; pte++, addr += PAGE_SIZE) {
                ptent = *pte;
                if (!pte_present(ptent))
                        continue;
@@ -235,57 +243,64 @@ static void smaps_pte_range(struct vm_area_struct *vma, 
pmd_t *pmd,
                        else
                                mss->private_clean += PAGE_SIZE;
                }
-       } while (pte++, addr += PAGE_SIZE, addr != end);
+       }
        pte_unmap_unlock(pte - 1, ptl);
        cond_resched();
 }
 
-static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud,
-                               unsigned long addr, unsigned long end,
-                               struct mem_size_stats *mss)
+static inline void for_each_pmd_in_pud(struct pmd_walker *walker, pud_t *pud,
+                                      unsigned long addr, unsigned long end)
 {
        pmd_t *pmd;
        unsigned long next;
 
-       pmd = pmd_offset(pud, addr);
-       do {
+       for (pmd = pmd_offset(pud, addr); addr != end;
+            pmd++, addr = next) {
                next = pmd_addr_end(addr, end);
                if (pmd_none_or_clear_bad(pmd))
                        continue;
-               smaps_pte_range(vma, pmd, addr, next, mss);
-       } while (pmd++, addr = next, addr != end);
+               walker->action(walker->vma, pmd, addr, next, walker->private);
+       }
 }
 
-static inline void smaps_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
-                               unsigned long addr, unsigned long end,
-                               struct mem_size_stats *mss)
+static inline void for_each_pud_in_pgd(struct pmd_walker *walker, pgd_t *pgd,
+                                      unsigned long addr, unsigned long end)
 {
        pud_t *pud;
        unsigned long next;
 
-       pud = pud_offset(pgd, addr);
-       do {
+       for (pud = pud_offset(pgd, addr); addr != end;
+            pud++, addr = next) {
                next = pud_addr_end(addr, end);
                if (pud_none_or_clear_bad(pud))
                        continue;
-               smaps_pmd_range(vma, pud, addr, next, mss);
-       } while (pud++, addr = next, addr != end);
+               for_each_pmd_in_pud(walker, pud, addr, next);
+       }
 }
 
-static inline void smaps_pgd_range(struct vm_area_struct *vma,
-                               unsigned long addr, unsigned long end,
-                               struct mem_size_stats *mss)
+static inline void for_each_pmd(struct vm_area_struct *vma,
+                               void (*action)(struct vm_area_struct *, pmd_t *,
+                                              unsigned long, unsigned long,
+                                              void *),
+                               void *private)
 {
+       unsigned long addr = vma->vm_start;
+       unsigned long end = vma->vm_end;
+       struct pmd_walker walker = {
+               .vma            = vma,
+               .private        = private,
+               .action         = action,
+       };
        pgd_t *pgd;
        unsigned long next;
 
-       pgd = pgd_offset(vma->vm_mm, addr);
-       do {
+       for (pgd = pgd_offset(vma->vm_mm, addr); addr != end;
+            pgd++, addr = next) {
                next = pgd_addr_end(addr, end);
                if (pgd_none_or_clear_bad(pgd))
                        continue;
-               smaps_pud_range(vma, pgd, addr, next, mss);
-       } while (pgd++, addr = next, addr != end);
+               for_each_pud_in_pgd(&walker, pgd, addr, next);
+       }
 }
 
 static int show_smap(struct seq_file *m, void *v)
@@ -295,7 +310,7 @@ static int show_smap(struct seq_file *m, void *v)
 
        memset(&mss, 0, sizeof mss);
        if (vma->vm_mm && !is_vm_hugetlb_page(vma))
-               smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss);
+               for_each_pmd(vma, smaps_one_pmd, &mss);
        return show_map_internal(m, v, &mss);
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to