]> git.itanic.dy.fi Git - scan-pagemap/commitdiff
Parser: Read kpageflags and kpagecount
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 29 Aug 2010 10:21:38 +0000 (13:21 +0300)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 29 Aug 2010 10:21:38 +0000 (13:21 +0300)
Read the /proc/kpageflags and /proc/kpagecount data for every page
frame.

Signed-off-by: Timo Kokkonen <kaapeli@itanic.dy.fi>
main.c
pagemap.h
parse.c
parse.h

diff --git a/main.c b/main.c
index c28ed2a8a7320b4c413a675b53162daf8a29f439..9fc6d7114b081699c73051585b08d42a2f06f7b4 100644 (file)
--- a/main.c
+++ b/main.c
@@ -130,6 +130,8 @@ int main(int argc, char *argv[])
        if (scan_all_pids(&pf, &process_list, &opts))
                return 1;
 
+       update_kpageflags(&pf);
+
        if (opts.parse_mask & PARSE_DUMP)
                dump_process_maps(&pf, &process_list, &opts);
        else
index 0eb280cd35673b0649003cbca97bcdf4b61b2803..ffc55efd5ffb2f60da6b91b6233234968148a3a1 100644 (file)
--- a/pagemap.h
+++ b/pagemap.h
@@ -26,6 +26,8 @@ struct pageframe {
        struct list_head ml;    /* List of mappings which refer to this pfn */
 
        unsigned long long pf;  /* page frame entry from /proc/pid/pagemap */
+       unsigned long long kpageflags;
+       unsigned long long kpagecount;
 
        int refcount;
 };
diff --git a/parse.c b/parse.c
index e21935f4543c753ce0b4194e4d9ffe61f8d60a95..67fc0f781dd0e2b284bdc598e872aba010d1e747 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -1,7 +1,11 @@
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include "parse.h"
 #include "pagemap.h"
@@ -385,3 +389,78 @@ int scan_all_pids(struct pageframe *pf, struct process *process_list,
 
        return 0;
 }
+
+struct kpageflag_data {
+       struct bintree_ops ops;
+
+       int kpageflags_fd;
+       int kpagecount_fd;
+};
+
+#define bintree_ops_to_kpfd(bintree_ops)                       \
+       container_of((bintree_ops), struct kpageflag_data, ops)
+
+static void _update_kpageflags(struct bintree *bt, struct bintree_ops *ops)
+{
+       struct pageframe *pf = tree_to_pageframe(bt);
+       struct kpageflag_data *kpfd = bintree_ops_to_kpfd(ops);
+       int ret, error;
+       long int pfnn = pfn(pf) * sizeof(pf->kpageflags);
+
+       ret = lseek(kpfd->kpageflags_fd, pfnn, SEEK_SET);
+       if (ret < 0) {
+               error = errno;
+               fprintf(stderr, "Error seeking to %lx: %s\n",
+                       pfnn, strerror(error));
+               return;
+       }
+
+       ret = read(kpfd->kpageflags_fd, &pf->kpageflags,
+               sizeof(pf->kpageflags));
+       if (ret < 0) {
+               error = errno;
+               fprintf(stderr, "Error reading from %llx: %s\n",
+                       pf->pf * sizeof(pf->kpageflags),
+                       strerror(error));
+               return;
+       }
+
+       ret = lseek(kpfd->kpagecount_fd, pfnn, SEEK_SET);
+       if (ret < 0) {
+               error = errno;
+               fprintf(stderr, "Error seeking to %lx: %s\n",
+                       pfnn, strerror(error));
+               return;
+       }
+
+       ret = read(kpfd->kpagecount_fd, &pf->kpagecount,
+               sizeof(pf->kpagecount));
+       if (ret < 0) {
+               error = errno;
+               fprintf(stderr, "Error reading from %llx: %s\n",
+                       pf->pf * sizeof(pf->kpagecount),
+                       strerror(error));
+               return;
+       }
+}
+
+int update_kpageflags(struct pageframe *pf)
+{
+       struct kpageflag_data kpfd = {
+               .ops = {
+                       .callback = _update_kpageflags,
+               },
+               .kpageflags_fd = open("/proc/kpageflags", O_RDONLY),
+               .kpagecount_fd = open("/proc/kpagecount", O_RDONLY),
+       };
+
+       if (kpfd.kpageflags_fd == -1 || kpfd.kpagecount_fd == -1)
+               return -1;
+
+       bintree_walk(&pf->tree, &kpfd.ops);
+
+       close(kpfd.kpageflags_fd);
+       close(kpfd.kpagecount_fd);
+
+       return 0;
+}
diff --git a/parse.h b/parse.h
index 83d0bcd09bd528ca040a8f9918514f532711e30b..d915ce3516a09db8df2365d49e580406efc269ef 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -5,5 +5,6 @@
 
 int scan_all_pids(struct pageframe *pf, struct process *process_list,
                struct parse_opts *opts);
+int update_kpageflags(struct pageframe *pf);
 
 #endif