162306a36Sopenharmony_ci#!/usr/bin/env perl 262306a36Sopenharmony_ci# This is a POC (proof of concept or piece of crap, take your pick) for reading the 362306a36Sopenharmony_ci# text representation of trace output related to page allocation. It makes an attempt 462306a36Sopenharmony_ci# to extract some high-level information on what is going on. The accuracy of the parser 562306a36Sopenharmony_ci# may vary considerably 662306a36Sopenharmony_ci# 762306a36Sopenharmony_ci# Example usage: trace-pagealloc-postprocess.pl < /sys/kernel/tracing/trace_pipe 862306a36Sopenharmony_ci# other options 962306a36Sopenharmony_ci# --prepend-parent Report on the parent proc and PID 1062306a36Sopenharmony_ci# --read-procstat If the trace lacks process info, get it from /proc 1162306a36Sopenharmony_ci# --ignore-pid Aggregate processes of the same name together 1262306a36Sopenharmony_ci# 1362306a36Sopenharmony_ci# Copyright (c) IBM Corporation 2009 1462306a36Sopenharmony_ci# Author: Mel Gorman <mel@csn.ul.ie> 1562306a36Sopenharmony_ciuse strict; 1662306a36Sopenharmony_ciuse Getopt::Long; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci# Tracepoint events 1962306a36Sopenharmony_ciuse constant MM_PAGE_ALLOC => 1; 2062306a36Sopenharmony_ciuse constant MM_PAGE_FREE => 2; 2162306a36Sopenharmony_ciuse constant MM_PAGE_FREE_BATCHED => 3; 2262306a36Sopenharmony_ciuse constant MM_PAGE_PCPU_DRAIN => 4; 2362306a36Sopenharmony_ciuse constant MM_PAGE_ALLOC_ZONE_LOCKED => 5; 2462306a36Sopenharmony_ciuse constant MM_PAGE_ALLOC_EXTFRAG => 6; 2562306a36Sopenharmony_ciuse constant EVENT_UNKNOWN => 7; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci# Constants used to track state 2862306a36Sopenharmony_ciuse constant STATE_PCPU_PAGES_DRAINED => 8; 2962306a36Sopenharmony_ciuse constant STATE_PCPU_PAGES_REFILLED => 9; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci# High-level events extrapolated from tracepoints 3262306a36Sopenharmony_ciuse constant HIGH_PCPU_DRAINS => 10; 3362306a36Sopenharmony_ciuse constant HIGH_PCPU_REFILLS => 11; 3462306a36Sopenharmony_ciuse constant HIGH_EXT_FRAGMENT => 12; 3562306a36Sopenharmony_ciuse constant HIGH_EXT_FRAGMENT_SEVERE => 13; 3662306a36Sopenharmony_ciuse constant HIGH_EXT_FRAGMENT_MODERATE => 14; 3762306a36Sopenharmony_ciuse constant HIGH_EXT_FRAGMENT_CHANGED => 15; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cimy %perprocesspid; 4062306a36Sopenharmony_cimy %perprocess; 4162306a36Sopenharmony_cimy $opt_ignorepid; 4262306a36Sopenharmony_cimy $opt_read_procstat; 4362306a36Sopenharmony_cimy $opt_prepend_parent; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci# Catch sigint and exit on request 4662306a36Sopenharmony_cimy $sigint_report = 0; 4762306a36Sopenharmony_cimy $sigint_exit = 0; 4862306a36Sopenharmony_cimy $sigint_pending = 0; 4962306a36Sopenharmony_cimy $sigint_received = 0; 5062306a36Sopenharmony_cisub sigint_handler { 5162306a36Sopenharmony_ci my $current_time = time; 5262306a36Sopenharmony_ci if ($current_time - 2 > $sigint_received) { 5362306a36Sopenharmony_ci print "SIGINT received, report pending. Hit ctrl-c again to exit\n"; 5462306a36Sopenharmony_ci $sigint_report = 1; 5562306a36Sopenharmony_ci } else { 5662306a36Sopenharmony_ci if (!$sigint_exit) { 5762306a36Sopenharmony_ci print "Second SIGINT received quickly, exiting\n"; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci $sigint_exit++; 6062306a36Sopenharmony_ci } 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci if ($sigint_exit > 3) { 6362306a36Sopenharmony_ci print "Many SIGINTs received, exiting now without report\n"; 6462306a36Sopenharmony_ci exit; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci $sigint_received = $current_time; 6862306a36Sopenharmony_ci $sigint_pending = 1; 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci$SIG{INT} = "sigint_handler"; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci# Parse command line options 7362306a36Sopenharmony_ciGetOptions( 7462306a36Sopenharmony_ci 'ignore-pid' => \$opt_ignorepid, 7562306a36Sopenharmony_ci 'read-procstat' => \$opt_read_procstat, 7662306a36Sopenharmony_ci 'prepend-parent' => \$opt_prepend_parent, 7762306a36Sopenharmony_ci); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci# Defaults for dynamically discovered regex's 8062306a36Sopenharmony_cimy $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])'; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci# Dyanically discovered regex 8362306a36Sopenharmony_cimy $regex_fragdetails; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci# Static regex used. Specified like this for readability and for use with /o 8662306a36Sopenharmony_ci# (process_pid) (cpus ) ( time ) (tpoint ) (details) 8762306a36Sopenharmony_cimy $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)'; 8862306a36Sopenharmony_cimy $regex_statname = '[-0-9]*\s\((.*)\).*'; 8962306a36Sopenharmony_cimy $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*'; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cisub generate_traceevent_regex { 9262306a36Sopenharmony_ci my $event = shift; 9362306a36Sopenharmony_ci my $default = shift; 9462306a36Sopenharmony_ci my $regex; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci # Read the event format or use the default 9762306a36Sopenharmony_ci if (!open (FORMAT, "/sys/kernel/tracing/events/$event/format")) { 9862306a36Sopenharmony_ci $regex = $default; 9962306a36Sopenharmony_ci } else { 10062306a36Sopenharmony_ci my $line; 10162306a36Sopenharmony_ci while (!eof(FORMAT)) { 10262306a36Sopenharmony_ci $line = <FORMAT>; 10362306a36Sopenharmony_ci if ($line =~ /^print fmt:\s"(.*)",.*/) { 10462306a36Sopenharmony_ci $regex = $1; 10562306a36Sopenharmony_ci $regex =~ s/%p/\([0-9a-f]*\)/g; 10662306a36Sopenharmony_ci $regex =~ s/%d/\([-0-9]*\)/g; 10762306a36Sopenharmony_ci $regex =~ s/%lu/\([0-9]*\)/g; 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci } 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci # Verify fields are in the right order 11362306a36Sopenharmony_ci my $tuple; 11462306a36Sopenharmony_ci foreach $tuple (split /\s/, $regex) { 11562306a36Sopenharmony_ci my ($key, $value) = split(/=/, $tuple); 11662306a36Sopenharmony_ci my $expected = shift; 11762306a36Sopenharmony_ci if ($key ne $expected) { 11862306a36Sopenharmony_ci print("WARNING: Format not as expected '$key' != '$expected'"); 11962306a36Sopenharmony_ci $regex =~ s/$key=\((.*)\)/$key=$1/; 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci if (defined shift) { 12462306a36Sopenharmony_ci die("Fewer fields than expected in format"); 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci return $regex; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci$regex_fragdetails = generate_traceevent_regex("kmem/mm_page_alloc_extfrag", 13062306a36Sopenharmony_ci $regex_fragdetails_default, 13162306a36Sopenharmony_ci "page", "pfn", 13262306a36Sopenharmony_ci "alloc_order", "fallback_order", "pageblock_order", 13362306a36Sopenharmony_ci "alloc_migratetype", "fallback_migratetype", 13462306a36Sopenharmony_ci "fragmenting", "change_ownership"); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cisub read_statline($) { 13762306a36Sopenharmony_ci my $pid = $_[0]; 13862306a36Sopenharmony_ci my $statline; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci if (open(STAT, "/proc/$pid/stat")) { 14162306a36Sopenharmony_ci $statline = <STAT>; 14262306a36Sopenharmony_ci close(STAT); 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci if ($statline eq '') { 14662306a36Sopenharmony_ci $statline = "-1 (UNKNOWN_PROCESS_NAME) R 0"; 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci return $statline; 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cisub guess_process_pid($$) { 15362306a36Sopenharmony_ci my $pid = $_[0]; 15462306a36Sopenharmony_ci my $statline = $_[1]; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci if ($pid == 0) { 15762306a36Sopenharmony_ci return "swapper-0"; 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci if ($statline !~ /$regex_statname/o) { 16162306a36Sopenharmony_ci die("Failed to math stat line for process name :: $statline"); 16262306a36Sopenharmony_ci } 16362306a36Sopenharmony_ci return "$1-$pid"; 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cisub parent_info($$) { 16762306a36Sopenharmony_ci my $pid = $_[0]; 16862306a36Sopenharmony_ci my $statline = $_[1]; 16962306a36Sopenharmony_ci my $ppid; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci if ($pid == 0) { 17262306a36Sopenharmony_ci return "NOPARENT-0"; 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci if ($statline !~ /$regex_statppid/o) { 17662306a36Sopenharmony_ci die("Failed to match stat line process ppid:: $statline"); 17762306a36Sopenharmony_ci } 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci # Read the ppid stat line 18062306a36Sopenharmony_ci $ppid = $1; 18162306a36Sopenharmony_ci return guess_process_pid($ppid, read_statline($ppid)); 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cisub process_events { 18562306a36Sopenharmony_ci my $traceevent; 18662306a36Sopenharmony_ci my $process_pid; 18762306a36Sopenharmony_ci my $cpus; 18862306a36Sopenharmony_ci my $timestamp; 18962306a36Sopenharmony_ci my $tracepoint; 19062306a36Sopenharmony_ci my $details; 19162306a36Sopenharmony_ci my $statline; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci # Read each line of the event log 19462306a36Sopenharmony_ciEVENT_PROCESS: 19562306a36Sopenharmony_ci while ($traceevent = <STDIN>) { 19662306a36Sopenharmony_ci if ($traceevent =~ /$regex_traceevent/o) { 19762306a36Sopenharmony_ci $process_pid = $1; 19862306a36Sopenharmony_ci $tracepoint = $4; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci if ($opt_read_procstat || $opt_prepend_parent) { 20162306a36Sopenharmony_ci $process_pid =~ /(.*)-([0-9]*)$/; 20262306a36Sopenharmony_ci my $process = $1; 20362306a36Sopenharmony_ci my $pid = $2; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci $statline = read_statline($pid); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci if ($opt_read_procstat && $process eq '') { 20862306a36Sopenharmony_ci $process_pid = guess_process_pid($pid, $statline); 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci if ($opt_prepend_parent) { 21262306a36Sopenharmony_ci $process_pid = parent_info($pid, $statline) . " :: $process_pid"; 21362306a36Sopenharmony_ci } 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci # Unnecessary in this script. Uncomment if required 21762306a36Sopenharmony_ci # $cpus = $2; 21862306a36Sopenharmony_ci # $timestamp = $3; 21962306a36Sopenharmony_ci } else { 22062306a36Sopenharmony_ci next; 22162306a36Sopenharmony_ci } 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci # Perl Switch() sucks majorly 22462306a36Sopenharmony_ci if ($tracepoint eq "mm_page_alloc") { 22562306a36Sopenharmony_ci $perprocesspid{$process_pid}->{MM_PAGE_ALLOC}++; 22662306a36Sopenharmony_ci } elsif ($tracepoint eq "mm_page_free") { 22762306a36Sopenharmony_ci $perprocesspid{$process_pid}->{MM_PAGE_FREE}++ 22862306a36Sopenharmony_ci } elsif ($tracepoint eq "mm_page_free_batched") { 22962306a36Sopenharmony_ci $perprocesspid{$process_pid}->{MM_PAGE_FREE_BATCHED}++; 23062306a36Sopenharmony_ci } elsif ($tracepoint eq "mm_page_pcpu_drain") { 23162306a36Sopenharmony_ci $perprocesspid{$process_pid}->{MM_PAGE_PCPU_DRAIN}++; 23262306a36Sopenharmony_ci $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED}++; 23362306a36Sopenharmony_ci } elsif ($tracepoint eq "mm_page_alloc_zone_locked") { 23462306a36Sopenharmony_ci $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED}++; 23562306a36Sopenharmony_ci $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED}++; 23662306a36Sopenharmony_ci } elsif ($tracepoint eq "mm_page_alloc_extfrag") { 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci # Extract the details of the event now 23962306a36Sopenharmony_ci $details = $5; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci my ($page, $pfn); 24262306a36Sopenharmony_ci my ($alloc_order, $fallback_order, $pageblock_order); 24362306a36Sopenharmony_ci my ($alloc_migratetype, $fallback_migratetype); 24462306a36Sopenharmony_ci my ($fragmenting, $change_ownership); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci if ($details !~ /$regex_fragdetails/o) { 24762306a36Sopenharmony_ci print "WARNING: Failed to parse mm_page_alloc_extfrag as expected\n"; 24862306a36Sopenharmony_ci next; 24962306a36Sopenharmony_ci } 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG}++; 25262306a36Sopenharmony_ci $page = $1; 25362306a36Sopenharmony_ci $pfn = $2; 25462306a36Sopenharmony_ci $alloc_order = $3; 25562306a36Sopenharmony_ci $fallback_order = $4; 25662306a36Sopenharmony_ci $pageblock_order = $5; 25762306a36Sopenharmony_ci $alloc_migratetype = $6; 25862306a36Sopenharmony_ci $fallback_migratetype = $7; 25962306a36Sopenharmony_ci $fragmenting = $8; 26062306a36Sopenharmony_ci $change_ownership = $9; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci if ($fragmenting) { 26362306a36Sopenharmony_ci $perprocesspid{$process_pid}->{HIGH_EXT_FRAG}++; 26462306a36Sopenharmony_ci if ($fallback_order <= 3) { 26562306a36Sopenharmony_ci $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE}++; 26662306a36Sopenharmony_ci } else { 26762306a36Sopenharmony_ci $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE}++; 26862306a36Sopenharmony_ci } 26962306a36Sopenharmony_ci } 27062306a36Sopenharmony_ci if ($change_ownership) { 27162306a36Sopenharmony_ci $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED}++; 27262306a36Sopenharmony_ci } 27362306a36Sopenharmony_ci } else { 27462306a36Sopenharmony_ci $perprocesspid{$process_pid}->{EVENT_UNKNOWN}++; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci # Catch a full pcpu drain event 27862306a36Sopenharmony_ci if ($perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED} && 27962306a36Sopenharmony_ci $tracepoint ne "mm_page_pcpu_drain") { 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci $perprocesspid{$process_pid}->{HIGH_PCPU_DRAINS}++; 28262306a36Sopenharmony_ci $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED} = 0; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci # Catch a full pcpu refill event 28662306a36Sopenharmony_ci if ($perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED} && 28762306a36Sopenharmony_ci $tracepoint ne "mm_page_alloc_zone_locked") { 28862306a36Sopenharmony_ci $perprocesspid{$process_pid}->{HIGH_PCPU_REFILLS}++; 28962306a36Sopenharmony_ci $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED} = 0; 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci if ($sigint_pending) { 29362306a36Sopenharmony_ci last EVENT_PROCESS; 29462306a36Sopenharmony_ci } 29562306a36Sopenharmony_ci } 29662306a36Sopenharmony_ci} 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_cisub dump_stats { 29962306a36Sopenharmony_ci my $hashref = shift; 30062306a36Sopenharmony_ci my %stats = %$hashref; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci # Dump per-process stats 30362306a36Sopenharmony_ci my $process_pid; 30462306a36Sopenharmony_ci my $max_strlen = 0; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci # Get the maximum process name 30762306a36Sopenharmony_ci foreach $process_pid (keys %perprocesspid) { 30862306a36Sopenharmony_ci my $len = length($process_pid); 30962306a36Sopenharmony_ci if ($len > $max_strlen) { 31062306a36Sopenharmony_ci $max_strlen = $len; 31162306a36Sopenharmony_ci } 31262306a36Sopenharmony_ci } 31362306a36Sopenharmony_ci $max_strlen += 2; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci printf("\n"); 31662306a36Sopenharmony_ci printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", 31762306a36Sopenharmony_ci "Process", "Pages", "Pages", "Pages", "Pages", "PCPU", "PCPU", "PCPU", "Fragment", "Fragment", "MigType", "Fragment", "Fragment", "Unknown"); 31862306a36Sopenharmony_ci printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", 31962306a36Sopenharmony_ci "details", "allocd", "allocd", "freed", "freed", "pages", "drains", "refills", "Fallback", "Causing", "Changed", "Severe", "Moderate", ""); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", 32262306a36Sopenharmony_ci "", "", "under lock", "direct", "pagevec", "drain", "", "", "", "", "", "", "", ""); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci foreach $process_pid (keys %stats) { 32562306a36Sopenharmony_ci # Dump final aggregates 32662306a36Sopenharmony_ci if ($stats{$process_pid}->{STATE_PCPU_PAGES_DRAINED}) { 32762306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_PCPU_DRAINS}++; 32862306a36Sopenharmony_ci $stats{$process_pid}->{STATE_PCPU_PAGES_DRAINED} = 0; 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci if ($stats{$process_pid}->{STATE_PCPU_PAGES_REFILLED}) { 33162306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_PCPU_REFILLS}++; 33262306a36Sopenharmony_ci $stats{$process_pid}->{STATE_PCPU_PAGES_REFILLED} = 0; 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci printf("%-" . $max_strlen . "s %8d %10d %8d %8d %8d %8d %8d %8d %8d %8d %8d %8d %8d\n", 33662306a36Sopenharmony_ci $process_pid, 33762306a36Sopenharmony_ci $stats{$process_pid}->{MM_PAGE_ALLOC}, 33862306a36Sopenharmony_ci $stats{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED}, 33962306a36Sopenharmony_ci $stats{$process_pid}->{MM_PAGE_FREE}, 34062306a36Sopenharmony_ci $stats{$process_pid}->{MM_PAGE_FREE_BATCHED}, 34162306a36Sopenharmony_ci $stats{$process_pid}->{MM_PAGE_PCPU_DRAIN}, 34262306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_PCPU_DRAINS}, 34362306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_PCPU_REFILLS}, 34462306a36Sopenharmony_ci $stats{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG}, 34562306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_EXT_FRAG}, 34662306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED}, 34762306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE}, 34862306a36Sopenharmony_ci $stats{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE}, 34962306a36Sopenharmony_ci $stats{$process_pid}->{EVENT_UNKNOWN}); 35062306a36Sopenharmony_ci } 35162306a36Sopenharmony_ci} 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_cisub aggregate_perprocesspid() { 35462306a36Sopenharmony_ci my $process_pid; 35562306a36Sopenharmony_ci my $process; 35662306a36Sopenharmony_ci undef %perprocess; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci foreach $process_pid (keys %perprocesspid) { 35962306a36Sopenharmony_ci $process = $process_pid; 36062306a36Sopenharmony_ci $process =~ s/-([0-9])*$//; 36162306a36Sopenharmony_ci if ($process eq '') { 36262306a36Sopenharmony_ci $process = "NO_PROCESS_NAME"; 36362306a36Sopenharmony_ci } 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci $perprocess{$process}->{MM_PAGE_ALLOC} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC}; 36662306a36Sopenharmony_ci $perprocess{$process}->{MM_PAGE_ALLOC_ZONE_LOCKED} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED}; 36762306a36Sopenharmony_ci $perprocess{$process}->{MM_PAGE_FREE} += $perprocesspid{$process_pid}->{MM_PAGE_FREE}; 36862306a36Sopenharmony_ci $perprocess{$process}->{MM_PAGE_FREE_BATCHED} += $perprocesspid{$process_pid}->{MM_PAGE_FREE_BATCHED}; 36962306a36Sopenharmony_ci $perprocess{$process}->{MM_PAGE_PCPU_DRAIN} += $perprocesspid{$process_pid}->{MM_PAGE_PCPU_DRAIN}; 37062306a36Sopenharmony_ci $perprocess{$process}->{HIGH_PCPU_DRAINS} += $perprocesspid{$process_pid}->{HIGH_PCPU_DRAINS}; 37162306a36Sopenharmony_ci $perprocess{$process}->{HIGH_PCPU_REFILLS} += $perprocesspid{$process_pid}->{HIGH_PCPU_REFILLS}; 37262306a36Sopenharmony_ci $perprocess{$process}->{MM_PAGE_ALLOC_EXTFRAG} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG}; 37362306a36Sopenharmony_ci $perprocess{$process}->{HIGH_EXT_FRAG} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAG}; 37462306a36Sopenharmony_ci $perprocess{$process}->{HIGH_EXT_FRAGMENT_CHANGED} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED}; 37562306a36Sopenharmony_ci $perprocess{$process}->{HIGH_EXT_FRAGMENT_SEVERE} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE}; 37662306a36Sopenharmony_ci $perprocess{$process}->{HIGH_EXT_FRAGMENT_MODERATE} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE}; 37762306a36Sopenharmony_ci $perprocess{$process}->{EVENT_UNKNOWN} += $perprocesspid{$process_pid}->{EVENT_UNKNOWN}; 37862306a36Sopenharmony_ci } 37962306a36Sopenharmony_ci} 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_cisub report() { 38262306a36Sopenharmony_ci if (!$opt_ignorepid) { 38362306a36Sopenharmony_ci dump_stats(\%perprocesspid); 38462306a36Sopenharmony_ci } else { 38562306a36Sopenharmony_ci aggregate_perprocesspid(); 38662306a36Sopenharmony_ci dump_stats(\%perprocess); 38762306a36Sopenharmony_ci } 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci# Process events or signals until neither is available 39162306a36Sopenharmony_cisub signal_loop() { 39262306a36Sopenharmony_ci my $sigint_processed; 39362306a36Sopenharmony_ci do { 39462306a36Sopenharmony_ci $sigint_processed = 0; 39562306a36Sopenharmony_ci process_events(); 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci # Handle pending signals if any 39862306a36Sopenharmony_ci if ($sigint_pending) { 39962306a36Sopenharmony_ci my $current_time = time; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci if ($sigint_exit) { 40262306a36Sopenharmony_ci print "Received exit signal\n"; 40362306a36Sopenharmony_ci $sigint_pending = 0; 40462306a36Sopenharmony_ci } 40562306a36Sopenharmony_ci if ($sigint_report) { 40662306a36Sopenharmony_ci if ($current_time >= $sigint_received + 2) { 40762306a36Sopenharmony_ci report(); 40862306a36Sopenharmony_ci $sigint_report = 0; 40962306a36Sopenharmony_ci $sigint_pending = 0; 41062306a36Sopenharmony_ci $sigint_processed = 1; 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci } 41362306a36Sopenharmony_ci } 41462306a36Sopenharmony_ci } while ($sigint_pending || $sigint_processed); 41562306a36Sopenharmony_ci} 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_cisignal_loop(); 41862306a36Sopenharmony_cireport(); 419