-
Notifications
You must be signed in to change notification settings - Fork 27
Added UFS functional tests #220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # UFS Clock Scaling and Gating Validation | ||
| ## Overview | ||
|
|
||
| This shell script executes on the DUT (Device-Under-Test) and verifies the UFS clock scaling and clock gating functionality by monitoring clock frequency changes during I/O load and idle states. | ||
|
|
||
| The test script performs these functional checks: | ||
|
|
||
| 1. **Kernel Configuration**: | ||
| - Validates presence of mandatory configs: `CONFIG_SCSI_UFSHCD`, `CONFIG_SCSI_UFS_QCOM` | ||
| - Checks optional configs: `CONFIG_SCSI_UFSHCD_PLATFORM`, `CONFIG_SCSI_UFSHCD_PCI`, `CONFIG_SCSI_UFS_CDNS_PLATFORM`, `CONFIG_SCSI_UFS_HISI`, `CONFIG_SCSI_UFS_EXYNOS`, `CONFIG_SCSI_UFS_ROCKCHIP`, `CONFIG_SCSI_UFS_BSG` | ||
|
|
||
| 2. **Device Tree Validation**: | ||
| - Verifies UFS device tree nodes exist at `/sys/bus/platform/devices/*ufs*` | ||
| - Detects UFS block device partition | ||
|
|
||
| 3. **Clock Frequency Node Detection**: | ||
| - Locates current frequency node: `/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/cur_freq` | ||
| - Locates max frequency node: `/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/max_freq` | ||
| - Locates min frequency node: `/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/min_freq` | ||
|
|
||
| 4. **Clock Scaling Verification**: | ||
| - Generates I/O load using `dd` command (writes 2GB of data) | ||
| - Monitors whether UFS clock scales up to maximum frequency during load | ||
| - Validates clock frequency on application of load | ||
|
|
||
| 5. **Clock Gating Verification**: | ||
| - Waits for UFS driver to enter idle state | ||
| - Monitors whether UFS clock gates down to minimum frequency when idle | ||
| - Validates ufs clock is gated when no load is present | ||
|
|
||
| ## How to Run | ||
|
|
||
| ```sh | ||
| source init_env | ||
| cd suites/Kernel/Baseport/Storage/ufs_clock_scaling | ||
| ./run.sh | ||
| ``` | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - `dd`, `sleep` must be available | ||
| - Root access may be required for complete validation | ||
| - Sufficient storage space for temporary test file (approximately 2GB) | ||
|
|
||
| ## Result Format | ||
|
|
||
| Test result will be saved in `ufs_clock_scaling.res` as: | ||
| - `ufs_clock_scaling PASS` – if both clock scaling and gating validations pass | ||
| - `ufs_clock_scaling FAIL` – if either clock scaling or gating check fails | ||
| - `ufs_clock_scaling SKIP` – if required kernel configs, device tree nodes, or UFS devices are not found | ||
|
|
||
| ## License | ||
|
|
||
| ``` | ||
| Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. | ||
| SPDX-License-Identifier: BSD-3-Clause-Clear |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| #!/bin/sh | ||
|
|
||
| # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. | ||
| # SPDX-License-Identifier: BSD-3-Clause-Clear | ||
|
|
||
| # Robustly find and source init_env | ||
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| INIT_ENV="" | ||
| SEARCH="$SCRIPT_DIR" | ||
| while [ "$SEARCH" != "/" ]; do | ||
| if [ -f "$SEARCH/init_env" ]; then | ||
| INIT_ENV="$SEARCH/init_env" | ||
| break | ||
| fi | ||
| SEARCH=$(dirname "$SEARCH") | ||
| done | ||
|
|
||
| if [ -z "$INIT_ENV" ]; then | ||
| echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Only source if not already loaded | ||
| if [ -z "$__INIT_ENV_LOADED" ]; then | ||
| # shellcheck disable=SC1090 | ||
| . "$INIT_ENV" | ||
| export __INIT_ENV_LOADED=1 | ||
| fi | ||
|
|
||
| # Always source functestlib.sh | ||
| # shellcheck disable=SC1090,SC1091 | ||
| . "$TOOLS/functestlib.sh" | ||
|
|
||
| TESTNAME="ufs_clock_scaling" | ||
| test_path=$(find_test_case_by_name "$TESTNAME") | ||
| cd "$test_path" || exit 0 | ||
| res_file="./$TESTNAME.res" | ||
|
|
||
| log_info "--------------------------------------------------" | ||
| log_info "------------- Starting $TESTNAME Test ------------" | ||
|
|
||
| check_dependencies dd sleep | ||
|
|
||
| # Run common UFS prechecks | ||
| if ! ufs_precheck_common; then | ||
| log_skip "Required UFS configurations are not available" | ||
| echo "$TESTNAME SKIP" > "$res_file" | ||
| exit 0 | ||
| fi | ||
| log_info "UFS prechecks successful" | ||
|
|
||
| log_info "Validating UFS clock scaling & clock gating" | ||
| # Check for UFS clock freq node and assign to variable | ||
| log_info "Checking for UFS clock freq node..." | ||
| if UFS_CLOCK_FREQ_NODE=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/cur_freq"); then | ||
| log_info "Found UFS clock frequency node: $UFS_CLOCK_FREQ_NODE" | ||
| else | ||
| log_skip "Failed to get UFS clock frequency node" | ||
| echo "$TESTNAME SKIP" > "$res_file" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Check for UFS clock max freq node and assign to variable | ||
| log_info "Checking for UFS max clock freq node..." | ||
| if UFS_MAX_FREQ_NODE=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/max_freq"); then | ||
| log_info "Found UFS controller's max_frequency node: $UFS_MAX_FREQ_NODE" | ||
| else | ||
| log_skip "Failed to get UFS max clock frequency node" | ||
| echo "$TESTNAME SKIP" > "$res_file" | ||
| exit 0 | ||
| fi | ||
|
|
||
| UFS_MAX_FREQ=$(cat "$UFS_MAX_FREQ_NODE" 2>/dev/null) | ||
| if [ -z "$UFS_MAX_FREQ" ]; then | ||
| log_skip "Failed to read max frequency from $UFS_MAX_FREQ_NODE" | ||
| echo "$TESTNAME FAIL" > "$res_file" | ||
| exit 0 | ||
| fi | ||
| log_info "Max UFS clock frequency supported is $UFS_MAX_FREQ" | ||
|
|
||
| # Check for UFS clock min freq node and assign to variable | ||
| log_info "Checking for UFS min clock freq node..." | ||
| if UFS_MIN_FREQ_NODE=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/min_freq"); then | ||
| log_info "Found UFS controller's min_frequency node: $UFS_MIN_FREQ_NODE" | ||
| else | ||
| log_skip "Failed to get UFS min clock frequency node" | ||
| echo "$TESTNAME SKIP" > "$res_file" | ||
| exit 0 | ||
| fi | ||
|
|
||
| UFS_MIN_FREQ=$(cat "$UFS_MIN_FREQ_NODE" 2>/dev/null) | ||
| if [ -z "$UFS_MIN_FREQ" ]; then | ||
| log_skip "Failed to read min frequency from $UFS_MIN_FREQ" | ||
| echo "$TESTNAME FAIL" > "$res_file" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Failing to read max_freq currently leads to FAIL (good), but elsewhere similar read failures are treated as SKIP. Rule of thumb: |
||
| exit 0 | ||
| fi | ||
| log_info "Min UFS clock frequency supported is $UFS_MIN_FREQ" | ||
|
|
||
| # Generate load using dd command and check for ufs cur_freq | ||
| log_info "Starting I/O load test to verify UFS clock scaling..." | ||
| tmpfile="$test_path/${TESTNAME}.tmp" | ||
|
|
||
| # Start dd in background | ||
| dd if=/dev/zero of="$tmpfile" bs=2M count=1024 >/dev/null 2>&1 & | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too big for CU and slow stroage. Use smaller writes (e.g., 64–256MB), or looped reads to avoid wear.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still it is not addressed. Default smaller (64–256MB) and allow override via env: |
||
| DD_PID=$! | ||
|
|
||
| log_info "Checking whether UFS clock is scaled during load..." | ||
| UFS_CLOCK_SCALED=0 | ||
| RETRIES=10 | ||
| RETRY_TIMEOUT=1 | ||
| attempt=1 | ||
|
|
||
| while [ $attempt -le $RETRIES ]; do | ||
| current_freq=$(cat "$UFS_CLOCK_FREQ_NODE" 2>/dev/null | tr -d '\n' | tr -d '\r') | ||
|
|
||
| if [ -n "$current_freq" ] && [ "$current_freq" -gt "$UFS_MIN_FREQ" ]; then | ||
| log_pass "UFS clock is scaled to $current_freq (greater than MIN_FREQ: $UFS_MIN_FREQ)" | ||
| UFS_CLOCK_SCALED=1 | ||
| break | ||
| fi | ||
|
|
||
| log_info "Attempt $attempt/$RETRIES: Current frequency $current_freq" | ||
|
|
||
| if [ $attempt -lt $RETRIES ]; then | ||
| sleep $RETRY_TIMEOUT | ||
| fi | ||
|
|
||
| attempt=$((attempt + 1)) | ||
| done | ||
|
|
||
| # Wait for dd to complete if it's still running | ||
| if kill -0 $DD_PID 2>/dev/null; then | ||
| log_info "Waiting for I/O load test to complete..." | ||
| wait $DD_PID 2>/dev/null | ||
| sync | ||
| fi | ||
|
|
||
| # Clean up temp file | ||
| rm -f "$tmpfile" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For every test using temp files: |
||
|
|
||
| log_info "Checking whether UFS clock is gated when no load is applied" | ||
| UFS_CLOCK_GATED=0 | ||
|
|
||
| # Use check_node_status to verify ufs clock scaling | ||
| if ! check_node_status_with_timeout "$UFS_CLOCK_FREQ_NODE" "$UFS_MIN_FREQ" 60; then | ||
| log_fail "UFS clock is not gated" | ||
| else | ||
| log_pass "UFS clock is gated to $UFS_MIN_FREQ" | ||
| UFS_CLOCK_GATED=1 | ||
| fi | ||
|
|
||
| if [ "$UFS_CLOCK_SCALED" -ne 1 ] || [ "$UFS_CLOCK_GATED" -ne 1 ]; then | ||
| log_fail "UFS clock scaling & gating test failed" | ||
| echo "$TESTNAME FAIL" > "$res_file" | ||
| exit 0 | ||
| fi | ||
|
|
||
| scan_dmesg_errors "$test_path" "ufs" | ||
| log_pass "$TESTNAME completed successfully" | ||
| echo "$TESTNAME PASS" > "$res_file" | ||
| exit 0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| metadata: | ||
| name: ufs-clock-scaling | ||
| format: "Lava-Test Test Definition 1.0" | ||
| description: "Check whether UFS clock is scaled when load is applied" | ||
| os: | ||
| - linux | ||
| scope: | ||
| - functional | ||
|
|
||
| run: | ||
| steps: | ||
| - REPO_PATH=$PWD | ||
| - cd Runner/suites/Kernel/Baseport/Storage/ufs_clock_scaling | ||
| - ./run.sh || true | ||
| - $REPO_PATH/Runner/utils/send-to-lava.sh ufs_clock_scaling.res || true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not a SKIP condition, you mark FAIL, but log_skip. Use log_fail
Also you mean Failed to read min frequency from $UFS_MIN_FREQ_NODE ?