File process_vmstat.awk of Package mmdebug-tools

#!/usr/bin/awk -f
# Process output of read_vmstat tool 
# Format
#
#		TS		SCANNING STATS				RECLAIM STATS			SUCC RATE (reclaim/scan)	INVOCATIONS		RECLAIM/ROTATION/REFILL/SWAPOUT (percentage wrt scan)
# RECLAIM ts: 1623960193 pgscan_kswapd 8288 pgscan_direct 12672 kswapd_steal 6827 direct_steal 7309 kswad_succ 82% direct_succ 57% pageoutrun 82 allocstall 124 reclaimed 14136 67% pgrotated 1103 5% pgrefill 7201 34% pswpout 5585 26%
#
# Allocation stats
# 		TS	 Page allocator			Page faults
# ALLOC: ts:1623960188 pgalloc 50173 pgfree 58791 pgfault 110799 pgmajfault 12
#
# IO stats
# 		TS	read IO   write IO      SWAP IN/OU           Overall 	    IMMEDIATE SWAPOUT/write IO
# IO ts: 1623960191 pgpgin 2624 pgpgout 14900 pswpin 0 pswpout 3725 pswpin/out 3% pswpout/pgpgout 25%
#
# LRU stats
# 		TS	Free pages    ANON/FILE LRUS Inactive/active    Unevict       SLABS     Reclaim/unreclaim
# STATE ts: 1623960209 nr_free 70926 anon 7898603 0.11 file 58729 0.98 unevictable 0 slab 40217 1.01
#
# Trashing detection
# refaults_per - refaults wrt major faults (can be more than 100% due to readahead)
# *activation_per - activations per refault for the resp. lru
# *restore_per - restores per refaults for the resp lru
# REFAULT ts: 1655144526 refault_anon 2880 activate_anon 412 restore_anon 7 refault_file 556 activate_file 469 restore_file 154 refaults_per 116% anon_activations_per 0% file_activations_per 0% anon_restore_per 0% file_restore_per 0%

BEGIN { first=1}
/^=S/ {
	ts=$2
}
/^E=/ {
	# relative counters report diffs
	if (!first) {
		# Reclaim statistics
		printf("RECLAIM ts: %s pgscan_kswapd %d pgscan_direct %d pgsteal_kswapd %d pgsteal_direct %d ", ts,
		       pgscan_kswapd, pgscan_direct, pgsteal_kswapd, pgsteal_direct);

		direct_succ=kswapd_succ=0
		if (pgscan_kswapd)
			kswapd_succ=pgsteal_kswapd * 100 / pgscan_kswapd
		if (pgscan_direct)
			direct_succ=pgsteal_direct * 100 / pgscan_direct
		printf("kswapd_succ %d%% direct_succ %d%% ",
		       kswapd_succ, direct_succ);

		printf("pageoutrun %d allocstall %d direct_throttled %d oom_kill %d ",
		       pageoutrun, allocstall,
		       direct_throttled, oom_kill)

		scanned=pgscan_kswapd+pgscan_direct
		pgrotate_per = pgrefill_per = swapout_per = steal_per = 0;
		if (scanned) {
			pgrotate_per= pgrotate * 100 / scanned
			pgrefill_per = pgrefill * 100 / scanned
			swapout_per=pswpout * 100 / scanned
			steal_per=(pgsteal_kswapd+pgsteal_direct) * 100 /scanned
		}
		reclaimed = pgsteal_kswapd + pgsteal_direct
		printf("reclaimed %d %d%% pgrotated %d %d%% pgrefill %d %d%% pswpout %d %d%%\n",
		          reclaimed, steal_per,
			  pgrotated, pgrotate_per,
			  pgrefill, pgrefill_per,
			  pswpout, swapout_per);

		# Allocation statistics
		printf("ALLOC ts: %s pgalloc %d pgfree %d pgfault %d pgmajfault %d\n", ts,
		       pgalloc, pgfree, pgfault, pgmajfault)

		# IO stats
		printf("IO ts: %s pgpgin %d pgpgout %d pswpin %d pswpout %d ", ts,
		       pgpgin, pgpgout, pswpin, pswpout)

		pswpout_per=pswpin_per=0
		if (pgpgout)
			pswpout_per=pswpout * 100 / pgpgout
		if (pswpout)
			pswpin_per=pswpin * 100 / pswpout
		printf("pswpin/out %d%% pswpout/pgpgout %d%%\n",
		       pswpin_per, pswpout_per)

		# Refault stats were more coarse in older kernels
		printf ("REFAULT ts: %s ", ts)
		if (refault_ver) {
			printf("refault %d activate %d ", refault, activate)
			# Proportion of refaults wrt major faults
			refaults_per = 0
			if (pgmajfault)
				refaults_per = refault * 100 / pgmajfault
			printf("refaults_per %d%% ", refaults_per)
			activations_per = 0
			if (refault)
				activations_per = activations * 100 / refault
			printf("activations_per %d%%\n", activations_per)
		} else {
			printf("refault_anon %d activate_anon %d restore_anon %d refault_file %d activate_file %d restore_file %d ",
			       refault_anon, activate_anon, restore_anon,
			       refault_file, activate_file, restore_file)
			# Proportion of refaults wrt major faults
			refaults_per = 0
			if (pgmajfault)
				refaults_per = (refault_anon + refault_file) * 100 / pgmajfault
			printf("refaults_per %d%% ", refaults_per)

			# Recent enough to activate
			anon_activations_per = file_activations_per = 0
			if (refault_anon)
				anon_activations_per = anon_activations * 100 / refault_anon
			if (refault_file)
				file_activations_per = file_activations * 100 / refault_file
			printf("anon_activations_per %d%% file_activations_per %d%% ",
			       anon_activations_per, file_activations_per)

			# Workingset reclaimed
			anon_restore_per = file_restore_per = 0
			if (refault_anon)
				anon_restore_per = anon_restore * 100 / refault_anon
			if (refault_file)
				file_restore_per = file_restore * 100 / refault_file
			printf("anon_restore_per %d%% file_restore_per %d%%\n",
			       anon_restore_per, file_restore_per)
		}

		# Compaction stats
		compact_succ_per = 0
		if (compact_stall)
			compact_succ_per = compact_success * 100 / compact_stall;
		printf("COMPACT ts:%s compact_stall %d compact_fail %d compact_success %d %d%% free_scanned %d isolated %d ", ts,
		       compact_stall, compact_fail, compact_success, compact_succ_per,
		       compact_free_scanned, compact_isolated)
		printf("daenon_wake %d daemon_migrate_scanned %d daemon_free_scanned\n",
			  compact_daemon_wake, compact_daemon_migrate_scanned, compact_daemon_free_scanned)
	}

	first=0
	printf("STATE ts: %s nr_free %d anon %d %.2f file %d %.2f unevictable %d slab %d %.2f\n", ts,
	       nr_free_pages,
	       nr_active_anon+nr_inactive_anon, nr_inactive_anon/nr_active_anon,
	       nr_active_file+nr_inactive_file, nr_inactive_file/nr_active_file,
	       unevictable,
	       nr_slab_reclaimable+nr_slab_unreclaimable, nr_slab_reclaimable/nr_slab_unreclaimable)
}

