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