Before we would scan some processes twice: First when we find out the
pages of the interesting processes, then again when we scan the rest
of the processes. This patch changes the handling so that the second
time we ignore all interesting pids that we already scanned.
Signed-off-by: Timo Kokkonen <kaapeli@itanic.dy.fi>
#define PARSE_MAP_NAME 0x2
#define PARSE_PROCESS_NAME 0x4
#define PARSE_DUMP 0x8
#define PARSE_MAP_NAME 0x2
#define PARSE_PROCESS_NAME 0x4
#define PARSE_DUMP 0x8
+#define PARSE_NOADD_TREE 0x10
struct parse_opts {
int parse_mask;
struct parse_opts {
int parse_mask;
-static int check_parse_opts(struct parse_opts *opts, struct pageframe *pf,
- struct maps *map)
+static int should_scan_process(struct parse_opts *opts, struct process *process)
+ int match = 0;
+ char *name;
+
+ if (opts->parse_mask & PARSE_PROCESS_NAME) {
+ name = get_name_by_pid(process->pid);
+ if (!strcmp(opts->name, name ? name : ""))
+ match = 1;
+ }
+
if (opts->parse_mask & PARSE_PID) {
if (opts->parse_mask & PARSE_PID) {
- if (opts->pid == map->pid)
- return 1;
+ if (opts->pid == process->pid)
+ match = 1;
+ if (opts->parse_mask & PARSE_NOADD_TREE)
+ match = !match;
+
+ return match;
+}
+
+static int should_scan_mapping(struct parse_opts *opts, struct maps *map)
+{
+ int match = 0;
+
if (opts->parse_mask & PARSE_MAP_NAME) {
if (!strcmp(opts->name, map->name))
if (opts->parse_mask & PARSE_MAP_NAME) {
if (!strcmp(opts->name, map->name))
- if (opts->parse_mask & PARSE_PROCESS_NAME) {
- if (!strcmp(opts->name, get_name_by_pid(map->pid)))
- return 1;
- }
+ if (opts->parse_mask & PARSE_NOADD_TREE)
+ match = !match;
+ } else
+ match = 1;
+ return match;
+}
+
+static int should_add_to_tree(struct parse_opts *opts, struct pageframe *pf,
+ struct maps *map)
+{
+ if (opts->parse_mask & PARSE_NOADD_TREE)
+ return 0;
+
+ return 1;
}
/* Read data from the /proc/pid/pagemap file */
}
/* Read data from the /proc/pid/pagemap file */
start = map->start >> (PAGE_SHIFT - 3);
len = map->size >> (PAGE_SHIFT);
start = map->start >> (PAGE_SHIFT - 3);
len = map->size >> (PAGE_SHIFT);
+ if (!should_scan_mapping(opts, map))
+ continue;
+
ret = fseek(file, start, SEEK_SET);
if (ret) {
error = errno;
ret = fseek(file, start, SEEK_SET);
if (ret) {
error = errno;
pageframe->page_present))
continue;
pageframe->page_present))
continue;
- if (check_parse_opts(opts, pageframe, map)) {
+ if (should_add_to_tree(opts, pageframe, map)) {
match = tree_to_pageframe(
bintree_add(&pf_tree->tree,
&pageframe->tree,
match = tree_to_pageframe(
bintree_add(&pf_tree->tree,
&pageframe->tree,
process->pid = pid;
process->tid = tid;
process->pid = pid;
process->tid = tid;
+ if (!should_scan_process(opts, process))
+ goto free;
snprintf(path, sizeof(path), "/proc/%d/task/%d/maps", pid, tid);
file = fopen(path, "rb");
snprintf(path, sizeof(path), "/proc/%d/task/%d/maps", pid, tid);
file = fopen(path, "rb");
if (opts->parse_mask & PARSE_DUMP)
return 0;
if (opts->parse_mask & PARSE_DUMP)
return 0;
+ /* Do not add new pages in the tree after the initial scan */
+ opts->parse_mask |= PARSE_NOADD_TREE;
+
while (1) {
pid = get_next_pid(&dir);
if (pid <= 0)
while (1) {
pid = get_next_pid(&dir);
if (pid <= 0)