/nr_free_pages/ {nr_free_pages=$2}
/nr_inactive_anon/ {nr_inactive_anon=$2}
/nr_active_anon/ {nr_active_anon=$2; if (nr_active_anon == 0) nr_active_anon = 1}
/nr_inactive_file/ {nr_inactive_file=$2}
/nr_active_file/ {nr_active_file=$2; if (nr_active_file == 0) nr_active_file = 1}
/nr_unevictable/ {nr_unevictable=$2}
/nr_slab_reclaimable/ {nr_slab_reclaimable=$2}
/nr_slab_unreclaimable/ {nr_slab_unreclaimable=$2}

/pgpgin/{
	pgpgin=$2-last_pgpgin
	last_pgpgin=$2
}
/pgpgout/{
	pgpgout=$2-last_pgpgout
	last_pgpgout=$2
}

/pswpin/{
	pswpin=$2-last_pswpin
	last_pswpin=$2
}
/pswpout/{
	pswpout=$2-last_pswpout
	last_pswpout=$2
}


/pgalloc_dma/{pgalloc_sum=0}
/pgalloc_dma32/{pgalloc_sum+=$2}
/pgalloc_normal/{
	pgalloc_sum+=$2
	pgalloc=pgalloc_sum-last_pgalloc
	last_pgalloc=pgalloc_sum
}

/pgfree/{
	pgfree=$2-last_pgfree
	last_pgfree=$2
}

/pgfault/{
	pgfault=$2-last_pgfault
	last_pgfault=$2
}

/pgmajfault/{
	pgmajfault=$2-last_pgmajfault
	last_pgmajfault=$2
}

/pgrefill_dma/{pgrefill_sum=$2}
/pgrefill_dma32/{pgrefill_sum+=$2}
/pgrefill_normal/{
	pgrefill_sum+=$2
	pgrefill=pgrefill_sum-last_pgrefill
	last_pgrefill=pgrefill_sum
}

# Older kernels didn't have per zone break down
/pgrefill/{
	pgrefill=$2-last_pgrefill
	last_pgrefill=$2
}

