]> git.itanic.dy.fi Git - scan-pagemap/commitdiff
Compact pageframe structure
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Mon, 16 Aug 2010 18:23:30 +0000 (21:23 +0300)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Mon, 16 Aug 2010 20:02:09 +0000 (23:02 +0300)
Instead of decoding each entry to individual variables in the
pageframe structure, maintain them as a single raw 64 bit
value. Various helper functions are introduced for decoding the
information on the fly. This reduces the run time memory consumption
without really slowing down the execution.

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

index bb0679f3a1c1e27c7fd650602372dbc8dafad355..59481efd8e23ed5692c02f80a487c7fa21c06e61 100644 (file)
--- a/analyze.c
+++ b/analyze.c
@@ -53,9 +53,9 @@ static void count_pages(struct bintree *b, struct bintree_ops *ops)
        }
 
 get_stats:
        }
 
 get_stats:
-       if (pf->page_present)
+       if (page_present(pf))
                af->pages_present++;
                af->pages_present++;
-       else if (pf->page_swapped)
+       else if (page_swapped(pf))
                af->pages_swapped++;
        if (pf->refcount == 1)
                af->pages_unique++;
                af->pages_swapped++;
        if (pf->refcount == 1)
                af->pages_unique++;
index b06afb69f142755c0e5f2c7239b2fa2b72f6d13f..d7dacdf151b908d6f5e5b0557ebe53d591d6ba48 100644 (file)
--- a/pagemap.h
+++ b/pagemap.h
@@ -17,21 +17,50 @@ struct maps_list {
 #define list_to_maps_list(list_head)                           \
        container_of((list_head), struct maps_list, list)
 
 #define list_to_maps_list(list_head)                           \
        container_of((list_head), struct maps_list, list)
 
+#define BITRANGE(first, last) (((2ll << (last - first)) - 1) << first)
+
 struct pageframe {
        struct bintree tree;
        struct maps_list ml;    /* List to mappings which point to this pfn */
 struct pageframe {
        struct bintree tree;
        struct maps_list ml;    /* List to mappings which point to this pfn */
-       unsigned long pfn;      /* page frame number */
-       int swap_type;
-       int swap_offset;
-       int page_shift;
-       int page_swapped;
-       int page_present;
+
+       unsigned long long pf;  /* page frame entry from /proc/pid/pagemap */
+
        int refcount;
 };
 
 #define tree_to_pageframe(tree_struct)                         \
        container_of((tree_struct), struct pageframe, tree)
 
        int refcount;
 };
 
 #define tree_to_pageframe(tree_struct)                         \
        container_of((tree_struct), struct pageframe, tree)
 
+static inline int page_present(struct pageframe *p)
+{
+       return !!(BITRANGE(63, 63) & p->pf);
+}
+
+static inline int page_swapped(struct pageframe *p)
+{
+       return !!(BITRANGE(62, 62) & p->pf);
+}
+
+static inline int page_shift(struct pageframe *p)
+{
+       return (BITRANGE(55, 60) & p->pf) >> 55;
+}
+
+static inline long int pfn(struct pageframe *p)
+{
+       return (BITRANGE(0, 54) & p->pf);
+}
+
+static inline int swap_type(struct pageframe *p)
+{
+       return (BITRANGE(0, 4) & p->pf);
+}
+
+static inline int swap_offset(struct pageframe *p)
+{
+       return (BITRANGE(5, 54) & p->pf) >> 5;
+}
+
 struct maps {
        struct list_head list;
 
 struct maps {
        struct list_head list;
 
diff --git a/parse.c b/parse.c
index a4b878a3b85e0006de7b4fefbcf8cd0ae2f277ca..fc7d69e4d41ba65f40797aa17b602aa8e06c0e70 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -96,30 +96,13 @@ err:
        return pageframe;
 }
 
        return pageframe;
 }
 
-#define BITRANGE(first, last) (((2ll << (last - first)) - 1) << first)
-
-static void pageframe_to_struct(unsigned long long p, struct pageframe *pf)
-{
-       /* Refer Documentation/vm/pagemap.txt for the format */
-       pf->page_present = !!(BITRANGE(63, 63) & p);
-       pf->page_swapped = !!(BITRANGE(62, 62) & p);
-       pf->page_shift   =   (BITRANGE(55, 60) & p) >> 55;
-       pf->pfn          =   (BITRANGE(0, 54) & p);
-       pf->swap_type    =   (BITRANGE(0, 4) & p);
-       pf->swap_offset  =   (BITRANGE(5, 54) & p) >> 5;
-#if 0
-       printf("pfn: %lx shift: %d present: %d swapped %d\n",
-               pf->pfn, pf->page_shift, pf->page_present, pf->page_swapped);
-#endif
-}
-
 static int compare_pageframe(struct bintree *at, struct bintree *bt)
 {
        struct pageframe *a, *b;
        a = tree_to_pageframe(at);
        b = tree_to_pageframe(bt);
 
 static int compare_pageframe(struct bintree *at, struct bintree *bt)
 {
        struct pageframe *a, *b;
        a = tree_to_pageframe(at);
        b = tree_to_pageframe(bt);
 
-       return a->pfn - b->pfn;
+       return a->pf - b->pf;
 }
 
 struct bintree_ops pageframe_ops = {
 }
 
 struct bintree_ops pageframe_ops = {
@@ -263,11 +246,11 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
                        if (!pf[ret / sizeof(pf[0])])
                                continue;
 
                        if (!pf[ret / sizeof(pf[0])])
                                continue;
 
-                       pageframe_to_struct(pf[ret / sizeof(pf[0])], pageframe);
+                       pageframe->pf = (pf[ret / sizeof(pf[0])]);
 
                        /* ignore unused pages */
 
                        /* ignore unused pages */
-                       if (!(pageframe->page_swapped ||
-                                       pageframe->page_present))
+                       if (!(page_swapped(pageframe) ||
+                                       page_present(pageframe)))
                                continue;
 
                        if (should_add_to_tree(opts, pageframe, map)) {
                                continue;
 
                        if (should_add_to_tree(opts, pageframe, map)) {
@@ -297,9 +280,9 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
                        tmp->map = map;
                        list_add(&tmp->list, &match->ml.list);
 
                        tmp->map = map;
                        list_add(&tmp->list, &match->ml.list);
 
-                       if (match->page_present)
+                       if (page_present(match))
                                map->pages_present++;
                                map->pages_present++;
-                       else if (match->page_swapped)
+                       else if (page_swapped(match))
                                map->pages_swapped++;
                }
        }
                                map->pages_swapped++;
                }
        }