From fbc509e652001520d4b35d36b49be439b3eef4e4 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 31 Mar 2026 16:08:07 +0530 Subject: [PATCH 1/3] kernel: add shared interrupt counter parsing helpers Add reusable helpers in Runner/utils/functestlib.sh for interrupt-based tests: - get_interrupt_line_by_name() - extract_interrupt_cpu_counts() - count_interrupt_cpu_counts() These helpers parse only numeric per-CPU interrupt counters from /proc/interrupts and avoid hardcoded assumptions about CPU count. Signed-off-by: Srikanth Muppandam --- Runner/utils/functestlib.sh | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Runner/utils/functestlib.sh b/Runner/utils/functestlib.sh index 7483f056..ac26bc32 100755 --- a/Runner/utils/functestlib.sh +++ b/Runner/utils/functestlib.sh @@ -4687,3 +4687,40 @@ file_size_bytes() { printf '%s\n' "$size" return 0 } + +# Return the first /proc/interrupts line matching the given pattern. +# Prints the full line and returns 0 on success, 1 if no match is found. +get_interrupt_line_by_name() { + pattern="$1" + [ -n "$pattern" ] || return 1 + grep "$pattern" /proc/interrupts 2>/dev/null | head -n 1 +} + +# Extract only numeric per-CPU interrupt counters from a /proc/interrupts line. +# Prints one counter per line, stopping at the first non-numeric token after the IRQ field. +extract_interrupt_cpu_counts() { + printf '%s\n' "$1" | awk ' + { + seen_irq = 0 + for (i = 1; i <= NF; i++) { + if (seen_irq == 0) { + if ($i ~ /:$/) { + seen_irq = 1 + } + continue + } + if ($i ~ /^[0-9]+$/) { + print $i + } else { + break + } + } + } + ' +} + +# Count extracted per-CPU interrupt counters. +# Prints the count as a decimal integer. +count_interrupt_cpu_counts() { + printf '%s\n' "$1" | awk 'NF { c++ } END { print c + 0 }' +} From af3d3c591e7263e5acb5c7f87a25347b7ec4f15b Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 31 Mar 2026 16:08:29 +0530 Subject: [PATCH 2/3] kernel: use shared interrupt parsing helpers in irq test Update the irq test to use shared interrupt parsing helpers from functestlib.sh instead of assuming a fixed number of CPU interrupt columns. The test now: - locates the arch_timer line through a shared helper - extracts only numeric per-CPU interrupt counters - validates the detected counter count before comparison Signed-off-by: Srikanth Muppandam --- Runner/suites/Kernel/Baseport/irq/run.sh | 46 ++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/Runner/suites/Kernel/Baseport/irq/run.sh b/Runner/suites/Kernel/Baseport/irq/run.sh index 50792d7c..63d9e92f 100755 --- a/Runner/suites/Kernel/Baseport/irq/run.sh +++ b/Runner/suites/Kernel/Baseport/irq/run.sh @@ -40,7 +40,7 @@ log_info "=== Test Initialization ===" # Function to get the timer count get_timer_count() { - grep arch_timer /proc/interrupts + get_interrupt_line_by_name "arch_timer" } # Get the initial timer count @@ -61,17 +61,45 @@ log_info "Comparing timer counts:" while IFS= read -r line; do [ -n "$line" ] || continue - cpu=$(printf '%s\n' "$line" | awk '{print $1}') - initial_values=$(printf '%s\n' "$line" | awk '{for(i=2;i<=9;i++) print $i}') - final_values=$(printf '%s\n' "$final_count" | awk -v cpu="$cpu" '$1 == cpu {for(i=2;i<=9;i++) print $i}') + irq_id=$(printf '%s\n' "$line" | awk '{print $1}') + final_line=$(printf '%s\n' "$final_count" | awk -v irq="$irq_id" '$1 == irq { print; exit }') + + if [ -z "$final_line" ]; then + log_fail "Could not find matching final timer line for IRQ $irq_id" + log_fail "$TESTNAME : Test Failed" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 + fi + + initial_values=$(extract_interrupt_cpu_counts "$line") + final_values=$(extract_interrupt_cpu_counts "$final_line") + + initial_cpu_count=$(count_interrupt_cpu_counts "$initial_values") + final_cpu_count=$(count_interrupt_cpu_counts "$final_values") + + log_info "Detected timer counters: initial=${initial_cpu_count} final=${final_cpu_count}" + + if [ "$initial_cpu_count" -eq 0 ] || [ "$final_cpu_count" -eq 0 ]; then + log_fail "No per-CPU timer counters could be parsed from /proc/interrupts" + log_fail "$TESTNAME : Test Failed" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 + fi + + if [ "$initial_cpu_count" -ne "$final_cpu_count" ]; then + log_fail "Mismatch in parsed CPU timer counters: initial=${initial_cpu_count} final=${final_cpu_count}" + log_fail "$TESTNAME : Test Failed" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 + fi fail_test=false i=0 - while IFS= read -r initial_value; do - [ -n "$initial_value" ] || continue - + while [ "$i" -lt "$initial_cpu_count" ]; do + initial_value=$(printf '%s\n' "$initial_values" | sed -n "$((i + 1))p") final_value=$(printf '%s\n' "$final_values" | sed -n "$((i + 1))p") + if [ "$initial_value" -lt "$final_value" ]; then log_pass "CPU $i: Timer count has incremented. Test PASSED" else @@ -79,9 +107,7 @@ while IFS= read -r line; do fail_test=true fi i=$((i + 1)) - done < Date: Tue, 31 Mar 2026 16:08:45 +0530 Subject: [PATCH 3/3] kernel: use shared interrupt parsing helpers in Interrupts test Update the Interrupts test to use shared interrupt parsing helpers from functestlib.sh instead of assuming a fixed number of CPU interrupt columns. The test now: - locates the arch_timer line through a shared helper - extracts only numeric per-CPU interrupt counters - validates the detected counter count before comparison Signed-off-by: Srikanth Muppandam --- .../suites/Kernel/Baseport/Interrupts/run.sh | 47 ++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/Runner/suites/Kernel/Baseport/Interrupts/run.sh b/Runner/suites/Kernel/Baseport/Interrupts/run.sh index 63ad6aa7..23a68aae 100755 --- a/Runner/suites/Kernel/Baseport/Interrupts/run.sh +++ b/Runner/suites/Kernel/Baseport/Interrupts/run.sh @@ -40,7 +40,7 @@ log_info "=== Test Initialization ===" # Function to get the timer count get_timer_count() { - grep arch_timer /proc/interrupts + get_interrupt_line_by_name "arch_timer" } # Get the initial timer count @@ -61,17 +61,45 @@ echo "Comparing timer counts:" while IFS= read -r line; do [ -n "$line" ] || continue - cpu=$(printf '%s\n' "$line" | awk '{print $1}') - initial_values=$(printf '%s\n' "$line" | awk '{for(i=2;i<=9;i++) print $i}') - final_values=$(printf '%s\n' "$final_count" | awk -v cpu="$cpu" '$1 == cpu {for(i=2;i<=9;i++) print $i}') + irq_id=$(printf '%s\n' "$line" | awk '{print $1}') + final_line=$(printf '%s\n' "$final_count" | awk -v irq="$irq_id" '$1 == irq { print; exit }') + + if [ -z "$final_line" ]; then + log_fail "Could not find matching final timer line for IRQ $irq_id" + log_fail "$TESTNAME : Test Failed" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 + fi + + initial_values=$(extract_interrupt_cpu_counts "$line") + final_values=$(extract_interrupt_cpu_counts "$final_line") + + initial_cpu_count=$(count_interrupt_cpu_counts "$initial_values") + final_cpu_count=$(count_interrupt_cpu_counts "$final_values") + + log_info "Detected timer counters: initial=${initial_cpu_count} final=${final_cpu_count}" + + if [ "$initial_cpu_count" -eq 0 ] || [ "$final_cpu_count" -eq 0 ]; then + log_fail "No per-CPU timer counters could be parsed from /proc/interrupts" + log_fail "$TESTNAME : Test Failed" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 + fi + + if [ "$initial_cpu_count" -ne "$final_cpu_count" ]; then + log_fail "Mismatch in parsed CPU timer counters: initial=${initial_cpu_count} final=${final_cpu_count}" + log_fail "$TESTNAME : Test Failed" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 + fi fail_test=false i=0 - while IFS= read -r initial_value; do - [ -n "$initial_value" ] || continue - + while [ "$i" -lt "$initial_cpu_count" ]; do + initial_value=$(printf '%s\n' "$initial_values" | sed -n "$((i + 1))p") final_value=$(printf '%s\n' "$final_values" | sed -n "$((i + 1))p") + if [ "$initial_value" -lt "$final_value" ]; then echo "CPU $i: Timer count has incremented. Test PASSED" log_pass "CPU $i: Timer count has incremented. Test PASSED" @@ -81,11 +109,8 @@ while IFS= read -r line; do fail_test=true fi i=$((i + 1)) - done < "$res_file"