18c2ecf20Sopenharmony_ci#!/usr/bin/env perl
28c2ecf20Sopenharmony_ci# This is a POC for reading the text representation of trace output related to
38c2ecf20Sopenharmony_ci# page reclaim. It makes an attempt to extract some high-level information on
48c2ecf20Sopenharmony_ci# what is going on. The accuracy of the parser may vary
58c2ecf20Sopenharmony_ci#
68c2ecf20Sopenharmony_ci# Example usage: trace-vmscan-postprocess.pl < /sys/kernel/debug/tracing/trace_pipe
78c2ecf20Sopenharmony_ci# other options
88c2ecf20Sopenharmony_ci#   --read-procstat	If the trace lacks process info, get it from /proc
98c2ecf20Sopenharmony_ci#   --ignore-pid	Aggregate processes of the same name together
108c2ecf20Sopenharmony_ci#
118c2ecf20Sopenharmony_ci# Copyright (c) IBM Corporation 2009
128c2ecf20Sopenharmony_ci# Author: Mel Gorman <mel@csn.ul.ie>
138c2ecf20Sopenharmony_ciuse strict;
148c2ecf20Sopenharmony_ciuse Getopt::Long;
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci# Tracepoint events
178c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN	=> 1;
188c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_DIRECT_RECLAIM_END	=> 2;
198c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_KSWAPD_WAKE		=> 3;
208c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_KSWAPD_SLEEP		=> 4;
218c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_LRU_SHRINK_ACTIVE	=> 5;
228c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_LRU_SHRINK_INACTIVE	=> 6;
238c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_LRU_ISOLATE		=> 7;
248c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_WRITEPAGE_FILE_SYNC	=> 8;
258c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_WRITEPAGE_ANON_SYNC	=> 9;
268c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_WRITEPAGE_FILE_ASYNC	=> 10;
278c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_WRITEPAGE_ANON_ASYNC	=> 11;
288c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_WRITEPAGE_ASYNC		=> 12;
298c2ecf20Sopenharmony_ciuse constant EVENT_UNKNOWN			=> 13;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci# Per-order events
328c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER => 11;
338c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_WAKEUP_KSWAPD_PERORDER 	=> 12;
348c2ecf20Sopenharmony_ciuse constant MM_VMSCAN_KSWAPD_WAKE_PERORDER	=> 13;
358c2ecf20Sopenharmony_ciuse constant HIGH_KSWAPD_REWAKEUP_PERORDER	=> 14;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci# Constants used to track state
388c2ecf20Sopenharmony_ciuse constant STATE_DIRECT_BEGIN 		=> 15;
398c2ecf20Sopenharmony_ciuse constant STATE_DIRECT_ORDER 		=> 16;
408c2ecf20Sopenharmony_ciuse constant STATE_KSWAPD_BEGIN			=> 17;
418c2ecf20Sopenharmony_ciuse constant STATE_KSWAPD_ORDER			=> 18;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci# High-level events extrapolated from tracepoints
448c2ecf20Sopenharmony_ciuse constant HIGH_DIRECT_RECLAIM_LATENCY	=> 19;
458c2ecf20Sopenharmony_ciuse constant HIGH_KSWAPD_LATENCY		=> 20;
468c2ecf20Sopenharmony_ciuse constant HIGH_KSWAPD_REWAKEUP		=> 21;
478c2ecf20Sopenharmony_ciuse constant HIGH_NR_SCANNED			=> 22;
488c2ecf20Sopenharmony_ciuse constant HIGH_NR_TAKEN			=> 23;
498c2ecf20Sopenharmony_ciuse constant HIGH_NR_RECLAIMED			=> 24;
508c2ecf20Sopenharmony_ciuse constant HIGH_NR_FILE_SCANNED		=> 25;
518c2ecf20Sopenharmony_ciuse constant HIGH_NR_ANON_SCANNED		=> 26;
528c2ecf20Sopenharmony_ciuse constant HIGH_NR_FILE_RECLAIMED		=> 27;
538c2ecf20Sopenharmony_ciuse constant HIGH_NR_ANON_RECLAIMED		=> 28;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cimy %perprocesspid;
568c2ecf20Sopenharmony_cimy %perprocess;
578c2ecf20Sopenharmony_cimy %last_procmap;
588c2ecf20Sopenharmony_cimy $opt_ignorepid;
598c2ecf20Sopenharmony_cimy $opt_read_procstat;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cimy $total_wakeup_kswapd;
628c2ecf20Sopenharmony_cimy ($total_direct_reclaim, $total_direct_nr_scanned);
638c2ecf20Sopenharmony_cimy ($total_direct_nr_file_scanned, $total_direct_nr_anon_scanned);
648c2ecf20Sopenharmony_cimy ($total_direct_latency, $total_kswapd_latency);
658c2ecf20Sopenharmony_cimy ($total_direct_nr_reclaimed);
668c2ecf20Sopenharmony_cimy ($total_direct_nr_file_reclaimed, $total_direct_nr_anon_reclaimed);
678c2ecf20Sopenharmony_cimy ($total_direct_writepage_file_sync, $total_direct_writepage_file_async);
688c2ecf20Sopenharmony_cimy ($total_direct_writepage_anon_sync, $total_direct_writepage_anon_async);
698c2ecf20Sopenharmony_cimy ($total_kswapd_nr_scanned, $total_kswapd_wake);
708c2ecf20Sopenharmony_cimy ($total_kswapd_nr_file_scanned, $total_kswapd_nr_anon_scanned);
718c2ecf20Sopenharmony_cimy ($total_kswapd_writepage_file_sync, $total_kswapd_writepage_file_async);
728c2ecf20Sopenharmony_cimy ($total_kswapd_writepage_anon_sync, $total_kswapd_writepage_anon_async);
738c2ecf20Sopenharmony_cimy ($total_kswapd_nr_reclaimed);
748c2ecf20Sopenharmony_cimy ($total_kswapd_nr_file_reclaimed, $total_kswapd_nr_anon_reclaimed);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci# Catch sigint and exit on request
778c2ecf20Sopenharmony_cimy $sigint_report = 0;
788c2ecf20Sopenharmony_cimy $sigint_exit = 0;
798c2ecf20Sopenharmony_cimy $sigint_pending = 0;
808c2ecf20Sopenharmony_cimy $sigint_received = 0;
818c2ecf20Sopenharmony_cisub sigint_handler {
828c2ecf20Sopenharmony_ci	my $current_time = time;
838c2ecf20Sopenharmony_ci	if ($current_time - 2 > $sigint_received) {
848c2ecf20Sopenharmony_ci		print "SIGINT received, report pending. Hit ctrl-c again to exit\n";
858c2ecf20Sopenharmony_ci		$sigint_report = 1;
868c2ecf20Sopenharmony_ci	} else {
878c2ecf20Sopenharmony_ci		if (!$sigint_exit) {
888c2ecf20Sopenharmony_ci			print "Second SIGINT received quickly, exiting\n";
898c2ecf20Sopenharmony_ci		}
908c2ecf20Sopenharmony_ci		$sigint_exit++;
918c2ecf20Sopenharmony_ci	}
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	if ($sigint_exit > 3) {
948c2ecf20Sopenharmony_ci		print "Many SIGINTs received, exiting now without report\n";
958c2ecf20Sopenharmony_ci		exit;
968c2ecf20Sopenharmony_ci	}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	$sigint_received = $current_time;
998c2ecf20Sopenharmony_ci	$sigint_pending = 1;
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci$SIG{INT} = "sigint_handler";
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci# Parse command line options
1048c2ecf20Sopenharmony_ciGetOptions(
1058c2ecf20Sopenharmony_ci	'ignore-pid'	 =>	\$opt_ignorepid,
1068c2ecf20Sopenharmony_ci	'read-procstat'	 =>	\$opt_read_procstat,
1078c2ecf20Sopenharmony_ci);
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci# Defaults for dynamically discovered regex's
1108c2ecf20Sopenharmony_cimy $regex_direct_begin_default = 'order=([0-9]*) may_writepage=([0-9]*) gfp_flags=([A-Z_|]*)';
1118c2ecf20Sopenharmony_cimy $regex_direct_end_default = 'nr_reclaimed=([0-9]*)';
1128c2ecf20Sopenharmony_cimy $regex_kswapd_wake_default = 'nid=([0-9]*) order=([0-9]*)';
1138c2ecf20Sopenharmony_cimy $regex_kswapd_sleep_default = 'nid=([0-9]*)';
1148c2ecf20Sopenharmony_cimy $regex_wakeup_kswapd_default = 'nid=([0-9]*) zid=([0-9]*) order=([0-9]*) gfp_flags=([A-Z_|]*)';
1158c2ecf20Sopenharmony_cimy $regex_lru_isolate_default = 'isolate_mode=([0-9]*) classzone_idx=([0-9]*) order=([0-9]*) nr_requested=([0-9]*) nr_scanned=([0-9]*) nr_skipped=([0-9]*) nr_taken=([0-9]*) lru=([a-z_]*)';
1168c2ecf20Sopenharmony_cimy $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_|]*)';
1178c2ecf20Sopenharmony_cimy $regex_lru_shrink_active_default = 'lru=([A-Z_]*) nr_scanned=([0-9]*) nr_rotated=([0-9]*) priority=([0-9]*)';
1188c2ecf20Sopenharmony_cimy $regex_writepage_default = 'page=([0-9a-f]*) pfn=([0-9]*) flags=([A-Z_|]*)';
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci# Dyanically discovered regex
1218c2ecf20Sopenharmony_cimy $regex_direct_begin;
1228c2ecf20Sopenharmony_cimy $regex_direct_end;
1238c2ecf20Sopenharmony_cimy $regex_kswapd_wake;
1248c2ecf20Sopenharmony_cimy $regex_kswapd_sleep;
1258c2ecf20Sopenharmony_cimy $regex_wakeup_kswapd;
1268c2ecf20Sopenharmony_cimy $regex_lru_isolate;
1278c2ecf20Sopenharmony_cimy $regex_lru_shrink_inactive;
1288c2ecf20Sopenharmony_cimy $regex_lru_shrink_active;
1298c2ecf20Sopenharmony_cimy $regex_writepage;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci# Static regex used. Specified like this for readability and for use with /o
1328c2ecf20Sopenharmony_ci#                      (process_pid)     (cpus      )   ( time  )   (tpoint    ) (details)
1338c2ecf20Sopenharmony_cimy $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*(.*)';
1348c2ecf20Sopenharmony_cimy $regex_statname = '[-0-9]*\s\((.*)\).*';
1358c2ecf20Sopenharmony_cimy $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*';
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_cisub generate_traceevent_regex {
1388c2ecf20Sopenharmony_ci	my $event = shift;
1398c2ecf20Sopenharmony_ci	my $default = shift;
1408c2ecf20Sopenharmony_ci	my $regex;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	# Read the event format or use the default
1438c2ecf20Sopenharmony_ci	if (!open (FORMAT, "/sys/kernel/debug/tracing/events/$event/format")) {
1448c2ecf20Sopenharmony_ci		print("WARNING: Event $event format string not found\n");
1458c2ecf20Sopenharmony_ci		return $default;
1468c2ecf20Sopenharmony_ci	} else {
1478c2ecf20Sopenharmony_ci		my $line;
1488c2ecf20Sopenharmony_ci		while (!eof(FORMAT)) {
1498c2ecf20Sopenharmony_ci			$line = <FORMAT>;
1508c2ecf20Sopenharmony_ci			$line =~ s/, REC->.*//;
1518c2ecf20Sopenharmony_ci			if ($line =~ /^print fmt:\s"(.*)".*/) {
1528c2ecf20Sopenharmony_ci				$regex = $1;
1538c2ecf20Sopenharmony_ci				$regex =~ s/%s/\([0-9a-zA-Z|_]*\)/g;
1548c2ecf20Sopenharmony_ci				$regex =~ s/%p/\([0-9a-f]*\)/g;
1558c2ecf20Sopenharmony_ci				$regex =~ s/%d/\([-0-9]*\)/g;
1568c2ecf20Sopenharmony_ci				$regex =~ s/%ld/\([-0-9]*\)/g;
1578c2ecf20Sopenharmony_ci				$regex =~ s/%lu/\([0-9]*\)/g;
1588c2ecf20Sopenharmony_ci			}
1598c2ecf20Sopenharmony_ci		}
1608c2ecf20Sopenharmony_ci	}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	# Can't handle the print_flags stuff but in the context of this
1638c2ecf20Sopenharmony_ci	# script, it really doesn't matter
1648c2ecf20Sopenharmony_ci	$regex =~ s/\(REC.*\) \? __print_flags.*//;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	# Verify fields are in the right order
1678c2ecf20Sopenharmony_ci	my $tuple;
1688c2ecf20Sopenharmony_ci	foreach $tuple (split /\s/, $regex) {
1698c2ecf20Sopenharmony_ci		my ($key, $value) = split(/=/, $tuple);
1708c2ecf20Sopenharmony_ci		my $expected = shift;
1718c2ecf20Sopenharmony_ci		if ($key ne $expected) {
1728c2ecf20Sopenharmony_ci			print("WARNING: Format not as expected for event $event '$key' != '$expected'\n");
1738c2ecf20Sopenharmony_ci			$regex =~ s/$key=\((.*)\)/$key=$1/;
1748c2ecf20Sopenharmony_ci		}
1758c2ecf20Sopenharmony_ci	}
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	if (defined shift) {
1788c2ecf20Sopenharmony_ci		die("Fewer fields than expected in format");
1798c2ecf20Sopenharmony_ci	}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	return $regex;
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci$regex_direct_begin = generate_traceevent_regex(
1858c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_direct_reclaim_begin",
1868c2ecf20Sopenharmony_ci			$regex_direct_begin_default,
1878c2ecf20Sopenharmony_ci			"order", "may_writepage",
1888c2ecf20Sopenharmony_ci			"gfp_flags");
1898c2ecf20Sopenharmony_ci$regex_direct_end = generate_traceevent_regex(
1908c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_direct_reclaim_end",
1918c2ecf20Sopenharmony_ci			$regex_direct_end_default,
1928c2ecf20Sopenharmony_ci			"nr_reclaimed");
1938c2ecf20Sopenharmony_ci$regex_kswapd_wake = generate_traceevent_regex(
1948c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_kswapd_wake",
1958c2ecf20Sopenharmony_ci			$regex_kswapd_wake_default,
1968c2ecf20Sopenharmony_ci			"nid", "order");
1978c2ecf20Sopenharmony_ci$regex_kswapd_sleep = generate_traceevent_regex(
1988c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_kswapd_sleep",
1998c2ecf20Sopenharmony_ci			$regex_kswapd_sleep_default,
2008c2ecf20Sopenharmony_ci			"nid");
2018c2ecf20Sopenharmony_ci$regex_wakeup_kswapd = generate_traceevent_regex(
2028c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_wakeup_kswapd",
2038c2ecf20Sopenharmony_ci			$regex_wakeup_kswapd_default,
2048c2ecf20Sopenharmony_ci			"nid", "zid", "order", "gfp_flags");
2058c2ecf20Sopenharmony_ci$regex_lru_isolate = generate_traceevent_regex(
2068c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_lru_isolate",
2078c2ecf20Sopenharmony_ci			$regex_lru_isolate_default,
2088c2ecf20Sopenharmony_ci			"isolate_mode", "classzone_idx", "order",
2098c2ecf20Sopenharmony_ci			"nr_requested", "nr_scanned", "nr_skipped", "nr_taken",
2108c2ecf20Sopenharmony_ci			"lru");
2118c2ecf20Sopenharmony_ci$regex_lru_shrink_inactive = generate_traceevent_regex(
2128c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_lru_shrink_inactive",
2138c2ecf20Sopenharmony_ci			$regex_lru_shrink_inactive_default,
2148c2ecf20Sopenharmony_ci			"nid", "nr_scanned", "nr_reclaimed", "nr_dirty", "nr_writeback",
2158c2ecf20Sopenharmony_ci			"nr_congested", "nr_immediate", "nr_activate_anon",
2168c2ecf20Sopenharmony_ci			"nr_activate_file", "nr_ref_keep",
2178c2ecf20Sopenharmony_ci			"nr_unmap_fail", "priority", "flags");
2188c2ecf20Sopenharmony_ci$regex_lru_shrink_active = generate_traceevent_regex(
2198c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_lru_shrink_active",
2208c2ecf20Sopenharmony_ci			$regex_lru_shrink_active_default,
2218c2ecf20Sopenharmony_ci			"nid", "zid",
2228c2ecf20Sopenharmony_ci			"lru",
2238c2ecf20Sopenharmony_ci			"nr_scanned", "nr_rotated", "priority");
2248c2ecf20Sopenharmony_ci$regex_writepage = generate_traceevent_regex(
2258c2ecf20Sopenharmony_ci			"vmscan/mm_vmscan_writepage",
2268c2ecf20Sopenharmony_ci			$regex_writepage_default,
2278c2ecf20Sopenharmony_ci			"page", "pfn", "flags");
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_cisub read_statline($) {
2308c2ecf20Sopenharmony_ci	my $pid = $_[0];
2318c2ecf20Sopenharmony_ci	my $statline;
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	if (open(STAT, "/proc/$pid/stat")) {
2348c2ecf20Sopenharmony_ci		$statline = <STAT>;
2358c2ecf20Sopenharmony_ci		close(STAT);
2368c2ecf20Sopenharmony_ci	}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	if ($statline eq '') {
2398c2ecf20Sopenharmony_ci		$statline = "-1 (UNKNOWN_PROCESS_NAME) R 0";
2408c2ecf20Sopenharmony_ci	}
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	return $statline;
2438c2ecf20Sopenharmony_ci}
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_cisub guess_process_pid($$) {
2468c2ecf20Sopenharmony_ci	my $pid = $_[0];
2478c2ecf20Sopenharmony_ci	my $statline = $_[1];
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	if ($pid == 0) {
2508c2ecf20Sopenharmony_ci		return "swapper-0";
2518c2ecf20Sopenharmony_ci	}
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	if ($statline !~ /$regex_statname/o) {
2548c2ecf20Sopenharmony_ci		die("Failed to math stat line for process name :: $statline");
2558c2ecf20Sopenharmony_ci	}
2568c2ecf20Sopenharmony_ci	return "$1-$pid";
2578c2ecf20Sopenharmony_ci}
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci# Convert sec.usec timestamp format
2608c2ecf20Sopenharmony_cisub timestamp_to_ms($) {
2618c2ecf20Sopenharmony_ci	my $timestamp = $_[0];
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	my ($sec, $usec) = split (/\./, $timestamp);
2648c2ecf20Sopenharmony_ci	return ($sec * 1000) + ($usec / 1000);
2658c2ecf20Sopenharmony_ci}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_cisub process_events {
2688c2ecf20Sopenharmony_ci	my $traceevent;
2698c2ecf20Sopenharmony_ci	my $process_pid;
2708c2ecf20Sopenharmony_ci	my $cpus;
2718c2ecf20Sopenharmony_ci	my $timestamp;
2728c2ecf20Sopenharmony_ci	my $tracepoint;
2738c2ecf20Sopenharmony_ci	my $details;
2748c2ecf20Sopenharmony_ci	my $statline;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	# Read each line of the event log
2778c2ecf20Sopenharmony_ciEVENT_PROCESS:
2788c2ecf20Sopenharmony_ci	while ($traceevent = <STDIN>) {
2798c2ecf20Sopenharmony_ci		if ($traceevent =~ /$regex_traceevent/o) {
2808c2ecf20Sopenharmony_ci			$process_pid = $1;
2818c2ecf20Sopenharmony_ci			$timestamp = $4;
2828c2ecf20Sopenharmony_ci			$tracepoint = $5;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci			$process_pid =~ /(.*)-([0-9]*)$/;
2858c2ecf20Sopenharmony_ci			my $process = $1;
2868c2ecf20Sopenharmony_ci			my $pid = $2;
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci			if ($process eq "") {
2898c2ecf20Sopenharmony_ci				$process = $last_procmap{$pid};
2908c2ecf20Sopenharmony_ci				$process_pid = "$process-$pid";
2918c2ecf20Sopenharmony_ci			}
2928c2ecf20Sopenharmony_ci			$last_procmap{$pid} = $process;
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci			if ($opt_read_procstat) {
2958c2ecf20Sopenharmony_ci				$statline = read_statline($pid);
2968c2ecf20Sopenharmony_ci				if ($opt_read_procstat && $process eq '') {
2978c2ecf20Sopenharmony_ci					$process_pid = guess_process_pid($pid, $statline);
2988c2ecf20Sopenharmony_ci				}
2998c2ecf20Sopenharmony_ci			}
3008c2ecf20Sopenharmony_ci		} else {
3018c2ecf20Sopenharmony_ci			next;
3028c2ecf20Sopenharmony_ci		}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci		# Perl Switch() sucks majorly
3058c2ecf20Sopenharmony_ci		if ($tracepoint eq "mm_vmscan_direct_reclaim_begin") {
3068c2ecf20Sopenharmony_ci			$timestamp = timestamp_to_ms($timestamp);
3078c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}++;
3088c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN} = $timestamp;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci			$details = $6;
3118c2ecf20Sopenharmony_ci			if ($details !~ /$regex_direct_begin/o) {
3128c2ecf20Sopenharmony_ci				print "WARNING: Failed to parse mm_vmscan_direct_reclaim_begin as expected\n";
3138c2ecf20Sopenharmony_ci				print "         $details\n";
3148c2ecf20Sopenharmony_ci				print "         $regex_direct_begin\n";
3158c2ecf20Sopenharmony_ci				next;
3168c2ecf20Sopenharmony_ci			}
3178c2ecf20Sopenharmony_ci			my $order = $1;
3188c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order]++;
3198c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{STATE_DIRECT_ORDER} = $order;
3208c2ecf20Sopenharmony_ci		} elsif ($tracepoint eq "mm_vmscan_direct_reclaim_end") {
3218c2ecf20Sopenharmony_ci			# Count the event itself
3228c2ecf20Sopenharmony_ci			my $index = $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_END};
3238c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_END}++;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci			# Record how long direct reclaim took this time
3268c2ecf20Sopenharmony_ci			if (defined $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN}) {
3278c2ecf20Sopenharmony_ci				$timestamp = timestamp_to_ms($timestamp);
3288c2ecf20Sopenharmony_ci				my $order = $perprocesspid{$process_pid}->{STATE_DIRECT_ORDER};
3298c2ecf20Sopenharmony_ci				my $latency = ($timestamp - $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN});
3308c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] = "$order-$latency";
3318c2ecf20Sopenharmony_ci			}
3328c2ecf20Sopenharmony_ci		} elsif ($tracepoint eq "mm_vmscan_kswapd_wake") {
3338c2ecf20Sopenharmony_ci			$details = $6;
3348c2ecf20Sopenharmony_ci			if ($details !~ /$regex_kswapd_wake/o) {
3358c2ecf20Sopenharmony_ci				print "WARNING: Failed to parse mm_vmscan_kswapd_wake as expected\n";
3368c2ecf20Sopenharmony_ci				print "         $details\n";
3378c2ecf20Sopenharmony_ci				print "         $regex_kswapd_wake\n";
3388c2ecf20Sopenharmony_ci				next;
3398c2ecf20Sopenharmony_ci			}
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci			my $order = $2;
3428c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{STATE_KSWAPD_ORDER} = $order;
3438c2ecf20Sopenharmony_ci			if (!$perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN}) {
3448c2ecf20Sopenharmony_ci				$timestamp = timestamp_to_ms($timestamp);
3458c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}++;
3468c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN} = $timestamp;
3478c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order]++;
3488c2ecf20Sopenharmony_ci			} else {
3498c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP}++;
3508c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP_PERORDER}[$order]++;
3518c2ecf20Sopenharmony_ci			}
3528c2ecf20Sopenharmony_ci		} elsif ($tracepoint eq "mm_vmscan_kswapd_sleep") {
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci			# Count the event itself
3558c2ecf20Sopenharmony_ci			my $index = $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_SLEEP};
3568c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_SLEEP}++;
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci			# Record how long kswapd was awake
3598c2ecf20Sopenharmony_ci			$timestamp = timestamp_to_ms($timestamp);
3608c2ecf20Sopenharmony_ci			my $order = $perprocesspid{$process_pid}->{STATE_KSWAPD_ORDER};
3618c2ecf20Sopenharmony_ci			my $latency = ($timestamp - $perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN});
3628c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index] = "$order-$latency";
3638c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN} = 0;
3648c2ecf20Sopenharmony_ci		} elsif ($tracepoint eq "mm_vmscan_wakeup_kswapd") {
3658c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}++;
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci			$details = $6;
3688c2ecf20Sopenharmony_ci			if ($details !~ /$regex_wakeup_kswapd/o) {
3698c2ecf20Sopenharmony_ci				print "WARNING: Failed to parse mm_vmscan_wakeup_kswapd as expected\n";
3708c2ecf20Sopenharmony_ci				print "         $details\n";
3718c2ecf20Sopenharmony_ci				print "         $regex_wakeup_kswapd\n";
3728c2ecf20Sopenharmony_ci				next;
3738c2ecf20Sopenharmony_ci			}
3748c2ecf20Sopenharmony_ci			my $order = $3;
3758c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]++;
3768c2ecf20Sopenharmony_ci		} elsif ($tracepoint eq "mm_vmscan_lru_isolate") {
3778c2ecf20Sopenharmony_ci			$details = $6;
3788c2ecf20Sopenharmony_ci			if ($details !~ /$regex_lru_isolate/o) {
3798c2ecf20Sopenharmony_ci				print "WARNING: Failed to parse mm_vmscan_lru_isolate as expected\n";
3808c2ecf20Sopenharmony_ci				print "         $details\n";
3818c2ecf20Sopenharmony_ci				print "         $regex_lru_isolate/o\n";
3828c2ecf20Sopenharmony_ci				next;
3838c2ecf20Sopenharmony_ci			}
3848c2ecf20Sopenharmony_ci			my $isolate_mode = $1;
3858c2ecf20Sopenharmony_ci			my $nr_scanned = $5;
3868c2ecf20Sopenharmony_ci			my $file = $8;
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci			# To closer match vmstat scanning statistics, only count isolate_both
3898c2ecf20Sopenharmony_ci			# and isolate_inactive as scanning. isolate_active is rotation
3908c2ecf20Sopenharmony_ci			# isolate_inactive == 1
3918c2ecf20Sopenharmony_ci			# isolate_active   == 2
3928c2ecf20Sopenharmony_ci			# isolate_both     == 3
3938c2ecf20Sopenharmony_ci			if ($isolate_mode != 2) {
3948c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
3958c2ecf20Sopenharmony_ci				if ($file =~ /_file/) {
3968c2ecf20Sopenharmony_ci					$perprocesspid{$process_pid}->{HIGH_NR_FILE_SCANNED} += $nr_scanned;
3978c2ecf20Sopenharmony_ci				} else {
3988c2ecf20Sopenharmony_ci					$perprocesspid{$process_pid}->{HIGH_NR_ANON_SCANNED} += $nr_scanned;
3998c2ecf20Sopenharmony_ci				}
4008c2ecf20Sopenharmony_ci			}
4018c2ecf20Sopenharmony_ci		} elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") {
4028c2ecf20Sopenharmony_ci			$details = $6;
4038c2ecf20Sopenharmony_ci			if ($details !~ /$regex_lru_shrink_inactive/o) {
4048c2ecf20Sopenharmony_ci				print "WARNING: Failed to parse mm_vmscan_lru_shrink_inactive as expected\n";
4058c2ecf20Sopenharmony_ci				print "         $details\n";
4068c2ecf20Sopenharmony_ci				print "         $regex_lru_shrink_inactive/o\n";
4078c2ecf20Sopenharmony_ci				next;
4088c2ecf20Sopenharmony_ci			}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci			my $nr_reclaimed = $3;
4118c2ecf20Sopenharmony_ci			my $flags = $13;
4128c2ecf20Sopenharmony_ci			my $file = 0;
4138c2ecf20Sopenharmony_ci			if ($flags =~ /RECLAIM_WB_FILE/) {
4148c2ecf20Sopenharmony_ci				$file = 1;
4158c2ecf20Sopenharmony_ci			}
4168c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED} += $nr_reclaimed;
4178c2ecf20Sopenharmony_ci			if ($file) {
4188c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{HIGH_NR_FILE_RECLAIMED} += $nr_reclaimed;
4198c2ecf20Sopenharmony_ci			} else {
4208c2ecf20Sopenharmony_ci				$perprocesspid{$process_pid}->{HIGH_NR_ANON_RECLAIMED} += $nr_reclaimed;
4218c2ecf20Sopenharmony_ci			}
4228c2ecf20Sopenharmony_ci		} elsif ($tracepoint eq "mm_vmscan_writepage") {
4238c2ecf20Sopenharmony_ci			$details = $6;
4248c2ecf20Sopenharmony_ci			if ($details !~ /$regex_writepage/o) {
4258c2ecf20Sopenharmony_ci				print "WARNING: Failed to parse mm_vmscan_writepage as expected\n";
4268c2ecf20Sopenharmony_ci				print "         $details\n";
4278c2ecf20Sopenharmony_ci				print "         $regex_writepage\n";
4288c2ecf20Sopenharmony_ci				next;
4298c2ecf20Sopenharmony_ci			}
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci			my $flags = $3;
4328c2ecf20Sopenharmony_ci			my $file = 0;
4338c2ecf20Sopenharmony_ci			my $sync_io = 0;
4348c2ecf20Sopenharmony_ci			if ($flags =~ /RECLAIM_WB_FILE/) {
4358c2ecf20Sopenharmony_ci				$file = 1;
4368c2ecf20Sopenharmony_ci			}
4378c2ecf20Sopenharmony_ci			if ($flags =~ /RECLAIM_WB_SYNC/) {
4388c2ecf20Sopenharmony_ci				$sync_io = 1;
4398c2ecf20Sopenharmony_ci			}
4408c2ecf20Sopenharmony_ci			if ($sync_io) {
4418c2ecf20Sopenharmony_ci				if ($file) {
4428c2ecf20Sopenharmony_ci					$perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC}++;
4438c2ecf20Sopenharmony_ci				} else {
4448c2ecf20Sopenharmony_ci					$perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}++;
4458c2ecf20Sopenharmony_ci				}
4468c2ecf20Sopenharmony_ci			} else {
4478c2ecf20Sopenharmony_ci				if ($file) {
4488c2ecf20Sopenharmony_ci					$perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC}++;
4498c2ecf20Sopenharmony_ci				} else {
4508c2ecf20Sopenharmony_ci					$perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}++;
4518c2ecf20Sopenharmony_ci				}
4528c2ecf20Sopenharmony_ci			}
4538c2ecf20Sopenharmony_ci		} else {
4548c2ecf20Sopenharmony_ci			$perprocesspid{$process_pid}->{EVENT_UNKNOWN}++;
4558c2ecf20Sopenharmony_ci		}
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_ci		if ($sigint_pending) {
4588c2ecf20Sopenharmony_ci			last EVENT_PROCESS;
4598c2ecf20Sopenharmony_ci		}
4608c2ecf20Sopenharmony_ci	}
4618c2ecf20Sopenharmony_ci}
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_cisub dump_stats {
4648c2ecf20Sopenharmony_ci	my $hashref = shift;
4658c2ecf20Sopenharmony_ci	my %stats = %$hashref;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	# Dump per-process stats
4688c2ecf20Sopenharmony_ci	my $process_pid;
4698c2ecf20Sopenharmony_ci	my $max_strlen = 0;
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	# Get the maximum process name
4728c2ecf20Sopenharmony_ci	foreach $process_pid (keys %perprocesspid) {
4738c2ecf20Sopenharmony_ci		my $len = length($process_pid);
4748c2ecf20Sopenharmony_ci		if ($len > $max_strlen) {
4758c2ecf20Sopenharmony_ci			$max_strlen = $len;
4768c2ecf20Sopenharmony_ci		}
4778c2ecf20Sopenharmony_ci	}
4788c2ecf20Sopenharmony_ci	$max_strlen += 2;
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci	# Work out latencies
4818c2ecf20Sopenharmony_ci	printf("\n") if !$opt_ignorepid;
4828c2ecf20Sopenharmony_ci	printf("Reclaim latencies expressed as order-latency_in_ms\n") if !$opt_ignorepid;
4838c2ecf20Sopenharmony_ci	foreach $process_pid (keys %stats) {
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci		if (!$stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[0] &&
4868c2ecf20Sopenharmony_ci				!$stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[0]) {
4878c2ecf20Sopenharmony_ci			next;
4888c2ecf20Sopenharmony_ci		}
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci		printf "%-" . $max_strlen . "s ", $process_pid if !$opt_ignorepid;
4918c2ecf20Sopenharmony_ci		my $index = 0;
4928c2ecf20Sopenharmony_ci		while (defined $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] ||
4938c2ecf20Sopenharmony_ci			defined $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]) {
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci			if ($stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) {
4968c2ecf20Sopenharmony_ci				printf("%s ", $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) if !$opt_ignorepid;
4978c2ecf20Sopenharmony_ci				my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]);
4988c2ecf20Sopenharmony_ci				$total_direct_latency += $latency;
4998c2ecf20Sopenharmony_ci			} else {
5008c2ecf20Sopenharmony_ci				printf("%s ", $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]) if !$opt_ignorepid;
5018c2ecf20Sopenharmony_ci				my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]);
5028c2ecf20Sopenharmony_ci				$total_kswapd_latency += $latency;
5038c2ecf20Sopenharmony_ci			}
5048c2ecf20Sopenharmony_ci			$index++;
5058c2ecf20Sopenharmony_ci		}
5068c2ecf20Sopenharmony_ci		print "\n" if !$opt_ignorepid;
5078c2ecf20Sopenharmony_ci	}
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci	# Print out process activity
5108c2ecf20Sopenharmony_ci	printf("\n");
5118c2ecf20Sopenharmony_ci	printf("%-" . $max_strlen . "s %8s %10s   %8s %8s  %8s %8s %8s %8s\n", "Process", "Direct",  "Wokeup", "Pages",   "Pages",   "Pages",   "Pages",     "Time");
5128c2ecf20Sopenharmony_ci	printf("%-" . $max_strlen . "s %8s %10s   %8s %8s  %8s %8s %8s %8s\n", "details", "Rclms",   "Kswapd", "Scanned", "Rclmed",  "Sync-IO", "ASync-IO",  "Stalled");
5138c2ecf20Sopenharmony_ci	foreach $process_pid (keys %stats) {
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ci		if (!$stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}) {
5168c2ecf20Sopenharmony_ci			next;
5178c2ecf20Sopenharmony_ci		}
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci		$total_direct_reclaim += $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN};
5208c2ecf20Sopenharmony_ci		$total_wakeup_kswapd += $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD};
5218c2ecf20Sopenharmony_ci		$total_direct_nr_scanned += $stats{$process_pid}->{HIGH_NR_SCANNED};
5228c2ecf20Sopenharmony_ci		$total_direct_nr_file_scanned += $stats{$process_pid}->{HIGH_NR_FILE_SCANNED};
5238c2ecf20Sopenharmony_ci		$total_direct_nr_anon_scanned += $stats{$process_pid}->{HIGH_NR_ANON_SCANNED};
5248c2ecf20Sopenharmony_ci		$total_direct_nr_reclaimed += $stats{$process_pid}->{HIGH_NR_RECLAIMED};
5258c2ecf20Sopenharmony_ci		$total_direct_nr_file_reclaimed += $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED};
5268c2ecf20Sopenharmony_ci		$total_direct_nr_anon_reclaimed += $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED};
5278c2ecf20Sopenharmony_ci		$total_direct_writepage_file_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC};
5288c2ecf20Sopenharmony_ci		$total_direct_writepage_anon_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC};
5298c2ecf20Sopenharmony_ci		$total_direct_writepage_file_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC};
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci		$total_direct_writepage_anon_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC};
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci		my $index = 0;
5348c2ecf20Sopenharmony_ci		my $this_reclaim_delay = 0;
5358c2ecf20Sopenharmony_ci		while (defined $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) {
5368c2ecf20Sopenharmony_ci			 my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]);
5378c2ecf20Sopenharmony_ci			$this_reclaim_delay += $latency;
5388c2ecf20Sopenharmony_ci			$index++;
5398c2ecf20Sopenharmony_ci		}
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci		printf("%-" . $max_strlen . "s %8d %10d   %8u %8u  %8u %8u %8.3f",
5428c2ecf20Sopenharmony_ci			$process_pid,
5438c2ecf20Sopenharmony_ci			$stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN},
5448c2ecf20Sopenharmony_ci			$stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD},
5458c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_SCANNED},
5468c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_FILE_SCANNED},
5478c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_ANON_SCANNED},
5488c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_RECLAIMED},
5498c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED},
5508c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED},
5518c2ecf20Sopenharmony_ci			$stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC},
5528c2ecf20Sopenharmony_ci			$stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC},
5538c2ecf20Sopenharmony_ci			$this_reclaim_delay / 1000);
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci		if ($stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}) {
5568c2ecf20Sopenharmony_ci			print "      ";
5578c2ecf20Sopenharmony_ci			for (my $order = 0; $order < 20; $order++) {
5588c2ecf20Sopenharmony_ci				my $count = $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order];
5598c2ecf20Sopenharmony_ci				if ($count != 0) {
5608c2ecf20Sopenharmony_ci					print "direct-$order=$count ";
5618c2ecf20Sopenharmony_ci				}
5628c2ecf20Sopenharmony_ci			}
5638c2ecf20Sopenharmony_ci		}
5648c2ecf20Sopenharmony_ci		if ($stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}) {
5658c2ecf20Sopenharmony_ci			print "      ";
5668c2ecf20Sopenharmony_ci			for (my $order = 0; $order < 20; $order++) {
5678c2ecf20Sopenharmony_ci				my $count = $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order];
5688c2ecf20Sopenharmony_ci				if ($count != 0) {
5698c2ecf20Sopenharmony_ci					print "wakeup-$order=$count ";
5708c2ecf20Sopenharmony_ci				}
5718c2ecf20Sopenharmony_ci			}
5728c2ecf20Sopenharmony_ci		}
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci		print "\n";
5758c2ecf20Sopenharmony_ci	}
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci	# Print out kswapd activity
5788c2ecf20Sopenharmony_ci	printf("\n");
5798c2ecf20Sopenharmony_ci	printf("%-" . $max_strlen . "s %8s %10s   %8s   %8s %8s %8s\n", "Kswapd",   "Kswapd",  "Order",     "Pages",   "Pages",   "Pages",  "Pages");
5808c2ecf20Sopenharmony_ci	printf("%-" . $max_strlen . "s %8s %10s   %8s   %8s %8s %8s\n", "Instance", "Wakeups", "Re-wakeup", "Scanned", "Rclmed",  "Sync-IO", "ASync-IO");
5818c2ecf20Sopenharmony_ci	foreach $process_pid (keys %stats) {
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci		if (!$stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}) {
5848c2ecf20Sopenharmony_ci			next;
5858c2ecf20Sopenharmony_ci		}
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci		$total_kswapd_wake += $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE};
5888c2ecf20Sopenharmony_ci		$total_kswapd_nr_scanned += $stats{$process_pid}->{HIGH_NR_SCANNED};
5898c2ecf20Sopenharmony_ci		$total_kswapd_nr_file_scanned += $stats{$process_pid}->{HIGH_NR_FILE_SCANNED};
5908c2ecf20Sopenharmony_ci		$total_kswapd_nr_anon_scanned += $stats{$process_pid}->{HIGH_NR_ANON_SCANNED};
5918c2ecf20Sopenharmony_ci		$total_kswapd_nr_reclaimed += $stats{$process_pid}->{HIGH_NR_RECLAIMED};
5928c2ecf20Sopenharmony_ci		$total_kswapd_nr_file_reclaimed += $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED};
5938c2ecf20Sopenharmony_ci		$total_kswapd_nr_anon_reclaimed += $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED};
5948c2ecf20Sopenharmony_ci		$total_kswapd_writepage_file_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC};
5958c2ecf20Sopenharmony_ci		$total_kswapd_writepage_anon_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC};
5968c2ecf20Sopenharmony_ci		$total_kswapd_writepage_file_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC};
5978c2ecf20Sopenharmony_ci		$total_kswapd_writepage_anon_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC};
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci		printf("%-" . $max_strlen . "s %8d %10d   %8u %8u  %8i %8u",
6008c2ecf20Sopenharmony_ci			$process_pid,
6018c2ecf20Sopenharmony_ci			$stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE},
6028c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP},
6038c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_SCANNED},
6048c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_FILE_SCANNED},
6058c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_ANON_SCANNED},
6068c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_RECLAIMED},
6078c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED},
6088c2ecf20Sopenharmony_ci			$stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED},
6098c2ecf20Sopenharmony_ci			$stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC},
6108c2ecf20Sopenharmony_ci			$stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC});
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_ci		if ($stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}) {
6138c2ecf20Sopenharmony_ci			print "      ";
6148c2ecf20Sopenharmony_ci			for (my $order = 0; $order < 20; $order++) {
6158c2ecf20Sopenharmony_ci				my $count = $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order];
6168c2ecf20Sopenharmony_ci				if ($count != 0) {
6178c2ecf20Sopenharmony_ci					print "wake-$order=$count ";
6188c2ecf20Sopenharmony_ci				}
6198c2ecf20Sopenharmony_ci			}
6208c2ecf20Sopenharmony_ci		}
6218c2ecf20Sopenharmony_ci		if ($stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP}) {
6228c2ecf20Sopenharmony_ci			print "      ";
6238c2ecf20Sopenharmony_ci			for (my $order = 0; $order < 20; $order++) {
6248c2ecf20Sopenharmony_ci				my $count = $stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP_PERORDER}[$order];
6258c2ecf20Sopenharmony_ci				if ($count != 0) {
6268c2ecf20Sopenharmony_ci					print "rewake-$order=$count ";
6278c2ecf20Sopenharmony_ci				}
6288c2ecf20Sopenharmony_ci			}
6298c2ecf20Sopenharmony_ci		}
6308c2ecf20Sopenharmony_ci		printf("\n");
6318c2ecf20Sopenharmony_ci	}
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	# Print out summaries
6348c2ecf20Sopenharmony_ci	$total_direct_latency /= 1000;
6358c2ecf20Sopenharmony_ci	$total_kswapd_latency /= 1000;
6368c2ecf20Sopenharmony_ci	print "\nSummary\n";
6378c2ecf20Sopenharmony_ci	print "Direct reclaims:     			$total_direct_reclaim\n";
6388c2ecf20Sopenharmony_ci	print "Direct reclaim pages scanned:		$total_direct_nr_scanned\n";
6398c2ecf20Sopenharmony_ci	print "Direct reclaim file pages scanned:	$total_direct_nr_file_scanned\n";
6408c2ecf20Sopenharmony_ci	print "Direct reclaim anon pages scanned:	$total_direct_nr_anon_scanned\n";
6418c2ecf20Sopenharmony_ci	print "Direct reclaim pages reclaimed:		$total_direct_nr_reclaimed\n";
6428c2ecf20Sopenharmony_ci	print "Direct reclaim file pages reclaimed:	$total_direct_nr_file_reclaimed\n";
6438c2ecf20Sopenharmony_ci	print "Direct reclaim anon pages reclaimed:	$total_direct_nr_anon_reclaimed\n";
6448c2ecf20Sopenharmony_ci	print "Direct reclaim write file sync I/O:	$total_direct_writepage_file_sync\n";
6458c2ecf20Sopenharmony_ci	print "Direct reclaim write anon sync I/O:	$total_direct_writepage_anon_sync\n";
6468c2ecf20Sopenharmony_ci	print "Direct reclaim write file async I/O:	$total_direct_writepage_file_async\n";
6478c2ecf20Sopenharmony_ci	print "Direct reclaim write anon async I/O:	$total_direct_writepage_anon_async\n";
6488c2ecf20Sopenharmony_ci	print "Wake kswapd requests:			$total_wakeup_kswapd\n";
6498c2ecf20Sopenharmony_ci	printf "Time stalled direct reclaim: 		%-1.2f seconds\n", $total_direct_latency;
6508c2ecf20Sopenharmony_ci	print "\n";
6518c2ecf20Sopenharmony_ci	print "Kswapd wakeups:				$total_kswapd_wake\n";
6528c2ecf20Sopenharmony_ci	print "Kswapd pages scanned:			$total_kswapd_nr_scanned\n";
6538c2ecf20Sopenharmony_ci	print "Kswapd file pages scanned:		$total_kswapd_nr_file_scanned\n";
6548c2ecf20Sopenharmony_ci	print "Kswapd anon pages scanned:		$total_kswapd_nr_anon_scanned\n";
6558c2ecf20Sopenharmony_ci	print "Kswapd pages reclaimed:			$total_kswapd_nr_reclaimed\n";
6568c2ecf20Sopenharmony_ci	print "Kswapd file pages reclaimed:		$total_kswapd_nr_file_reclaimed\n";
6578c2ecf20Sopenharmony_ci	print "Kswapd anon pages reclaimed:		$total_kswapd_nr_anon_reclaimed\n";
6588c2ecf20Sopenharmony_ci	print "Kswapd reclaim write file sync I/O:	$total_kswapd_writepage_file_sync\n";
6598c2ecf20Sopenharmony_ci	print "Kswapd reclaim write anon sync I/O:	$total_kswapd_writepage_anon_sync\n";
6608c2ecf20Sopenharmony_ci	print "Kswapd reclaim write file async I/O:	$total_kswapd_writepage_file_async\n";
6618c2ecf20Sopenharmony_ci	print "Kswapd reclaim write anon async I/O:	$total_kswapd_writepage_anon_async\n";
6628c2ecf20Sopenharmony_ci	printf "Time kswapd awake:			%-1.2f seconds\n", $total_kswapd_latency;
6638c2ecf20Sopenharmony_ci}
6648c2ecf20Sopenharmony_ci
6658c2ecf20Sopenharmony_cisub aggregate_perprocesspid() {
6668c2ecf20Sopenharmony_ci	my $process_pid;
6678c2ecf20Sopenharmony_ci	my $process;
6688c2ecf20Sopenharmony_ci	undef %perprocess;
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci	foreach $process_pid (keys %perprocesspid) {
6718c2ecf20Sopenharmony_ci		$process = $process_pid;
6728c2ecf20Sopenharmony_ci		$process =~ s/-([0-9])*$//;
6738c2ecf20Sopenharmony_ci		if ($process eq '') {
6748c2ecf20Sopenharmony_ci			$process = "NO_PROCESS_NAME";
6758c2ecf20Sopenharmony_ci		}
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN} += $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN};
6788c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_KSWAPD_WAKE} += $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE};
6798c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_WAKEUP_KSWAPD} += $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD};
6808c2ecf20Sopenharmony_ci		$perprocess{$process}->{HIGH_KSWAPD_REWAKEUP} += $perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP};
6818c2ecf20Sopenharmony_ci		$perprocess{$process}->{HIGH_NR_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_SCANNED};
6828c2ecf20Sopenharmony_ci		$perprocess{$process}->{HIGH_NR_FILE_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_FILE_SCANNED};
6838c2ecf20Sopenharmony_ci		$perprocess{$process}->{HIGH_NR_ANON_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_ANON_SCANNED};
6848c2ecf20Sopenharmony_ci		$perprocess{$process}->{HIGH_NR_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED};
6858c2ecf20Sopenharmony_ci		$perprocess{$process}->{HIGH_NR_FILE_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_FILE_RECLAIMED};
6868c2ecf20Sopenharmony_ci		$perprocess{$process}->{HIGH_NR_ANON_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_ANON_RECLAIMED};
6878c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC};
6888c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC};
6898c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC};
6908c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC};
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_ci		for (my $order = 0; $order < 20; $order++) {
6938c2ecf20Sopenharmony_ci			$perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order];
6948c2ecf20Sopenharmony_ci			$perprocess{$process}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order];
6958c2ecf20Sopenharmony_ci			$perprocess{$process}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order];
6968c2ecf20Sopenharmony_ci
6978c2ecf20Sopenharmony_ci		}
6988c2ecf20Sopenharmony_ci
6998c2ecf20Sopenharmony_ci		# Aggregate direct reclaim latencies
7008c2ecf20Sopenharmony_ci		my $wr_index = $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END};
7018c2ecf20Sopenharmony_ci		my $rd_index = 0;
7028c2ecf20Sopenharmony_ci		while (defined $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$rd_index]) {
7038c2ecf20Sopenharmony_ci			$perprocess{$process}->{HIGH_DIRECT_RECLAIM_LATENCY}[$wr_index] = $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$rd_index];
7048c2ecf20Sopenharmony_ci			$rd_index++;
7058c2ecf20Sopenharmony_ci			$wr_index++;
7068c2ecf20Sopenharmony_ci		}
7078c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END} = $wr_index;
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci		# Aggregate kswapd latencies
7108c2ecf20Sopenharmony_ci		my $wr_index = $perprocess{$process}->{MM_VMSCAN_KSWAPD_SLEEP};
7118c2ecf20Sopenharmony_ci		my $rd_index = 0;
7128c2ecf20Sopenharmony_ci		while (defined $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$rd_index]) {
7138c2ecf20Sopenharmony_ci			$perprocess{$process}->{HIGH_KSWAPD_LATENCY}[$wr_index] = $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$rd_index];
7148c2ecf20Sopenharmony_ci			$rd_index++;
7158c2ecf20Sopenharmony_ci			$wr_index++;
7168c2ecf20Sopenharmony_ci		}
7178c2ecf20Sopenharmony_ci		$perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END} = $wr_index;
7188c2ecf20Sopenharmony_ci	}
7198c2ecf20Sopenharmony_ci}
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_cisub report() {
7228c2ecf20Sopenharmony_ci	if (!$opt_ignorepid) {
7238c2ecf20Sopenharmony_ci		dump_stats(\%perprocesspid);
7248c2ecf20Sopenharmony_ci	} else {
7258c2ecf20Sopenharmony_ci		aggregate_perprocesspid();
7268c2ecf20Sopenharmony_ci		dump_stats(\%perprocess);
7278c2ecf20Sopenharmony_ci	}
7288c2ecf20Sopenharmony_ci}
7298c2ecf20Sopenharmony_ci
7308c2ecf20Sopenharmony_ci# Process events or signals until neither is available
7318c2ecf20Sopenharmony_cisub signal_loop() {
7328c2ecf20Sopenharmony_ci	my $sigint_processed;
7338c2ecf20Sopenharmony_ci	do {
7348c2ecf20Sopenharmony_ci		$sigint_processed = 0;
7358c2ecf20Sopenharmony_ci		process_events();
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci		# Handle pending signals if any
7388c2ecf20Sopenharmony_ci		if ($sigint_pending) {
7398c2ecf20Sopenharmony_ci			my $current_time = time;
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_ci			if ($sigint_exit) {
7428c2ecf20Sopenharmony_ci				print "Received exit signal\n";
7438c2ecf20Sopenharmony_ci				$sigint_pending = 0;
7448c2ecf20Sopenharmony_ci			}
7458c2ecf20Sopenharmony_ci			if ($sigint_report) {
7468c2ecf20Sopenharmony_ci				if ($current_time >= $sigint_received + 2) {
7478c2ecf20Sopenharmony_ci					report();
7488c2ecf20Sopenharmony_ci					$sigint_report = 0;
7498c2ecf20Sopenharmony_ci					$sigint_pending = 0;
7508c2ecf20Sopenharmony_ci					$sigint_processed = 1;
7518c2ecf20Sopenharmony_ci				}
7528c2ecf20Sopenharmony_ci			}
7538c2ecf20Sopenharmony_ci		}
7548c2ecf20Sopenharmony_ci	} while ($sigint_pending || $sigint_processed);
7558c2ecf20Sopenharmony_ci}
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_cisignal_loop();
7588c2ecf20Sopenharmony_cireport();
759