~ [ 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 (Version linux-6.12-rc7) and /Documentation/trace/postprocess/trace-pagealloc-postprocess.pl (Version linux-2.6.0)


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