-
Notifications
You must be signed in to change notification settings - Fork 37
pelt scheduler: add new tests to validate pelt #447
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
Open
vnarapar
wants to merge
1
commit into
qualcomm-linux:main
Choose a base branch
from
vnarapar:pelt_scheduler
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
Runner/suites/Kernel/Scheduler/PELT_config/PELT_config.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| metadata: | ||
| name: pelt-config | ||
| format: "Lava-Test Test Definition 1.0" | ||
| description: "Validates kernel configuration required for PELT (Per-Entity Load Tracking) scheduler" | ||
| maintainer: | ||
| - vnarapar@qti.qualcomm.com | ||
| os: | ||
| - linux | ||
| scope: | ||
| - functional | ||
| devices: | ||
| - rb3gen2 | ||
| - qcs6490 | ||
| - qcs8300 | ||
| - qcs9100 | ||
| - sa8775p | ||
|
|
||
| run: | ||
| steps: | ||
| - REPO_PATH=$PWD | ||
| - cd "$REPO_PATH/Runner/suites/Kernel/Scheduler/PELT_config" | ||
| - ./run.sh | ||
| - $REPO_PATH/Runner/utils/send-to-lava.sh PELT_config.res |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # PELT_config — PELT Kernel Configuration Validation | ||
|
|
||
| ## Overview | ||
|
|
||
| Validates that the kernel is built with the configurations required for | ||
| **PELT (Per-Entity Load Tracking)**, the Linux CFS scheduler mechanism that | ||
| tracks CPU utilization per scheduling entity (tasks and task groups). | ||
|
|
||
| ## What Is Tested | ||
|
|
||
| | Config | Required | Purpose | | ||
| |---|---|---| | ||
| | `CONFIG_SMP` | Yes | Multi-CPU support — PELT load balancing is SMP-only | | ||
| | `CONFIG_FAIR_GROUP_SCHED` | Optional | Per-entity load tracking across scheduling groups | | ||
| | `CONFIG_SCHED_DEBUG` | Optional | Enables `/sys/kernel/debug/sched` and `/proc/<pid>/sched` | | ||
| | `CONFIG_CFS_BANDWIDTH` | Optional | CFS bandwidth control (uses PELT util signals) | | ||
| | `CONFIG_NO_HZ_COMMON` | Optional | Tickless kernel — affects PELT decay accuracy | | ||
| | `CONFIG_SCHED_AUTOGROUP` | Optional | Automatic task group creation | | ||
| | `CONFIG_CGROUP_SCHED` | Optional | cgroup-based scheduling (PELT tracks per cgroup) | | ||
| | `CONFIG_CPU_FREQ_GOV_SCHEDUTIL` | Optional | schedutil governor — consumes PELT util_avg | | ||
|
|
||
| ## Pass / Fail / Skip Criteria | ||
|
|
||
| - **SKIP**: `/proc/config.gz` not present (CONFIG_IKCONFIG not enabled) | ||
| - **FAIL**: `CONFIG_SMP` not enabled | ||
| - **PASS**: All required configs enabled (optional configs logged as warnings only) | ||
|
|
||
| ## Usage | ||
|
|
||
| ```sh | ||
| ./run.sh | ||
| ``` | ||
|
|
||
| ## Dependencies | ||
|
|
||
| - `/proc/config.gz` (CONFIG_IKCONFIG + CONFIG_IKCONFIG_PROC) | ||
| - `grep`, `zgrep` or `gzip` (provided by functestlib) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| #!/bin/sh | ||
|
|
||
| # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. | ||
| # SPDX-License-Identifier: BSD-3-Clause | ||
|
|
||
| # 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 1 | ||
| fi | ||
|
|
||
| if [ -z "${__INIT_ENV_LOADED:-}" ]; then | ||
| # shellcheck disable=SC1090 | ||
| . "$INIT_ENV" | ||
| fi | ||
|
|
||
| # shellcheck disable=SC1090,SC1091 | ||
| . "$TOOLS/functestlib.sh" | ||
|
|
||
| TESTNAME="PELT_config" | ||
| test_path=$(find_test_case_by_name "$TESTNAME") | ||
| cd "$test_path" || exit 1 | ||
| res_file="./$TESTNAME.res" | ||
|
|
||
| log_info "================================================================================" | ||
| log_info "============ Starting $TESTNAME Testcase =======================================" | ||
| log_info "================================================================================" | ||
| log_info "Validates kernel configuration required for PELT (Per-Entity Load Tracking)" | ||
|
|
||
| if ! check_dependencies zgrep; then | ||
| log_skip "$TESTNAME SKIP - missing required zgrep utility" | ||
| echo "$TESTNAME SKIP" > "$res_file" | ||
| exit 0 | ||
| fi | ||
|
|
||
| pass="true" | ||
|
|
||
| log_info "=== Core PELT / CFS Kernel Configs ===" | ||
|
|
||
| if [ ! -f /proc/config.gz ]; then | ||
| log_warn "/proc/config.gz not found - kernel config checks will be skipped" | ||
| log_warn "Ensure CONFIG_IKCONFIG and CONFIG_IKCONFIG_PROC are enabled in the kernel" | ||
| echo "$TESTNAME SKIP" > "$res_file" | ||
| exit 0 | ||
| else | ||
| CORE_CONFIGS="CONFIG_SMP" | ||
|
|
||
| if ! check_kernel_config "$CORE_CONFIGS"; then | ||
| log_fail "Core Scheduler kernel config validation failed" | ||
| pass=false | ||
| else | ||
| log_pass "Core Scheduler configs available" | ||
| fi | ||
|
|
||
| OPTIONAL_CONFIGS="CONFIG_SCHED_DEBUG CONFIG_CFS_BANDWIDTH CONFIG_NO_HZ_COMMON CONFIG_SCHED_AUTOGROUP CONFIG_CGROUP_SCHED CONFIG_CPU_FREQ_GOV_SCHEDUTIL CONFIG_FAIR_GROUP_SCHED" | ||
|
|
||
| if ! check_optional_config "$OPTIONAL_CONFIGS"; then | ||
| log_info "Optional Scheduler kernel configs are not available" | ||
| else | ||
| log_pass "Optional Scheduler configs available" | ||
|
vnarapar marked this conversation as resolved.
|
||
| fi | ||
|
|
||
| fi | ||
|
|
||
| if [ "$pass" = "true" ]; then | ||
| log_pass "$TESTNAME : Test Passed" | ||
| echo "$TESTNAME PASS" > "$res_file" | ||
| else | ||
| log_fail "$TESTNAME : Test Failed" | ||
| echo "$TESTNAME FAIL" > "$res_file" | ||
| fi | ||
|
|
||
| log_info "-------------------Completed $TESTNAME Testcase----------------------------" | ||
| exit 0 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| metadata: | ||
| name: pelt-decay | ||
| format: "Lava-Test Test Definition 1.0" | ||
| description: "Validates PELT exponential decay: util_avg must decrease after CPU load stops" | ||
| maintainer: | ||
| - vnarapar@qti.qualcomm.com | ||
| os: | ||
| - linux | ||
| scope: | ||
| - functional | ||
| devices: | ||
| - rb3gen2 | ||
| - qcs6490 | ||
| - qcs8300 | ||
| - qcs9100 | ||
| - sa8775p | ||
|
|
||
| run: | ||
| steps: | ||
| - REPO_PATH=$PWD | ||
| - cd "$REPO_PATH/Runner/suites/Kernel/Scheduler/PELT_decay" | ||
| - ./run.sh | ||
| - $REPO_PATH/Runner/utils/send-to-lava.sh PELT_decay.res |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| # PELT_decay — PELT Exponential Decay Validation | ||
|
|
||
| ## Overview | ||
|
|
||
| Validates that **PELT (Per-Entity Load Tracking) exponential decay** is | ||
| functioning correctly in the kernel. PELT uses a geometric series with a | ||
| ~32 ms half-life to track CPU utilization. After a task stops running, | ||
| its `util_avg` must decay toward zero — this is the mechanism that allows | ||
| the scheduler and cpufreq governors to reduce CPU frequency after load drops. | ||
|
|
||
| This is the **only** testcase in the PELT suite that explicitly validates | ||
| decay. The other tests (`PELT_load_tracking`, `PELT_schedutil`) only validate | ||
| accumulation (load going up), not the decay direction. | ||
|
|
||
| ## PELT Decay Theory | ||
|
|
||
| ``` | ||
| util_avg(t) = util_avg(t0) × 0.5^( Δt / 32ms ) | ||
|
|
||
| Half-life = 32 ms (one PELT period = 1024 µs) | ||
| After 100ms idle: util_avg → 11.5% of peak | ||
| After 200ms idle: util_avg → 1.3% of peak | ||
| After 1000ms idle: util_avg → ~0% of peak (< 0.001%) | ||
| ``` | ||
|
|
||
| ## Two Validation Methods | ||
|
|
||
| ### Method 1: `/proc/self/sched` `se.avg.util_avg` (Primary) | ||
|
|
||
| **Requires:** `CONFIG_SCHED_DEBUG` | ||
|
|
||
| The test script itself performs a CPU-bound busy loop for ~3 seconds, | ||
| saturating its own PELT `util_avg`. It then reads `util_avg` immediately | ||
| after the loop (should be high), sleeps 1 second, and reads again (should | ||
| be near zero). | ||
|
|
||
| ``` | ||
| 1. Read baseline util_avg (shell is idle → low) | ||
| 2. Run arithmetic busy loop for ~3s (saturates util_avg → near 1024) | ||
| 3. Read peak util_avg (should be > 100/1024) | ||
| 4. Sleep 1 second (~31 PELT half-lives → >99.9% theoretical decay) | ||
| 5. Read decayed util_avg (should be < peak/2) | ||
| 6. Assert: decayed_util < peak_util / 2 | ||
| ``` | ||
|
|
||
| **Pass threshold:** `decayed_util < peak_util / 2` (50% decay after 1s). | ||
| This is extremely conservative — theoretical decay after 1s is >99.9%. | ||
|
|
||
| ### Method 2: schedutil Frequency Proxy (Secondary) | ||
|
|
||
| **Requires:** `schedutil` cpufreq governor active | ||
|
|
||
| `schedutil` translates PELT `util_avg` into CPU frequency requests. When | ||
| `util_avg` decays after load stops, `schedutil` should lower the frequency. | ||
|
|
||
| ``` | ||
| 1. Record idle frequency | ||
| 2. Spawn background busy loop for 3s → record peak frequency | ||
| 3. Kill load, wait 2 seconds | ||
| 4. Record post-decay frequency | ||
| 5. Assert: post_decay_freq < load_freq | ||
| ``` | ||
|
|
||
| This method is **informational** — a warning is issued if frequency does | ||
| not drop, but it does not cause a FAIL (thermal floors, rate_limit_us, or | ||
| platform-specific governor behaviour can prevent immediate frequency drop). | ||
|
|
||
| ## Pass / Fail / Skip Criteria | ||
|
|
||
| | Condition | Result | | ||
| |---|---| | ||
| | Neither method available | SKIP | | ||
| | Method 1 available, decay ≥ 50% after 1s | PASS | | ||
| | Method 1 available, decay < 50% after 1s | FAIL | | ||
| | Method 2 only, frequency dropped after load | PASS (informational) | | ||
| | Method 2 only, frequency did not drop | WARN (not FAIL) | | ||
|
|
||
| ## Why Existing Tests Don't Cover Decay | ||
|
|
||
| | Test | What it measures | Decay? | | ||
| |---|---|---| | ||
| | `PELT_schedstat` | `rq_cpu_time` (monotonic counter, never decays) | ✗ | | ||
| | `PELT_load_tracking` | `rq_cpu_time` increases under load | ✗ | | ||
| | `PELT_schedutil` | Frequency rises under load | ✗ (rise only) | | ||
| | **`PELT_decay`** | `util_avg` decreases after load stops | **✓** | | ||
|
|
||
| ## Usage | ||
|
|
||
| ```sh | ||
| ./run.sh | ||
| ``` | ||
|
|
||
| ## Dependencies | ||
|
|
||
| - `/proc/self/sched` — `CONFIG_SCHED_DEBUG` (Method 1) | ||
| - `schedutil` governor — `CONFIG_CPU_FREQ_GOV_SCHEDUTIL` (Method 2) | ||
| - `grep`, `awk`, `cat`, `date` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.