From 246458f95a29fd2adccfa82e9dc1fbe4e3e0906b Mon Sep 17 00:00:00 2001 From: "Al-Fahad, Rakib" Date: Thu, 10 Jul 2025 15:56:09 -0700 Subject: [PATCH 1/6] [madvise] Adapted the code to take care of variable names as we transition from 6.13 kernel baseline to 6.15 --- tests/madvise/collect_bpftraces.sh | 14 +++++++++++++- tests/madvise/collect_single_page.sh | 2 +- tests/madvise/enable_kernel_iaa.sh | 13 +++++++++++-- tests/madvise/madvise_test.c | 4 ++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/tests/madvise/collect_bpftraces.sh b/tests/madvise/collect_bpftraces.sh index 2e86690..35ba65a 100755 --- a/tests/madvise/collect_bpftraces.sh +++ b/tests/madvise/collect_bpftraces.sh @@ -75,7 +75,19 @@ else fi echo ${DBATCH} > /proc/sys/vm/page-cluster || handle_error "Failed to set page-cluster" -sysctl vm.compress-batchsize=${CBATCH} || handle_error "Failed to set compress-batchsize" + +# Note: This is a temporary solution as we transition the parameter names. +PARAM_VALUE=$(sysctl -n vm.compress-batchsize 2>/dev/null) +EXIT_CODE=$? +if [ ${EXIT_CODE} -eq 0 ]; then + sysctl vm.compress-batchsize=${CBATCH} || handle_error "Failed to set compress-batchsize" +fi + +PARAM_VALUE=$(sysctl -n vm.reclaim-batchsize 2>/dev/null) +EXIT_CODE=$? +if [ ${EXIT_CODE} -eq 0 ]; then + sysctl vm.reclaim-batchsize=${CBATCH} || handle_error "Failed to set compress-batchsize" +fi # Clear transparent huge pages configuration echo 'never' > /sys/kernel/mm/transparent_hugepage/hugepages-2048kB/enabled || handle_error "Failed to clear hugepages-2048kB configuration" diff --git a/tests/madvise/collect_single_page.sh b/tests/madvise/collect_single_page.sh index 8a7619b..77e30ab 100755 --- a/tests/madvise/collect_single_page.sh +++ b/tests/madvise/collect_single_page.sh @@ -53,7 +53,7 @@ fi comp_list=() # Create the compression algorihm list. Keep the alphabetical order for easy reporting if [ ${iaa_devices} -gt 0 ]; then - comp_list+=("deflate-iaa-canned" "deflate-iaa") + comp_list+=("deflate-iaa") fi comp_list+=("lz4") if [ ${QAT_ENABLED_IN_KERNEL} -gt 0 ]; then diff --git a/tests/madvise/enable_kernel_iaa.sh b/tests/madvise/enable_kernel_iaa.sh index 5142e8e..7d60b81 100755 --- a/tests/madvise/enable_kernel_iaa.sh +++ b/tests/madvise/enable_kernel_iaa.sh @@ -71,8 +71,17 @@ echo $config_json # apply verify-compress echo $verify_compress > ${VERIFY_COMPRESS_PATH} || handle_error "did not change verify_compress" -echo 1 > /sys/bus/dsa/drivers/crypto/g_wqs_per_iaa || handle_error "did not set g_wqs_per_iaa" -echo 1 > /sys/bus/dsa/drivers/crypto/g_consec_descs_per_gwq || handle_error "did not set g_consec_descs_per_gwq" +# Note: This is a temporary solution for during the kernel transition. +if [ -f /sys/bus/dsa/drivers/crypto/g_comp_wqs_per_iaa ];then + echo 1 > /sys/bus/dsa/drivers/crypto/g_comp_wqs_per_iaa || handle_error "did not set g_comp_wqs_per_iaa" +elif [ -f /sys/bus/dsa/drivers/crypto/g_wqs_per_iaa ];then + echo 1 > /sys/bus/dsa/drivers/crypto/g_comp_wqs_per_iaa || handle_error "did not set g_wqs_per_iaa" +fi + +if [ -f /sys/bus/dsa/drivers/crypto/g_consec_descs_per_gwq ];then + echo 1 > /sys/bus/dsa/drivers/crypto/g_consec_descs_per_gwq || handle_error "did not set g_consec_descs_per_gwq" +fi + echo ${iaa_crypto_mode} > /sys/bus/dsa/drivers/crypto/sync_mode || handle_error "could not set sync_mode" #echo sync > /sys/bus/dsa/drivers/crypto/sync_mode || handle_error "could not set sync_mode" diff --git a/tests/madvise/madvise_test.c b/tests/madvise/madvise_test.c index 1801da3..8a1add3 100644 --- a/tests/madvise/madvise_test.c +++ b/tests/madvise/madvise_test.c @@ -123,6 +123,10 @@ int main(int argc, char **argv) // Replace the newline character with a null terminator compressor[newline_pos] = '\0'; int cbatch = read_sysfs("/proc/sys/vm/compress-batchsize"); + // NOTE: This is a temporary solution as we transition to the new kernel + if ( cbatch == EXIT_FAILURE ) { + cbatch = read_sysfs("/proc/sys/vm/reclaim-batchsize"); + } int dbatch = read_sysfs("/proc/sys/vm/page-cluster"); // Add compress and decompress batch setting sprintf(compressor, "%s-c%d-d%d", compressor, cbatch, dbatch); From a93e4e2807bb2db23840840e9b1bb57db278886f Mon Sep 17 00:00:00 2001 From: bravindr Date: Fri, 11 Jul 2025 09:14:51 -0700 Subject: [PATCH 2/6] [madvise] cleaned up the input parameters --- tests/madvise/configure_iaa.sh | 96 ++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100755 tests/madvise/configure_iaa.sh diff --git a/tests/madvise/configure_iaa.sh b/tests/madvise/configure_iaa.sh new file mode 100755 index 0000000..d57c536 --- /dev/null +++ b/tests/madvise/configure_iaa.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +#SPDX-License-Identifier: BSD-3-Clause +#Copyright (c) 2025, Intel Corporation +#Description: Configure IAA devices + +# Usage : ./configure_iaa.sh +# devices: 0 - all devices or comma seperated device numbers +# wq_size: 0 - all devices or comma seperated device numbers +# For example, ./configure_iaa.sh 1 2 - configure 1 IAA device(s) and 2 WQs per device +# ./configure_iaa.sh 4 2 - configure 4 IAA device(s) and 2 WQs per device + +dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +#echo ${dir} +# +# count iax instances +# +iax_dev_id="0cfe" +num_iax=$(lspci -d:${iax_dev_id} | wc -l) +echo "Found ${num_iax} instances" + +device_num=${1:-$num_iax}; shift +iaa_wqs=${1:-2}; shift +iaa_engines=8 +wq_size=$(( 128 / iaa_wqs )) +mode="dedicated" + +# Take care of the enumeration, if DSA is enabled. +dsa=`lspci | grep -c 0b25` +#set first,step counters to correctly enumerate iax devices based on whether running on guest or host with or without dsa +first=0 +step=1 +[[ $dsa -gt 0 && -d /sys/bus/dsa/devices/dsa0 ]] && first=1 && step=2 +echo "first index: ${first}, step: ${step}" + +# +# disable iax wqs and devices +# +echo "Disable IAA devices before configuring" + +for ((i = ${first}; i < ${step} * ${num_iax}; i += ${step})); do + for ((j = 0; j < ${iaa_wqs}; j += 1)); do + cmd="accel-config disable-wq iax${i}/wq${i}.{j} >& /dev/null" + echo $cmd; eval $cmd + done + cmd="accel-config disable-device iax${i} >& /dev/null" + echo $cmd; eval $cmd +done + +echo "Configuring devices: ${device_num}" + +if [ ${device_num} == $num_iax ]; then + echo "Configuring all devices" + start=${first} + end=$(( ${step} * ${num_iax} )) +else + echo "Configuring devices ${device_num}" + declare -a array=($(echo ${device_num}| tr "," " ")) + start=${array[0]} + if [ ${array[1]} ];then + end=$((${array[1]} + 1 )) + else + end=$((${array[0]} + 1 )) + fi +fi + + + +# +# enable all iax devices and wqs +# +echo "Enable ${start} to ${end}" +for ((i = ${start}; i < ${end}; i += ${step})); do + # Config Devices, Engines and groups + for ((j = 0; j < ${iaa_engines}; j += 1)); do + cmd="accel-config config-engine iax${i}/engine${i}.${j} --group-id=0" + echo $cmd; eval $cmd + done + + # Config WQs + for ((j = 0; j < ${iaa_wqs}; j += 1)); do + # Config WQ: group 0, priority=10, mode=shared, type = kernel name=kernel, driver_name=crypto + cmd="accel-config config-wq iax${i}/wq${i}.${j} -g 0 -s ${wq_size} -p 10 -m ${mode} -y kernel -n iaa_crypto -b 1 -d crypto" + echo $cmd; eval $cmd + done + + # Enable Device and WQs + cmd="accel-config enable-device iax${i}" + echo $cmd; eval $cmd + for ((j = 0; j < ${iaa_wqs}; j += 1)); do + cmd="accel-config enable-wq iax${i}/wq${i}.${j}" + echo $cmd; eval $cmd + done + +done + + From e78f11c18daa04796b1d305e17a610880c2e9ddd Mon Sep 17 00:00:00 2001 From: Binuraj Ravindran Date: Fri, 11 Jul 2025 15:48:10 -0700 Subject: [PATCH 3/6] [madvise] updates for multi-socket --- tests/madvise/configure_iaa.sh | 109 +++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 39 deletions(-) diff --git a/tests/madvise/configure_iaa.sh b/tests/madvise/configure_iaa.sh index d57c536..cecc435 100755 --- a/tests/madvise/configure_iaa.sh +++ b/tests/madvise/configure_iaa.sh @@ -3,26 +3,56 @@ #Copyright (c) 2025, Intel Corporation #Description: Configure IAA devices -# Usage : ./configure_iaa.sh -# devices: 0 - all devices or comma seperated device numbers -# wq_size: 0 - all devices or comma seperated device numbers -# For example, ./configure_iaa.sh 1 2 - configure 1 IAA device(s) and 2 WQs per device -# ./configure_iaa.sh 4 2 - configure 4 IAA device(s) and 2 WQs per device - -dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -#echo ${dir} -# -# count iax instances -# iax_dev_id="0cfe" -num_iax=$(lspci -d:${iax_dev_id} | wc -l) -echo "Found ${num_iax} instances" +num_iaa=$(lspci -d:${iax_dev_id} | wc -l) +sockets=$(lscpu | grep Socket | awk '{print $2}') +echo "Found ${num_iaa} instances in ${sockets} sockets(s)" + +# The same number of devices will be configured in each socket, if there are more than one socket +# Normalize with respect to the number of sockets +device_num_per_socket=$(( num_iaa/sockets )) +num_iaa_per_socket=$(( num_iaa / sockets )) -device_num=${1:-$num_iax}; shift -iaa_wqs=${1:-2}; shift +iaa_wqs=2 +verbose=0 iaa_engines=8 -wq_size=$(( 128 / iaa_wqs )) mode="dedicated" +wq_type="kernel" + + +# Process arguments + +while getopts "d:hq:v" opt; do + case $opt in + d) + device_num_per_socket=$OPTARG + ;; + q) + iaa_wqs=$OPTARG + ;; + v) + verbose=1 + ;; + h) + echo "Usage: $0 [-d ][-q ][-v]" + echo " -d - number of devices" + echo " -q - number of WQs per device" + echo " -v - verbose mode" + echo " -h - help" + exit + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + ;; + esac +done + +LOG="configure_iaa.log" + +# Update wq_size based on number of wqs +wq_size=$(( 128 / iaa_wqs )) + + # Take care of the enumeration, if DSA is enabled. dsa=`lspci | grep -c 0b25` @@ -37,60 +67,61 @@ echo "first index: ${first}, step: ${step}" # echo "Disable IAA devices before configuring" -for ((i = ${first}; i < ${step} * ${num_iax}; i += ${step})); do +for ((i = ${first}; i < ${step} * ${num_iaa}; i += ${step})); do for ((j = 0; j < ${iaa_wqs}; j += 1)); do - cmd="accel-config disable-wq iax${i}/wq${i}.{j} >& /dev/null" - echo $cmd; eval $cmd + cmd="accel-config disable-wq iax${i}/wq${i}.${j} >& /dev/null" + [[ $verbose == 1 ]] && echo $cmd; eval $cmd done cmd="accel-config disable-device iax${i} >& /dev/null" - echo $cmd; eval $cmd + [[ $verbose == 1 ]] && echo $cmd; eval $cmd done -echo "Configuring devices: ${device_num}" -if [ ${device_num} == $num_iax ]; then + + +echo "Configuring ${device_num_per_socket} device(s) out of $num_iaa_per_socket per socket" +if [ "${device_num_per_socket}" -le "${num_iaa_per_socket}" ]; then echo "Configuring all devices" start=${first} - end=$(( ${step} * ${num_iax} )) + end=$(( ${step} * ${device_num_per_socket} )) else - echo "Configuring devices ${device_num}" - declare -a array=($(echo ${device_num}| tr "," " ")) - start=${array[0]} - if [ ${array[1]} ];then - end=$((${array[1]} + 1 )) - else - end=$((${array[0]} + 1 )) - fi + echo "ERROR: Not enough devices" + exit fi - # # enable all iax devices and wqs # -echo "Enable ${start} to ${end}" +for (( socket = 0; socket < ${sockets}; socket += 1 )); do for ((i = ${start}; i < ${end}; i += ${step})); do - # Config Devices, Engines and groups + + echo "Configuring iaa$i on socket ${socket}" + for ((j = 0; j < ${iaa_engines}; j += 1)); do cmd="accel-config config-engine iax${i}/engine${i}.${j} --group-id=0" - echo $cmd; eval $cmd + [[ $verbose == 1 ]] && echo $cmd; eval $cmd done # Config WQs for ((j = 0; j < ${iaa_wqs}; j += 1)); do # Config WQ: group 0, priority=10, mode=shared, type = kernel name=kernel, driver_name=crypto - cmd="accel-config config-wq iax${i}/wq${i}.${j} -g 0 -s ${wq_size} -p 10 -m ${mode} -y kernel -n iaa_crypto -b 1 -d crypto" - echo $cmd; eval $cmd + cmd="accel-config config-wq iax${i}/wq${i}.${j} -g 0 -s ${wq_size} -p 10 -m ${mode} -y ${wq_type} -n iaa_crypto${i}${j} -d crypto" + [[ $verbose == 1 ]] && echo $cmd; eval $cmd done # Enable Device and WQs cmd="accel-config enable-device iax${i}" - echo $cmd; eval $cmd + [[ $verbose == 1 ]] && echo $cmd; eval $cmd + for ((j = 0; j < ${iaa_wqs}; j += 1)); do cmd="accel-config enable-wq iax${i}/wq${i}.${j}" - echo $cmd; eval $cmd + [[ $verbose == 1 ]] && echo $cmd; eval $cmd done done + start=$(( start + ${step} * ${num_iaa_per_socket} )) + end=$(( start + (${step} * ${device_num_per_socket}) )) +done From 617e9f05bc43eb8514be339829c2cccaa8625b4e Mon Sep 17 00:00:00 2001 From: bravindr Date: Fri, 11 Jul 2025 16:04:21 -0700 Subject: [PATCH 4/6] [madvise] added the checks for configured devices --- tests/madvise/configure_iaa.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/madvise/configure_iaa.sh b/tests/madvise/configure_iaa.sh index cecc435..b043cd6 100755 --- a/tests/madvise/configure_iaa.sh +++ b/tests/madvise/configure_iaa.sh @@ -125,3 +125,6 @@ done done +# Check if the configuration is correct +echo "Configured IAA devices:" +accel-config list | grep iax From b83ad98bb9b70a661c9a3ba569c5fada902f862e Mon Sep 17 00:00:00 2001 From: bravindr Date: Fri, 11 Jul 2025 18:32:59 -0700 Subject: [PATCH 5/6] [madvise] refactored IAA configuration file to a single file and removed json files. updated the single and batch scripts accordingly --- tests/madvise/collect_batch.sh | 3 +- tests/madvise/collect_single_page.sh | 3 +- .../{configure_iaa.sh => enable_iaa.sh} | 48 +++++++++++++++++-- tests/madvise/madvise_test.c | 4 +- 4 files changed, 49 insertions(+), 9 deletions(-) rename tests/madvise/{configure_iaa.sh => enable_iaa.sh} (71%) diff --git a/tests/madvise/collect_batch.sh b/tests/madvise/collect_batch.sh index d637d26..876796f 100755 --- a/tests/madvise/collect_batch.sh +++ b/tests/madvise/collect_batch.sh @@ -25,7 +25,8 @@ while getopts "hd:p:" arg; do done # Configure IAA -./enable_kernel_iaa.sh 0 1 ${iaa_devices} 8 2 async +#./enable_kernel_iaa.sh 0 1 ${iaa_devices} 8 2 async +./enable_iaa.sh -d ${iaa_devices} -m async # Configure zswap and zram. ./enable_zswap.sh # swap disk can be used instead of zram. However, zram will avoid any disk access overheads diff --git a/tests/madvise/collect_single_page.sh b/tests/madvise/collect_single_page.sh index 77e30ab..c02f0b7 100755 --- a/tests/madvise/collect_single_page.sh +++ b/tests/madvise/collect_single_page.sh @@ -29,7 +29,8 @@ echo "Number of IAA device: $iaa_devices" # Configure IAA devices if [ ${iaa_devices} -gt 0 ]; then - ./enable_kernel_iaa.sh 0 1 ${iaa_devices} 8 2 sync + #./enable_kernel_iaa.sh 0 1 ${iaa_devices} 8 2 sync + ./enable_iaa.sh -d ${iaa_devices} -m sync fi # Configure zswap and zram. diff --git a/tests/madvise/configure_iaa.sh b/tests/madvise/enable_iaa.sh similarity index 71% rename from tests/madvise/configure_iaa.sh rename to tests/madvise/enable_iaa.sh index b043cd6..4293d47 100755 --- a/tests/madvise/configure_iaa.sh +++ b/tests/madvise/enable_iaa.sh @@ -3,6 +3,8 @@ #Copyright (c) 2025, Intel Corporation #Description: Configure IAA devices +VERIFY_COMPRESS_PATH="/sys/bus/dsa/drivers/crypto/verify_compress" + iax_dev_id="0cfe" num_iaa=$(lspci -d:${iax_dev_id} | wc -l) sockets=$(lscpu | grep Socket | awk '{print $2}') @@ -18,21 +20,35 @@ verbose=0 iaa_engines=8 mode="dedicated" wq_type="kernel" +iaa_crypto_mode="async" +verify_compress=0 + +# Function to handle errors +handle_error() { + echo "Error: $1" + exit 1 +} # Process arguments -while getopts "d:hq:v" opt; do +while getopts "d:hm:q:vD" opt; do case $opt in d) device_num_per_socket=$OPTARG ;; + m) + iaa_crypto_mode=$OPTARG + ;; q) iaa_wqs=$OPTARG ;; - v) + D) verbose=1 ;; + v) + verify_compress=1 + ;; h) echo "Usage: $0 [-d ][-q ][-v]" echo " -d - number of devices" @@ -43,6 +59,7 @@ while getopts "d:hq:v" opt; do ;; \?) echo "Invalid option: -$OPTARG" >&2 + exit ;; esac done @@ -52,8 +69,6 @@ LOG="configure_iaa.log" # Update wq_size based on number of wqs wq_size=$(( 128 / iaa_wqs )) - - # Take care of the enumeration, if DSA is enabled. dsa=`lspci | grep -c 0b25` #set first,step counters to correctly enumerate iax devices based on whether running on guest or host with or without dsa @@ -62,9 +77,14 @@ step=1 [[ $dsa -gt 0 && -d /sys/bus/dsa/devices/dsa0 ]] && first=1 && step=2 echo "first index: ${first}, step: ${step}" + # -# disable iax wqs and devices +# Switch to software compressors and disable IAAs to have a clean start # +COMPRESSOR=/sys/module/zswap/parameters/compressor +last_comp=`cat ${COMPRESSOR}` +echo lzo > ${COMPRESSOR} + echo "Disable IAA devices before configuring" for ((i = ${first}; i < ${step} * ${num_iaa}; i += ${step})); do @@ -76,6 +96,21 @@ for ((i = ${first}; i < ${step} * ${num_iaa}; i += ${step})); do [[ $verbose == 1 ]] && echo $cmd; eval $cmd done +rmmod iaa_crypto +modprobe iaa_crypto + +# apply crypto parameters +echo $verify_compress > ${VERIFY_COMPRESS_PATH} || handle_error "did not change verify_compress" +# Note: This is a temporary solution for during the kernel transition. +if [ -f /sys/bus/dsa/drivers/crypto/g_comp_wqs_per_iaa ];then + echo 1 > /sys/bus/dsa/drivers/crypto/g_comp_wqs_per_iaa || handle_error "did not set g_comp_wqs_per_iaa" +elif [ -f /sys/bus/dsa/drivers/crypto/g_wqs_per_iaa ];then + echo 1 > /sys/bus/dsa/drivers/crypto/g_wqs_per_iaa || handle_error "did not set g_wqs_per_iaa" +fi +if [ -f /sys/bus/dsa/drivers/crypto/g_consec_descs_per_gwq ];then + echo 1 > /sys/bus/dsa/drivers/crypto/g_consec_descs_per_gwq || handle_error "did not set g_consec_descs_per_gwq" +fi +echo ${iaa_crypto_mode} > /sys/bus/dsa/drivers/crypto/sync_mode || handle_error "could not set sync_mode" @@ -124,7 +159,10 @@ done end=$(( start + (${step} * ${device_num_per_socket}) )) done +# Restore the last compressor +echo "$last_comp" > ${COMPRESSOR} # Check if the configuration is correct echo "Configured IAA devices:" accel-config list | grep iax + diff --git a/tests/madvise/madvise_test.c b/tests/madvise/madvise_test.c index 8a1add3..e552d0e 100644 --- a/tests/madvise/madvise_test.c +++ b/tests/madvise/madvise_test.c @@ -33,7 +33,7 @@ long read_sysfs(char *path ){ FILE* fp = fopen(path, "r"); char buf[128]; if (!fp) { - perror("Couldn't open file"); + //perror("Couldn't open file"); return EXIT_FAILURE; } fgets(buf, sizeof(buf), fp); @@ -46,7 +46,7 @@ long read_sysfs_str(char *path , char *str, int size){ FILE* fp = fopen(path, "r"); if (!fp) { - perror("Couldn't open file"); + //perror("Couldn't open file"); return EXIT_FAILURE; } fgets(str, size, fp); From e7a7953e156445f87cfb3bf3c6a899a7340210e6 Mon Sep 17 00:00:00 2001 From: Binuraj Ravindran Date: Mon, 14 Jul 2025 11:50:07 -0700 Subject: [PATCH 6/6] code clean up --- tests/madvise/collect_single_page.sh | 118 ++++++++++++++++----- tests/madvise/process_bpftraces.py | 149 ++++++++++++++++++++------- 2 files changed, 200 insertions(+), 67 deletions(-) diff --git a/tests/madvise/collect_single_page.sh b/tests/madvise/collect_single_page.sh index c02f0b7..42b3882 100755 --- a/tests/madvise/collect_single_page.sh +++ b/tests/madvise/collect_single_page.sh @@ -1,8 +1,23 @@ -#!/usr/bin/bash +#!/bin/bash #SPDX-License-Identifier: BSD-3-Clause -#Copyright (c) 2025, Intel Corporation +#Copyright (c) 2025, I# If QAT is available in kernel, enable it as well +QAT_ENABLED_IN_KERNEL=$(bpftrace -l 2>/dev/null | grep qat_comp_alg_compress | wc -l) +if [ ${QAT_ENABLED_IN_KERNEL} -gt 0 ]; then + echo "QAT detected in kernel, enabling..." + ./enable_qat.sh || handle_error "Failed to enable QAT" +fi + + +comp_list=() +# Create the compression algorithm list. Keep the alphabetical order for easy reportingoration #Description: Top level script to collect datapoints for single page (no batching) +# Error handling function +handle_error() { + echo "ERROR: $1" >&2 + exit 1 +} + # Initialize variables iaa_devices=4 # Turn on this for preserving the intermediate results @@ -27,24 +42,45 @@ done echo "Number of IAA device: $iaa_devices" +# Check for root privileges +if [ "$(id -u)" -ne 0 ]; then + handle_error "This script requires root privileges. Please run with sudo." +fi + # Configure IAA devices if [ ${iaa_devices} -gt 0 ]; then + echo "Configuring IAA with $iaa_devices device(s) per socket..." #./enable_kernel_iaa.sh 0 1 ${iaa_devices} 8 2 sync - ./enable_iaa.sh -d ${iaa_devices} -m sync + ./enable_iaa.sh -d ${iaa_devices} -m sync || handle_error "Failed to configure IAA devices" fi # Configure zswap and zram. -./enable_zswap.sh +echo "Configuring zswap..." +./enable_zswap.sh || handle_error "Failed to configure zswap" + # swap disk can be used instead of zram. However, zram will avoid any disk access overheads -./enable_zram.sh +echo "Configuring zram..." +./enable_zram.sh || handle_error "Failed to configure zram" + +# Check for dataset +if [ ! -f "silesia.tar" ]; then + echo "Dataset silesia.tar not found. Attempting to download..." + wget --no-check-certificate http://wanos.co/assets/silesia.tar || handle_error "Failed to download silesia.tar" +fi # Install bpftrace if it is not available if [ ! -f /usr/bin/bpftrace ]; then echo "Installing bpftrace..." - yum install bpftrace -y || handle_error "Failed to install bpftrace" + if command -v apt-get &> /dev/null; then + apt-get update && apt-get install -y bpftrace || handle_error "Failed to install bpftrace" + elif command -v yum &> /dev/null; then + yum install bpftrace -y || handle_error "Failed to install bpftrace" + else + handle_error "Package manager not found. Please install bpftrace manually." + fi fi -# If QAT is avaialble in kernel, enable it as well +# If QAT is available in kernel, enable it as well QAT_ENABLED_IN_KERNEL=`bpftrace -l | grep qat_comp_alg_compress | wc -l` if [ ${QAT_ENABLED_IN_KERNEL} -gt 0 ]; then ./enable_qat.sh @@ -52,15 +88,19 @@ fi comp_list=() -# Create the compression algorihm list. Keep the alphabetical order for easy reporting +# Create the compression algorithm list. Keep the alphabetical order for easy reporting if [ ${iaa_devices} -gt 0 ]; then comp_list+=("deflate-iaa") + echo "Added deflate-iaa to compressor list" fi comp_list+=("lz4") if [ ${QAT_ENABLED_IN_KERNEL} -gt 0 ]; then - comp_list+=("qat_deflate") + comp_list+=("qat_deflate") + echo "Added qat_deflate to compressor list" fi -comp_list+=("zstd" ) +comp_list+=("zstd") + +echo "Final compressor list: ${comp_list[*]}" # Other possible values for compressors @@ -77,34 +117,56 @@ mthp_list=("4kB") #mthp_list=("4kB" "16kB" "64kB" "16kB,32kB,64kB") # clear old logs for a fresh start +echo "Clearing old logs..." ./clear_logs.sh +# Check if zswap module is loaded +if [ ! -d "/sys/module/zswap" ]; then + handle_error "zswap kernel module is not loaded" +fi + for freq in "${freq_list[@]}"; do for dataset in "${dataset_list[@]}"; do echo -e "\nData Corpus: ${dataset}\n" for cbatch in "${cbatch_list[@]}"; do for dbatch in "${dbatch_list[@]}"; do for mthp in "${mthp_list[@]}"; do - rm -r run.log + # Remove old run log if it exists + [ -f run.log ] && rm -f run.log + for comp in "${comp_list[@]}"; do - echo "Removing ${comp}_output" - rm -f ${comp}_output - echo $comp > /sys/module/zswap/parameters/compressor + echo "Removing ${comp}_output if it exists" + [ -f "${comp}_output" ] && rm -f "${comp}_output" + + echo "Setting compressor to $comp" + echo "$comp" > /sys/module/zswap/parameters/compressor || handle_error "Failed to set compressor to $comp" + echo "Collecting data for $comp at ${freq}MHz, cbatch ${cbatch}, dbatch ${dbatch}, mthp ${mthp}" - ./collect_bpftraces.sh -f ${freq} -t ${dataset} -c ${cbatch} -d ${dbatch} -m ${mthp} | tee -a run.log + ./collect_bpftraces.sh -f ${freq} -t ${dataset} -c ${cbatch} -d ${dbatch} -m ${mthp} | tee -a run.log || + handle_error "Failed to collect bpftraces for $comp" done - ./process_bpftraces.py | tee -a run.log - ./summarize_single_page.sh run.log | tee -a run.log - mthp_suffix=`echo ${mthp} | tr -d ' ' | tr ',' '_'` - result_dir="result_${freq}_${dataset}_c${cbatch}_d${dbatch}_${mthp_suffix}" - rm -rf ${result_dir} + echo "Processing bpftraces..." + ./process_bpftraces.py | tee -a run.log || handle_error "Failed to process bpftraces" + + echo "Summarizing results..." + ./summarize_single_page.sh run.log | tee -a run.log || handle_error "Failed to summarize results" + + mthp_suffix=$(echo ${mthp} | tr -d ' ' | tr ',' '_') + result_dir="result_${freq}_${dataset}_c${cbatch}_d${dbatch}_${mthp_suffix}" + + echo "Creating results directory: ${result_dir}" + [ -d "${result_dir}" ] && rm -rf "${result_dir}" + mkdir -p "${result_dir}" || handle_error "Failed to create results directory" + echo "Copying results to ${result_dir}" - mkdir ${result_dir} - cp *_output ${result_dir} - cp *.html ${result_dir} - cp *.xlsx ${result_dir} - cp perf_* ${result_dir} - cp run.log ${result_dir} + # Use for loop to handle case where no files match pattern + for file in *_output *.html *.xlsx perf_* run.log; do + if [ -f "$file" ]; then + cp "$file" "${result_dir}/" || handle_error "Failed to copy $file to results directory" + fi + done + + echo "Results saved to ${result_dir}" done done done @@ -115,10 +177,12 @@ done # Clear intermediate logs as needed if [ "${preserve_logs}" == "1" ]; then - echo "Saving temporary logs for debugging purposes" + echo "Saving temporary logs for debugging purposes" else echo "Removing all the temporary logs" ./clear_logs.sh fi +echo "Collection completed successfully!" + diff --git a/tests/madvise/process_bpftraces.py b/tests/madvise/process_bpftraces.py index 5b2c55e..16634d4 100755 --- a/tests/madvise/process_bpftraces.py +++ b/tests/madvise/process_bpftraces.py @@ -42,12 +42,22 @@ def draw_cdf(fig, fl, color, label_name, filter_col,line_style,log_scale=False): pd.options.display.float_format = '{:,.0f}'.format # Extract zswap_compress size and zswa_compress return code - comp_size=df[1][(df[0] == "R") & (df[1] >= 0)].sum() + # Handle the case when there are no valid compression ratio values + if filter_col == 'R': + comp_size_df = df[df[0] == "R"] + if comp_size_df.empty: + comp_size = 0 + else: + # Get valid values from comp_size_df directly without using df as reference + valid_indices = comp_size_df[1] >= 0 + comp_size = comp_size_df.loc[valid_indices, 1].sum() if valid_indices.any() else 0 + else: + comp_size = df.loc[(df[0] == "R") & (df[1] >= 0), 1].sum() + # Filter the dataframe df = df[df[0] == filter_col] df = df[df[1] >= 0] - if df.empty: print(f'DataFrame is empty for {filter_col}!') return None @@ -60,23 +70,39 @@ def draw_cdf(fig, fl, color, label_name, filter_col,line_style,log_scale=False): if len(df) > max_len: df = df.sample(max_len, random_state=42) - - df = df.transform(np.sort) + # Safe transformation to avoid NaN issues + df = df.copy() + df[1] = np.sort(df[1].values) df = df.reset_index(drop=True) - total_p99 = df[df.columns[-1]].quantile(0.99) - # filtering only for large values - if filter_col != 'BC' and filter_col != 'BD': - df = df[df[df.columns[-1]] < total_p99] + # Safely calculate quantiles to avoid NumPy warnings + if len(df) > 0: + total_p99 = df[df.columns[-1]].quantile(0.99) + # filtering only for large values + if filter_col != 'BC' and filter_col != 'BD': + df = df[df[df.columns[-1]] < total_p99] + else: + # Handle empty dataframe case + return None df['percentile'] = df.index / len(df) - p50 = df[1].quantile(0.50) #if not log_scale else df['numbers'].quantile(0.50) - p99 = df[1].quantile(0.99) #if not log_scale else df['numbers'].quantile(0.99) + if filter_col == 'R': + # Handle potential NaN values when calculating compression ratio + valid_values = df[1].dropna() + if valid_values.empty: + p50 = np.nan + p99 = np.nan + else: + p50 = valid_values.quantile(0.50) + p99 = valid_values.quantile(0.99) + else: + p50 = df[1].quantile(0.50) + p99 = df[1].quantile(0.99) PERF_LOG=str(f"perf_{label_name}.log") sys_time=0 @@ -98,22 +124,47 @@ def draw_cdf(fig, fl, color, label_name, filter_col,line_style,log_scale=False): 'comp_size':comp_size, 'sys_time':sys_time } - print(f'{label_name} {filter_col} {p50:.1f} {p99:.1f} {comp_size:.1f} {sys_time:.2f} ' if filter_col == 'R' else f'{label_name} {filter_col} {p50:.0f} {p99:.0f} {comp_size:.1f} {sys_time:.2f}') + + # Format output based on filter_col and handle NaN values + if filter_col == 'R': + if np.isnan(p50) or np.isnan(p99): + print(f'{label_name} {filter_col} N/A N/A {comp_size:.1f} {sys_time:.2f}') + else: + print(f'{label_name} {filter_col} {p50:.1f} {p99:.1f} {comp_size:.1f} {sys_time:.2f}') + else: + print(f'{label_name} {filter_col} {p50:.0f} {p99:.0f} {comp_size:.1f} {sys_time:.2f}') label_name = transform_test_column(label_name) + + # Handle different cases for plotting if log_scale and filter_col != 'R': - df[1] = np.log(df[1]) - df = df.replace([np.inf, -np.inf], np.nan).dropna() - fig.line(df[1], df['percentile'], line_width=4, color=color, - legend_label=f'{label_name} (p50: {p50:.0f}, p99: {p99:.0f})', name=label_name,line_dash=line_style) + # For log scale, handle values that might be negative or zero + valid_values = df[1][df[1] > 0] # Only positive values can be logged + if valid_values.empty: + return dicts # Return without plotting if no valid values + + df_valid = df.copy() + df_valid[1] = np.log(valid_values) + df_valid = df_valid.replace([np.inf, -np.inf], np.nan).dropna() + + fig.line(df_valid[1], df_valid['percentile'], line_width=4, color=color, + legend_label=f'{label_name} (p50: {p50:.0f}, p99: {p99:.0f})', name=label_name, line_dash=line_style) else: if filter_col == 'R': - fig.line(df[1], df['percentile'], line_width=4, color=color, legend_label=f'{label_name} (p50: {p50:.2f}, p99: {p99:.2f})', name=label_name,line_dash=line_style) - + if np.isnan(p50) or np.isnan(p99): + label_text = f'{label_name} (No valid ratio data)' + else: + label_text = f'{label_name} (p50: {p50:.2f}, p99: {p99:.2f})' + + # Only plot if we have valid data + if not df[1].isna().all(): + fig.line(df[1], df['percentile'], line_width=4, color=color, + legend_label=label_text, name=label_name, line_dash=line_style) else: - fig.line(df[1], df['percentile'], line_width=4, color=color, legend_label=f'{label_name} (p50: {p50:.0f}, p99: {p99:.0f})', name=label_name, line_dash=line_style) + fig.line(df[1], df['percentile'], line_width=4, color=color, + legend_label=f'{label_name} (p50: {p50:.0f}, p99: {p99:.0f})', name=label_name, line_dash=line_style) - return dicts + return dicts def create_figure(title, x_axis_label, y_axis_label, log_scale): fig = figure( @@ -151,21 +202,30 @@ def plot_df(files, log_scale=False): figures_cp = figures.copy() print(f'compressor field p50 p99 zpsize sys_time ') print(f'------------------------------------ ') + + # Check if we have any output files + if not files: + print("No output files found. Skipping analysis.") + return + for fl in files: label = fl.replace('_output', '') for key, fig in figures.items(): - line_style = line_styles[files.index(fl) % len(line_styles)] - - # Add header - df_dict=draw_cdf(fig, fl, colors[files.index(fl) % len(colors)], label, key,line_style, log_scale) - - if ( df_dict is not None ): - # Only add valid entries - results.append(df_dict) - else: - # Remove entries that are not valid - if key in figures_cp: - del figures_cp[key] + try: + line_style = line_styles[files.index(fl) % len(line_styles)] + # Add header + df_dict=draw_cdf(fig, fl, colors[files.index(fl) % len(colors)], label, key,line_style, log_scale) + + if ( df_dict is not None ): + # Only add valid entries + results.append(df_dict) + else: + # Remove entries that are not valid + if key in figures_cp: + del figures_cp[key] + except Exception as e: + print(f"Error processing {fl} for {key}: {e}") + continue for key, fig in figures_cp.items(): @@ -179,14 +239,23 @@ def plot_df(files, log_scale=False): if (log_scale == False): - results_df = pd.DataFrame(results) - results_df = results_df.sort_values(by=['var', 'compressor']) - results_df = results_df.reset_index(drop=True) - print('Saving summary results at summary.xlsx') - results_df.to_excel('summary.xlsx') + try: + if results: + results_df = pd.DataFrame(results) + results_df = results_df.sort_values(by=['var', 'compressor']) + results_df = results_df.reset_index(drop=True) + print('Saving summary results at summary.xlsx') + results_df.to_excel('summary.xlsx') + else: + print("No valid results to save to Excel") + except Exception as e: + print(f"Error saving results to Excel: {e}") # Main script -files = glob.glob('*_output') -files.sort() -plot_df(files, log_scale=False) -#plot_df(files, log_scale=True) +try: + files = glob.glob('*_output') + files.sort() + plot_df(files, log_scale=False) + #plot_df(files, log_scale=True) +except Exception as e: + print(f"An error occurred during script execution: {e}")