diff options
| author | David Rientjes <rientjes@google.com> | 2018-01-31 19:21:23 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 20:18:40 -0500 |
| commit | c7905f200225d4257536f19b11d18f598fee5f44 (patch) | |
| tree | 4eb2efaa0d330e6ed9b53e4f943eb7b776111389 /tools/vm | |
| parent | e02a9f048ef79a411904bef075fd3ce4204052a9 (diff) | |
tools, vm: new option to specify kpageflags file
page-types currently hardcodes /proc/kpageflags as the file to parse.
This works when using the tool to examine the state of pageflags on the
same system, but does not allow storing a snapshot of pageflags at a
given time to debug issues nor on a different system.
This allows the user to specify a saved version of kpageflags with a new
page-types -F option.
[akpm@linux-foundation.org: add "filename" to fix usage() string]
[rientjes@google.com: fix layout]
Link: http://lkml.kernel.org/r/alpine.DEB.2.10.1801301840050.140969@chino.kir.corp.google.com
Link: http://lkml.kernel.org/r/alpine.DEB.2.10.1801301458180.153857@chino.kir.corp.google.com
Signed-off-by: David Rientjes <rientjes@google.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools/vm')
| -rw-r--r-- | tools/vm/page-types.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c index e92903fc7113..a8783f48f77f 100644 --- a/tools/vm/page-types.c +++ b/tools/vm/page-types.c | |||
| @@ -169,9 +169,10 @@ static int opt_raw; /* for kernel developers */ | |||
| 169 | static int opt_list; /* list pages (in ranges) */ | 169 | static int opt_list; /* list pages (in ranges) */ |
| 170 | static int opt_no_summary; /* don't show summary */ | 170 | static int opt_no_summary; /* don't show summary */ |
| 171 | static pid_t opt_pid; /* process to walk */ | 171 | static pid_t opt_pid; /* process to walk */ |
| 172 | const char * opt_file; /* file or directory path */ | 172 | const char *opt_file; /* file or directory path */ |
| 173 | static uint64_t opt_cgroup; /* cgroup inode */ | 173 | static uint64_t opt_cgroup; /* cgroup inode */ |
| 174 | static int opt_list_cgroup;/* list page cgroup */ | 174 | static int opt_list_cgroup;/* list page cgroup */ |
| 175 | static const char *opt_kpageflags;/* kpageflags file to parse */ | ||
| 175 | 176 | ||
| 176 | #define MAX_ADDR_RANGES 1024 | 177 | #define MAX_ADDR_RANGES 1024 |
| 177 | static int nr_addr_ranges; | 178 | static int nr_addr_ranges; |
| @@ -258,7 +259,7 @@ static int checked_open(const char *pathname, int flags) | |||
| 258 | * pagemap/kpageflags routines | 259 | * pagemap/kpageflags routines |
| 259 | */ | 260 | */ |
| 260 | 261 | ||
| 261 | static unsigned long do_u64_read(int fd, char *name, | 262 | static unsigned long do_u64_read(int fd, const char *name, |
| 262 | uint64_t *buf, | 263 | uint64_t *buf, |
| 263 | unsigned long index, | 264 | unsigned long index, |
| 264 | unsigned long count) | 265 | unsigned long count) |
| @@ -283,7 +284,7 @@ static unsigned long kpageflags_read(uint64_t *buf, | |||
| 283 | unsigned long index, | 284 | unsigned long index, |
| 284 | unsigned long pages) | 285 | unsigned long pages) |
| 285 | { | 286 | { |
| 286 | return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages); | 287 | return do_u64_read(kpageflags_fd, opt_kpageflags, buf, index, pages); |
| 287 | } | 288 | } |
| 288 | 289 | ||
| 289 | static unsigned long kpagecgroup_read(uint64_t *buf, | 290 | static unsigned long kpagecgroup_read(uint64_t *buf, |
| @@ -293,7 +294,7 @@ static unsigned long kpagecgroup_read(uint64_t *buf, | |||
| 293 | if (kpagecgroup_fd < 0) | 294 | if (kpagecgroup_fd < 0) |
| 294 | return pages; | 295 | return pages; |
| 295 | 296 | ||
| 296 | return do_u64_read(kpagecgroup_fd, PROC_KPAGEFLAGS, buf, index, pages); | 297 | return do_u64_read(kpagecgroup_fd, opt_kpageflags, buf, index, pages); |
| 297 | } | 298 | } |
| 298 | 299 | ||
| 299 | static unsigned long pagemap_read(uint64_t *buf, | 300 | static unsigned long pagemap_read(uint64_t *buf, |
| @@ -743,7 +744,7 @@ static void walk_addr_ranges(void) | |||
| 743 | { | 744 | { |
| 744 | int i; | 745 | int i; |
| 745 | 746 | ||
| 746 | kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY); | 747 | kpageflags_fd = checked_open(opt_kpageflags, O_RDONLY); |
| 747 | 748 | ||
| 748 | if (!nr_addr_ranges) | 749 | if (!nr_addr_ranges) |
| 749 | add_addr_range(0, ULONG_MAX); | 750 | add_addr_range(0, ULONG_MAX); |
| @@ -790,6 +791,7 @@ static void usage(void) | |||
| 790 | " -N|--no-summary Don't show summary info\n" | 791 | " -N|--no-summary Don't show summary info\n" |
| 791 | " -X|--hwpoison hwpoison pages\n" | 792 | " -X|--hwpoison hwpoison pages\n" |
| 792 | " -x|--unpoison unpoison pages\n" | 793 | " -x|--unpoison unpoison pages\n" |
| 794 | " -F|--kpageflags filename kpageflags file to parse\n" | ||
| 793 | " -h|--help Show this usage message\n" | 795 | " -h|--help Show this usage message\n" |
| 794 | "flags:\n" | 796 | "flags:\n" |
| 795 | " 0x10 bitfield format, e.g.\n" | 797 | " 0x10 bitfield format, e.g.\n" |
| @@ -1013,7 +1015,7 @@ static void walk_page_cache(void) | |||
| 1013 | { | 1015 | { |
| 1014 | struct stat st; | 1016 | struct stat st; |
| 1015 | 1017 | ||
| 1016 | kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY); | 1018 | kpageflags_fd = checked_open(opt_kpageflags, O_RDONLY); |
| 1017 | pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY); | 1019 | pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY); |
| 1018 | sigaction(SIGBUS, &sigbus_action, NULL); | 1020 | sigaction(SIGBUS, &sigbus_action, NULL); |
| 1019 | 1021 | ||
| @@ -1164,6 +1166,11 @@ static void parse_bits_mask(const char *optarg) | |||
| 1164 | add_bits_filter(mask, bits); | 1166 | add_bits_filter(mask, bits); |
| 1165 | } | 1167 | } |
| 1166 | 1168 | ||
| 1169 | static void parse_kpageflags(const char *name) | ||
| 1170 | { | ||
| 1171 | opt_kpageflags = name; | ||
| 1172 | } | ||
| 1173 | |||
| 1167 | static void describe_flags(const char *optarg) | 1174 | static void describe_flags(const char *optarg) |
| 1168 | { | 1175 | { |
| 1169 | uint64_t flags = parse_flag_names(optarg, 0); | 1176 | uint64_t flags = parse_flag_names(optarg, 0); |
| @@ -1188,6 +1195,7 @@ static const struct option opts[] = { | |||
| 1188 | { "no-summary", 0, NULL, 'N' }, | 1195 | { "no-summary", 0, NULL, 'N' }, |
| 1189 | { "hwpoison" , 0, NULL, 'X' }, | 1196 | { "hwpoison" , 0, NULL, 'X' }, |
| 1190 | { "unpoison" , 0, NULL, 'x' }, | 1197 | { "unpoison" , 0, NULL, 'x' }, |
| 1198 | { "kpageflags", 0, NULL, 'F' }, | ||
| 1191 | { "help" , 0, NULL, 'h' }, | 1199 | { "help" , 0, NULL, 'h' }, |
| 1192 | { NULL , 0, NULL, 0 } | 1200 | { NULL , 0, NULL, 0 } |
| 1193 | }; | 1201 | }; |
| @@ -1199,7 +1207,7 @@ int main(int argc, char *argv[]) | |||
| 1199 | page_size = getpagesize(); | 1207 | page_size = getpagesize(); |
| 1200 | 1208 | ||
| 1201 | while ((c = getopt_long(argc, argv, | 1209 | while ((c = getopt_long(argc, argv, |
| 1202 | "rp:f:a:b:d:c:ClLNXxh", opts, NULL)) != -1) { | 1210 | "rp:f:a:b:d:c:ClLNXxF:h", opts, NULL)) != -1) { |
| 1203 | switch (c) { | 1211 | switch (c) { |
| 1204 | case 'r': | 1212 | case 'r': |
| 1205 | opt_raw = 1; | 1213 | opt_raw = 1; |
| @@ -1242,6 +1250,9 @@ int main(int argc, char *argv[]) | |||
| 1242 | opt_unpoison = 1; | 1250 | opt_unpoison = 1; |
| 1243 | prepare_hwpoison_fd(); | 1251 | prepare_hwpoison_fd(); |
| 1244 | break; | 1252 | break; |
| 1253 | case 'F': | ||
| 1254 | parse_kpageflags(optarg); | ||
| 1255 | break; | ||
| 1245 | case 'h': | 1256 | case 'h': |
| 1246 | usage(); | 1257 | usage(); |
| 1247 | exit(0); | 1258 | exit(0); |
| @@ -1251,6 +1262,9 @@ int main(int argc, char *argv[]) | |||
| 1251 | } | 1262 | } |
| 1252 | } | 1263 | } |
| 1253 | 1264 | ||
| 1265 | if (!opt_kpageflags) | ||
| 1266 | opt_kpageflags = PROC_KPAGEFLAGS; | ||
| 1267 | |||
| 1254 | if (opt_cgroup || opt_list_cgroup) | 1268 | if (opt_cgroup || opt_list_cgroup) |
| 1255 | kpagecgroup_fd = checked_open(PROC_KPAGECGROUP, O_RDONLY); | 1269 | kpagecgroup_fd = checked_open(PROC_KPAGECGROUP, O_RDONLY); |
| 1256 | 1270 | ||
