xref: /spdk/scripts/perf/pm/collect-vmstat (revision 355312bfcd3751f9af17fbefc90373fb8a269614)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2023 Intel Corporation
4#  All rights reserved.
5
6shopt -s nullglob extglob
7
8pmdir=$(readlink -f "$(dirname "$0")")
9rootdir=$(readlink -f "$pmdir/../../../")
10source "$pmdir/common"
11
12help() {
13	cat <<- HELP
14
15		Usage: $0 [-h] [-c count] [-d dir] [-p prefix] [-r reprint_header_count]
16
17		-h - Print this message.
18		-c - Execute count times. 0 is the default and it means to run
19		     indefinitely.
20		-d - Directory where results should be saved. Default is /tmp.
21		-p - Add prefix to saved files.
22		-r - Stat count after which header should be re-printed. Default is 20.
23		-t - How long to wait before each stat dump. Default is 1s.
24
25		When started, ${0##*/} will enter loop to continuosly dump
26		vmstat. Each iteration will be logged to stderr and a log file
27		(dir/${0##*/}.pm.log).
28
29	HELP
30}
31
32get_extra_meminfo() {
33	local match="" data
34
35	match+="|MemAvailable"
36	match+="|Shmem"
37	match+="|HugePages_(Total|Free)"
38	match+="|Hugepagesize"
39
40	data=($(grep -E "^($match):" /proc/meminfo | awk '{print $2}'))
41	echo "${data[*]}"
42}
43
44_vmstat() {
45	local count=$1 interval=$2 reprint_header=${3:-20} _count
46	local vmstat _vmstat stat_idx header=()
47
48	_count=$count
49	while ((stat_idx = stat_idx == reprint_header ? 1 : ++stat_idx, count <= 0 ? 1 : _count--)); do
50		mapfile -t vmstat < <(vmstat --timestamp)
51		# Enhance output to include stuff we are most interested in
52		vmstat[2]="${vmstat[2]} $(get_extra_meminfo) (test:$TEST_TAG)"
53		if ((stat_idx == 1)); then
54			header=("${vmstat[@]::2}")
55			header[0]="${header[0]}     ----extra memory----"
56			# Keep the header ordered as in get_extra_meminfo()
57			header[1]="${header[1]}     avail shmem hp_total hp_free hp_size"
58			_vmstat=("${header[@]}" "${vmstat[2]}")
59		else
60			_vmstat=("${vmstat[2]}")
61		fi
62		printf '%s\n' "${_vmstat[@]}"
63		sleep "${interval}s"
64	done > >(tee "$output_dir/$log_file")
65}
66
67count=0
68interval=1
69output_dir=/tmp
70prefix=""
71reprint_header=20
72
73while getopts c:d:hp:r:t: opt; do
74	case "$opt" in
75		c) count=$OPTARG ;;
76		d) output_dir=$OPTARG ;;
77		h)
78			help
79			exit 0
80			;;
81		p) prefix=$OPTARG ;;
82		r) reprint_header=$OPTARG ;;
83		t) interval=$OPTARG ;;
84		*) ;;
85	esac
86done
87
88declare -r log_file=${prefix:+${prefix}_}${0##*/}.pm.log
89
90mkdir -p "$output_dir"
91
92trap 'retag' USR1
93
94_vmstat "$count" "$interval" "$reprint_header"
95