page-types: decode flags directly from command line
Subsystems (2)
PATCH 1/1 page-types: decode flags directly from command line
Teach page-types to decode page flags directly from the command line.
Why is this useful? For instance, if you're using memory hotplug and see this in /var/log/messages:
kernel: removing from LRU failed 3836dd0/1/1e00000000000400
It would be nice to decode those page flags without staring at the source.
Example usage and output:
linux-2.6/Documentation/vm$ ./page-types -d 0x1e00000000000400
flags page-count MB symbolic-flags long-symbolic-flags
0x1e00000000000400 1 0 __________B_______________________buddy
total 1 0--- page-types.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
---
Documentation/vm/page-types.c +24 -2
@@ -674,6 +674,7 @@ static void usage(void)printf ("page-types [options]\n" " -r|--raw Raw mode, for kernel developers\n" +" -d|--decode flags Decode a single page's flags\n" " -a|--addr addr-spec Walk a range of pages\n" " -b|--bits bits-spec Walk pages with specified bits\n" " -p|--pid pid Walk process address space\n"
@@ -682,10 +683,12 @@ static void usage(void)#endif " -l|--list Show page details in ranges\n" " -L|--list-each Show page details one by one\n" -" -N|--no-summary Don't show summay info\n" +" -N|--no-summary Don't show summary info\n" " -X|--hwpoison hwpoison pages\n" " -x|--unpoison unpoison pages\n" " -h|--help Show this usage message\n" +"flags:\n" +" 0x0000000000000400 A single page's flags, e.g.\n" "addr-spec:\n" " N one page at offset N (unit: pages)\n" " N+M pages range from N to N+M-1\n"
@@ -884,12 +887,28 @@ static void parse_bits_mask(const char *optarg)add_bits_filter (mask, bits); } +static void decode_flags_and_exit (const char *optarg) +{ +uint64_t flags; + + flags =parse_number (optarg); + + opt_list =0 ; + opt_hwpoison =0 ; + opt_unpoison =0 ; + +add_page (0 ,0 , flags); +show_summary (); + +exit (0 ); +}static struct option opts[] = { {"raw" ,0 ,NULL ,'r' }, {"pid" ,1 ,NULL ,'p' }, {"file" ,1 ,NULL ,'f' }, {"addr" ,1 ,NULL ,'a' }, + {"decode" ,1 ,NULL ,'d' }, {"bits" ,1 ,NULL ,'b' }, {"list" ,0 ,NULL ,'l' }, {"list-each" ,0 ,NULL ,'L' },
@@ -907,7 +926,7 @@ int main(int argc, char *argv[]) page_size =getpagesize ();while ((c =getopt_long (argc, argv, -"rp:f:a:b:lLNXxh" , opts,NULL )) !=-1 ) { +"rp:f:a:b:d:lLNXxh" , opts,NULL )) !=-1 ) {switch (c) {case 'r' : opt_raw =1 ;
@@ -924,6 +943,9 @@ int main(int argc, char *argv[])case 'b' :parse_bits_mask (optarg);break ; +case 'd' : +decode_flags_and_exit (optarg); +break ;case 'l' : opt_list =1 ;break ;
Hi Alex,
Quoted 2 lines · Alex Chiang
Teach page-types to decode page flags directly from the command line.
This is good feature to have - I considered adding it, too ;)
Quoted 8 lines
Why is this useful? For instance, if you're using memory hotplug and see this in
/var/log/messages:kernel: removing from LRU failed 3836dd0/1/1e00000000000400It would be nice to decode those page flags without staring at the source.
In fact it's more than decode - encoding is also possible with the _same_ code! So maybe "-d" and help message will not be all that appropriate.
Quoted 6 lines
Example usage and output:
linux-2.6/Documentation/vm$ ./page-types -d
0x1e00000000000400
flags page-count MB symbolic-flags long-symbolic-flags0x1e00000000000400 1 0 __________B_______________________buddy total 1 0
The output is a bit redundant - so does the code. Could you simplify them a bit?
Thanks,
Fengguang
Quoted 79 lines
Signed-off-by Alex Chiang <[email protected]>--- page-types.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)---
Documentation/vm/page-types.c +24
-2@@ -674,6 +674,7 @@ static void usage(void)printf ("page-types [options]\n" " -r|--raw Raw mode, for kernel developers\n" +" -d|--decode flags Decode a single page's flags\n" " -a|--addr addr-spec Walk a range of pages\n" " -b|--bits bits-spec Walk pages with specified bits\n" " -p|--pid pid Walk process address space\n"@@ -682,10 +683,12 @@ static void usage(void)#endif " -l|--list Show page details in ranges\n" " -L|--list-each Show page details one by one\n" -" -N|--no-summary Don't show summay info\n" +" -N|--no-summary Don't show summary info\n" " -X|--hwpoison hwpoison pages\n" " -x|--unpoison unpoison pages\n" " -h|--help Show this usage message\n" +"flags:\n" +" 0x0000000000000400 A single page's flags, e.g.\n" "addr-spec:\n" " N one page at offset N (unit: pages)\n" " N+M pages range from N to N+M-1\n" @@ -884,12 +887,28 @@ static void parse_bits_mask(const char *optarg)add_bits_filter (mask, bits); } +static void decode_flags_and_exit (const char *optarg) +{ +uint64_t flags; + + flags =parse_number (optarg); + + opt_list =0 ; + opt_hwpoison =0 ; + opt_unpoison =0 ; + +add_page (0 ,0 , flags); +show_summary (); + +exit (0 ); +}static struct option opts[] = { {"raw" ,0 ,NULL ,'r' }, {"pid" ,1 ,NULL ,'p' }, {"file" ,1 ,NULL ,'f' }, {"addr" ,1 ,NULL ,'a' }, + {"decode" ,1 ,NULL ,'d' }, {"bits" ,1 ,NULL ,'b' }, {"list" ,0 ,NULL ,'l' }, {"list-each" ,0 ,NULL ,'L' },@@ -907,7 +926,7 @@ int main(int argc, char *argv[]) page_size =getpagesize ();while ((c =getopt_long (argc, argv, -"rp:f:a:b:lLNXxh" , opts,NULL )) !=-1 ) { +"rp:f:a:b:d:lLNXxh" , opts,NULL )) !=-1 ) {switch (c) {case 'r' : opt_raw =1 ;@@ -924,6 +943,9 @@ int main(int argc, char *argv[])case 'b' :parse_bits_mask (optarg);break ; +case 'd' : +decode_flags_and_exit (optarg); +break ;case 'l' : opt_list =1 ;break ;
Hi Fengguang,
* Wu Fengguang <[email protected]>:
Quoted 12 lines · Alex Chiang
Quoted 7 lines
Why is this useful? For instance, if you're using memory hotplug and see this in
/var/log/messages:kernel: removing from LRU failed 3836dd0/1/1e00000000000400It would be nice to decode those page flags without staring at the source.
In fact it's more than decode - encoding is also possible with the _same_ code! So maybe "-d" and help message will not be all that appropriate.
I'm sorry, I don't understand this use case, so I'm not sure what you're asking me to do.
You're saying that a use case would be something like:
./page-types --encode referenced,mmap 0x0000000000000004
?
If that's what you're asking for, I guess I'm not sure why that's so useful, but then again, I'm a vm n00b so there are probably lots of things I don't understand. ;)
Quoted 9 lines
Quoted 6 lines
Example usage and output:
linux-2.6/Documentation/vm$ ./page-types -d
0x1e00000000000400
flags page-count MB symbolic-flags long-symbolic-flags0x1e00000000000400 1 0 __________B_______________________buddy total 1 0The output is a bit redundant - so does the code. Could you simplify them a bit?
Well, the code is redundant, but add_page() / show_summary() is a simple sequence.
In contrast, I think I'd have to modify walk_addr_ranges() and maybe walk_pfn() to do something special when we don't really want to do any address space walking, and simply want to decode/encode some user input.
Maybe I don't understand you fully? Could you give me a better idea of what you're looking for?
As for the output, I'm just reusing show_summary(). Maybe we don't need the flags, page-count, and MB columns, but again, the patch would be more intrusisive because we'd have to teach show_summary() about the special case.
Anyway, I'm happy to make changes closer to what you're looking for, but I'd like some more guidance as to what you're expecting.
Thanks,
/ac
Hi Alex,
It's easier to illustrate the idea with example and code :)
# Documentation/vm/page-types -d 0x10,anon0x0000000000001010 ____D_______a_____________________ dirty,anonymous
+static void describe_flags(const char *optarg)
+{
+ uint64_t flags = parse_flag_names(optarg, 0);
+
+ printf("0x%016llx\t%s\t%s\n",
+ (unsigned long long)flags, + page_flag_name(flags), + page_flag_longname(flags));
+}
+ case 'd':
+ opt_no_summary = 1;
+ describe_flags(optarg);
+ break;
Thanks,
Fengguang
Quoted 61 lines · Alex Chiang
Hi Fengguang,
* Wu Fengguang <[email protected]>:
Quoted 12 lines · Alex Chiang
Quoted 7 lines
Why is this useful? For instance, if you're using memory hotplug and see this in
/var/log/messages:kernel: removing from LRU failed 3836dd0/1/1e00000000000400It would be nice to decode those page flags without staring at the source.
In fact it's more than decode - encoding is also possible with the _same_ code! So maybe "-d" and help message will not be all that appropriate.
I'm sorry, I don't understand this use case, so I'm not sure what you're asking me to do.
You're saying that a use case would be something like:
./page-types --encode referenced,mmap 0x0000000000000004?
If that's what you're asking for, I guess I'm not sure why that's so useful, but then again, I'm a vm n00b so there are probably lots of things I don't understand. ;)
Quoted 9 lines
Quoted 6 lines
Example usage and output:
linux-2.6/Documentation/vm$ ./page-types -d
0x1e00000000000400
flags page-count MB symbolic-flags long-symbolic-flags0x1e00000000000400 1 0 __________B_______________________buddy total 1 0The output is a bit redundant - so does the code. Could you simplify them a bit?
Well, the code is redundant, but
add_page()/show_summary()is a simple sequence.In contrast, I think I'd have to modify
walk_addr_ranges()and maybewalk_pfn()to do something special when we don't really want to do any address space walking, and simply want to decode/encode some user input.Maybe I don't understand you fully? Could you give me a better idea of what you're looking for?
As for the output, I'm just reusing
show_summary(). Maybe we don't need the flags, page-count, and MB columns, but again, the patch would be more intrusisive because we'd have to teachshow_summary()about the special case.Anyway, I'm happy to make changes closer to what you're looking for, but I'd like some more guidance as to what you're expecting.
Thanks,
/ac