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

TOMOYO Linux Cross Reference
Linux/Documentation/trace/postprocess/trace-pagealloc-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-pagealloc-postprocess.pl (Architecture m68k) and /Documentation/trace/postprocess/trace-pagealloc-postprocess.pl (Architecture i386)


  1 #!/usr/bin/env perl                                 1 #!/usr/bin/env perl
  2 # This is a POC (proof of concept or piece of       2 # This is a POC (proof of concept or piece of crap, take your pick) for reading the
  3 # text representation of trace output related       3 # text representation of trace output related to page allocation. It makes an attempt
  4 # to extract some high-level information on wh      4 # to extract some high-level information on what is going on. The accuracy of the parser
  5 # may vary considerably                             5 # may vary considerably
  6 #                                                   6 #
  7 # Example usage: trace-pagealloc-postprocess.p      7 # Example usage: trace-pagealloc-postprocess.pl < /sys/kernel/tracing/trace_pipe
  8 # other options                                     8 # other options
  9 #   --prepend-parent    Report on the parent p      9 #   --prepend-parent    Report on the parent proc and PID
 10 #   --read-procstat     If the trace lacks pro     10 #   --read-procstat     If the trace lacks process info, get it from /proc
 11 #   --ignore-pid        Aggregate processes of     11 #   --ignore-pid        Aggregate processes of the same name together
 12 #                                                  12 #
 13 # Copyright (c) IBM Corporation 2009               13 # Copyright (c) IBM Corporation 2009
 14 # Author: Mel Gorman <mel@csn.ul.ie>                14 # Author: Mel Gorman <mel@csn.ul.ie>
 15 use strict;                                        15 use strict;
 16 use Getopt::Long;                                  16 use Getopt::Long;
 17                                                    17 
 18 # Tracepoint events                                18 # Tracepoint events
 19 use constant MM_PAGE_ALLOC              => 1;      19 use constant MM_PAGE_ALLOC              => 1;
 20 use constant MM_PAGE_FREE               => 2;      20 use constant MM_PAGE_FREE               => 2;
 21 use constant MM_PAGE_FREE_BATCHED       => 3;      21 use constant MM_PAGE_FREE_BATCHED       => 3;
 22 use constant MM_PAGE_PCPU_DRAIN         => 4;      22 use constant MM_PAGE_PCPU_DRAIN         => 4;
 23 use constant MM_PAGE_ALLOC_ZONE_LOCKED  => 5;      23 use constant MM_PAGE_ALLOC_ZONE_LOCKED  => 5;
 24 use constant MM_PAGE_ALLOC_EXTFRAG      => 6;      24 use constant MM_PAGE_ALLOC_EXTFRAG      => 6;
 25 use constant EVENT_UNKNOWN              => 7;      25 use constant EVENT_UNKNOWN              => 7;
 26                                                    26 
 27 # Constants used to track state                    27 # Constants used to track state
 28 use constant STATE_PCPU_PAGES_DRAINED   => 8;      28 use constant STATE_PCPU_PAGES_DRAINED   => 8;
 29 use constant STATE_PCPU_PAGES_REFILLED  => 9;      29 use constant STATE_PCPU_PAGES_REFILLED  => 9;
 30                                                    30 
 31 # High-level events extrapolated from tracepoi     31 # High-level events extrapolated from tracepoints
 32 use constant HIGH_PCPU_DRAINS           => 10;     32 use constant HIGH_PCPU_DRAINS           => 10;
 33 use constant HIGH_PCPU_REFILLS          => 11;     33 use constant HIGH_PCPU_REFILLS          => 11;
 34 use constant HIGH_EXT_FRAGMENT          => 12;     34 use constant HIGH_EXT_FRAGMENT          => 12;
 35 use constant HIGH_EXT_FRAGMENT_SEVERE   => 13;     35 use constant HIGH_EXT_FRAGMENT_SEVERE   => 13;
 36 use constant HIGH_EXT_FRAGMENT_MODERATE => 14;     36 use constant HIGH_EXT_FRAGMENT_MODERATE => 14;
 37 use constant HIGH_EXT_FRAGMENT_CHANGED  => 15;     37 use constant HIGH_EXT_FRAGMENT_CHANGED  => 15;
 38                                                    38 
 39 my %perprocesspid;                                 39 my %perprocesspid;
 40 my %perprocess;                                    40 my %perprocess;
 41 my $opt_ignorepid;                                 41 my $opt_ignorepid;
 42 my $opt_read_procstat;                             42 my $opt_read_procstat;
 43 my $opt_prepend_parent;                            43 my $opt_prepend_parent;
 44                                                    44 
 45 # Catch sigint and exit on request                 45 # Catch sigint and exit on request
 46 my $sigint_report = 0;                             46 my $sigint_report = 0;
 47 my $sigint_exit = 0;                               47 my $sigint_exit = 0;
 48 my $sigint_pending = 0;                            48 my $sigint_pending = 0;
 49 my $sigint_received = 0;                           49 my $sigint_received = 0;
 50 sub sigint_handler {                               50 sub sigint_handler {
 51         my $current_time = time;                   51         my $current_time = time;
 52         if ($current_time - 2 > $sigint_receiv     52         if ($current_time - 2 > $sigint_received) {
 53                 print "SIGINT received, report     53                 print "SIGINT received, report pending. Hit ctrl-c again to exit\n";
 54                 $sigint_report = 1;                54                 $sigint_report = 1;
 55         } else {                                   55         } else {
 56                 if (!$sigint_exit) {               56                 if (!$sigint_exit) {
 57                         print "Second SIGINT r     57                         print "Second SIGINT received quickly, exiting\n";
 58                 }                                  58                 }
 59                 $sigint_exit++;                    59                 $sigint_exit++;
 60         }                                          60         }
 61                                                    61 
 62         if ($sigint_exit > 3) {                    62         if ($sigint_exit > 3) {
 63                 print "Many SIGINTs received,      63                 print "Many SIGINTs received, exiting now without report\n";
 64                 exit;                              64                 exit;
 65         }                                          65         }
 66                                                    66 
 67         $sigint_received = $current_time;          67         $sigint_received = $current_time;
 68         $sigint_pending = 1;                       68         $sigint_pending = 1;
 69 }                                                  69 }
 70 $SIG{INT} = "sigint_handler";                      70 $SIG{INT} = "sigint_handler";
 71                                                    71 
 72 # Parse command line options                       72 # Parse command line options
 73 GetOptions(                                        73 GetOptions(
 74         'ignore-pid'     =>     \$opt_ignorepi     74         'ignore-pid'     =>     \$opt_ignorepid,
 75         'read-procstat'  =>     \$opt_read_pro     75         'read-procstat'  =>     \$opt_read_procstat,
 76         'prepend-parent' =>     \$opt_prepend_     76         'prepend-parent' =>     \$opt_prepend_parent,
 77 );                                                 77 );
 78                                                    78 
 79 # Defaults for dynamically discovered regex's      79 # Defaults for dynamically discovered regex's
 80 my $regex_fragdetails_default = 'page=([0-9a-f     80 my $regex_fragdetails_default = 'page=([0-9a-f]*) pfn=([0-9]*) alloc_order=([-0-9]*) fallback_order=([-0-9]*) pageblock_order=([-0-9]*) alloc_migratetype=([-0-9]*) fallback_migratetype=([-0-9]*) fragmenting=([-0-9]) change_ownership=([-0-9])';
 81                                                    81 
 82 # Dyanically discovered regex                      82 # Dyanically discovered regex
 83 my $regex_fragdetails;                             83 my $regex_fragdetails;
 84                                                    84 
 85 # Static regex used. Specified like this for r     85 # Static regex used. Specified like this for readability and for use with /o
 86 #                      (process_pid)     (cpus     86 #                      (process_pid)     (cpus      )   ( time  )   (tpoint    ) (details)
 87 my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(     87 my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)';
 88 my $regex_statname = '[-0-9]*\s\((.*)\).*';        88 my $regex_statname = '[-0-9]*\s\((.*)\).*';
 89 my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z     89 my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*';
 90                                                    90 
 91 sub generate_traceevent_regex {                    91 sub generate_traceevent_regex {
 92         my $event = shift;                         92         my $event = shift;
 93         my $default = shift;                       93         my $default = shift;
 94         my $regex;                                 94         my $regex;
 95                                                    95 
 96         # Read the event format or use the def     96         # Read the event format or use the default
 97         if (!open (FORMAT, "/sys/kernel/tracin     97         if (!open (FORMAT, "/sys/kernel/tracing/events/$event/format")) {
 98                 $regex = $default;                 98                 $regex = $default;
 99         } else {                                   99         } else {
100                 my $line;                         100                 my $line;
101                 while (!eof(FORMAT)) {            101                 while (!eof(FORMAT)) {
102                         $line = <FORMAT>;         102                         $line = <FORMAT>;
103                         if ($line =~ /^print f    103                         if ($line =~ /^print fmt:\s"(.*)",.*/) {
104                                 $regex = $1;      104                                 $regex = $1;
105                                 $regex =~ s/%p    105                                 $regex =~ s/%p/\([0-9a-f]*\)/g;
106                                 $regex =~ s/%d    106                                 $regex =~ s/%d/\([-0-9]*\)/g;
107                                 $regex =~ s/%l    107                                 $regex =~ s/%lu/\([0-9]*\)/g;
108                         }                         108                         }
109                 }                                 109                 }
110         }                                         110         }
111                                                   111 
112         # Verify fields are in the right order    112         # Verify fields are in the right order
113         my $tuple;                                113         my $tuple;
114         foreach $tuple (split /\s/, $regex) {     114         foreach $tuple (split /\s/, $regex) {
115                 my ($key, $value) = split(/=/,    115                 my ($key, $value) = split(/=/, $tuple);
116                 my $expected = shift;             116                 my $expected = shift;
117                 if ($key ne $expected) {          117                 if ($key ne $expected) {
118                         print("WARNING: Format    118                         print("WARNING: Format not as expected '$key' != '$expected'");
119                         $regex =~ s/$key=\((.*    119                         $regex =~ s/$key=\((.*)\)/$key=$1/;
120                 }                                 120                 }
121         }                                         121         }
122                                                   122 
123         if (defined shift) {                      123         if (defined shift) {
124                 die("Fewer fields than expecte    124                 die("Fewer fields than expected in format");
125         }                                         125         }
126                                                   126 
127         return $regex;                            127         return $regex;
128 }                                                 128 }
129 $regex_fragdetails = generate_traceevent_regex    129 $regex_fragdetails = generate_traceevent_regex("kmem/mm_page_alloc_extfrag",
130                         $regex_fragdetails_def    130                         $regex_fragdetails_default,
131                         "page", "pfn",            131                         "page", "pfn",
132                         "alloc_order", "fallba    132                         "alloc_order", "fallback_order", "pageblock_order",
133                         "alloc_migratetype", "    133                         "alloc_migratetype", "fallback_migratetype",
134                         "fragmenting", "change    134                         "fragmenting", "change_ownership");
135                                                   135 
136 sub read_statline($) {                            136 sub read_statline($) {
137         my $pid = $_[0];                          137         my $pid = $_[0];
138         my $statline;                             138         my $statline;
139                                                   139 
140         if (open(STAT, "/proc/$pid/stat")) {      140         if (open(STAT, "/proc/$pid/stat")) {
141                 $statline = <STAT>;               141                 $statline = <STAT>;
142                 close(STAT);                      142                 close(STAT);
143         }                                         143         }
144                                                   144 
145         if ($statline eq '') {                    145         if ($statline eq '') {
146                 $statline = "-1 (UNKNOWN_PROCE    146                 $statline = "-1 (UNKNOWN_PROCESS_NAME) R 0";
147         }                                         147         }
148                                                   148 
149         return $statline;                         149         return $statline;
150 }                                                 150 }
151                                                   151 
152 sub guess_process_pid($$) {                       152 sub guess_process_pid($$) {
153         my $pid = $_[0];                          153         my $pid = $_[0];
154         my $statline = $_[1];                     154         my $statline = $_[1];
155                                                   155 
156         if ($pid == 0) {                          156         if ($pid == 0) {
157                 return "swapper-0";               157                 return "swapper-0";
158         }                                         158         }
159                                                   159 
160         if ($statline !~ /$regex_statname/o) {    160         if ($statline !~ /$regex_statname/o) {
161                 die("Failed to math stat line     161                 die("Failed to math stat line for process name :: $statline");
162         }                                         162         }
163         return "$1-$pid";                         163         return "$1-$pid";
164 }                                                 164 }
165                                                   165 
166 sub parent_info($$) {                             166 sub parent_info($$) {
167         my $pid = $_[0];                          167         my $pid = $_[0];
168         my $statline = $_[1];                     168         my $statline = $_[1];
169         my $ppid;                                 169         my $ppid;
170                                                   170 
171         if ($pid == 0) {                          171         if ($pid == 0) {
172                 return "NOPARENT-0";              172                 return "NOPARENT-0";
173         }                                         173         }
174                                                   174 
175         if ($statline !~ /$regex_statppid/o) {    175         if ($statline !~ /$regex_statppid/o) {
176                 die("Failed to match stat line    176                 die("Failed to match stat line process ppid:: $statline");
177         }                                         177         }
178                                                   178 
179         # Read the ppid stat line                 179         # Read the ppid stat line
180         $ppid = $1;                               180         $ppid = $1;
181         return guess_process_pid($ppid, read_s    181         return guess_process_pid($ppid, read_statline($ppid));
182 }                                                 182 }
183                                                   183 
184 sub process_events {                              184 sub process_events {
185         my $traceevent;                           185         my $traceevent;
186         my $process_pid;                          186         my $process_pid;
187         my $cpus;                                 187         my $cpus;
188         my $timestamp;                            188         my $timestamp;
189         my $tracepoint;                           189         my $tracepoint;
190         my $details;                              190         my $details;
191         my $statline;                             191         my $statline;
192                                                   192 
193         # Read each line of the event log         193         # Read each line of the event log
194 EVENT_PROCESS:                                    194 EVENT_PROCESS:
195         while ($traceevent = <STDIN>) {           195         while ($traceevent = <STDIN>) {
196                 if ($traceevent =~ /$regex_tra    196                 if ($traceevent =~ /$regex_traceevent/o) {
197                         $process_pid = $1;        197                         $process_pid = $1;
198                         $tracepoint = $4;         198                         $tracepoint = $4;
199                                                   199 
200                         if ($opt_read_procstat    200                         if ($opt_read_procstat || $opt_prepend_parent) {
201                                 $process_pid =    201                                 $process_pid =~ /(.*)-([0-9]*)$/;
202                                 my $process =     202                                 my $process = $1;
203                                 my $pid = $2;     203                                 my $pid = $2;
204                                                   204 
205                                 $statline = re    205                                 $statline = read_statline($pid);
206                                                   206 
207                                 if ($opt_read_    207                                 if ($opt_read_procstat && $process eq '') {
208                                         $proce    208                                         $process_pid = guess_process_pid($pid, $statline);
209                                 }                 209                                 }
210                                                   210 
211                                 if ($opt_prepe    211                                 if ($opt_prepend_parent) {
212                                         $proce    212                                         $process_pid = parent_info($pid, $statline) . " :: $process_pid";
213                                 }                 213                                 }
214                         }                         214                         }
215                                                   215 
216                         # Unnecessary in this     216                         # Unnecessary in this script. Uncomment if required
217                         # $cpus = $2;             217                         # $cpus = $2;
218                         # $timestamp = $3;        218                         # $timestamp = $3;
219                 } else {                          219                 } else {
220                         next;                     220                         next;
221                 }                                 221                 }
222                                                   222 
223                 # Perl Switch() sucks majorly     223                 # Perl Switch() sucks majorly
224                 if ($tracepoint eq "mm_page_al    224                 if ($tracepoint eq "mm_page_alloc") {
225                         $perprocesspid{$proces    225                         $perprocesspid{$process_pid}->{MM_PAGE_ALLOC}++;
226                 } elsif ($tracepoint eq "mm_pa    226                 } elsif ($tracepoint eq "mm_page_free") {
227                         $perprocesspid{$proces    227                         $perprocesspid{$process_pid}->{MM_PAGE_FREE}++
228                 } elsif ($tracepoint eq "mm_pa    228                 } elsif ($tracepoint eq "mm_page_free_batched") {
229                         $perprocesspid{$proces    229                         $perprocesspid{$process_pid}->{MM_PAGE_FREE_BATCHED}++;
230                 } elsif ($tracepoint eq "mm_pa    230                 } elsif ($tracepoint eq "mm_page_pcpu_drain") {
231                         $perprocesspid{$proces    231                         $perprocesspid{$process_pid}->{MM_PAGE_PCPU_DRAIN}++;
232                         $perprocesspid{$proces    232                         $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED}++;
233                 } elsif ($tracepoint eq "mm_pa    233                 } elsif ($tracepoint eq "mm_page_alloc_zone_locked") {
234                         $perprocesspid{$proces    234                         $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED}++;
235                         $perprocesspid{$proces    235                         $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED}++;
236                 } elsif ($tracepoint eq "mm_pa    236                 } elsif ($tracepoint eq "mm_page_alloc_extfrag") {
237                                                   237 
238                         # Extract the details     238                         # Extract the details of the event now
239                         $details = $5;            239                         $details = $5;
240                                                   240 
241                         my ($page, $pfn);         241                         my ($page, $pfn);
242                         my ($alloc_order, $fal    242                         my ($alloc_order, $fallback_order, $pageblock_order);
243                         my ($alloc_migratetype    243                         my ($alloc_migratetype, $fallback_migratetype);
244                         my ($fragmenting, $cha    244                         my ($fragmenting, $change_ownership);
245                                                   245 
246                         if ($details !~ /$rege    246                         if ($details !~ /$regex_fragdetails/o) {
247                                 print "WARNING    247                                 print "WARNING: Failed to parse mm_page_alloc_extfrag as expected\n";
248                                 next;             248                                 next;
249                         }                         249                         }
250                                                   250 
251                         $perprocesspid{$proces    251                         $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG}++;
252                         $page = $1;               252                         $page = $1;
253                         $pfn = $2;                253                         $pfn = $2;
254                         $alloc_order = $3;        254                         $alloc_order = $3;
255                         $fallback_order = $4;     255                         $fallback_order = $4;
256                         $pageblock_order = $5;    256                         $pageblock_order = $5;
257                         $alloc_migratetype = $    257                         $alloc_migratetype = $6;
258                         $fallback_migratetype     258                         $fallback_migratetype = $7;
259                         $fragmenting = $8;        259                         $fragmenting = $8;
260                         $change_ownership = $9    260                         $change_ownership = $9;
261                                                   261 
262                         if ($fragmenting) {       262                         if ($fragmenting) {
263                                 $perprocesspid    263                                 $perprocesspid{$process_pid}->{HIGH_EXT_FRAG}++;
264                                 if ($fallback_    264                                 if ($fallback_order <= 3) {
265                                         $perpr    265                                         $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE}++;
266                                 } else {          266                                 } else {
267                                         $perpr    267                                         $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE}++;
268                                 }                 268                                 }
269                         }                         269                         }
270                         if ($change_ownership)    270                         if ($change_ownership) {
271                                 $perprocesspid    271                                 $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED}++;
272                         }                         272                         }
273                 } else {                          273                 } else {
274                         $perprocesspid{$proces    274                         $perprocesspid{$process_pid}->{EVENT_UNKNOWN}++;
275                 }                                 275                 }
276                                                   276 
277                 # Catch a full pcpu drain even    277                 # Catch a full pcpu drain event
278                 if ($perprocesspid{$process_pi    278                 if ($perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED} &&
279                                 $tracepoint ne    279                                 $tracepoint ne "mm_page_pcpu_drain") {
280                                                   280 
281                         $perprocesspid{$proces    281                         $perprocesspid{$process_pid}->{HIGH_PCPU_DRAINS}++;
282                         $perprocesspid{$proces    282                         $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED} = 0;
283                 }                                 283                 }
284                                                   284 
285                 # Catch a full pcpu refill eve    285                 # Catch a full pcpu refill event
286                 if ($perprocesspid{$process_pi    286                 if ($perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED} &&
287                                 $tracepoint ne    287                                 $tracepoint ne "mm_page_alloc_zone_locked") {
288                         $perprocesspid{$proces    288                         $perprocesspid{$process_pid}->{HIGH_PCPU_REFILLS}++;
289                         $perprocesspid{$proces    289                         $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED} = 0;
290                 }                                 290                 }
291                                                   291 
292                 if ($sigint_pending) {            292                 if ($sigint_pending) {
293                         last EVENT_PROCESS;       293                         last EVENT_PROCESS;
294                 }                                 294                 }
295         }                                         295         }
296 }                                                 296 }
297                                                   297 
298 sub dump_stats {                                  298 sub dump_stats {
299         my $hashref = shift;                      299         my $hashref = shift;
300         my %stats = %$hashref;                    300         my %stats = %$hashref;
301                                                   301 
302         # Dump per-process stats                  302         # Dump per-process stats
303         my $process_pid;                          303         my $process_pid;
304         my $max_strlen = 0;                       304         my $max_strlen = 0;
305                                                   305 
306         # Get the maximum process name            306         # Get the maximum process name
307         foreach $process_pid (keys %perprocess    307         foreach $process_pid (keys %perprocesspid) {
308                 my $len = length($process_pid)    308                 my $len = length($process_pid);
309                 if ($len > $max_strlen) {         309                 if ($len > $max_strlen) {
310                         $max_strlen = $len;       310                         $max_strlen = $len;
311                 }                                 311                 }
312         }                                         312         }
313         $max_strlen += 2;                         313         $max_strlen += 2;
314                                                   314 
315         printf("\n");                             315         printf("\n");
316         printf("%-" . $max_strlen . "s %8s %10    316         printf("%-" . $max_strlen . "s %8s %10s   %8s %8s   %8s %8s %8s   %8s %8s %8s %8s %8s %8s\n",
317                 "Process", "Pages",  "Pages",     317                 "Process", "Pages",  "Pages",      "Pages", "Pages", "PCPU",  "PCPU",   "PCPU",    "Fragment",  "Fragment", "MigType", "Fragment", "Fragment", "Unknown");
318         printf("%-" . $max_strlen . "s %8s %10    318         printf("%-" . $max_strlen . "s %8s %10s   %8s %8s   %8s %8s %8s   %8s %8s %8s %8s %8s %8s\n",
319                 "details", "allocd", "allocd",    319                 "details", "allocd", "allocd",     "freed", "freed", "pages", "drains", "refills", "Fallback", "Causing",   "Changed", "Severe", "Moderate", "");
320                                                   320 
321         printf("%-" . $max_strlen . "s %8s %10    321         printf("%-" . $max_strlen . "s %8s %10s   %8s %8s   %8s %8s %8s   %8s %8s %8s %8s %8s %8s\n",
322                 "",        "",       "under lo    322                 "",        "",       "under lock", "direct", "pagevec", "drain", "", "", "", "", "", "", "", "");
323                                                   323 
324         foreach $process_pid (keys %stats) {      324         foreach $process_pid (keys %stats) {
325                 # Dump final aggregates           325                 # Dump final aggregates
326                 if ($stats{$process_pid}->{STA    326                 if ($stats{$process_pid}->{STATE_PCPU_PAGES_DRAINED}) {
327                         $stats{$process_pid}->    327                         $stats{$process_pid}->{HIGH_PCPU_DRAINS}++;
328                         $stats{$process_pid}->    328                         $stats{$process_pid}->{STATE_PCPU_PAGES_DRAINED} = 0;
329                 }                                 329                 }
330                 if ($stats{$process_pid}->{STA    330                 if ($stats{$process_pid}->{STATE_PCPU_PAGES_REFILLED}) {
331                         $stats{$process_pid}->    331                         $stats{$process_pid}->{HIGH_PCPU_REFILLS}++;
332                         $stats{$process_pid}->    332                         $stats{$process_pid}->{STATE_PCPU_PAGES_REFILLED} = 0;
333                 }                                 333                 }
334                                                   334 
335                 printf("%-" . $max_strlen . "s    335                 printf("%-" . $max_strlen . "s %8d %10d   %8d %8d   %8d %8d %8d   %8d %8d %8d %8d %8d %8d\n",
336                         $process_pid,             336                         $process_pid,
337                         $stats{$process_pid}->    337                         $stats{$process_pid}->{MM_PAGE_ALLOC},
338                         $stats{$process_pid}->    338                         $stats{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED},
339                         $stats{$process_pid}->    339                         $stats{$process_pid}->{MM_PAGE_FREE},
340                         $stats{$process_pid}->    340                         $stats{$process_pid}->{MM_PAGE_FREE_BATCHED},
341                         $stats{$process_pid}->    341                         $stats{$process_pid}->{MM_PAGE_PCPU_DRAIN},
342                         $stats{$process_pid}->    342                         $stats{$process_pid}->{HIGH_PCPU_DRAINS},
343                         $stats{$process_pid}->    343                         $stats{$process_pid}->{HIGH_PCPU_REFILLS},
344                         $stats{$process_pid}->    344                         $stats{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG},
345                         $stats{$process_pid}->    345                         $stats{$process_pid}->{HIGH_EXT_FRAG},
346                         $stats{$process_pid}->    346                         $stats{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED},
347                         $stats{$process_pid}->    347                         $stats{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE},
348                         $stats{$process_pid}->    348                         $stats{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE},
349                         $stats{$process_pid}->    349                         $stats{$process_pid}->{EVENT_UNKNOWN});
350         }                                         350         }
351 }                                                 351 }
352                                                   352 
353 sub aggregate_perprocesspid() {                   353 sub aggregate_perprocesspid() {
354         my $process_pid;                          354         my $process_pid;
355         my $process;                              355         my $process;
356         undef %perprocess;                        356         undef %perprocess;
357                                                   357 
358         foreach $process_pid (keys %perprocess    358         foreach $process_pid (keys %perprocesspid) {
359                 $process = $process_pid;          359                 $process = $process_pid;
360                 $process =~ s/-([0-9])*$//;       360                 $process =~ s/-([0-9])*$//;
361                 if ($process eq '') {             361                 if ($process eq '') {
362                         $process = "NO_PROCESS    362                         $process = "NO_PROCESS_NAME";
363                 }                                 363                 }
364                                                   364 
365                 $perprocess{$process}->{MM_PAG    365                 $perprocess{$process}->{MM_PAGE_ALLOC} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC};
366                 $perprocess{$process}->{MM_PAG    366                 $perprocess{$process}->{MM_PAGE_ALLOC_ZONE_LOCKED} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED};
367                 $perprocess{$process}->{MM_PAG    367                 $perprocess{$process}->{MM_PAGE_FREE} += $perprocesspid{$process_pid}->{MM_PAGE_FREE};
368                 $perprocess{$process}->{MM_PAG    368                 $perprocess{$process}->{MM_PAGE_FREE_BATCHED} += $perprocesspid{$process_pid}->{MM_PAGE_FREE_BATCHED};
369                 $perprocess{$process}->{MM_PAG    369                 $perprocess{$process}->{MM_PAGE_PCPU_DRAIN} += $perprocesspid{$process_pid}->{MM_PAGE_PCPU_DRAIN};
370                 $perprocess{$process}->{HIGH_P    370                 $perprocess{$process}->{HIGH_PCPU_DRAINS} += $perprocesspid{$process_pid}->{HIGH_PCPU_DRAINS};
371                 $perprocess{$process}->{HIGH_P    371                 $perprocess{$process}->{HIGH_PCPU_REFILLS} += $perprocesspid{$process_pid}->{HIGH_PCPU_REFILLS};
372                 $perprocess{$process}->{MM_PAG    372                 $perprocess{$process}->{MM_PAGE_ALLOC_EXTFRAG} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG};
373                 $perprocess{$process}->{HIGH_E    373                 $perprocess{$process}->{HIGH_EXT_FRAG} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAG};
374                 $perprocess{$process}->{HIGH_E    374                 $perprocess{$process}->{HIGH_EXT_FRAGMENT_CHANGED} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED};
375                 $perprocess{$process}->{HIGH_E    375                 $perprocess{$process}->{HIGH_EXT_FRAGMENT_SEVERE} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE};
376                 $perprocess{$process}->{HIGH_E    376                 $perprocess{$process}->{HIGH_EXT_FRAGMENT_MODERATE} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE};
377                 $perprocess{$process}->{EVENT_    377                 $perprocess{$process}->{EVENT_UNKNOWN} += $perprocesspid{$process_pid}->{EVENT_UNKNOWN};
378         }                                         378         }
379 }                                                 379 }
380                                                   380 
381 sub report() {                                    381 sub report() {
382         if (!$opt_ignorepid) {                    382         if (!$opt_ignorepid) {
383                 dump_stats(\%perprocesspid);      383                 dump_stats(\%perprocesspid);
384         } else {                                  384         } else {
385                 aggregate_perprocesspid();        385                 aggregate_perprocesspid();
386                 dump_stats(\%perprocess);         386                 dump_stats(\%perprocess);
387         }                                         387         }
388 }                                                 388 }
389                                                   389 
390 # Process events or signals until neither is a    390 # Process events or signals until neither is available
391 sub signal_loop() {                               391 sub signal_loop() {
392         my $sigint_processed;                     392         my $sigint_processed;
393         do {                                      393         do {
394                 $sigint_processed = 0;            394                 $sigint_processed = 0;
395                 process_events();                 395                 process_events();
396                                                   396 
397                 # Handle pending signals if an    397                 # Handle pending signals if any
398                 if ($sigint_pending) {            398                 if ($sigint_pending) {
399                         my $current_time = tim    399                         my $current_time = time;
400                                                   400 
401                         if ($sigint_exit) {       401                         if ($sigint_exit) {
402                                 print "Receive    402                                 print "Received exit signal\n";
403                                 $sigint_pendin    403                                 $sigint_pending = 0;
404                         }                         404                         }
405                         if ($sigint_report) {     405                         if ($sigint_report) {
406                                 if ($current_t    406                                 if ($current_time >= $sigint_received + 2) {
407                                         report    407                                         report();
408                                         $sigin    408                                         $sigint_report = 0;
409                                         $sigin    409                                         $sigint_pending = 0;
410                                         $sigin    410                                         $sigint_processed = 1;
411                                 }                 411                                 }
412                         }                         412                         }
413                 }                                 413                 }
414         } while ($sigint_pending || $sigint_pr    414         } while ($sigint_pending || $sigint_processed);
415 }                                                 415 }
416                                                   416 
417 signal_loop();                                    417 signal_loop();
418 report();                                         418 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