From 70726de93e4e5e8322ba6bd3f8334a51522dc797 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Mon, 16 Aug 2010 21:23:30 +0300 Subject: [PATCH] Compact pageframe structure 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 --- analyze.c | 4 ++-- pagemap.h | 41 +++++++++++++++++++++++++++++++++++------ parse.c | 29 ++++++----------------------- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/analyze.c b/analyze.c index bb0679f..59481ef 100644 --- a/analyze.c +++ b/analyze.c @@ -53,9 +53,9 @@ static void count_pages(struct bintree *b, struct bintree_ops *ops) } get_stats: - if (pf->page_present) + if (page_present(pf)) af->pages_present++; - else if (pf->page_swapped) + else if (page_swapped(pf)) af->pages_swapped++; if (pf->refcount == 1) af->pages_unique++; diff --git a/pagemap.h b/pagemap.h index b06afb6..d7dacdf 100644 --- 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 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 */ - 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) +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; diff --git a/parse.c b/parse.c index a4b878a..fc7d69e 100644 --- a/parse.c +++ b/parse.c @@ -96,30 +96,13 @@ err: 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); - return a->pfn - b->pfn; + return a->pf - b->pf; } 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; - pageframe_to_struct(pf[ret / sizeof(pf[0])], pageframe); + pageframe->pf = (pf[ret / sizeof(pf[0])]); /* 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)) { @@ -297,9 +280,9 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree, tmp->map = map; list_add(&tmp->list, &match->ml.list); - if (match->page_present) + if (page_present(match)) map->pages_present++; - else if (match->page_swapped) + else if (page_swapped(match)) map->pages_swapped++; } } -- 2.44.0