]> git.itanic.dy.fi Git - scan-pagemap/blob - pagemap.h
Add a copyright notes on each source file
[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
23 #include "utils.h"
24 #include "list.h"
25 #include "bintree.h"
26
27 #define PAGE_SHIFT      12
28 #define PAGE_SIZE       (1 << PAGE_SHIFT)
29
30 struct maps;
31
32 struct maps_list {
33         struct maps *map;
34         struct list_head list;
35 };
36 #define list_to_maps_list(list_head)                            \
37         container_of((list_head), struct maps_list, list)
38
39 #define BITRANGE(first, last) (((2ll << (last - first)) - 1) << first)
40
41 struct pageframe {
42         struct bintree tree;
43         struct list_head ml;    /* List of mappings which refer to this pfn */
44
45         unsigned long long pf;  /* page frame entry from /proc/pid/pagemap */
46         unsigned long long kpageflags;
47         unsigned long long kpagecount;
48
49         int refcount;
50 };
51
52 #define tree_to_pageframe(tree_struct)                          \
53         container_of((tree_struct), struct pageframe, tree)
54
55 static inline void clear_pageframe(struct pageframe *pf)
56 {
57         memset(pf, 0, sizeof(*pf));
58         INIT_LIST_HEAD(&pf->ml);
59 }
60
61 static inline int page_present(struct pageframe *p)
62 {
63         return !!(BITRANGE(63, 63) & p->pf);
64 }
65
66 static inline int page_swapped(struct pageframe *p)
67 {
68         return !!(BITRANGE(62, 62) & p->pf);
69 }
70
71 static inline int page_shift(struct pageframe *p)
72 {
73         return (BITRANGE(55, 60) & p->pf) >> 55;
74 }
75
76 static inline long int pfn(struct pageframe *p)
77 {
78         return (BITRANGE(0, 54) & p->pf);
79 }
80
81 static inline int swap_type(struct pageframe *p)
82 {
83         return (BITRANGE(0, 4) & p->pf);
84 }
85
86 static inline int swap_offset(struct pageframe *p)
87 {
88         return (BITRANGE(5, 54) & p->pf) >> 5;
89 }
90
91 #define KPAGEFLAGS_NUM 22
92
93 enum kpageflags {
94         LOCKED,
95         ERROR,
96         REFERENCED,
97         UPTODATE,
98         DIRTY,
99         LRU,
100         ACTIVE,
101         SLAB,
102         WRITEBACK,
103         RECLAIM,
104         BUDDY,
105         MMAP,
106         ANON,
107         SWAPCACHE,
108         SWAPBACKED,
109         COMPOUND_HEAD,
110         COMPOUND_TAIL,
111         HUGE,
112         UNEVICTABLE,
113         HWPOISON,
114         NOPAGE,
115         KSM,
116 };
117
118 struct kpageflag_str {
119         int flag;
120         char *str;
121 };
122
123 extern struct kpageflag_str kpageflag_str[];
124
125 static inline int kpageflag_is_set(struct pageframe *p, int flag)
126 {
127         return !!(BITRANGE(flag, flag) & p->kpageflags);
128 }
129
130 static inline char *kpageflag_to_str(int flag)
131 {
132         int i;
133
134         for (i = 0; i < KPAGEFLAGS_NUM; i++)
135                 if (kpageflag_str[i].flag == flag)
136                         return kpageflag_str[i].str;
137
138         return NULL;
139 }
140
141 struct maps {
142         struct list_head list;
143
144         /* Memory segment of a mapping */
145         unsigned long start;
146         unsigned long end;
147         unsigned long size;
148
149         long int pages_present;
150         long int pages_swapped;
151
152         /* Name of the mapping, such as library name or something else */
153         char name[128];
154         int pid; /* Process which address space the mapping belongs to */
155         int tid; /* thread id */
156 };
157
158 #define list_to_maps(list_head)                         \
159         container_of((list_head), struct maps, list)
160
161 struct process {
162         struct maps *maps;
163         struct list_head list;
164         int pid;
165         int tid;
166         char name[256];
167
168         long int pages_present;
169         long int pages_swapped;
170         long int pages_unique;
171
172         int is_initial_pid;
173 };
174
175 #define PARSE_PID               0x1
176 #define PARSE_MAP_NAME          0x2
177 #define PARSE_DUMP              0x8
178 #define PARSE_NOADD_TREE        0x10
179 #define PARSE_SHARED_MAPPING    0x20
180
181 struct pidlist {
182         struct list_head list;
183
184         int pid;
185 };
186
187 struct parse_opts {
188         struct list_head pidlist;
189
190         int parse_mask;
191         char *name;
192         int with_threads;
193 };
194
195 static inline void init_parse_opts(struct parse_opts *p)
196 {
197         memset(p, 0, sizeof(*p));
198         INIT_LIST_HEAD(&p->pidlist);
199 }
200
201 static inline struct pidlist *alloc_pidlist(void)
202 {
203         struct pidlist *p = malloc(sizeof(*p));
204
205         if (p == NULL)
206                 return p;
207
208         memset(p, 0, sizeof(*p));
209         INIT_LIST_HEAD(&p->list);
210
211         return p;
212 }
213
214 #define is_parse_option(parse_opts, flag) \
215         (!!((parse_opts)->parse_mask & (flag)))
216
217 #endif