Skip to content

Commit 812acf6

Browse files
committed
add CMA (Contiguous Memory Allocator) enablement test script
Introduce a CMA enablement/validation script that verifies configuration, initialization, runtime behavior, and statistics on Qualcomm platforms. Key capabilities: - Kernel config validation: CONFIG_CMA, CONFIG_DMA_CMA, CONFIG_CMA_DEBUG, CONFIG_CMA_DEBUGFS (mandatory), plus optional CMA sizing and areas. - Memory stats collection: total, free, used, and usage% with size sanity checks (≥ 1 MB). - DT configuration checks: CMA size/alignment and reserved-memory regions. - Runtime verification: dmesg for CMA reservation/alloc/release messages, error/warning detection, and activity counts. - Sysfs/Debugfs interfaces: enumerate `/sys/kernel/debug/cma` areas and report per-area stats; include relevant `/proc/vmstat` counters. - Result artifacts: writes `cma.res` (PASS/FAIL) and logs detailed output to the console. Signed-off-by: Vamsee Narapareddi <vnarapar@qti.qualcomm.com>
1 parent d37dcc2 commit 812acf6

File tree

3 files changed

+371
-0
lines changed

3 files changed

+371
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# CMA (Contiguous Memory Allocator) Enablement Test
2+
3+
## Overview
4+
5+
This test validates CMA (Contiguous Memory Allocator) enablement, configuration, and functionality on Qualcomm platforms. CMA is essential for allocating large contiguous memory blocks required by multimedia devices like cameras, displays, and video encoders.
6+
7+
## What is CMA?
8+
9+
CMA (Contiguous Memory Allocator) is a Linux kernel framework that:
10+
- Reserves a pool of physically contiguous memory at boot time
11+
- Allows normal page allocations from this pool when not in use
12+
- Provides large contiguous allocations when needed by devices
13+
- Critical for DMA operations requiring physically contiguous buffers
14+
15+
## Test Coverage
16+
17+
### 1. CMA Kernel Configuration
18+
- **CONFIG_CMA** - Core CMA support (mandatory)
19+
- **CONFIG_DMA_CMA** - Core CMA support (mandatory)
20+
- **CONFIG_CMA_DEBUG** - Core CMA support (mandatory)
21+
- **CONFIG_CMA_DEBUGFS** - Core CMA support (mandatory)
22+
- **CONFIG_CMA_SIZE_MBYTES** - Default CMA size configuration
23+
- **CONFIG_CMA_SIZE_SEL_MBYTES** - CMA size selection method
24+
- **CONFIG_CMA_AREAS** - Maximum number of CMA areas
25+
26+
### 2. CMA Memory Statistics
27+
- Total CMA memory available
28+
- Free CMA memory
29+
- Used CMA memory
30+
- Usage percentage calculation
31+
- Size validation (minimum 1MB)
32+
33+
### 3. CMA Device Tree Configuration
34+
- CMA size from device tree
35+
- CMA alignment properties
36+
- Reserved memory region enumeration
37+
38+
### 4. CMA Initialization and Runtime
39+
- CMA reservation messages in kernel logs
40+
- CMA allocation/release activity
41+
- Error and warning detection
42+
- Runtime behavior validation
43+
44+
### 5. CMA Sysfs/Debugfs Interface
45+
- CMA debugfs (`/sys/kernel/debug/cma`)
46+
- CMA area enumeration
47+
- Per-area allocation statistics
48+
- CMA statistics in `/proc/vmstat`
49+
50+
## Usage
51+
52+
### Run directly:
53+
```bash
54+
cd /path/to/Runner/suites/Kernel/Baseport/cma
55+
./run.sh
56+
```
57+
58+
### Run via test runner:
59+
```bash
60+
cd /path/to/Runner
61+
./run-test.sh cma
62+
```
63+
64+
## Test Results
65+
66+
Generates:
67+
- `cma.res` - Final result (PASS/FAIL)
68+
- Console output with detailed CMA information
69+
70+
## Prerequisites
71+
72+
### Required:
73+
- `CONFIG_DMA_CMA=y` `CONFIG_CMA=y` `CONFIG_CMA_DEBUG=y` `CONFIG_CMA_DEBUGFS=y` in kernel configuration
74+
- CMA memory reserved (via device tree or kernel command line)
75+
76+
### Optional:
77+
- Debugfs mounted at `/sys/kernel/debug` (for detailed statistics)
78+
- Root or appropriate permissions
79+
80+
## Expected Output
81+
82+
```
83+
[INFO] 1980-01-06 00:18:47 - ================================================================================
84+
[INFO] 1980-01-06 00:18:47 - ============ Starting cma Testcase =======================================
85+
[INFO] 1980-01-06 00:18:47 - ================================================================================
86+
[INFO] 1980-01-06 00:18:47 - === CMA Kernel Configuration Validation ===
87+
[PASS] 1980-01-06 00:18:47 - Kernel config CONFIG_CMA is enabled
88+
[PASS] 1980-01-06 00:18:47 - Kernel config CONFIG_DMA_CMA is enabled
89+
[PASS] 1980-01-06 00:18:47 - Kernel config CONFIG_CMA_DEBUG is enabled
90+
[PASS] 1980-01-06 00:18:47 - Kernel config CONFIG_CMA_DEBUGFS is enabled
91+
[PASS] 1980-01-06 00:18:47 - CMA kernel configuration validated
92+
[INFO] 1980-01-06 00:18:47 - Checking optional CMA configurations...
93+
[FAIL] 1980-01-06 00:18:47 - Kernel config CONFIG_CMA_SIZE_MBYTES is missing or not enabled
94+
[INFO] 1980-01-06 00:18:47 - CONFIG_CMA_SIZE_MBYTES: not set (optional)
95+
[PASS] 1980-01-06 00:18:47 - Kernel config CONFIG_CMA_SIZE_SEL_MBYTES is enabled
96+
[INFO] 1980-01-06 00:18:47 - CONFIG_CMA_SIZE_SEL_MBYTES:
97+
[FAIL] 1980-01-06 00:18:48 - Kernel config CONFIG_CMA_AREAS is missing or not enabled
98+
[INFO] 1980-01-06 00:18:48 - CONFIG_CMA_AREAS: not set (optional)
99+
[INFO] 1980-01-06 00:18:48 - === CMA Memory Statistics ===
100+
[INFO] 1980-01-06 00:18:48 - CMA Memory Statistics:
101+
[INFO] 1980-01-06 00:18:48 - Total: 172 MB (176128 kB)
102+
[INFO] 1980-01-06 00:18:48 - Free: 119 MB (122548 kB)
103+
[INFO] 1980-01-06 00:18:48 - Used: 52 MB (53580 kB)
104+
[INFO] 1980-01-06 00:18:48 - Usage: 30%
105+
[PASS] 1980-01-06 00:18:48 - CMA memory statistics validated
106+
[INFO] 1980-01-06 00:18:48 - Total reserved memory regions: 32
107+
[INFO] 1980-01-06 00:18:48 - === CMA Initialization and Runtime ===
108+
[PASS] 1980-01-06 00:18:48 - CMA initialization messages found in dmesg:
109+
[INFO] 1980-01-06 00:18:48 - [ 17.510276] cma: cma_alloc(cma ffffffc0823f1b38, name: reserved, count 2, align 1)
110+
[INFO] 1980-01-06 00:18:48 - [ 17.924390] cma: cma_alloc(cma ffffffc0823f1b38, name: reserved, count 32, align 5)
111+
[INFO] 1980-01-06 00:18:48 - [ 17.935579] cma: cma_alloc(cma ffffffc0823f1b38, name: reserved, count 128, align 7)
112+
[INFO] 1980-01-06 00:18:48 - [ 18.501219] cma: cma_alloc(cma ffffffc0823f1b38, name: reserved, count 2, align 1)
113+
[INFO] 1980-01-06 00:18:48 - CMA allocation/release activity detected
114+
[INFO] 1980-01-06 00:18:48 - Allocations: 42
115+
[INFO] 1980-01-06 00:18:48 - Releases: 8
116+
[INFO] 1980-01-06 00:18:48 - === CMA Sysfs/Debugfs Interface ===
117+
[INFO] 1980-01-06 00:18:48 - Found CMA debugfs: /sys/kernel/debug/cma
118+
[INFO] 1980-01-06 00:18:48 - CMA area: reserved
119+
[INFO] 1980-01-06 00:18:48 - Total CMA areas: 1
120+
[PASS] 1980-01-06 00:18:48 - CMA statistics in /proc/vmstat:
121+
[INFO] 1980-01-06 00:18:48 - nr_free_cma 30637
122+
[INFO] 1980-01-06 00:18:48 - cma_alloc_success 21
123+
[INFO] 1980-01-06 00:18:48 - cma_alloc_fail 0
124+
[INFO] 1980-01-06 00:18:48 - ================================================================================
125+
[PASS] 1980-01-06 00:18:48 - cma : Test Passed
126+
```
127+
128+
## CMA Configuration Methods
129+
130+
### 1. Device Tree Configuration (Recommended)
131+
```dts
132+
reserved-memory {
133+
#address-cells = <2>;
134+
#size-cells = <2>;
135+
ranges;
136+
137+
linux,cma {
138+
compatible = "shared-dma-pool";
139+
reusable;
140+
size = <0x0 0x20000000>; /* 512 MB */
141+
alignment = <0x0 0x00400000>; /* 4 MB */
142+
linux,cma-default;
143+
};
144+
};
145+
```
146+
147+
### 2. Kernel Command Line
148+
```bash
149+
cma=512M
150+
```
151+
152+
### 3. Kernel Config Default
153+
```
154+
CONFIG_CMA_SIZE_MBYTES=512
155+
```
156+
157+
158+
159+
## License
160+
161+
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
162+
SPDX-License-Identifier: BSD-3-Clause
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
metadata:
2+
format: Lava-Test Test Definition 1.0
3+
name: cma
4+
description: "CMA (Contiguous Memory Allocator) enablement and functionality validation"
5+
maintainer:
6+
- vnarapar@qti.qualcomm.com
7+
os:
8+
- openembedded
9+
scope:
10+
- functional
11+
devices:
12+
- rb3gen2
13+
- qcs6490
14+
- qcs8300
15+
- qcs9100
16+
- sa8775p
17+
18+
run:
19+
steps:
20+
- cd $PWD/suites/Kernel/Baseport/cma
21+
- ./run.sh
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#!/bin/sh
2+
3+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
# SPDX-License-Identifier: BSD-3-Clause
5+
6+
# Robustly find and source init_env
7+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8+
INIT_ENV=""
9+
SEARCH="$SCRIPT_DIR"
10+
while [ "$SEARCH" != "/" ]; do
11+
if [ -f "$SEARCH/init_env" ]; then
12+
INIT_ENV="$SEARCH/init_env"
13+
break
14+
fi
15+
SEARCH=$(dirname "$SEARCH")
16+
done
17+
18+
if [ -z "$INIT_ENV" ]; then
19+
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
20+
exit 1
21+
fi
22+
23+
if [ -z "$__INIT_ENV_LOADED" ]; then
24+
# shellcheck disable=SC1090
25+
. "$INIT_ENV"
26+
fi
27+
28+
# shellcheck disable=SC1090,SC1091
29+
. "$TOOLS/functestlib.sh"
30+
31+
TESTNAME="cma"
32+
test_path=$(find_test_case_by_name "$TESTNAME")
33+
cd "$test_path" || exit 1
34+
res_file="./$TESTNAME.res"
35+
36+
log_info "================================================================================"
37+
log_info "============ Starting $TESTNAME Testcase ======================================="
38+
log_info "================================================================================"
39+
40+
pass=true
41+
42+
log_info "=== CMA Kernel Configuration Validation ==="
43+
44+
# Core CMA configs
45+
CORE_CMA_CONFIGS="CONFIG_CMA CONFIG_DMA_CMA CONFIG_CMA_DEBUG CONFIG_CMA_DEBUGFS"
46+
47+
if ! check_kernel_config "$CORE_CMA_CONFIGS"; then
48+
log_fail "CMA kernel configuration not enabled"
49+
pass=false
50+
else
51+
log_pass "CMA kernel configuration validated"
52+
fi
53+
54+
OPTIONAL_CMA_CONFIGS="CONFIG_CMA_SIZE_MBYTES CONFIG_CMA_SIZE_SEL_MBYTES CONFIG_CMA_AREAS"
55+
56+
log_info "Checking optional CMA configurations..."
57+
for cfg in $OPTIONAL_CMA_CONFIGS; do
58+
if check_kernel_config "$cfg" 2>/dev/null; then
59+
value=$(grep "^$cfg=" /proc/config.gz 2>/dev/null | cut -d'=' -f2 || echo "enabled")
60+
log_info " $cfg: $value"
61+
else
62+
log_info " $cfg: not set (optional)"
63+
fi
64+
done
65+
66+
log_info "=== CMA Memory Statistics ==="
67+
68+
if [ -f "/proc/meminfo" ]; then
69+
if grep -q "CmaTotal" /proc/meminfo; then
70+
cma_total=$(grep "CmaTotal" /proc/meminfo | awk '{print $2}')
71+
cma_free=$(grep "CmaFree" /proc/meminfo | awk '{print $2}')
72+
cma_used=$((cma_total - cma_free))
73+
74+
# Convert to MB for readability
75+
cma_total_mb=$((cma_total / 1024))
76+
cma_free_mb=$((cma_free / 1024))
77+
cma_used_mb=$((cma_used / 1024))
78+
79+
log_info "CMA Memory Statistics:"
80+
log_info " Total: ${cma_total_mb} MB (${cma_total} kB)"
81+
log_info " Free: ${cma_free_mb} MB (${cma_free} kB)"
82+
log_info " Used: ${cma_used_mb} MB (${cma_used} kB)"
83+
84+
# Calculate usage percentage
85+
if [ "$cma_total" -gt 0 ]; then
86+
usage_percent=$((cma_used * 100 / cma_total))
87+
log_info " Usage: ${usage_percent}%"
88+
fi
89+
90+
if [ "$cma_total" -lt 1024 ]; then
91+
log_fail "CMA total size is very small (< 1 MB)"
92+
pass=false
93+
else
94+
log_pass "CMA memory statistics validated"
95+
fi
96+
else
97+
log_fail "CMA statistics not found in /proc/meminfo"
98+
pass=false
99+
fi
100+
else
101+
log_fail "/proc/meminfo not accessible"
102+
pass=false
103+
fi
104+
105+
if [ -d "/proc/device-tree/reserved-memory" ]; then
106+
region_count=0
107+
for region in /proc/device-tree/reserved-memory/*; do
108+
if [ -d "$region" ]; then
109+
region_count=$((region_count + 1))
110+
fi
111+
done
112+
log_info "Total reserved memory regions: $region_count"
113+
fi
114+
115+
log_info "=== CMA Initialization and Runtime ==="
116+
117+
# Check dmesg for CMA initialization
118+
if dmesg | grep -i -q "cma.*reserved"; then
119+
log_pass "CMA initialization messages found in dmesg:"
120+
121+
dmesg | grep -i "cma.*reserved" | tail -n 5 | while IFS= read -r line; do
122+
log_info " $line"
123+
done
124+
else
125+
log_fail "No CMA initialization messages found in dmesg"
126+
pass=false
127+
fi
128+
129+
if dmesg | grep -i -q "cma.*alloc\|cma.*release"; then
130+
log_info "CMA allocation/release activity detected"
131+
alloc_count=$(dmesg | grep -i -c "cma.*alloc" || echo 0)
132+
release_count=$(dmesg | grep -i -c "cma.*release" || echo 0)
133+
log_info " Allocations: $alloc_count"
134+
log_info " Releases: $release_count"
135+
fi
136+
137+
if dmesg | grep -i "cma" | grep -i -q "error\|fail\|warn"; then
138+
log_fail "CMA warnings/errors found in dmesg:"
139+
pass=false
140+
dmesg | grep -i "cma" | grep -i "error\|fail\|warn" | tail -n 3 | while IFS= read -r line; do
141+
log_warn " $line"
142+
done
143+
fi
144+
145+
log_info "=== CMA Sysfs/Debugfs Interface ==="
146+
147+
if [ -d "/sys/kernel/debug/cma" ]; then
148+
log_info "Found CMA debugfs: /sys/kernel/debug/cma"
149+
150+
# List CMA areas
151+
if [ -d "/sys/kernel/debug/cma" ]; then
152+
cma_area_count=0
153+
for area in /sys/kernel/debug/cma/*; do
154+
if [ -d "$area" ]; then
155+
area_name=$(basename "$area")
156+
log_info " CMA area: $area_name"
157+
cma_area_count=$((cma_area_count + 1))
158+
fi
159+
done
160+
log_info " Total CMA areas: $cma_area_count"
161+
fi
162+
else
163+
log_warn "CMA debugfs not found (may need debugfs mounted)"
164+
fi
165+
166+
if [ -f "/proc/vmstat" ]; then
167+
if grep -q "cma" /proc/vmstat; then
168+
log_pass "CMA statistics in /proc/vmstat:"
169+
grep "cma" /proc/vmstat | while IFS= read -r line; do
170+
log_info " $line"
171+
done
172+
else
173+
log_fail "CMA statistics not found in /proc/vmstat:"
174+
pass=false
175+
fi
176+
fi
177+
178+
log_info "================================================================================"
179+
180+
if $pass; then
181+
log_pass "$TESTNAME : Test Passed"
182+
echo "$TESTNAME PASS" > "$res_file"
183+
exit 0
184+
else
185+
log_fail "$TESTNAME : Test Failed"
186+
echo "$TESTNAME FAIL" > "$res_file"
187+
exit 1
188+
fi

0 commit comments

Comments
 (0)