]> git.itanic.dy.fi Git - scan-pagemap/blob - pagemap.h
Makefile: Do not force pretty print
[scan-pagemap] / pagemap.h
1 /*
2  * Copyright (C) 2010 Timo Kokkonen <kaapeli@itanic.dy.fi>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16  */
17
18 #ifndef _PAGEMAP_H
19 #define _PAGEMAP_H
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "utils.h"
25 #include "list.h"
26 #include "rbtree.h"
27
28 #define PAGE_SHIFT      12
29 #define PAGE_SIZE       (1 << PAGE_SHIFT)
30
31 struct maps;
32
33 struct maps_list {
34         struct maps *map;
35         struct list_head list;
36 };
37 #define list_to_maps_list(list_head)                            \
38         container_of((list_head), struct maps_list, list)
39
40 #define BITRANGE(first, last) (((2ll << (last - first)) - 1) << first)
41
42 struct pageframe {
43         struct rb_node tree;
44         struct list_head ml;    /* List of mappings which refer to this pfn */
45
46         unsigned long long pf;  /* page frame entry from /proc/pid/pagemap */
47         unsigned long long kpageflags;
48         unsigned long long kpagecount;
49
50         int refcount;
51 };
52
53 struct pageframe *pf_insert(struct rb_root *root, struct pageframe *pf);
54 struct pageframe *pf_search(struct rb_root *root, struct pageframe *pf);
55
56 #define rb_to_pageframe(tree_struct)                            \
57         container_of((tree_struct), struct pageframe, tree)
58
59 static inline void clear_pageframe(struct pageframe *pf)
60 {
61         memset(pf, 0, sizeof(*pf));
62         INIT_LIST_HEAD(&pf->ml);
63 }
64
65 static inline int page_present(struct pageframe *p)
66 {
67         return !!(BITRANGE(63, 63) & p->pf);
68 }
69
70 static inline int page_swapped(struct pageframe *p)
71 {
72         return !!(BITRANGE(62, 62) & p->pf);
73 }
74
75 static inline int page_shift(struct pageframe *p)
76 {
77         return (BITRANGE(55, 60) & p->pf) >> 55;
78 }
79
80 static inline long int pfn(struct pageframe *p)
81 {
82         return (BITRANGE(0, 54) & p->pf);
83 }
84
85 static inline int swap_type(struct pageframe *p)
86 {
87         return (BITRANGE(0, 4) & p->pf);
88 }
89
90 static inline int swap_offset(struct pageframe *p)
91 {
92         return (BITRANGE(5, 54) & p->pf) >> 5;
93 }
94
95 #define KPAGEFLAGS_NUM 22
96
97 enum kpageflags {
98         LOCKED,
99         ERROR,
100         REFERENCED,
101         UPTODATE,
102         DIRTY,
103         LRU,
104         ACTIVE,
105         SLAB,
106         WRITEBACK,
107         RECLAIM,
108         BUDDY,
109         MMAP,
110         ANON,
111         SWAPCACHE,
112         SWAPBACKED,
113         COMPOUND_HEAD,
114         COMPOUND_TAIL,
115         HUGE,
116         UNEVICTABLE,
117         HWPOISON,
118         NOPAGE,
119         KSM,
120 };
121
122 struct kpageflag_str {
123         int flag;
124         char *str;
125 };
126
127 extern struct kpageflag_str kpageflag_str[];
128
129 static inline int kpageflag_is_set(struct pageframe *p, int flag)
130 {
131         return !!(BITRANGE(flag, flag) & p->kpageflags);
132 }
133
134 static inline char *kpageflag_to_str(int flag)
135 {
136         int i;
137
138         for (i = 0; i < KPAGEFLAGS_NUM; i++)
139                 if (kpageflag_str[i].flag == flag)
140                         return kpageflag_str[i].str;
141
142         return NULL;
143 }
144
145 struct maps {
146         struct list_head list;
147
148         /* Memory segment of a mapping */
149         unsigned long start;
150         unsigned long end;
151         unsigned long size;
152
153         long int pages_present;
154         long int pages_swapped;
155
156         /* Name of the mapping, such as library name or something else */
157         char name[128];
158         int pid; /* Process which address space the mapping belongs to */
159         int tid; /* thread id */
160 };
161
162 #define list_to_maps(list_head)                         \
163         container_of((list_head), struct maps, list)
164
165 struct process {
166         struct maps *maps;
167         struct list_head list;
168         int pid;
169         int tid;
170         char name[256];
171
172         long int pages_present;
173         long int pages_swapped;
174         long int pages_unique;
175
176         int is_initial_pid;
177 };
178
179 #define PARSE_PID               0x1
180 #define PARSE_MAP_NAME          0x2
181 #define PARSE_DUMP              0x8
182 #define PARSE_NOADD_TREE        0x10
183 #define PARSE_SHARED_MAPPING    0x20
184
185 struct pidlist {
186         struct list_head list;
187
188         int pid;
189 };
190
191 struct parse_opts {
192         struct list_head pidlist;
193
194         int parse_mask;
195         char *name;
196         int with_threads;
197 };
198
199 static inline void init_parse_opts(struct parse_opts *p)
200 {
201         memset(p, 0, sizeof(*p));
202         INIT_LIST_HEAD(&p->pidlist);
203 }
204
205 static inline struct pidlist *alloc_pidlist(void)
206 {
207         struct pidlist *p = calloc(sizeof(*p), 1);
208
209         if (p == NULL)
210                 return p;
211
212         INIT_LIST_HEAD(&p->list);
213
214         return p;
215 }
216
217 #define is_parse_option(parse_opts, flag) \
218         (!!((parse_opts)->parse_mask & (flag)))
219
220 #endif