From patchwork Sat Jan 25 06:45:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jim Cromie X-Patchwork-Id: 13950799 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C4584C0218E for ; Sun, 26 Jan 2025 16:41:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5E2DA10E46D; Sun, 26 Jan 2025 16:41:00 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="S6NldZpF"; dkim-atps=neutral Received: from mail-io1-f48.google.com (mail-io1-f48.google.com [209.85.166.48]) by gabe.freedesktop.org (Postfix) with ESMTPS id 70DA010EA64; Sat, 25 Jan 2025 06:47:07 +0000 (UTC) Received: by mail-io1-f48.google.com with SMTP id ca18e2360f4ac-851c4ee2a37so198190739f.3; Fri, 24 Jan 2025 22:47:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1737787627; x=1738392427; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZUFY1/p4cwMapYCElPuw4n+JFAz595e4pdu5x+kllYo=; b=S6NldZpFhmT55EHkGhUIG6Y/MCE9Wkb8fcq28t9djO6gpwTWP4wNb7l9shAGRLamhw Bx/OGhZFQHHTPY8H7ufFSvlq7InOvSaY5/3GIrt2HL2Ihp/jjbZS10VrUV//7uQl4azb uIJSoN7jWpwvssrMQb7qcvyRkXC6awLPPusVNaaMDN+4dFfQ7tad+ibagwtIPA2koz2t b49ugQ0BuHOBHcUHs3rn23H7c8klrrfoODw3mex4iXLZfpKqTGth5iVohpXIjCA3H/RH dLqfS1I11gkSx/2Yb0YQIRCJ/tMk+2SGBiX3YnSf4ZI4bpxKDZFInkZToRBK+bB36df8 TdCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737787627; x=1738392427; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZUFY1/p4cwMapYCElPuw4n+JFAz595e4pdu5x+kllYo=; b=BYtjgyN33EXworOHY5tDJlRWqN5b7cRSrPke4NkYncNQfuC52+M5xhnKy4bMQJ4zos K+96VVJLlwRSmH2L8jyrpNsEXXYugxOu3BAjONqEhrzdV8JiIDhWhelZ1JYyzYD+JrA1 fWXD67AKDBR9ahOKe9blYUbaugJ7+nIHvZeH7xE+BHKd3wEwVuvJgADeUsWqSdUJ00D7 0qZf2qUl2LtvN5TmhOd0tR+U7KF5205BQZCsV3xmg+imq1/mOHaN6rmhPZg2Y92BfxCp C2aJbHeqQf0f7Y/4S7K1rMhlPluK7XF+UB/RwrSpHGAtMpoSQ6ih/9NeQ+VihbLHMYwR 0HcQ== X-Forwarded-Encrypted: i=1; AJvYcCVM2tC/NV4cAd2CkRf2eM2qNXwBUcaN50mOcd20VhKXx7/teImVgI7Lim+ZO7y+PKrw28P7mGN0@lists.freedesktop.org, AJvYcCW0dUmhfvSn2n/lmOZn2gKS9izEpIY9n7iglDuzPfoE5XX1OPTWOetfwgHrPLwcnz8aHU7mHIF/yK4u@lists.freedesktop.org, AJvYcCWTH3CyJVUzy7yl8VfzyMmZ+VYD0/Vp7PQZ8jZDjxeLO//Aea/KjnWMYI8PP6dBssgVKNxbEj1OCBsxpVIoJA==@lists.freedesktop.org, AJvYcCXNOaZBDZlKPQpyFBjDtUCpZm0B6xs0nDicX3Hr/seds7snCnrqbQ6qJCrUv53wt4m7VBOh8CmDvlr+@lists.freedesktop.org X-Gm-Message-State: AOJu0YxA7RrFDTJQPBAcYbrkvCJ0FhGqm4xzu70UYPPKBTQeHAs4KetM /xshBEO2hmhfscW+iI3ldbLzLsVTFQhepoFSsqyQTk4VsNvgFAT3 X-Gm-Gg: ASbGnculnSNyQ4/9H/QPHcnMGgKDabvOmoBeqcvBPTyrVE/6Wly/gcAIkR2/cyAnrgB 4j/iOU1VrOL2Z66d2Cb7F2fvgXlyXP8WIH/wpWCupaUIPA9PTULzn6CmSTlKhzy+C9VcKQrEPHM XSP1uGbguRQBjbMA8Z62YBMkpYFjxRRV+Q0lR5MMYOltwE96N39fsa/H9WMmNAOwmmtMBFxxjYr O1RPo90SccUyRzADWXTINSiKdvToWkEkfvz1S+gZZ84eYRtqFs819keUGzmZfzr5CmU+U0wkLJj wVK21NxbpWcT8g0KdsgEgtBrlaLNlcba7j9m4A== X-Google-Smtp-Source: AGHT+IFNi6k74yWo8JFoUX0FA2mOzPOZaMw9sxfyiZBj57HkmJfOHCUtm05G1Ba+XY1KZ2w6PJRKAA== X-Received: by 2002:a05:6602:26c5:b0:83b:5221:2a87 with SMTP id ca18e2360f4ac-851b616986dmr3118410539f.3.1737787626594; Fri, 24 Jan 2025 22:47:06 -0800 (PST) Received: from gandalf.. (c-67-165-245-5.hsd1.co.comcast.net. [67.165.245.5]) by smtp.googlemail.com with ESMTPSA id 8926c6da1cb9f-4ec1da476fesm1174144173.58.2025.01.24.22.47.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jan 2025 22:47:06 -0800 (PST) From: Jim Cromie To: linux-kernel@vger.kernel.org, jbaron@akamai.com, gregkh@linuxfoundation.org, ukaszb@chromium.org Cc: intel-gfx-trybot@lists.freedesktop.org, dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, daniel.vetter@ffwll.ch, tvrtko.ursulin@linux.intel.com, jani.nikula@intel.com, ville.syrjala@linux.intel.com, Jim Cromie Subject: [PATCH 27/63] selftests-dyndbg: add tools/testing/selftests/dynamic_debug/* Date: Fri, 24 Jan 2025 23:45:41 -0700 Message-ID: <20250125064619.8305-28-jim.cromie@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250125064619.8305-1-jim.cromie@gmail.com> References: <20250125064619.8305-1-jim.cromie@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 26 Jan 2025 16:39:35 +0000 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Add a selftest script for dynamic-debug. The config requires CONFIG_TEST_DYNAMIC_DEBUG=m (and CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m), which tacitly requires either CONFIG_DYNAMIC_DEBUG=y or CONFIG_DYNAMIC_DEBUG_CORE=y ATM this has just basic_tests(), which modifies pr_debug flags in module params, which to handle boot args/options, must be a builtin. This is backported from another feature branch; the support-fns (thx Lukas) have unused features at the moment, they'll get used shortly. The script enables simple virtme-ng testing: $> vng V=1 -- ./tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh virtme: waiting for virtiofsd to start virtme: use 'microvm' QEMU architecture ... [ 4.136168] virtme-init: Setting hostname to v6.8-32-g30d431000676... [ 4.240874] virtme-init: starting script ... [ 4.474435] virtme-init: script returned {0} Powering off. [ 4.529318] ACPI: PM: Preparing to enter system sleep state S5 [ 4.529991] kvm: exiting hardware virtualization [ 4.530428] reboot: Power down And add dynamic_debug to TARGETS, so `make run_tests` sees it properly for the impatient, set TARGETS explicitly: bash-5.2# make TARGETS=dynamic_debug run_tests make[1]: ... TAP version 13 1..1 [ 35.552922] dyndbg: read 3 bytes from userspace [ 35.553099] dyndbg: query 0: "=_" mod:* [ 35.553544] dyndbg: processed 1 queries, with 1778 matches, 0 errs ... Signed-off-by: Jim Cromie Co-developed-by: Łukasz Bartosik Signed-off-by: Łukasz Bartosik --- - check KCONFIG_CONFIG to avoid silly fails Several tests are dependent upon config choices. Lets avoid failing where that is noise. The KCONFIG_CONFIG var exists to convey the config-file around. If the var names a file, read it and extract the relevant CONFIG items, and use them to skip the dependent tests, thus avoiding the fails that would follow, and the disruption to whatever CI is running these selftests. If the envar doesn't name a config-file, ".config" is assumed. CONFIG_DYNAMIC_DEBUG=y: basic-tests() and comma-terminator-tests() test for the presence of the builtin pr_debugs in module/main.c, which I deemed stable and therefore safe to count. That said, the test fails if only CONFIG_DYNAMIC_DEBUG_CORE=y is set. It could be rewritten to test against test-dynamic-debug.ko, but that just trades one config dependence for another. CONFIG_TEST_DYNAMIC_DEBUG=m As written, test_percent_splitting() modprobes test_dynamic_debug, enables several classes, and count them. It could be re-written to work for the builtin module also, but builtin test modules are not a common or desirable build/config. CONFIG_TEST_DYNAMIC_DEBUG=m && CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m test_mod_submod() recaps the bug found in DRM-CI where drivers werent enabled by drm.debug=. It modprobes both test_dynamic_debug & test_dynamic_debug_submod, so it depends on a loadable modules config. It could be rewritten to work in a builtin parent config; DRM=y is common enough to be pertinent, but testing that config also wouldn't really test anything more fully than all-loadable modules, since they default together. --- MAINTAINERS | 1 + tools/testing/selftests/Makefile | 1 + .../testing/selftests/dynamic_debug/Makefile | 9 + tools/testing/selftests/dynamic_debug/config | 2 + .../dynamic_debug/dyndbg_selftest.sh | 256 ++++++++++++++++++ 5 files changed, 269 insertions(+) create mode 100644 tools/testing/selftests/dynamic_debug/Makefile create mode 100644 tools/testing/selftests/dynamic_debug/config create mode 100755 tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh diff --git a/MAINTAINERS b/MAINTAINERS index 38afccb3b71e..b707421229e3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8042,6 +8042,7 @@ S: Maintained F: include/linux/dynamic_debug.h F: lib/dynamic_debug.c F: lib/test_dynamic_debug*.c +F: tools/testing/selftests/dynamic_debug/* DYNAMIC INTERRUPT MODERATION M: Tal Gilboa diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 2401e973c359..e632f3fc97ac 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -25,6 +25,7 @@ TARGETS += drivers/net/team TARGETS += drivers/net/virtio_net TARGETS += drivers/platform/x86/intel/ifs TARGETS += dt +TARGETS += dynamic_debug TARGETS += efivarfs TARGETS += exec TARGETS += fchmodat2 diff --git a/tools/testing/selftests/dynamic_debug/Makefile b/tools/testing/selftests/dynamic_debug/Makefile new file mode 100644 index 000000000000..6d06fa7f1040 --- /dev/null +++ b/tools/testing/selftests/dynamic_debug/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-only +# borrowed from Makefile for user memory selftests + +# No binaries, but make sure arg-less "make" doesn't trigger "run_tests" +all: + +TEST_PROGS := dyndbg_selftest.sh + +include ../lib.mk diff --git a/tools/testing/selftests/dynamic_debug/config b/tools/testing/selftests/dynamic_debug/config new file mode 100644 index 000000000000..d080da571ac0 --- /dev/null +++ b/tools/testing/selftests/dynamic_debug/config @@ -0,0 +1,2 @@ +CONFIG_TEST_DYNAMIC_DEBUG=m +CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh new file mode 100755 index 000000000000..68a9046405f2 --- /dev/null +++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh @@ -0,0 +1,256 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only + +V=${V:=0} # invoke as V=1 $0 for global verbose +RED="\033[0;31m" +GREEN="\033[0;32m" +YELLOW="\033[0;33m" +BLUE="\033[0;34m" +MAGENTA="\033[0;35m" +CYAN="\033[0;36m" +NC="\033[0;0m" +error_msg="" + +[ -e /proc/dynamic_debug/control ] || { + echo -e "${RED}: this test requires CONFIG_DYNAMIC_DEBUG=y ${NC}" + exit 0 # nothing to test here, no good reason to fail. +} + +# need info to avoid failures due to untestable configs + +[ -f "$KCONFIG_CONFIG" ] || KCONFIG_CONFIG=".config" +if [ -f "$KCONFIG_CONFIG" ]; then + echo "# consulting KCONFIG_CONFIG: $KCONFIG_CONFIG" + grep -q "CONFIG_DYNAMIC_DEBUG=y" $KCONFIG_CONFIG ; LACK_DD_BUILTIN=$? + grep -q "CONFIG_TEST_DYNAMIC_DEBUG=m" $KCONFIG_CONFIG ; LACK_TMOD=$? + grep -q "CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m" $KCONFIG_CONFIG ; LACK_TMOD_SUBMOD=$? + if [ $V -eq 1 ]; then + echo LACK_DD_BUILTIN: $LACK_DD_BUILTIN + echo LACK_TMOD: $LACK_TMOD + echo LACK_TMOD_SUBMOD: $LACK_TMOD_SUBMOD + fi +else + LACK_DD_BUILTIN=0 + LACK_TMOD=0 + LACK_TMOD_SUBMOD=0 +fi + +function vx () { + echo $1 > /sys/module/dynamic_debug/parameters/verbose +} + +function ddgrep () { + grep $1 /proc/dynamic_debug/control +} + +function doprints () { + cat /sys/module/test_dynamic_debug/parameters/do_prints +} + +function ddcmd () { + exp_exit_code=0 + num_args=$# + if [ "${@:$#}" = "pass" ]; then + num_args=$#-1 + elif [ "${@:$#}" = "fail" ]; then + num_args=$#-1 + exp_exit_code=1 + fi + args=${@:1:$num_args} + output=$((echo "$args" > /proc/dynamic_debug/control) 2>&1) + exit_code=$? + error_msg=$(echo $output | cut -d ":" -f 5 | sed -e 's/^[[:space:]]*//') + handle_exit_code $BASH_LINENO $FUNCNAME $exit_code $exp_exit_code +} + +function handle_exit_code() { + local exp_exit_code=0 + [ $# == 4 ] && exp_exit_code=$4 + if [ $3 -ne $exp_exit_code ]; then + echo -e "${RED}: $BASH_SOURCE:$1 $2() expected to exit with code $exp_exit_code" + [ $3 == 1 ] && echo "Error: '$error_msg'" + exit + fi +} + +# $1 - pattern to match, pattern in $1 is enclosed by spaces for a match ""\s$1\s" +# $2 - number of times the pattern passed in $1 is expected to match +# $3 - optional can be set either to "-r" or "-v" +# "-r" means relaxed matching in this case pattern provided in $1 is passed +# as is without enclosing it with spaces +# "-v" prints matching lines +# $4 - optional when $3 is set to "-r" then $4 can be used to pass "-v" +function check_match_ct { + pattern="\s$1\s" + exp_cnt=0 + + [ "$3" == "-r" ] && pattern="$1" + let cnt=$(ddgrep "$pattern" | wc -l) + if [ $V -eq 1 ] || [ "$3" == "-v" ] || [ "$4" == "-v" ]; then + echo -ne "${BLUE}" && ddgrep $pattern && echo -ne "${NC}" + fi + [ $# -gt 1 ] && exp_cnt=$2 + if [ $cnt -ne $exp_cnt ]; then + echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO check failed expected $exp_cnt on $1, got $cnt" + exit + else + echo ": $cnt matches on $1" + fi +} + +# $1 - trace instance name +# #2 - if > 0 then directory is expected to exist, if <= 0 then otherwise +# $3 - "-v" for verbose +function check_trace_instance_dir { + if [ -e /sys/kernel/tracing/instances/$1 ]; then + if [ "$3" == "-v" ] ; then + echo "ls -l /sys/kernel/tracing/instances/$1: " + ls -l /sys/kernel/tracing/instances/$1 + fi + if [ $2 -le 0 ]; then + echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO error trace instance \ + '/sys/kernel/tracing/instances/$1' does exist" + exit + fi + else + if [ $2 -gt 0 ]; then + echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO error trace instance \ + '/sys/kernel/tracing/instances/$1' does not exist" + exit + fi + fi +} + +function tmark { + echo $* > /sys/kernel/tracing/trace_marker +} + +# $1 - trace instance name +# $2 - line number +# $3 - if > 0 then the instance is expected to be opened, otherwise +# the instance is expected to be closed +function check_trace_instance { + output=$(tail -n9 /proc/dynamic_debug/control | grep ": Opened trace instances" \ + | xargs -n1 | grep $1) + if [ "$output" != $1 ] && [ $3 -gt 0 ]; then + echo -e "${RED}: $BASH_SOURCE:$2 trace instance $1 is not opened" + exit + fi + if [ "$output" == $1 ] && [ $3 -le 0 ]; then + echo -e "${RED}: $BASH_SOURCE:$2 trace instance $1 is not closed" + exit + fi +} + +function is_trace_instance_opened { + check_trace_instance $1 $BASH_LINENO 1 +} + +function is_trace_instance_closed { + check_trace_instance $1 $BASH_LINENO 0 +} + +# $1 - trace instance directory to delete +# $2 - if > 0 then directory is expected to be deleted successfully, if <= 0 then otherwise +function del_trace_instance_dir() { + exp_exit_code=1 + [ $2 -gt 0 ] && exp_exit_code=0 + output=$((rmdir /sys/kernel/debug/tracing/instances/$1) 2>&1) + exit_code=$? + error_msg=$(echo $output | cut -d ":" -f 3 | sed -e 's/^[[:space:]]*//') + handle_exit_code $BASH_LINENO $FUNCNAME $exit_code $exp_exit_code +} + +function error_log_ref { + # to show what I got + : echo "# error-log-ref: $1" + : echo cat \$2 +} + +function ifrmmod { + lsmod | grep $1 2>&1>/dev/null && rmmod $1 +} + +# $1 - text to search for +function search_trace() { + search_trace_name 0 1 $1 +} + +# $1 - trace instance name, 0 for global event trace +# $2 - line number counting from the bottom +# $3 - text to search for +function search_trace_name() { + if [ "$1" = "0" ]; then + buf=$(cat /sys/kernel/debug/tracing/trace) + line=$(tail -$2 /sys/kernel/debug/tracing/trace | head -1 | sed -e 's/^[[:space:]]*//') + else + buf=$(cat /sys/kernel/debug/tracing/instances/$1/trace) + line=$(tail -$2 /sys/kernel/debug/tracing/instances/$1/trace | head -1 | \ + sed -e 's/^[[:space:]]*//') + fi + if [ $2 = 0 ]; then + # whole-buf check + output=$(echo $buf | grep "$3") + else + output=$(echo $line | grep "$3") + fi + if [ "$output" = "" ]; then + echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO search for '$3' failed \ + in line '$line' or '$buf'" + exit + fi + if [ $V = 1 ]; then + echo -e "${MAGENTA}: search_trace_name in $1 found: \n$output \nin:${BLUE} $buf ${NC}" + fi +} + +# $1 - error message to check +function check_err_msg() { + if [ "$error_msg" != "$1" ]; then + echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO error message '$error_msg' \ + does not match with '$1'" + exit + fi +} + +function basic_tests { + echo -e "${GREEN}# BASIC_TESTS ${NC}" + if [ $LACK_DD_BUILTIN -eq 1 ]; then + echo "SKIP" + return + fi + ddcmd =_ # zero everything + check_match_ct =p 0 + + # module params are builtin to handle boot args + check_match_ct '\[params\]' 4 -r + ddcmd module params +mpf + check_match_ct =pmf 4 + + # multi-cmd input, newline separated, with embedded comments + cat <<"EOF" > /proc/dynamic_debug/control + module params =_ # clear params + module params +mf # set flags + module params func parse_args +sl # other flags +EOF + check_match_ct =mf 3 + check_match_ct =mfsl 1 + ddcmd =_ +} + +tests_list=( + basic_tests +) + +# Run tests + +ifrmmod test_dynamic_debug_submod +ifrmmod test_dynamic_debug + +for test in "${tests_list[@]}" +do + $test + echo "" +done +echo -en "${GREEN}# Done on: " +date