]> git.itanic.dy.fi Git - scan-pagemap/commitdiff
analyze.c: Factor out counting stats for a single pageframe
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 16 Oct 2011 18:19:08 +0000 (21:19 +0300)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 16 Oct 2011 18:19:08 +0000 (21:19 +0300)
This makes it possible to re-use the pageframe stats counting in cases
it is not desirable to count the stats for every pages in the tree.

Signed-off-by: Timo Kokkonen <kaapeli@itanic.dy.fi>
analyze.c

index a032eff139e271eede59eaa3e26fdf2687748193..547a3add74a7c64289006988bb6e51d30cc916bc 100644 (file)
--- a/analyze.c
+++ b/analyze.c
@@ -84,89 +84,93 @@ struct analyze_frames {
 #define bintree_ops_to_af(bintree_ops)                         \
        container_of((bintree_ops), struct analyze_frames, ops)
 
-static int count_pages(struct rb_root *root, struct analyze_frames *af)
+static void count_page(struct pageframe *pf, struct analyze_frames *af)
 {
-       struct pageframe *pf;
        struct maps_list *ml;
-       int i, pages = 0;
-
-       pf = rb_to_pageframe(rb_first(root));
+       int i;
 
-       while (pf) {
-               pages++;
+       if (af->pid) {
+               /* Find pages which reference at least once a pid */
+               list_for_each_entry(ml, &pf->ml, list) {
+                       if (ml->map->pid == af->pid)
+                               goto get_stats;
+               }
+               return;
+       } else if (af->pidlist && af->map) {
+               /*
+                * Find pages that reference at least once all of the
+                * given pids and a given mapping
+                */
+               struct pidlist *pid;
+               int matches = 0;
 
-               if (af->pid) {
-                       /* Find pages which reference at least once a pid */
-                       list_for_each_entry(ml, &pf->ml, list) {
-                               if (ml->map->pid == af->pid)
-                                       goto get_stats;
+               /*
+                * Check that we reference the given mapping at least
+                * once
+                */
+               list_for_each_entry(ml, &pf->ml, list) {
+                       if (ml->map == af->map) {
+                               matches++;
+                               break;
                        }
-                       goto next;
-               } else if (af->pidlist && af->map) {
-                       /*
-                        * Find pages that reference at least once all
-                        * of the given pids and a given mapping
-                        */
-                       struct pidlist *pid;
-                       int matches = 0;
+               }
 
-                       /*
-                        * Check that we reference the given mapping
-                        * at least once
-                        */
+               if (!matches)
+                       return;
+               matches = 0;
+
+               /*
+                * Check that we reference all of the given pids
+                * too. The order of the loops is important here. We
+                * must scan through all the references and test for a
+                * given pid. If we would iterate through the
+                * references in the outer loop, we might get
+                * duplicate matches for a pid since it is possible
+                * that a page is mapped multiple times in a process's
+                * addrses space.
+                */
+               list_for_each_entry(pid, af->pidlist, list) {
                        list_for_each_entry(ml, &pf->ml, list) {
-                               if (ml->map == af->map) {
+                               if (ml->map->pid == pid->pid) {
                                        matches++;
                                        break;
                                }
                        }
 
-                       if (!matches)
-                               goto next;
-                       matches = 0;
-
                        /*
-                        * Check that we reference all of the given
-                        * pids too. The order of the loops is
-                        * important here. We must scan through all
-                        * the references and test for a given pid. If
-                        * we would iterate through the references in
-                        * the outer loop, we might get duplicate
-                        * matches for a pid since it is possible that
-                        * a page is mapped multiple times in a
-                        * process's addrses space.
+                        * If we have found as many matches as ther
+                        * are pids, we will count the stats
                         */
-                       list_for_each_entry(pid, af->pidlist, list) {
-                               list_for_each_entry(ml, &pf->ml, list) {
-                                       if (ml->map->pid == pid->pid) {
-                                               matches++;
-                                               break;
-                                       }
-                               }
-
-                               /*
-                                * If we have found as many matches as ther
-                                * are pids, we will count the stats
-                                */
-                               if (matches == af->pids)
-                                       goto get_stats;
-                       }
-                       goto next;
+                       if (matches == af->pids)
+                               goto get_stats;
                }
+               return;
+       }
 
 get_stats:
-               if (page_present(pf))
-                       af->pages_present++;
-               else if (page_swapped(pf))
-                       af->pages_swapped++;
-               if (pf->kpagecount == 1)
-                       af->pages_unique++;
-
-               for (i = 0; i < KPAGEFLAGS_NUM; i++)
-                       if (kpageflag_is_set(pf, i))
-                               af->kpageflag[i]++;
-
-next:
+       if (page_present(pf))
+               af->pages_present++;
+       else if (page_swapped(pf))
+               af->pages_swapped++;
+       if (pf->kpagecount == 1)
+               af->pages_unique++;
+
+       for (i = 0; i < KPAGEFLAGS_NUM; i++)
+               if (kpageflag_is_set(pf, i))
+                       af->kpageflag[i]++;
+}
+
+static int count_pages(struct rb_root *root, struct analyze_frames *af)
+{
+       struct pageframe *pf;
+       int pages = 0;
+
+       pf = rb_to_pageframe(rb_first(root));
+
+       while (pf) {
+               pages++;
+               count_page(pf, af);
+
                pf = rb_to_pageframe(rb_next(&pf->tree));
        }