# kswapd + direct
/pgsteal_dma/{pgsteal_sum=$2}
/pgsteal_dma32/{pgsteal_sum+=$2}
/pgsteal_normal/{
	pgsteal_sum+=$2
	pgsteal=pgsteal_sum-last_pgsteal
	last_pgsteal=pgsteal_sum
}

/pgscan_kswapd_dma/{pgscan_kswapd_sum=$2}
/pgscan_kswapd_dma32/{pgscan_kswapd_sum+=$2}
/pgscan_kswapd_normal/{
	pgscan_kswapd_sum+=$2
	pgscan_kswapd=pgscan_kswapd_sum-last_pgscan_kswapd
	last_pgscan_kswapd=pgscan_kswapd_sum
}

/pgscan_direct_dma/{pgscan_direct_sum=$2}
/pgscan_direct_dma32/{pgscan_direct_sum+=$2}
/pgscan_direct_normal/{
	pgscan_direct_sum+=$2
	pgscan_direct=pgscan_direct_sum-last_pgscan_direct
	last_pgscan_direct=pgscan_direct_sum
}
/kswapd_steal/{
	pgsteal_kswapd=$2-last_kswapd_steal
	pgsteal_direct=pgsteal-kswapd_steal
	last_kswapd_steal=$2
}

# older kernels had separate pgsteal for kswapd and direct reclaim
/pgsteal_kswapd/{
	pgsteal_kswapd = $2 - last_pgsteal_kswapd_diff;
	last_pgsteal_kswapd_diff = $2;
}
/pgsteal_direct/{
	pgsteal_direct = $2 - last_pgsteal_direct_diff;
	last_pgsteal_direct_diff = $2;
}
/pgscan_kswapd\>/{
	pgscan_kswapd=$2-last_pgscan_kswapd
	last_pgscan_kswapd=$2
}
/pgscan_direct\>/{
	pgscan_direct=$2-last_pgscan_direct
	last_pgscan_direct=$2
}

/pageoutrun/ {
	pageoutrun=$2-last_pageoutrun
	last_pageoutrun=$2
}

# Old kernels have per zone allocstall
/allocstall_dma/{allocstall_sum=$2}
/allocstall_dma32/{allocstall_sum+=$2}
/allocstall_normal/{
	allocstall_sum+=$2
	allocstall=allocstall_sum-last_allocstall
	last_allocstall=allocstall_sum
}

/allocstall\>/ {
	diff=$2-last_allocstall
	last_allocstall=$2
}

/pgrotated/ {
	pgrotated=$2-last_pgrotated
	last_pgrotated=$2
}

/pgscan_direct_throttle/{
	direct_throttle=$2-last_direct_throttle
	last_direct_throttle=$2
}
/oom_kill/{
	oom_kill=$2-last_oom_kill
	last_oom_kill=$2
}

/workingset_refault\>/{
	refault_ver = 1
	refault = $2 - last_refault;
	last_refault=$2
}
/workingset_refault_anon/{
	refault_anon = $2 - last_refault_anon;
	last_refault_anon=$2
}
/workingset_refault_file/{
	refault_file = $2 - last_refault_file;
	last_refault_file=$2
}

/workingset_activate/{
	activate = $2 - last_activate;
	last_activate=$2
}
/workingset_activate_anon/{
	activate_anon = $2 - last_activate_anon;
	last_activate_anon=$2
}
/workingset_activate_file/{
	activate_file = $2 - last_activate_file;
	last_activate_file=$2
}
/workingset_restore_anon/{
	restore_anon = $2 - last_restore_anon;
	last_restore_anon=$2
}
/workingset_restore_file/{
	restore_file = $2 - last_restore_file;
	last_restore_file=$2
}

/compact_stall/{
	compact_stall = $2 - last_compact_stall
	last_compact_stall = $2
}
/compact_fail/{
	compact_fail = $2 - last_compact_fail
	last_compact_fail = $2
}
/compact_success/{
	compact_success = $2 - last_compact_success
	last_compact_success = $2
}
/compact_free_scanned/{
	compact_free_scanned = $2 - last_compact_free_scanned
	last_compact_free_scanned = $2
}
/compact_isolated/{
	compact_isolated = $2 - last_compact_isolated
	last_compact_isolated = $2
}
/compact_daemon_wake/{
	compact_daemon_wake = $2 - last_compact_daemon_wake
	last_compact_daemon_wake = $2
}
/compact_daemon_migrate_scanned/{
	compact_daemon_migrate_scanned = $2 - last_compact_daemon_migrate_scanned
	last_compact_daemon_migrate_scanned = $2
}
/compact_daemon_free_scanned/{
	compact_daemon_free_scanned = $2 - last_compact_daemon_free_scanned
	last_compact_daemon_free_scanned = $2
}
openSUSE Build Service is sponsored by