]> git.itanic.dy.fi Git - scan-pagemap/blob - pagemap.h
Show full process argument list instead only executable name
[scan-pagemap] / pagemap.h
1 /*
2  * Copyright (C) 2010 Timo Kokkonen <timo.t.kokkonen@iki.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 enum kpageflags {
96         LOCKED,
97         ERROR,
98         REFERENCED,
99         UPTODATE,
100         DIRTY,
101         LRU,
102         ACTIVE,
103         SLAB,
104         WRITEBACK,
105         RECLAIM,
106         BUDDY,
107         MMAP,
108         ANON,
109         SWAPCACHE,
110         SWAPBACKED,
111         COMPOUND_HEAD,
112         COMPOUND_TAIL,
113         HUGE,
114         UNEVICTABLE,
115         HWPOISON,
116         NOPAGE,
117         KSM,
118         THP,
119         __PAGEFLAGS_LAST,
120 };
121
122 #define KPAGEFLAGS_NUM __PAGEFLAGS_LAST
123
124 struct kpageflag_str {
125         int flag;
126         char *str;
127 };
128
129 extern struct kpageflag_str kpageflag_str[];
130
131 static inline int kpageflag_is_set(struct pageframe *p, int flag)
132 {
133         return !!(BITRANGE(flag, flag) & p->kpageflags);
134 }
135
136 static inline char *kpageflag_to_str(int flag)
137 {
138         int i;
139
140         for (i = 0; i < KPAGEFLAGS_NUM; i++)
141                 if (kpageflag_str[i].flag == flag)
142                         return kpageflag_str[i].str;
143
144         return NULL;
145 }
146
147 struct maps {
148         struct list_head list;
149
150         /* Memory segment of a mapping */
151         unsigned long start;
152         unsigned long end;
153         unsigned long size;
154
155         long int pages_present;
156         long int pages_swapped;
157
158         /* Name of the mapping, such as library name or something else */
159         char name[128];
160         int pid; /* Process which address space the mapping belongs to */
161         int tid; /* thread id */
162 };
163
164 #define list_to_maps(list_head)                         \
165         container_of((list_head), struct maps, list)
166
167 struct process {
168         struct maps *maps;
169         struct list_head list;
170         int pid;
171         int tid;
172         char name[256];
173
174         long int pages_present;
175         long int pages_swapped;
176         long int pages_unique;
177
178         int is_initial_pid;
179 };
180
181 #define PARSE_PID               0x1
182 #define PARSE_MAP_NAME          0x2
183 #define PARSE_DUMP              0x8
184 #define PARSE_NOADD_TREE        0x10
185 #define PARSE_SHARED_MAPPING    0x20
186
187 struct pidlist {
188         struct list_head list;
189
190         int pid;
191 };
192
193 struct parse_opts {
194         struct list_head pidlist;
195
196         int parse_mask;
197         char *name;
198         int with_threads;
199 };
200
201 static inline void init_parse_opts(struct parse_opts *p)
202 {
203         memset(p, 0, sizeof(*p));
204         INIT_LIST_HEAD(&p->pidlist);
205 }
206
207 static inline struct pidlist *alloc_pidlist(void)
208 {
209         struct pidlist *p = calloc(sizeof(*p), 1);
210
211         if (p == NULL)
212                 return p;
213
214         INIT_LIST_HEAD(&p->list);
215
216         return p;
217 }
218
219 #define is_parse_option(parse_opts, flag) \
220         (!!((parse_opts)->parse_mask & (flag)))
221
222 #endif