~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/trace/postprocess/trace-vmscan-postprocess.pl

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/trace/postprocess/trace-vmscan-postprocess.pl (Version linux-6.12-rc7) and /Documentation/trace/postprocess/trace-vmscan-postprocess.pl (Version linux-6.7.12)


  1 #!/usr/bin/env perl                                 1 #!/usr/bin/env perl
  2 # This is a POC for reading the text represent      2 # This is a POC for reading the text representation of trace output related to
  3 # page reclaim. It makes an attempt to extract      3 # page reclaim. It makes an attempt to extract some high-level information on
  4 # what is going on. The accuracy of the parser      4 # what is going on. The accuracy of the parser may vary
  5 #                                                   5 #
  6 # Example usage: trace-vmscan-postprocess.pl <      6 # Example usage: trace-vmscan-postprocess.pl < /sys/kernel/tracing/trace_pipe
  7 # other options                                     7 # other options
  8 #   --read-procstat     If the trace lacks pro      8 #   --read-procstat     If the trace lacks process info, get it from /proc
  9 #   --ignore-pid        Aggregate processes of      9 #   --ignore-pid        Aggregate processes of the same name together
 10 #                                                  10 #
 11 # Copyright (c) IBM Corporation 2009               11 # Copyright (c) IBM Corporation 2009
 12 # Author: Mel Gorman <mel@csn.ul.ie>                12 # Author: Mel Gorman <mel@csn.ul.ie>
 13 use strict;                                        13 use strict;
 14 use Getopt::Long;                                  14 use Getopt::Long;
 15                                                    15 
 16 # Tracepoint events                                16 # Tracepoint events
 17 use constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN        17 use constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN     => 1;
 18 use constant MM_VMSCAN_DIRECT_RECLAIM_END          18 use constant MM_VMSCAN_DIRECT_RECLAIM_END       => 2;
 19 use constant MM_VMSCAN_KSWAPD_WAKE                 19 use constant MM_VMSCAN_KSWAPD_WAKE              => 3;
 20 use constant MM_VMSCAN_KSWAPD_SLEEP                20 use constant MM_VMSCAN_KSWAPD_SLEEP             => 4;
 21 use constant MM_VMSCAN_LRU_SHRINK_ACTIVE           21 use constant MM_VMSCAN_LRU_SHRINK_ACTIVE        => 5;
 22 use constant MM_VMSCAN_LRU_SHRINK_INACTIVE         22 use constant MM_VMSCAN_LRU_SHRINK_INACTIVE      => 6;
 23 use constant MM_VMSCAN_LRU_ISOLATE                 23 use constant MM_VMSCAN_LRU_ISOLATE              => 7;
 24 use constant MM_VMSCAN_WRITEPAGE_FILE_SYNC         24 use constant MM_VMSCAN_WRITEPAGE_FILE_SYNC      => 8;
 25 use constant MM_VMSCAN_WRITEPAGE_ANON_SYNC         25 use constant MM_VMSCAN_WRITEPAGE_ANON_SYNC      => 9;
 26 use constant MM_VMSCAN_WRITEPAGE_FILE_ASYNC        26 use constant MM_VMSCAN_WRITEPAGE_FILE_ASYNC     => 10;
 27 use constant MM_VMSCAN_WRITEPAGE_ANON_ASYNC        27 use constant MM_VMSCAN_WRITEPAGE_ANON_ASYNC     => 11;
 28 use constant MM_VMSCAN_WRITEPAGE_ASYNC             28 use constant MM_VMSCAN_WRITEPAGE_ASYNC          => 12;
 29 use constant EVENT_UNKNOWN                         29 use constant EVENT_UNKNOWN                      => 13;
 30                                                    30 
 31 # Per-order events                                 31 # Per-order events
 32 use constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PE     32 use constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER => 11;
 33 use constant MM_VMSCAN_WAKEUP_KSWAPD_PERORDER      33 use constant MM_VMSCAN_WAKEUP_KSWAPD_PERORDER   => 12;
 34 use constant MM_VMSCAN_KSWAPD_WAKE_PERORDER        34 use constant MM_VMSCAN_KSWAPD_WAKE_PERORDER     => 13;
 35 use constant HIGH_KSWAPD_REWAKEUP_PERORDER         35 use constant HIGH_KSWAPD_REWAKEUP_PERORDER      => 14;
 36                                                    36 
 37 # Constants used to track state                    37 # Constants used to track state
 38 use constant STATE_DIRECT_BEGIN                    38 use constant STATE_DIRECT_BEGIN                 => 15;
 39 use constant STATE_DIRECT_ORDER                    39 use constant STATE_DIRECT_ORDER                 => 16;
 40 use constant STATE_KSWAPD_BEGIN                    40 use constant STATE_KSWAPD_BEGIN                 => 17;
 41 use constant STATE_KSWAPD_ORDER                    41 use constant STATE_KSWAPD_ORDER                 => 18;
 42                                                    42 
 43 # High-level events extrapolated from tracepoi     43 # High-level events extrapolated from tracepoints
 44 use constant HIGH_DIRECT_RECLAIM_LATENCY           44 use constant HIGH_DIRECT_RECLAIM_LATENCY        => 19;
 45 use constant HIGH_KSWAPD_LATENCY                   45 use constant HIGH_KSWAPD_LATENCY                => 20;
 46 use constant HIGH_KSWAPD_REWAKEUP                  46 use constant HIGH_KSWAPD_REWAKEUP               => 21;
 47 use constant HIGH_NR_SCANNED                       47 use constant HIGH_NR_SCANNED                    => 22;
 48 use constant HIGH_NR_TAKEN                         48 use constant HIGH_NR_TAKEN                      => 23;
 49 use constant HIGH_NR_RECLAIMED                     49 use constant HIGH_NR_RECLAIMED                  => 24;
 50 use constant HIGH_NR_FILE_SCANNED                  50 use constant HIGH_NR_FILE_SCANNED               => 25;
 51 use constant HIGH_NR_ANON_SCANNED                  51 use constant HIGH_NR_ANON_SCANNED               => 26;
 52 use constant HIGH_NR_FILE_RECLAIMED                52 use constant HIGH_NR_FILE_RECLAIMED             => 27;
 53 use constant HIGH_NR_ANON_RECLAIMED                53 use constant HIGH_NR_ANON_RECLAIMED             => 28;
 54                                                    54 
 55 my %perprocesspid;                                 55 my %perprocesspid;
 56 my %perprocess;                                    56 my %perprocess;
 57 my %last_procmap;                                  57 my %last_procmap;
 58 my $opt_ignorepid;                                 58 my $opt_ignorepid;
 59 my $opt_read_procstat;                             59 my $opt_read_procstat;
 60                                                    60 
 61 my $total_wakeup_kswapd;                           61 my $total_wakeup_kswapd;
 62 my ($total_direct_reclaim, $total_direct_nr_sc     62 my ($total_direct_reclaim, $total_direct_nr_scanned);
 63 my ($total_direct_nr_file_scanned, $total_dire     63 my ($total_direct_nr_file_scanned, $total_direct_nr_anon_scanned);
 64 my ($total_direct_latency, $total_kswapd_laten     64 my ($total_direct_latency, $total_kswapd_latency);
 65 my ($total_direct_nr_reclaimed);                   65 my ($total_direct_nr_reclaimed);
 66 my ($total_direct_nr_file_reclaimed, $total_di     66 my ($total_direct_nr_file_reclaimed, $total_direct_nr_anon_reclaimed);
 67 my ($total_direct_writepage_file_sync, $total_     67 my ($total_direct_writepage_file_sync, $total_direct_writepage_file_async);
 68 my ($total_direct_writepage_anon_sync, $total_     68 my ($total_direct_writepage_anon_sync, $total_direct_writepage_anon_async);
 69 my ($total_kswapd_nr_scanned, $total_kswapd_wa     69 my ($total_kswapd_nr_scanned, $total_kswapd_wake);
 70 my ($total_kswapd_nr_file_scanned, $total_kswa     70 my ($total_kswapd_nr_file_scanned, $total_kswapd_nr_anon_scanned);
 71 my ($total_kswapd_writepage_file_sync, $total_     71 my ($total_kswapd_writepage_file_sync, $total_kswapd_writepage_file_async);
 72 my ($total_kswapd_writepage_anon_sync, $total_     72 my ($total_kswapd_writepage_anon_sync, $total_kswapd_writepage_anon_async);
 73 my ($total_kswapd_nr_reclaimed);                   73 my ($total_kswapd_nr_reclaimed);
 74 my ($total_kswapd_nr_file_reclaimed, $total_ks     74 my ($total_kswapd_nr_file_reclaimed, $total_kswapd_nr_anon_reclaimed);
 75                                                    75 
 76 # Catch sigint and exit on request                 76 # Catch sigint and exit on request
 77 my $sigint_report = 0;                             77 my $sigint_report = 0;
 78 my $sigint_exit = 0;                               78 my $sigint_exit = 0;
 79 my $sigint_pending = 0;                            79 my $sigint_pending = 0;
 80 my $sigint_received = 0;                           80 my $sigint_received = 0;
 81 sub sigint_handler {                               81 sub sigint_handler {
 82         my $current_time = time;                   82         my $current_time = time;
 83         if ($current_time - 2 > $sigint_receiv     83         if ($current_time - 2 > $sigint_received) {
 84                 print "SIGINT received, report     84                 print "SIGINT received, report pending. Hit ctrl-c again to exit\n";
 85                 $sigint_report = 1;                85                 $sigint_report = 1;
 86         } else {                                   86         } else {
 87                 if (!$sigint_exit) {               87                 if (!$sigint_exit) {
 88                         print "Second SIGINT r     88                         print "Second SIGINT received quickly, exiting\n";
 89                 }                                  89                 }
 90                 $sigint_exit++;                    90                 $sigint_exit++;
 91         }                                          91         }
 92                                                    92 
 93         if ($sigint_exit > 3) {                    93         if ($sigint_exit > 3) {
 94                 print "Many SIGINTs received,      94                 print "Many SIGINTs received, exiting now without report\n";
 95                 exit;                              95                 exit;
 96         }                                          96         }
 97                                                    97 
 98         $sigint_received = $current_time;          98         $sigint_received = $current_time;
 99         $sigint_pending = 1;                       99         $sigint_pending = 1;
100 }                                                 100 }
101 $SIG{INT} = "sigint_handler";                     101 $SIG{INT} = "sigint_handler";
102                                                   102 
103 # Parse command line options                      103 # Parse command line options
104 GetOptions(                                       104 GetOptions(
105         'ignore-pid'     =>     \$opt_ignorepi    105         'ignore-pid'     =>     \$opt_ignorepid,
106         'read-procstat'  =>     \$opt_read_pro    106         'read-procstat'  =>     \$opt_read_procstat,
107 );                                                107 );
108                                                   108 
109 # Defaults for dynamically discovered regex's     109 # Defaults for dynamically discovered regex's
110 my $regex_direct_begin_default = 'order=([0-9]    110 my $regex_direct_begin_default = 'order=([0-9]*) gfp_flags=([A-Z_|]*)';
111 my $regex_direct_end_default = 'nr_reclaimed=(    111 my $regex_direct_end_default = 'nr_reclaimed=([0-9]*)';
112 my $regex_kswapd_wake_default = 'nid=([0-9]*)     112 my $regex_kswapd_wake_default = 'nid=([0-9]*) order=([0-9]*)';
113 my $regex_kswapd_sleep_default = 'nid=([0-9]*)    113 my $regex_kswapd_sleep_default = 'nid=([0-9]*)';
114 my $regex_wakeup_kswapd_default = 'nid=([0-9]*    114 my $regex_wakeup_kswapd_default = 'nid=([0-9]*) order=([0-9]*) gfp_flags=([A-Z_|]*)';
115 my $regex_lru_isolate_default = 'classzone=([0    115 my $regex_lru_isolate_default = 'classzone=([0-9]*) order=([0-9]*) nr_requested=([0-9]*) nr_scanned=([0-9]*) nr_skipped=([0-9]*) nr_taken=([0-9]*) lru=([a-z_]*)';
116 my $regex_lru_shrink_inactive_default = 'nid=(    116 my $regex_lru_shrink_inactive_default = 'nid=([0-9]*) nr_scanned=([0-9]*) nr_reclaimed=([0-9]*) nr_dirty=([0-9]*) nr_writeback=([0-9]*) nr_congested=([0-9]*) nr_immediate=([0-9]*) nr_activate_anon=([0-9]*) nr_activate_file=([0-9]*) nr_ref_keep=([0-9]*) nr_unmap_fail=([0-9]*) priority=([0-9]*) flags=([A-Z_|]*)';
117 my $regex_lru_shrink_active_default = 'lru=([A    117 my $regex_lru_shrink_active_default = 'lru=([A-Z_]*) nr_taken=([0-9]*) nr_active=([0-9]*) nr_deactivated=([0-9]*) nr_referenced=([0-9]*) priority=([0-9]*) flags=([A-Z_|]*)' ;
118 my $regex_writepage_default = 'page=([0-9a-f]*    118 my $regex_writepage_default = 'page=([0-9a-f]*) pfn=([0-9]*) flags=([A-Z_|]*)';
119                                                   119 
120 # Dyanically discovered regex                     120 # Dyanically discovered regex
121 my $regex_direct_begin;                           121 my $regex_direct_begin;
122 my $regex_direct_end;                             122 my $regex_direct_end;
123 my $regex_kswapd_wake;                            123 my $regex_kswapd_wake;
124 my $regex_kswapd_sleep;                           124 my $regex_kswapd_sleep;
125 my $regex_wakeup_kswapd;                          125 my $regex_wakeup_kswapd;
126 my $regex_lru_isolate;                            126 my $regex_lru_isolate;
127 my $regex_lru_shrink_inactive;                    127 my $regex_lru_shrink_inactive;
128 my $regex_lru_shrink_active;                      128 my $regex_lru_shrink_active;
129 my $regex_writepage;                              129 my $regex_writepage;
130                                                   130 
131 # Static regex used. Specified like this for r    131 # Static regex used. Specified like this for readability and for use with /o
132 #                      (process_pid)     (cpus    132 #                      (process_pid)     (cpus      )   ( time  )   (tpoint    ) (details)
133 my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(    133 my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])(\s*[dX.][Nnp.][Hhs.][0-9a-fA-F.]*|)\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)';
134 my $regex_statname = '[-0-9]*\s\((.*)\).*';       134 my $regex_statname = '[-0-9]*\s\((.*)\).*';
135 my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z    135 my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*';
136                                                   136 
137 sub generate_traceevent_regex {                   137 sub generate_traceevent_regex {
138         my $event = shift;                        138         my $event = shift;
139         my $default = shift;                      139         my $default = shift;
140         my $regex;                                140         my $regex;
141                                                   141 
142         # Read the event format or use the def    142         # Read the event format or use the default
143         if (!open (FORMAT, "/sys/kernel/tracin    143         if (!open (FORMAT, "/sys/kernel/tracing/events/$event/format")) {
144                 print("WARNING: Event $event f    144                 print("WARNING: Event $event format string not found\n");
145                 return $default;                  145                 return $default;
146         } else {                                  146         } else {
147                 my $line;                         147                 my $line;
148                 while (!eof(FORMAT)) {            148                 while (!eof(FORMAT)) {
149                         $line = <FORMAT>;         149                         $line = <FORMAT>;
150                         $line =~ s/, REC->.*//    150                         $line =~ s/, REC->.*//;
151                         if ($line =~ /^print f    151                         if ($line =~ /^print fmt:\s"(.*)".*/) {
152                                 $regex = $1;      152                                 $regex = $1;
153                                 $regex =~ s/%s    153                                 $regex =~ s/%s/\([0-9a-zA-Z|_]*\)/g;
154                                 $regex =~ s/%p    154                                 $regex =~ s/%p/\([0-9a-f]*\)/g;
155                                 $regex =~ s/%d    155                                 $regex =~ s/%d/\([-0-9]*\)/g;
156                                 $regex =~ s/%l    156                                 $regex =~ s/%ld/\([-0-9]*\)/g;
157                                 $regex =~ s/%l    157                                 $regex =~ s/%lu/\([0-9]*\)/g;
158                         }                         158                         }
159                 }                                 159                 }
160         }                                         160         }
161                                                   161 
162         # Can't handle the print_flags stuff b    162         # Can't handle the print_flags stuff but in the context of this
163         # script, it really doesn't matter        163         # script, it really doesn't matter
164         $regex =~ s/\(REC.*\) \? __print_flags    164         $regex =~ s/\(REC.*\) \? __print_flags.*//;
165                                                   165 
166         # Verify fields are in the right order    166         # Verify fields are in the right order
167         my $tuple;                                167         my $tuple;
168         foreach $tuple (split /\s/, $regex) {     168         foreach $tuple (split /\s/, $regex) {
169                 my ($key, $value) = split(/=/,    169                 my ($key, $value) = split(/=/, $tuple);
170                 my $expected = shift;             170                 my $expected = shift;
171                 if ($key ne $expected) {          171                 if ($key ne $expected) {
172                         print("WARNING: Format    172                         print("WARNING: Format not as expected for event $event '$key' != '$expected'\n");
173                         $regex =~ s/$key=\((.*    173                         $regex =~ s/$key=\((.*)\)/$key=$1/;
174                 }                                 174                 }
175         }                                         175         }
176                                                   176 
177         if (defined shift) {                      177         if (defined shift) {
178                 die("Fewer fields than expecte    178                 die("Fewer fields than expected in format");
179         }                                         179         }
180                                                   180 
181         return $regex;                            181         return $regex;
182 }                                                 182 }
183                                                   183 
184 $regex_direct_begin = generate_traceevent_rege    184 $regex_direct_begin = generate_traceevent_regex(
185                         "vmscan/mm_vmscan_dire    185                         "vmscan/mm_vmscan_direct_reclaim_begin",
186                         $regex_direct_begin_de    186                         $regex_direct_begin_default,
187                         "order", "gfp_flags");    187                         "order", "gfp_flags");
188 $regex_direct_end = generate_traceevent_regex(    188 $regex_direct_end = generate_traceevent_regex(
189                         "vmscan/mm_vmscan_dire    189                         "vmscan/mm_vmscan_direct_reclaim_end",
190                         $regex_direct_end_defa    190                         $regex_direct_end_default,
191                         "nr_reclaimed");          191                         "nr_reclaimed");
192 $regex_kswapd_wake = generate_traceevent_regex    192 $regex_kswapd_wake = generate_traceevent_regex(
193                         "vmscan/mm_vmscan_kswa    193                         "vmscan/mm_vmscan_kswapd_wake",
194                         $regex_kswapd_wake_def    194                         $regex_kswapd_wake_default,
195                         "nid", "order");          195                         "nid", "order");
196 $regex_kswapd_sleep = generate_traceevent_rege    196 $regex_kswapd_sleep = generate_traceevent_regex(
197                         "vmscan/mm_vmscan_kswa    197                         "vmscan/mm_vmscan_kswapd_sleep",
198                         $regex_kswapd_sleep_de    198                         $regex_kswapd_sleep_default,
199                         "nid");                   199                         "nid");
200 $regex_wakeup_kswapd = generate_traceevent_reg    200 $regex_wakeup_kswapd = generate_traceevent_regex(
201                         "vmscan/mm_vmscan_wake    201                         "vmscan/mm_vmscan_wakeup_kswapd",
202                         $regex_wakeup_kswapd_d    202                         $regex_wakeup_kswapd_default,
203                         "nid", "order", "gfp_f    203                         "nid", "order", "gfp_flags");
204 $regex_lru_isolate = generate_traceevent_regex    204 $regex_lru_isolate = generate_traceevent_regex(
205                         "vmscan/mm_vmscan_lru_    205                         "vmscan/mm_vmscan_lru_isolate",
206                         $regex_lru_isolate_def    206                         $regex_lru_isolate_default,
207                         "classzone", "order",     207                         "classzone", "order",
208                         "nr_requested", "nr_sc    208                         "nr_requested", "nr_scanned", "nr_skipped", "nr_taken",
209                         "lru");                   209                         "lru");
210 $regex_lru_shrink_inactive = generate_traceeve    210 $regex_lru_shrink_inactive = generate_traceevent_regex(
211                         "vmscan/mm_vmscan_lru_    211                         "vmscan/mm_vmscan_lru_shrink_inactive",
212                         $regex_lru_shrink_inac    212                         $regex_lru_shrink_inactive_default,
213                         "nid", "nr_scanned", "    213                         "nid", "nr_scanned", "nr_reclaimed", "nr_dirty", "nr_writeback",
214                         "nr_congested", "nr_im    214                         "nr_congested", "nr_immediate", "nr_activate_anon",
215                         "nr_activate_file", "n    215                         "nr_activate_file", "nr_ref_keep",
216                         "nr_unmap_fail", "prio    216                         "nr_unmap_fail", "priority", "flags");
217 $regex_lru_shrink_active = generate_traceevent    217 $regex_lru_shrink_active = generate_traceevent_regex(
218                         "vmscan/mm_vmscan_lru_    218                         "vmscan/mm_vmscan_lru_shrink_active",
219                         $regex_lru_shrink_acti    219                         $regex_lru_shrink_active_default,
220                         "nid", "nr_taken", "nr    220                         "nid", "nr_taken", "nr_active", "nr_deactivated", "nr_referenced",
221                         "priority", "flags");     221                         "priority", "flags");
222 $regex_writepage = generate_traceevent_regex(     222 $regex_writepage = generate_traceevent_regex(
223                         "vmscan/mm_vmscan_writ    223                         "vmscan/mm_vmscan_write_folio",
224                         $regex_writepage_defau    224                         $regex_writepage_default,
225                         "page", "pfn", "flags"    225                         "page", "pfn", "flags");
226                                                   226 
227 sub read_statline($) {                            227 sub read_statline($) {
228         my $pid = $_[0];                          228         my $pid = $_[0];
229         my $statline;                             229         my $statline;
230                                                   230 
231         if (open(STAT, "/proc/$pid/stat")) {      231         if (open(STAT, "/proc/$pid/stat")) {
232                 $statline = <STAT>;               232                 $statline = <STAT>;
233                 close(STAT);                      233                 close(STAT);
234         }                                         234         }
235                                                   235 
236         if ($statline eq '') {                    236         if ($statline eq '') {
237                 $statline = "-1 (UNKNOWN_PROCE    237                 $statline = "-1 (UNKNOWN_PROCESS_NAME) R 0";
238         }                                         238         }
239                                                   239 
240         return $statline;                         240         return $statline;
241 }                                                 241 }
242                                                   242 
243 sub guess_process_pid($$) {                       243 sub guess_process_pid($$) {
244         my $pid = $_[0];                          244         my $pid = $_[0];
245         my $statline = $_[1];                     245         my $statline = $_[1];
246                                                   246 
247         if ($pid == 0) {                          247         if ($pid == 0) {
248                 return "swapper-0";               248                 return "swapper-0";
249         }                                         249         }
250                                                   250 
251         if ($statline !~ /$regex_statname/o) {    251         if ($statline !~ /$regex_statname/o) {
252                 die("Failed to math stat line     252                 die("Failed to math stat line for process name :: $statline");
253         }                                         253         }
254         return "$1-$pid";                         254         return "$1-$pid";
255 }                                                 255 }
256                                                   256 
257 # Convert sec.usec timestamp format               257 # Convert sec.usec timestamp format
258 sub timestamp_to_ms($) {                          258 sub timestamp_to_ms($) {
259         my $timestamp = $_[0];                    259         my $timestamp = $_[0];
260                                                   260 
261         my ($sec, $usec) = split (/\./, $times    261         my ($sec, $usec) = split (/\./, $timestamp);
262         return ($sec * 1000) + ($usec / 1000);    262         return ($sec * 1000) + ($usec / 1000);
263 }                                                 263 }
264                                                   264 
265 sub process_events {                              265 sub process_events {
266         my $traceevent;                           266         my $traceevent;
267         my $process_pid;                          267         my $process_pid;
268         my $cpus;                                 268         my $cpus;
269         my $timestamp;                            269         my $timestamp;
270         my $tracepoint;                           270         my $tracepoint;
271         my $details;                              271         my $details;
272         my $statline;                             272         my $statline;
273                                                   273 
274         # Read each line of the event log         274         # Read each line of the event log
275 EVENT_PROCESS:                                    275 EVENT_PROCESS:
276         while ($traceevent = <STDIN>) {           276         while ($traceevent = <STDIN>) {
277                 if ($traceevent =~ /$regex_tra    277                 if ($traceevent =~ /$regex_traceevent/o) {
278                         $process_pid = $1;        278                         $process_pid = $1;
279                         $timestamp = $4;          279                         $timestamp = $4;
280                         $tracepoint = $5;         280                         $tracepoint = $5;
281                                                   281 
282                         $process_pid =~ /(.*)-    282                         $process_pid =~ /(.*)-([0-9]*)$/;
283                         my $process = $1;         283                         my $process = $1;
284                         my $pid = $2;             284                         my $pid = $2;
285                                                   285 
286                         if ($process eq "") {     286                         if ($process eq "") {
287                                 $process = $la    287                                 $process = $last_procmap{$pid};
288                                 $process_pid =    288                                 $process_pid = "$process-$pid";
289                         }                         289                         }
290                         $last_procmap{$pid} =     290                         $last_procmap{$pid} = $process;
291                                                   291 
292                         if ($opt_read_procstat    292                         if ($opt_read_procstat) {
293                                 $statline = re    293                                 $statline = read_statline($pid);
294                                 if ($opt_read_    294                                 if ($opt_read_procstat && $process eq '') {
295                                         $proce    295                                         $process_pid = guess_process_pid($pid, $statline);
296                                 }                 296                                 }
297                         }                         297                         }
298                 } else {                          298                 } else {
299                         next;                     299                         next;
300                 }                                 300                 }
301                                                   301 
302                 # Perl Switch() sucks majorly     302                 # Perl Switch() sucks majorly
303                 if ($tracepoint eq "mm_vmscan_    303                 if ($tracepoint eq "mm_vmscan_direct_reclaim_begin") {
304                         $timestamp = timestamp    304                         $timestamp = timestamp_to_ms($timestamp);
305                         $perprocesspid{$proces    305                         $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}++;
306                         $perprocesspid{$proces    306                         $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN} = $timestamp;
307                                                   307 
308                         $details = $6;            308                         $details = $6;
309                         if ($details !~ /$rege    309                         if ($details !~ /$regex_direct_begin/o) {
310                                 print "WARNING    310                                 print "WARNING: Failed to parse mm_vmscan_direct_reclaim_begin as expected\n";
311                                 print "           311                                 print "         $details\n";
312                                 print "           312                                 print "         $regex_direct_begin\n";
313                                 next;             313                                 next;
314                         }                         314                         }
315                         my $order = $1;           315                         my $order = $1;
316                         $perprocesspid{$proces    316                         $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order]++;
317                         $perprocesspid{$proces    317                         $perprocesspid{$process_pid}->{STATE_DIRECT_ORDER} = $order;
318                 } elsif ($tracepoint eq "mm_vm    318                 } elsif ($tracepoint eq "mm_vmscan_direct_reclaim_end") {
319                         # Count the event itse    319                         # Count the event itself
320                         my $index = $perproces    320                         my $index = $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_END};
321                         $perprocesspid{$proces    321                         $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_END}++;
322                                                   322 
323                         # Record how long dire    323                         # Record how long direct reclaim took this time
324                         if (defined $perproces    324                         if (defined $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN}) {
325                                 $timestamp = t    325                                 $timestamp = timestamp_to_ms($timestamp);
326                                 my $order = $p    326                                 my $order = $perprocesspid{$process_pid}->{STATE_DIRECT_ORDER};
327                                 my $latency =     327                                 my $latency = ($timestamp - $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN});
328                                 $perprocesspid    328                                 $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] = "$order-$latency";
329                         }                         329                         }
330                 } elsif ($tracepoint eq "mm_vm    330                 } elsif ($tracepoint eq "mm_vmscan_kswapd_wake") {
331                         $details = $6;            331                         $details = $6;
332                         if ($details !~ /$rege    332                         if ($details !~ /$regex_kswapd_wake/o) {
333                                 print "WARNING    333                                 print "WARNING: Failed to parse mm_vmscan_kswapd_wake as expected\n";
334                                 print "           334                                 print "         $details\n";
335                                 print "           335                                 print "         $regex_kswapd_wake\n";
336                                 next;             336                                 next;
337                         }                         337                         }
338                                                   338 
339                         my $order = $2;           339                         my $order = $2;
340                         $perprocesspid{$proces    340                         $perprocesspid{$process_pid}->{STATE_KSWAPD_ORDER} = $order;
341                         if (!$perprocesspid{$p    341                         if (!$perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN}) {
342                                 $timestamp = t    342                                 $timestamp = timestamp_to_ms($timestamp);
343                                 $perprocesspid    343                                 $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}++;
344                                 $perprocesspid    344                                 $perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN} = $timestamp;
345                                 $perprocesspid    345                                 $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order]++;
346                         } else {                  346                         } else {
347                                 $perprocesspid    347                                 $perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP}++;
348                                 $perprocesspid    348                                 $perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP_PERORDER}[$order]++;
349                         }                         349                         }
350                 } elsif ($tracepoint eq "mm_vm    350                 } elsif ($tracepoint eq "mm_vmscan_kswapd_sleep") {
351                                                   351 
352                         # Count the event itse    352                         # Count the event itself
353                         my $index = $perproces    353                         my $index = $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_SLEEP};
354                         $perprocesspid{$proces    354                         $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_SLEEP}++;
355                                                   355 
356                         # Record how long kswa    356                         # Record how long kswapd was awake
357                         $timestamp = timestamp    357                         $timestamp = timestamp_to_ms($timestamp);
358                         my $order = $perproces    358                         my $order = $perprocesspid{$process_pid}->{STATE_KSWAPD_ORDER};
359                         my $latency = ($timest    359                         my $latency = ($timestamp - $perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN});
360                         $perprocesspid{$proces    360                         $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index] = "$order-$latency";
361                         $perprocesspid{$proces    361                         $perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN} = 0;
362                 } elsif ($tracepoint eq "mm_vm    362                 } elsif ($tracepoint eq "mm_vmscan_wakeup_kswapd") {
363                         $perprocesspid{$proces    363                         $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}++;
364                                                   364 
365                         $details = $6;            365                         $details = $6;
366                         if ($details !~ /$rege    366                         if ($details !~ /$regex_wakeup_kswapd/o) {
367                                 print "WARNING    367                                 print "WARNING: Failed to parse mm_vmscan_wakeup_kswapd as expected\n";
368                                 print "           368                                 print "         $details\n";
369                                 print "           369                                 print "         $regex_wakeup_kswapd\n";
370                                 next;             370                                 next;
371                         }                         371                         }
372                         my $order = $2;           372                         my $order = $2;
373                         $perprocesspid{$proces    373                         $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]++;
374                 } elsif ($tracepoint eq "mm_vm    374                 } elsif ($tracepoint eq "mm_vmscan_lru_isolate") {
375                         $details = $6;            375                         $details = $6;
376                         if ($details !~ /$rege    376                         if ($details !~ /$regex_lru_isolate/o) {
377                                 print "WARNING    377                                 print "WARNING: Failed to parse mm_vmscan_lru_isolate as expected\n";
378                                 print "           378                                 print "         $details\n";
379                                 print "           379                                 print "         $regex_lru_isolate/o\n";
380                                 next;             380                                 next;
381                         }                         381                         }
382                         my $nr_scanned = $4;      382                         my $nr_scanned = $4;
383                         my $lru = $7;             383                         my $lru = $7;
384                                                   384 
385                         # To closer match vmst    385                         # To closer match vmstat scanning statistics, only count
386                         # inactive lru as scan    386                         # inactive lru as scanning
387                         if ($lru =~ /inactive_    387                         if ($lru =~ /inactive_/) {
388                                 $perprocesspid    388                                 $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
389                                 if ($lru =~ /_    389                                 if ($lru =~ /_file/) {
390                                         $perpr    390                                         $perprocesspid{$process_pid}->{HIGH_NR_FILE_SCANNED} += $nr_scanned;
391                                 } else {          391                                 } else {
392                                         $perpr    392                                         $perprocesspid{$process_pid}->{HIGH_NR_ANON_SCANNED} += $nr_scanned;
393                                 }                 393                                 }
394                         }                         394                         }
395                 } elsif ($tracepoint eq "mm_vm    395                 } elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") {
396                         $details = $6;            396                         $details = $6;
397                         if ($details !~ /$rege    397                         if ($details !~ /$regex_lru_shrink_inactive/o) {
398                                 print "WARNING    398                                 print "WARNING: Failed to parse mm_vmscan_lru_shrink_inactive as expected\n";
399                                 print "           399                                 print "         $details\n";
400                                 print "           400                                 print "         $regex_lru_shrink_inactive/o\n";
401                                 next;             401                                 next;
402                         }                         402                         }
403                                                   403 
404                         my $nr_reclaimed = $3;    404                         my $nr_reclaimed = $3;
405                         my $flags = $13;          405                         my $flags = $13;
406                         my $file = 0;             406                         my $file = 0;
407                         if ($flags =~ /RECLAIM    407                         if ($flags =~ /RECLAIM_WB_FILE/) {
408                                 $file = 1;        408                                 $file = 1;
409                         }                         409                         }
410                         $perprocesspid{$proces    410                         $perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED} += $nr_reclaimed;
411                         if ($file) {              411                         if ($file) {
412                                 $perprocesspid    412                                 $perprocesspid{$process_pid}->{HIGH_NR_FILE_RECLAIMED} += $nr_reclaimed;
413                         } else {                  413                         } else {
414                                 $perprocesspid    414                                 $perprocesspid{$process_pid}->{HIGH_NR_ANON_RECLAIMED} += $nr_reclaimed;
415                         }                         415                         }
416                 } elsif ($tracepoint eq "mm_vm    416                 } elsif ($tracepoint eq "mm_vmscan_writepage") {
417                         $details = $6;            417                         $details = $6;
418                         if ($details !~ /$rege    418                         if ($details !~ /$regex_writepage/o) {
419                                 print "WARNING    419                                 print "WARNING: Failed to parse mm_vmscan_writepage as expected\n";
420                                 print "           420                                 print "         $details\n";
421                                 print "           421                                 print "         $regex_writepage\n";
422                                 next;             422                                 next;
423                         }                         423                         }
424                                                   424 
425                         my $flags = $3;           425                         my $flags = $3;
426                         my $file = 0;             426                         my $file = 0;
427                         my $sync_io = 0;          427                         my $sync_io = 0;
428                         if ($flags =~ /RECLAIM    428                         if ($flags =~ /RECLAIM_WB_FILE/) {
429                                 $file = 1;        429                                 $file = 1;
430                         }                         430                         }
431                         if ($flags =~ /RECLAIM    431                         if ($flags =~ /RECLAIM_WB_SYNC/) {
432                                 $sync_io = 1;     432                                 $sync_io = 1;
433                         }                         433                         }
434                         if ($sync_io) {           434                         if ($sync_io) {
435                                 if ($file) {      435                                 if ($file) {
436                                         $perpr    436                                         $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC}++;
437                                 } else {          437                                 } else {
438                                         $perpr    438                                         $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}++;
439                                 }                 439                                 }
440                         } else {                  440                         } else {
441                                 if ($file) {      441                                 if ($file) {
442                                         $perpr    442                                         $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC}++;
443                                 } else {          443                                 } else {
444                                         $perpr    444                                         $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}++;
445                                 }                 445                                 }
446                         }                         446                         }
447                 } else {                          447                 } else {
448                         $perprocesspid{$proces    448                         $perprocesspid{$process_pid}->{EVENT_UNKNOWN}++;
449                 }                                 449                 }
450                                                   450 
451                 if ($sigint_pending) {            451                 if ($sigint_pending) {
452                         last EVENT_PROCESS;       452                         last EVENT_PROCESS;
453                 }                                 453                 }
454         }                                         454         }
455 }                                                 455 }
456                                                   456 
457 sub dump_stats {                                  457 sub dump_stats {
458         my $hashref = shift;                      458         my $hashref = shift;
459         my %stats = %$hashref;                    459         my %stats = %$hashref;
460                                                   460 
461         # Dump per-process stats                  461         # Dump per-process stats
462         my $process_pid;                          462         my $process_pid;
463         my $max_strlen = 0;                       463         my $max_strlen = 0;
464                                                   464 
465         # Get the maximum process name            465         # Get the maximum process name
466         foreach $process_pid (keys %perprocess    466         foreach $process_pid (keys %perprocesspid) {
467                 my $len = length($process_pid)    467                 my $len = length($process_pid);
468                 if ($len > $max_strlen) {         468                 if ($len > $max_strlen) {
469                         $max_strlen = $len;       469                         $max_strlen = $len;
470                 }                                 470                 }
471         }                                         471         }
472         $max_strlen += 2;                         472         $max_strlen += 2;
473                                                   473 
474         # Work out latencies                      474         # Work out latencies
475         printf("\n") if !$opt_ignorepid;          475         printf("\n") if !$opt_ignorepid;
476         printf("Reclaim latencies expressed as    476         printf("Reclaim latencies expressed as order-latency_in_ms\n") if !$opt_ignorepid;
477         foreach $process_pid (keys %stats) {      477         foreach $process_pid (keys %stats) {
478                                                   478 
479                 if (!$stats{$process_pid}->{HI    479                 if (!$stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[0] &&
480                                 !$stats{$proce    480                                 !$stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[0]) {
481                         next;                     481                         next;
482                 }                                 482                 }
483                                                   483 
484                 printf "%-" . $max_strlen . "s    484                 printf "%-" . $max_strlen . "s ", $process_pid if !$opt_ignorepid;
485                 my $index = 0;                    485                 my $index = 0;
486                 while (defined $stats{$process    486                 while (defined $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] ||
487                         defined $stats{$proces    487                         defined $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]) {
488                                                   488 
489                         if ($stats{$process_pi    489                         if ($stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) {
490                                 printf("%s ",     490                                 printf("%s ", $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) if !$opt_ignorepid;
491                                 my ($dummy, $l    491                                 my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]);
492                                 $total_direct_    492                                 $total_direct_latency += $latency;
493                         } else {                  493                         } else {
494                                 printf("%s ",     494                                 printf("%s ", $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]) if !$opt_ignorepid;
495                                 my ($dummy, $l    495                                 my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]);
496                                 $total_kswapd_    496                                 $total_kswapd_latency += $latency;
497                         }                         497                         }
498                         $index++;                 498                         $index++;
499                 }                                 499                 }
500                 print "\n" if !$opt_ignorepid;    500                 print "\n" if !$opt_ignorepid;
501         }                                         501         }
502                                                   502 
503         # Print out process activity              503         # Print out process activity
504         printf("\n");                             504         printf("\n");
505         printf("%-" . $max_strlen . "s %8s %10    505         printf("%-" . $max_strlen . "s %8s %10s   %8s %8s  %8s %8s %8s %8s\n", "Process", "Direct",  "Wokeup", "Pages",   "Pages",   "Pages",   "Pages",     "Time");
506         printf("%-" . $max_strlen . "s %8s %10    506         printf("%-" . $max_strlen . "s %8s %10s   %8s %8s  %8s %8s %8s %8s\n", "details", "Rclms",   "Kswapd", "Scanned", "Rclmed",  "Sync-IO", "ASync-IO",  "Stalled");
507         foreach $process_pid (keys %stats) {      507         foreach $process_pid (keys %stats) {
508                                                   508 
509                 if (!$stats{$process_pid}->{MM    509                 if (!$stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}) {
510                         next;                     510                         next;
511                 }                                 511                 }
512                                                   512 
513                 $total_direct_reclaim += $stat    513                 $total_direct_reclaim += $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN};
514                 $total_wakeup_kswapd += $stats    514                 $total_wakeup_kswapd += $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD};
515                 $total_direct_nr_scanned += $s    515                 $total_direct_nr_scanned += $stats{$process_pid}->{HIGH_NR_SCANNED};
516                 $total_direct_nr_file_scanned     516                 $total_direct_nr_file_scanned += $stats{$process_pid}->{HIGH_NR_FILE_SCANNED};
517                 $total_direct_nr_anon_scanned     517                 $total_direct_nr_anon_scanned += $stats{$process_pid}->{HIGH_NR_ANON_SCANNED};
518                 $total_direct_nr_reclaimed +=     518                 $total_direct_nr_reclaimed += $stats{$process_pid}->{HIGH_NR_RECLAIMED};
519                 $total_direct_nr_file_reclaime    519                 $total_direct_nr_file_reclaimed += $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED};
520                 $total_direct_nr_anon_reclaime    520                 $total_direct_nr_anon_reclaimed += $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED};
521                 $total_direct_writepage_file_s    521                 $total_direct_writepage_file_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC};
522                 $total_direct_writepage_anon_s    522                 $total_direct_writepage_anon_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC};
523                 $total_direct_writepage_file_a    523                 $total_direct_writepage_file_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC};
524                                                   524 
525                 $total_direct_writepage_anon_a    525                 $total_direct_writepage_anon_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC};
526                                                   526 
527                 my $index = 0;                    527                 my $index = 0;
528                 my $this_reclaim_delay = 0;       528                 my $this_reclaim_delay = 0;
529                 while (defined $stats{$process    529                 while (defined $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) {
530                          my ($dummy, $latency)    530                          my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]);
531                         $this_reclaim_delay +=    531                         $this_reclaim_delay += $latency;
532                         $index++;                 532                         $index++;
533                 }                                 533                 }
534                                                   534 
535                 printf("%-" . $max_strlen . "s    535                 printf("%-" . $max_strlen . "s %8d %10d   %8u %8u  %8u %8u %8.3f",
536                         $process_pid,             536                         $process_pid,
537                         $stats{$process_pid}->    537                         $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN},
538                         $stats{$process_pid}->    538                         $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD},
539                         $stats{$process_pid}->    539                         $stats{$process_pid}->{HIGH_NR_SCANNED},
540                         $stats{$process_pid}->    540                         $stats{$process_pid}->{HIGH_NR_FILE_SCANNED},
541                         $stats{$process_pid}->    541                         $stats{$process_pid}->{HIGH_NR_ANON_SCANNED},
542                         $stats{$process_pid}->    542                         $stats{$process_pid}->{HIGH_NR_RECLAIMED},
543                         $stats{$process_pid}->    543                         $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED},
544                         $stats{$process_pid}->    544                         $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED},
545                         $stats{$process_pid}->    545                         $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC},
546                         $stats{$process_pid}->    546                         $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC},
547                         $this_reclaim_delay /     547                         $this_reclaim_delay / 1000);
548                                                   548 
549                 if ($stats{$process_pid}->{MM_    549                 if ($stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}) {
550                         print "      ";           550                         print "      ";
551                         for (my $order = 0; $o    551                         for (my $order = 0; $order < 20; $order++) {
552                                 my $count = $s    552                                 my $count = $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order];
553                                 if ($count !=     553                                 if ($count != 0) {
554                                         print     554                                         print "direct-$order=$count ";
555                                 }                 555                                 }
556                         }                         556                         }
557                 }                                 557                 }
558                 if ($stats{$process_pid}->{MM_    558                 if ($stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}) {
559                         print "      ";           559                         print "      ";
560                         for (my $order = 0; $o    560                         for (my $order = 0; $order < 20; $order++) {
561                                 my $count = $s    561                                 my $count = $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order];
562                                 if ($count !=     562                                 if ($count != 0) {
563                                         print     563                                         print "wakeup-$order=$count ";
564                                 }                 564                                 }
565                         }                         565                         }
566                 }                                 566                 }
567                                                   567 
568                 print "\n";                       568                 print "\n";
569         }                                         569         }
570                                                   570 
571         # Print out kswapd activity               571         # Print out kswapd activity
572         printf("\n");                             572         printf("\n");
573         printf("%-" . $max_strlen . "s %8s %10    573         printf("%-" . $max_strlen . "s %8s %10s   %8s   %8s %8s %8s\n", "Kswapd",   "Kswapd",  "Order",     "Pages",   "Pages",   "Pages",  "Pages");
574         printf("%-" . $max_strlen . "s %8s %10    574         printf("%-" . $max_strlen . "s %8s %10s   %8s   %8s %8s %8s\n", "Instance", "Wakeups", "Re-wakeup", "Scanned", "Rclmed",  "Sync-IO", "ASync-IO");
575         foreach $process_pid (keys %stats) {      575         foreach $process_pid (keys %stats) {
576                                                   576 
577                 if (!$stats{$process_pid}->{MM    577                 if (!$stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}) {
578                         next;                     578                         next;
579                 }                                 579                 }
580                                                   580 
581                 $total_kswapd_wake += $stats{$    581                 $total_kswapd_wake += $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE};
582                 $total_kswapd_nr_scanned += $s    582                 $total_kswapd_nr_scanned += $stats{$process_pid}->{HIGH_NR_SCANNED};
583                 $total_kswapd_nr_file_scanned     583                 $total_kswapd_nr_file_scanned += $stats{$process_pid}->{HIGH_NR_FILE_SCANNED};
584                 $total_kswapd_nr_anon_scanned     584                 $total_kswapd_nr_anon_scanned += $stats{$process_pid}->{HIGH_NR_ANON_SCANNED};
585                 $total_kswapd_nr_reclaimed +=     585                 $total_kswapd_nr_reclaimed += $stats{$process_pid}->{HIGH_NR_RECLAIMED};
586                 $total_kswapd_nr_file_reclaime    586                 $total_kswapd_nr_file_reclaimed += $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED};
587                 $total_kswapd_nr_anon_reclaime    587                 $total_kswapd_nr_anon_reclaimed += $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED};
588                 $total_kswapd_writepage_file_s    588                 $total_kswapd_writepage_file_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC};
589                 $total_kswapd_writepage_anon_s    589                 $total_kswapd_writepage_anon_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC};
590                 $total_kswapd_writepage_file_a    590                 $total_kswapd_writepage_file_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC};
591                 $total_kswapd_writepage_anon_a    591                 $total_kswapd_writepage_anon_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC};
592                                                   592 
593                 printf("%-" . $max_strlen . "s    593                 printf("%-" . $max_strlen . "s %8d %10d   %8u %8u  %8i %8u",
594                         $process_pid,             594                         $process_pid,
595                         $stats{$process_pid}->    595                         $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE},
596                         $stats{$process_pid}->    596                         $stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP},
597                         $stats{$process_pid}->    597                         $stats{$process_pid}->{HIGH_NR_SCANNED},
598                         $stats{$process_pid}->    598                         $stats{$process_pid}->{HIGH_NR_FILE_SCANNED},
599                         $stats{$process_pid}->    599                         $stats{$process_pid}->{HIGH_NR_ANON_SCANNED},
600                         $stats{$process_pid}->    600                         $stats{$process_pid}->{HIGH_NR_RECLAIMED},
601                         $stats{$process_pid}->    601                         $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED},
602                         $stats{$process_pid}->    602                         $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED},
603                         $stats{$process_pid}->    603                         $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC},
604                         $stats{$process_pid}->    604                         $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC});
605                                                   605 
606                 if ($stats{$process_pid}->{MM_    606                 if ($stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}) {
607                         print "      ";           607                         print "      ";
608                         for (my $order = 0; $o    608                         for (my $order = 0; $order < 20; $order++) {
609                                 my $count = $s    609                                 my $count = $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order];
610                                 if ($count !=     610                                 if ($count != 0) {
611                                         print     611                                         print "wake-$order=$count ";
612                                 }                 612                                 }
613                         }                         613                         }
614                 }                                 614                 }
615                 if ($stats{$process_pid}->{HIG    615                 if ($stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP}) {
616                         print "      ";           616                         print "      ";
617                         for (my $order = 0; $o    617                         for (my $order = 0; $order < 20; $order++) {
618                                 my $count = $s    618                                 my $count = $stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP_PERORDER}[$order];
619                                 if ($count !=     619                                 if ($count != 0) {
620                                         print     620                                         print "rewake-$order=$count ";
621                                 }                 621                                 }
622                         }                         622                         }
623                 }                                 623                 }
624                 printf("\n");                     624                 printf("\n");
625         }                                         625         }
626                                                   626 
627         # Print out summaries                     627         # Print out summaries
628         $total_direct_latency /= 1000;            628         $total_direct_latency /= 1000;
629         $total_kswapd_latency /= 1000;            629         $total_kswapd_latency /= 1000;
630         print "\nSummary\n";                      630         print "\nSummary\n";
631         print "Direct reclaims:                   631         print "Direct reclaims:                         $total_direct_reclaim\n";
632         print "Direct reclaim pages scanned:      632         print "Direct reclaim pages scanned:            $total_direct_nr_scanned\n";
633         print "Direct reclaim file pages scann    633         print "Direct reclaim file pages scanned:       $total_direct_nr_file_scanned\n";
634         print "Direct reclaim anon pages scann    634         print "Direct reclaim anon pages scanned:       $total_direct_nr_anon_scanned\n";
635         print "Direct reclaim pages reclaimed:    635         print "Direct reclaim pages reclaimed:          $total_direct_nr_reclaimed\n";
636         print "Direct reclaim file pages recla    636         print "Direct reclaim file pages reclaimed:     $total_direct_nr_file_reclaimed\n";
637         print "Direct reclaim anon pages recla    637         print "Direct reclaim anon pages reclaimed:     $total_direct_nr_anon_reclaimed\n";
638         print "Direct reclaim write file sync     638         print "Direct reclaim write file sync I/O:      $total_direct_writepage_file_sync\n";
639         print "Direct reclaim write anon sync     639         print "Direct reclaim write anon sync I/O:      $total_direct_writepage_anon_sync\n";
640         print "Direct reclaim write file async    640         print "Direct reclaim write file async I/O:     $total_direct_writepage_file_async\n";
641         print "Direct reclaim write anon async    641         print "Direct reclaim write anon async I/O:     $total_direct_writepage_anon_async\n";
642         print "Wake kswapd requests:              642         print "Wake kswapd requests:                    $total_wakeup_kswapd\n";
643         printf "Time stalled direct reclaim:      643         printf "Time stalled direct reclaim:            %-1.2f seconds\n", $total_direct_latency;
644         print "\n";                               644         print "\n";
645         print "Kswapd wakeups:                    645         print "Kswapd wakeups:                          $total_kswapd_wake\n";
646         print "Kswapd pages scanned:              646         print "Kswapd pages scanned:                    $total_kswapd_nr_scanned\n";
647         print "Kswapd file pages scanned:         647         print "Kswapd file pages scanned:               $total_kswapd_nr_file_scanned\n";
648         print "Kswapd anon pages scanned:         648         print "Kswapd anon pages scanned:               $total_kswapd_nr_anon_scanned\n";
649         print "Kswapd pages reclaimed:            649         print "Kswapd pages reclaimed:                  $total_kswapd_nr_reclaimed\n";
650         print "Kswapd file pages reclaimed:       650         print "Kswapd file pages reclaimed:             $total_kswapd_nr_file_reclaimed\n";
651         print "Kswapd anon pages reclaimed:       651         print "Kswapd anon pages reclaimed:             $total_kswapd_nr_anon_reclaimed\n";
652         print "Kswapd reclaim write file sync     652         print "Kswapd reclaim write file sync I/O:      $total_kswapd_writepage_file_sync\n";
653         print "Kswapd reclaim write anon sync     653         print "Kswapd reclaim write anon sync I/O:      $total_kswapd_writepage_anon_sync\n";
654         print "Kswapd reclaim write file async    654         print "Kswapd reclaim write file async I/O:     $total_kswapd_writepage_file_async\n";
655         print "Kswapd reclaim write anon async    655         print "Kswapd reclaim write anon async I/O:     $total_kswapd_writepage_anon_async\n";
656         printf "Time kswapd awake:                656         printf "Time kswapd awake:                      %-1.2f seconds\n", $total_kswapd_latency;
657 }                                                 657 }
658                                                   658 
659 sub aggregate_perprocesspid() {                   659 sub aggregate_perprocesspid() {
660         my $process_pid;                          660         my $process_pid;
661         my $process;                              661         my $process;
662         undef %perprocess;                        662         undef %perprocess;
663                                                   663 
664         foreach $process_pid (keys %perprocess    664         foreach $process_pid (keys %perprocesspid) {
665                 $process = $process_pid;          665                 $process = $process_pid;
666                 $process =~ s/-([0-9])*$//;       666                 $process =~ s/-([0-9])*$//;
667                 if ($process eq '') {             667                 if ($process eq '') {
668                         $process = "NO_PROCESS    668                         $process = "NO_PROCESS_NAME";
669                 }                                 669                 }
670                                                   670 
671                 $perprocess{$process}->{MM_VMS    671                 $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN} += $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN};
672                 $perprocess{$process}->{MM_VMS    672                 $perprocess{$process}->{MM_VMSCAN_KSWAPD_WAKE} += $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE};
673                 $perprocess{$process}->{MM_VMS    673                 $perprocess{$process}->{MM_VMSCAN_WAKEUP_KSWAPD} += $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD};
674                 $perprocess{$process}->{HIGH_K    674                 $perprocess{$process}->{HIGH_KSWAPD_REWAKEUP} += $perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP};
675                 $perprocess{$process}->{HIGH_N    675                 $perprocess{$process}->{HIGH_NR_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_SCANNED};
676                 $perprocess{$process}->{HIGH_N    676                 $perprocess{$process}->{HIGH_NR_FILE_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_FILE_SCANNED};
677                 $perprocess{$process}->{HIGH_N    677                 $perprocess{$process}->{HIGH_NR_ANON_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_ANON_SCANNED};
678                 $perprocess{$process}->{HIGH_N    678                 $perprocess{$process}->{HIGH_NR_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED};
679                 $perprocess{$process}->{HIGH_N    679                 $perprocess{$process}->{HIGH_NR_FILE_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_FILE_RECLAIMED};
680                 $perprocess{$process}->{HIGH_N    680                 $perprocess{$process}->{HIGH_NR_ANON_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_ANON_RECLAIMED};
681                 $perprocess{$process}->{MM_VMS    681                 $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC};
682                 $perprocess{$process}->{MM_VMS    682                 $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC};
683                 $perprocess{$process}->{MM_VMS    683                 $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC};
684                 $perprocess{$process}->{MM_VMS    684                 $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC};
685                                                   685 
686                 for (my $order = 0; $order < 2    686                 for (my $order = 0; $order < 20; $order++) {
687                         $perprocess{$process}-    687                         $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order];
688                         $perprocess{$process}-    688                         $perprocess{$process}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order];
689                         $perprocess{$process}-    689                         $perprocess{$process}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order];
690                                                   690 
691                 }                                 691                 }
692                                                   692 
693                 # Aggregate direct reclaim lat    693                 # Aggregate direct reclaim latencies
694                 my $wr_index = $perprocess{$pr    694                 my $wr_index = $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END};
695                 my $rd_index = 0;                 695                 my $rd_index = 0;
696                 while (defined $perprocesspid{    696                 while (defined $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$rd_index]) {
697                         $perprocess{$process}-    697                         $perprocess{$process}->{HIGH_DIRECT_RECLAIM_LATENCY}[$wr_index] = $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$rd_index];
698                         $rd_index++;              698                         $rd_index++;
699                         $wr_index++;              699                         $wr_index++;
700                 }                                 700                 }
701                 $perprocess{$process}->{MM_VMS    701                 $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END} = $wr_index;
702                                                   702 
703                 # Aggregate kswapd latencies      703                 # Aggregate kswapd latencies
704                 my $wr_index = $perprocess{$pr    704                 my $wr_index = $perprocess{$process}->{MM_VMSCAN_KSWAPD_SLEEP};
705                 my $rd_index = 0;                 705                 my $rd_index = 0;
706                 while (defined $perprocesspid{    706                 while (defined $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$rd_index]) {
707                         $perprocess{$process}-    707                         $perprocess{$process}->{HIGH_KSWAPD_LATENCY}[$wr_index] = $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$rd_index];
708                         $rd_index++;              708                         $rd_index++;
709                         $wr_index++;              709                         $wr_index++;
710                 }                                 710                 }
711                 $perprocess{$process}->{MM_VMS    711                 $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END} = $wr_index;
712         }                                         712         }
713 }                                                 713 }
714                                                   714 
715 sub report() {                                    715 sub report() {
716         if (!$opt_ignorepid) {                    716         if (!$opt_ignorepid) {
717                 dump_stats(\%perprocesspid);      717                 dump_stats(\%perprocesspid);
718         } else {                                  718         } else {
719                 aggregate_perprocesspid();        719                 aggregate_perprocesspid();
720                 dump_stats(\%perprocess);         720                 dump_stats(\%perprocess);
721         }                                         721         }
722 }                                                 722 }
723                                                   723 
724 # Process events or signals until neither is a    724 # Process events or signals until neither is available
725 sub signal_loop() {                               725 sub signal_loop() {
726         my $sigint_processed;                     726         my $sigint_processed;
727         do {                                      727         do {
728                 $sigint_processed = 0;            728                 $sigint_processed = 0;
729                 process_events();                 729                 process_events();
730                                                   730 
731                 # Handle pending signals if an    731                 # Handle pending signals if any
732                 if ($sigint_pending) {            732                 if ($sigint_pending) {
733                         my $current_time = tim    733                         my $current_time = time;
734                                                   734 
735                         if ($sigint_exit) {       735                         if ($sigint_exit) {
736                                 print "Receive    736                                 print "Received exit signal\n";
737                                 $sigint_pendin    737                                 $sigint_pending = 0;
738                         }                         738                         }
739                         if ($sigint_report) {     739                         if ($sigint_report) {
740                                 if ($current_t    740                                 if ($current_time >= $sigint_received + 2) {
741                                         report    741                                         report();
742                                         $sigin    742                                         $sigint_report = 0;
743                                         $sigin    743                                         $sigint_pending = 0;
744                                         $sigin    744                                         $sigint_processed = 1;
745                                 }                 745                                 }
746                         }                         746                         }
747                 }                                 747                 }
748         } while ($sigint_pending || $sigint_pr    748         } while ($sigint_pending || $sigint_processed);
749 }                                                 749 }
750                                                   750 
751 signal_loop();                                    751 signal_loop();
752 report();                                         752 report();
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php