155013c9eSMichal Berger#!/usr/bin/env bash 255013c9eSMichal Berger# SPDX-License-Identifier: BSD-3-Clause 355013c9eSMichal Berger# Copyright (C) 2023 Intel Corporation 455013c9eSMichal Berger# All rights reserved. 555013c9eSMichal Berger 655013c9eSMichal Bergershopt -s nullglob extglob 755013c9eSMichal Berger 855013c9eSMichal Bergerpmdir=$(readlink -f "$(dirname "$0")") 955013c9eSMichal Bergerrootdir=$(readlink -f "$pmdir/../../../") 108d588fbcSMichal Bergersource "$pmdir/common" 11*3fa77bf2SMichal Bergersource "$rootdir/test/scheduler/common.sh" 1255013c9eSMichal Berger 1355013c9eSMichal Bergerhelp() { 1455013c9eSMichal Berger cat <<- HELP 1555013c9eSMichal Berger 16d5fe62b2SMichal Berger Usage: $0 [-h] [-c count] [-d dir] [-l] [-p prefix] [-r reprint_header_count] 1755013c9eSMichal Berger 1855013c9eSMichal Berger -h - Print this message. 1955013c9eSMichal Berger -c - Execute count times. 0 is the default and it means to run 2055013c9eSMichal Berger indefinitely. 2155013c9eSMichal Berger -d - Directory where results should be saved. Default is /tmp. 22d5fe62b2SMichal Berger -l - Save output of the script to a log file (dir/${0##*/}.pm.log). 2355013c9eSMichal Berger -p - Add prefix to saved files. 2455013c9eSMichal Berger -r - Stat count after which header should be re-printed. Default is 20. 2555013c9eSMichal Berger -t - How long to wait before each stat dump. Default is 1s. 2655013c9eSMichal Berger 2734edd9f1SKamil Godzwon When started, ${0##*/} will enter loop to continuously dump 2855013c9eSMichal Berger vmstat. Each iteration will be logged to stderr and a log file 2955013c9eSMichal Berger (dir/${0##*/}.pm.log). 3055013c9eSMichal Berger 3155013c9eSMichal Berger HELP 3255013c9eSMichal Berger} 3355013c9eSMichal Berger 3406243cb0SMichal Bergerget_extra_info() { 35*3fa77bf2SMichal Berger local match="" data node hp hps 3655013c9eSMichal Berger 3706243cb0SMichal Berger case "$PM_OS" in 3806243cb0SMichal Berger Linux) 3955013c9eSMichal Berger match+="|MemAvailable" 4055013c9eSMichal Berger match+="|Shmem" 4155013c9eSMichal Berger match+="|HugePages_(Total|Free)" 4255013c9eSMichal Berger match+="|Hugepagesize" 4355013c9eSMichal Berger 4455013c9eSMichal Berger data=($(grep -E "^($match):" /proc/meminfo | awk '{print $2}')) 45*3fa77bf2SMichal Berger if is_numa; then 46*3fa77bf2SMichal Berger for node in "${nodes[@]}"; do 47*3fa77bf2SMichal Berger for hp in "/sys/devices/system/node/node$node/hugepages/"*; do 48*3fa77bf2SMichal Berger hps=${hps:+$hps,}N$node-${hp#*hugepages-}_f=$(< "$hp/free_hugepages") 49*3fa77bf2SMichal Berger hps=${hps:+$hps,}N$node-${hp#*hugepages-}_t=$(< "$hp/nr_hugepages") 50*3fa77bf2SMichal Berger done 51*3fa77bf2SMichal Berger done 52*3fa77bf2SMichal Berger data+=("$hps") 53*3fa77bf2SMichal Berger fi 5406243cb0SMichal Berger ;& 5506243cb0SMichal Berger *) data+=("$TEST_TAG") ;; 5606243cb0SMichal Berger esac 5755013c9eSMichal Berger echo "${data[*]}" 5855013c9eSMichal Berger} 5955013c9eSMichal Berger 6006243cb0SMichal Bergerset_extra_info_header() { 6106243cb0SMichal Berger local -n header_ref=$1 6206243cb0SMichal Berger local _header 6306243cb0SMichal Berger 6406243cb0SMichal Berger # Keep the header ordered as in get_extra_info() 6506243cb0SMichal Berger case "$PM_OS" in 66*3fa77bf2SMichal Berger Linux) 67*3fa77bf2SMichal Berger _header="avail shmem hp_total hp_free hp_size" 68*3fa77bf2SMichal Berger if is_numa; then 69*3fa77bf2SMichal Berger _header+=" hp_per_node" 70*3fa77bf2SMichal Berger fi 71*3fa77bf2SMichal Berger _header+=" test" 72*3fa77bf2SMichal Berger ;; 7306243cb0SMichal Berger FreeBSD) _header="test" ;; 7406243cb0SMichal Berger esac 7506243cb0SMichal Berger 7606243cb0SMichal Berger header_ref[0]="${header_ref[0]} ----extra info----" 7706243cb0SMichal Berger header_ref[1]="${header_ref[1]} $_header" 7806243cb0SMichal Berger} 7906243cb0SMichal Berger 8055013c9eSMichal Berger_vmstat() { 8155013c9eSMichal Berger local count=$1 interval=$2 reprint_header=${3:-20} _count 8206243cb0SMichal Berger local vmstat vmstat_cmdline=() _vmstat stat_idx header=() 8306243cb0SMichal Berger 8406243cb0SMichal Berger [[ $PM_OS == Linux ]] && vmstat_cmdline+=(--timestamp) 8555013c9eSMichal Berger 8655013c9eSMichal Berger _count=$count 8755013c9eSMichal Berger while ((stat_idx = stat_idx == reprint_header ? 1 : ++stat_idx, count <= 0 ? 1 : _count--)); do 8806243cb0SMichal Berger mapfile -t vmstat < <(vmstat "${vmstat_cmdline[@]}") 8955013c9eSMichal Berger # Enhance output to include stuff we are most interested in 9006243cb0SMichal Berger vmstat[2]="${vmstat[2]} $(get_extra_info)" 9155013c9eSMichal Berger if ((stat_idx == 1)); then 9255013c9eSMichal Berger header=("${vmstat[@]::2}") 9306243cb0SMichal Berger set_extra_info_header header 9455013c9eSMichal Berger _vmstat=("${header[@]}" "${vmstat[2]}") 9555013c9eSMichal Berger else 9655013c9eSMichal Berger _vmstat=("${vmstat[2]}") 9755013c9eSMichal Berger fi 9855013c9eSMichal Berger printf '%s\n' "${_vmstat[@]}" 9906243cb0SMichal Berger sleep "${interval}" 100d5fe62b2SMichal Berger done 101d5fe62b2SMichal Berger} 102d5fe62b2SMichal Berger 103d5fe62b2SMichal Bergercleanup() { 104d5fe62b2SMichal Berger rm_pm_pid 10555013c9eSMichal Berger} 10655013c9eSMichal Berger 10755013c9eSMichal Bergercount=0 10855013c9eSMichal Bergerinterval=1 109d5fe62b2SMichal Bergerlog_to_file=no 11055013c9eSMichal Bergerprefix="" 11155013c9eSMichal Bergerreprint_header=20 11255013c9eSMichal Berger 113d5fe62b2SMichal Bergerwhile getopts c:d:hlp:r:t: opt; do 11455013c9eSMichal Berger case "$opt" in 11555013c9eSMichal Berger c) count=$OPTARG ;; 116d5fe62b2SMichal Berger d) PM_OUTPUTDIR=$OPTARG ;; 11755013c9eSMichal Berger h) 11855013c9eSMichal Berger help 11955013c9eSMichal Berger exit 0 12055013c9eSMichal Berger ;; 121d5fe62b2SMichal Berger l) log_to_file=yes ;; 12255013c9eSMichal Berger p) prefix=$OPTARG ;; 12355013c9eSMichal Berger r) reprint_header=$OPTARG ;; 12455013c9eSMichal Berger t) interval=$OPTARG ;; 12555013c9eSMichal Berger *) ;; 12655013c9eSMichal Berger esac 12755013c9eSMichal Bergerdone 12855013c9eSMichal Berger 12955013c9eSMichal Bergerdeclare -r log_file=${prefix:+${prefix}_}${0##*/}.pm.log 13055013c9eSMichal Berger 131d5fe62b2SMichal Bergermkdir -p "$PM_OUTPUTDIR" 132d5fe62b2SMichal Bergerif [[ $log_to_file == yes ]]; then 133d5fe62b2SMichal Berger printf 'Redirecting to %s\n' "$PM_OUTPUTDIR/$log_file" >&2 134d5fe62b2SMichal Berger exec > "$PM_OUTPUTDIR/$log_file" 2>&1 135d5fe62b2SMichal Bergerfi 13655013c9eSMichal Berger 137d5fe62b2SMichal Bergersave_pm_pid 138d5fe62b2SMichal Bergertrap 'cleanup' EXIT 1398d588fbcSMichal Bergertrap 'retag' USR1 1408d588fbcSMichal Berger 141*3fa77bf2SMichal Bergermap_cpus 142*3fa77bf2SMichal Berger 14355013c9eSMichal Berger_vmstat "$count" "$interval" "$reprint_header" 144