Merge tag 'nfs-for-5.16-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[linux-2.6-microblaze.git] / tools / vm / page-types.c
index f62f10c..b1ed76d 100644 (file)
@@ -390,7 +390,7 @@ static void show_page_range(unsigned long voffset, unsigned long offset,
                if (opt_pid)
                        printf("%lx\t", voff);
                if (opt_file)
-                       printf("%lu\t", voff);
+                       printf("%lx\t", voff);
                if (opt_list_cgroup)
                        printf("@%llu\t", (unsigned long long)cgroup0);
                if (opt_list_mapcnt)
@@ -418,7 +418,7 @@ static void show_page(unsigned long voffset, unsigned long offset,
        if (opt_pid)
                printf("%lx\t", voffset);
        if (opt_file)
-               printf("%lu\t", voffset);
+               printf("%lx\t", voffset);
        if (opt_list_cgroup)
                printf("@%llu\t", (unsigned long long)cgroup);
        if (opt_list_mapcnt)
@@ -967,22 +967,19 @@ static struct sigaction sigbus_action = {
        .sa_flags = SA_SIGINFO,
 };
 
-static void walk_file(const char *name, const struct stat *st)
+static void walk_file_range(const char *name, int fd,
+                           unsigned long off, unsigned long end)
 {
        uint8_t vec[PAGEMAP_BATCH];
        uint64_t buf[PAGEMAP_BATCH], flags;
        uint64_t cgroup = 0;
        uint64_t mapcnt = 0;
        unsigned long nr_pages, pfn, i;
-       off_t off, end = st->st_size;
-       int fd;
        ssize_t len;
        void *ptr;
        int first = 1;
 
-       fd = checked_open(name, O_RDONLY|O_NOATIME|O_NOFOLLOW);
-
-       for (off = 0; off < end; off += len) {
+       for (; off < end; off += len) {
                nr_pages = (end - off + page_size - 1) / page_size;
                if (nr_pages > PAGEMAP_BATCH)
                        nr_pages = PAGEMAP_BATCH;
@@ -1037,12 +1034,26 @@ got_sigbus:
                        if (first && opt_list) {
                                first = 0;
                                flush_page_range();
-                               show_file(name, st);
                        }
                        add_page(off / page_size + i, pfn,
                                 flags, cgroup, mapcnt, buf[i]);
                }
        }
+}
+
+static void walk_file(const char *name, const struct stat *st)
+{
+       int i;
+       int fd;
+
+       fd = checked_open(name, O_RDONLY|O_NOATIME|O_NOFOLLOW);
+
+       if (!nr_addr_ranges)
+               add_addr_range(0, st->st_size / page_size);
+
+       for (i = 0; i < nr_addr_ranges; i++)
+               walk_file_range(name, fd, opt_offset[i] * page_size,
+                               (opt_offset[i] + opt_size[i]) * page_size);
 
        close(fd);
 }
@@ -1062,10 +1073,10 @@ int walk_tree(const char *name, const struct stat *st, int type, struct FTW *f)
        return 0;
 }
 
+struct stat st;
+
 static void walk_page_cache(void)
 {
-       struct stat st;
-
        kpageflags_fd = checked_open(opt_kpageflags, O_RDONLY);
        pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY);
        sigaction(SIGBUS, &sigbus_action, NULL);
@@ -1362,6 +1373,11 @@ int main(int argc, char *argv[])
        if (opt_list)
                printf("\n\n");
 
+       if (opt_file) {
+               show_file(opt_file, &st);
+               printf("\n");
+       }
+
        show_summary();
 
        if (opt_list_mapcnt)