Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

528 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AMD GPU Performance Monitoring - Perf PMU Stub
> **⚠️ EXPERIMENTAL - NOT FOR PRODUCTION USE**
>
> This is a research and development project. The module is not ready for general use and may cause system instability.
>
> **Requirements:**
> - GFX12/RDNA4 GPUs only (RX 9070 series)
>
> Use at your own risk in development/testing environments only.
A Linux kernel module implementing AMD GPU performance counter integration with the perf subsystem. This module provides AQL (Asynchronous Queuing Language) packet generation for GPU performance monitoring on GFX12/RDNA4 architectures.
## Overview
This kernel module bridges AMD GPU hardware performance counters with the Linux perf interface, enabling standard perf tools to monitor GPU performance events. It includes:
- **AQL C Library**: Pure C implementation of PM4 packet generation for GPU counter programming
- **Perf PMU Driver**: Complete Linux perf subsystem integration
- **Hardware Support**: GFX12/RDNA4 GPU architecture support
- **Counter Registry**: Architecture-specific performance event definitions
## Features
- ✅ Linux perf subsystem integration
- ✅ AQL/PM4 packet generation for GPU counter control
- ✅ GFX12/RDNA4 hardware support
- ✅ Multi-GPU architecture support
- ✅ Hardware block counter definitions (SQ, CPC, GL2C, etc.)
- ✅ **Dimension-Specific Monitoring** - Monitor specific SE/SA/WGP hardware units
- ✅ Standard perf tool compatibility
- ✅ DKMS-compatible installation
## Quick Start
### Prerequisites
```bash
# Install build tools and kernel headers
sudo apt update
sudo apt install build-essential linux-headers-$(uname -r)
# Verify perf tools are available
perf --version
```
### Building the Module
```bash
# Clone and enter directory
cd perf-dkms
# Build kernel module and tools
cmake -B build && cmake --build build
# The build produces:
# - build/src/amdgpu_pmu.ko (kernel module)
# - build/src/aql_c/tools/packet_gen_tool (PM4 packet generator)
# - build/src/aql_c/tools/pm4_decoder (PM4 packet decoder)
# - build/src/aql_c/tests/* (validation tests)
```
### Loading the Module
```bash
# Load the module
sudo insmod build/src/amdgpu_pmu.ko
# Or if using .o file (development kernels):
sudo insmod build/src/amdgpu_pmu.o
# Verify module is loaded
lsmod | grep amdgpu_pmu
# Check kernel messages
dmesg | tail -20
```
### Verification
```bash
# Check PMU device registration
ls -la /sys/bus/event_source/devices/ | grep pmu
# List available GPU performance events
perf list | grep amdgpu_pmu
# Or directly check sysfs
ls /sys/bus/event_source/devices/amdgpu_pmu/events/
```
## Testing with Perf
### Basic GPU Counter Test
Test GPU shader wave counting with detailed verbose output:
```bash
# Monitor SQ_WAVES counter with 800ms intervals
perf stat -I 800 -vv -C 0 -a --no-inherit -e amdgpu_pmu/sq_waves/ sleep 4
```
**Command breakdown:**
- `-I 800`: Print counter deltas every 800ms
- `-vv`: Very verbose output (shows counter reads and updates)
- `-C 0`: Monitor CPU 0 (or use `-a` for all CPUs)
- `-a`: System-wide monitoring
- `--no-inherit`: Don't inherit counters to child processes
- `-e amdgpu_pmu/sq_waves/`: Monitor the SQ_WAVES GPU counter
### Available Hardware Counters
The module exposes GPU hardware performance counters through the perf interface:
```bash
# Shader Processor (SQ) counters
perf stat -e amdgpu_pmu/sq_waves/ <command> # Active waves
perf stat -e amdgpu_pmu/sq_busy_cycles/ <command> # SQ busy cycles
perf stat -e amdgpu_pmu/sq_instructions/ <command> # Instructions executed
# L2 Cache (GL2C) counters
perf stat -e amdgpu_pmu/gl2c_hit/ <command> # L2 cache hits
perf stat -e amdgpu_pmu/gl2c_miss/ <command> # L2 cache misses
# Command Processor (CPC) counters
perf stat -e amdgpu_pmu/cpc_busy/ <command> # CP busy cycles
perf stat -e amdgpu_pmu/cpc_stall/ <command> # CP stall cycles
```
### Multi-Event Monitoring
```bash
# Monitor multiple GPU counters simultaneously
perf stat -e amdgpu_pmu/sq_waves/,pmu_stub/gl2c_hit/,pmu_stub/gl2c_miss/ sleep 5
# System-wide GPU monitoring
sudo perf stat -a -e amdgpu_pmu/sq_waves/ sleep 10
# Per-process GPU monitoring (when supported)
perf stat -e amdgpu_pmu/sq_waves/ ./gpu_workload
```
### Advanced Perf Usage
```bash
# Record GPU events with sampling
sudo perf record -e amdgpu_pmu/sq_waves/ -a sleep 5
sudo perf report
# Monitor with custom intervals
perf stat -I 1000 -e amdgpu_pmu/sq_waves/ sleep 10
# Export to JSON
perf stat -j -e amdgpu_pmu/sq_waves/ sleep 2
```
## Dimension-Specific Monitoring
The amdgpu_pmu driver supports monitoring specific GPU hardware dimensions (Shader Engines, Shader Arrays, Work Group Processors) for fine-grained performance analysis.
### Quick Examples
```bash
# Monitor specific Shader Engine (SE)
perf stat -e amdgpu_pmu/sq_waves,se=0/ -a sleep 1
# Monitor SE and Shader Array (SA)
perf stat -e amdgpu_pmu/sq_waves,se=1,sa=0/ -a sleep 1
# Monitor full dimension hierarchy
perf stat -e amdgpu_pmu/sq_waves,se=2,sa=1,wgp=3/ -a sleep 1
# Compare activity across all Shader Engines
perf stat -e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-e amdgpu_pmu/sq_waves,se=2/ \
-e amdgpu_pmu/sq_waves,se=3/ \
-a ./my_gpu_app
```
### Hardware Dimensions
AMD GPUs are organized hierarchically:
- **SE** (Shader Engine): Top-level parallel units, typically 4 per GPU
- **SA** (Shader Array): Subdivisions within SE, typically 2 per SE
- **WGP** (Work Group Processor): Compute units, typically 4 per SA
- **CU** (Compute Unit): Individual SIMD units
For GFX12: 4 SE × 2 SA × 4 WGP = 32 unique addressable locations
### Available Parameters
- `se=N` - Shader Engine index (0-3 typical)
- `sa=N` - Shader Array index (0-1 typical)
- `wgp=N` - Work Group Processor index (0-3 typical)
- `cu=N` - Compute Unit index (0-63 typical)
- `xcc=N` - XCC index (usually 0)
### Supported Counters
Not all counters support dimension targeting:
- **SQ Counters** (SE/SA/WGP): `sq_waves`, `sq_insts_valu`, `sq_busy_cycles`
- **TA Counters** (SE/SA/WGP): `ta_busy`, `ta_total_wavefronts`
- **GL2C Counters** (SE/SA): `gl2c_hit`, `gl2c_miss`
- **Global Counters** (no dimensions): `grbm_count`, `grbm_busy`
### Use Cases
**Load Balancing Analysis**: Check if work is evenly distributed across SEs
```bash
perf stat -e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-e amdgpu_pmu/sq_waves,se=2/ \
-e amdgpu_pmu/sq_waves,se=3/ \
-a ./workload
```
**Hotspot Detection**: Identify which hardware unit is most active
```bash
perf record -e amdgpu_pmu/sq_busy_cycles,se=0/ \
-e amdgpu_pmu/sq_busy_cycles,se=1/ \
-a sleep 10
```
**Memory Analysis**: Monitor cache behavior per Shader Array
```bash
perf stat -e amdgpu_pmu/gl2c_hit,se=0,sa=0/ \
-e amdgpu_pmu/gl2c_miss,se=0,sa=0/ \
-a ./memory_test
```
### Documentation
For detailed information, see:
- **User Guide**: `docs/user_guide_dimensions.md` - Complete usage guide with examples
- **Design Doc**: `docs/design.md` - Technical implementation details
- **Tests**: `test/load_test.sh`, `test/perf_test.sh` - Integration tests
## Architecture Support
### Supported GPUs
- **GFX12 (RDNA4)**: ✅ **Currently Supported**
- Radeon RX 9070 series
- All hardware blocks (SQ, CPC, CPF, GL1, GL2, CHA, CHC, etc.)
- **GFX9 (Vega/MI)**: ✅ **Supported**
- MI100, MI200, Vega series
- SQ, GL2C, TA, GRBM blocks
- **GFX10/11**: ❌ **Not Currently Supported**
- Framework exists but event mappings incomplete
### Hardware Blocks
The module provides counters for these GPU hardware blocks:
| Block | Description | Example Counters |
|-------|-------------|-----------------|
| SQ | Shader Processor (Sequencer) | waves, instructions, busy_cycles |
| GL2C | Graphics L2 Cache | hit, miss, requests |
| GL1A/C | Graphics L1 Cache | hit, miss, latency |
| CPC | Command Processor Compute | busy, stall, packets |
| CPF | Command Processor Fetcher | fetch_stall, me_busy |
| CHA/CHC | Cache Hierarchy Arbiters | requests, conflicts |
| TCC | Texture Cache Controller | hit, miss, write |
| TCP | Texture Cache Processor | read, write, stall |
## Development
### Building Components
```bash
# Build only kernel module
cmake -B build -DBUILD_KERNEL_MODULE=ON -DBUILD_USERSPACE_TOOLS=OFF -DBUILD_TESTS=OFF && cmake --build build --target kernel_module
# Build only userspace tools
cmake -B build -DBUILD_KERNEL_MODULE=OFF -DBUILD_USERSPACE_TOOLS=ON -DBUILD_TESTS=OFF && cmake --build build
# Build only tests
cmake -B build -DBUILD_KERNEL_MODULE=OFF -DBUILD_USERSPACE_TOOLS=OFF -DBUILD_TESTS=ON && cmake --build build
# Clean everything
rm -rf build
```
### Running Tests
```bash
# Build and run tests
cmake -B build -DBUILD_TESTS=ON && cmake --build build
# Run PM4 packet validation
build/src/aql_c/tests/test_pm4
# Run counter registry tests
build/src/aql_c/tests/test_counter_registry
# Run packet generation tests
build/src/aql_c/tests/test_packet_generation
```
### Debug Output
```bash
# Enable kernel debug messages
echo 'module amdgpu_pmu +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
# View trace output
sudo cat /sys/kernel/debug/tracing/trace
# Check kernel log
sudo dmesg -w | grep -i pmu
```
### Tools
**PM4 Packet Generator:**
```bash
build/src/aql_c/tools/packet_gen_tool <gpu_arch> <block> <event_id>
```
**PM4 Decoder:**
```bash
build/src/aql_c/tools/pm4_decoder <hex_packet_data>
```
## File Structure
```
perf-dkms/
├── src/
│ ├── pmu_main.c # Perf PMU driver
│ ├── pmu_events.c # Event definitions
│ ├── pmu_dimension.h # Dimension encoding/validation
│ ├── aql_perf.c/h # AQL session & GPU discovery
│ ├── aql_packet_ops.c # PM4 packet operations
│ ├── aql_pmu_integration.c # PMU-AQL bridge
│ ├── aql_error_recovery.c # Error handling & recovery
│ ├── aql_queue_manager.c/h # AQL queue lifecycle
│ ├── kfd_ioctl_bridge.c/h # KFD ioctl bridge (vm_mmap)
│ └── aql_c/ # AQL C library (kernel/userspace)
│ ├── packet_generation.c # PM4 packet generation
│ ├── pm4_packets.c # Low-level PM4 primitives
│ ├── counter_registry.c # Counter definitions
│ ├── arch_creator.c # Architecture factory
│ ├── gfx12_creator.c # GFX12 implementation
│ ├── gfx12_events.c # GFX12 event definitions
│ ├── gfx9_creator.c # GFX9 implementation
│ ├── gfx9_events.c # GFX9 event definitions
│ ├── aql_queue.c/h # Ring buffer & IB pool
│ ├── tests/ # Validation tests
│ └── tools/ # Packet tools
├── docs/ # Documentation
├── test/ # Integration tests
└── README.md # This file
```
## How It Works
### Architecture Overview
```
┌─────────────┐
│ perf tool │ (userspace)
└──────┬──────┘
│ syscall
┌──────▼──────────────────────┐
│ Linux Perf Subsystem │
└──────┬──────────────────────┘
│ PMU callbacks
┌──────▼──────────────────────┐
│ amdgpu_pmu (this module) │ (kernel)
│ ┌─────────────────────┐ │
│ │ AQL Packet Gen (C) │ │
│ │ - PM4 packets │ │
│ │ - Counter registry │ │
│ │ - Arch detection │ │
│ └─────────────────────┘ │
└──────┬──────────────────────┘
│ PM4 commands
┌──────▼──────────────────────┐
│ AMD GPU Hardware │
│ (GFX12/RDNA4) │
└─────────────────────────────┘
```
### Event Flow
1. **User runs perf**: `perf stat -e amdgpu_pmu/sq_waves/ <cmd>`
2. **Perf subsystem**: Calls PMU driver `add()` callback
3. **PMU driver**: Creates AQL measurement session
4. **AQL library**: Generates PM4 START packet
5. **Hardware**: GPU enables SQ_WAVES counter
6. **Monitoring**: Counter accumulates during execution
7. **Read**: PMU driver generates PM4 READ packet
8. **Hardware**: GPU returns counter value
9. **Perf**: Displays counter to user
## Troubleshooting
### Module won't load
```bash
# Check kernel version compatibility
uname -r
ls /lib/modules/$(uname -r)/build
# Check for errors
sudo dmesg | grep -i error
```
### No events visible
```bash
# Verify sysfs registration
ls /sys/bus/event_source/devices/amdgpu_pmu/
# Check event files
cat /sys/bus/event_source/devices/amdgpu_pmu/events/*
```
### Perf can't find events
```bash
# Refresh perf cache
sudo rm -rf ~/.debug/
perf list | grep amdgpu_pmu
# Check permissions
sudo chmod -R 755 /sys/bus/event_source/devices/amdgpu_pmu/
```
### Build failures
```bash
# Ensure kernel headers match running kernel
sudo apt install linux-headers-$(uname -r)
# Clean and rebuild
rm -rf build && cmake -B build && cmake --build build
```
## Unloading
```bash
# Remove module
sudo rmmod amdgpu_pmu
# Verify removal
lsmod | grep amdgpu_pmu
# Check for errors
dmesg | tail -20
```
## Limitations
### Known Bugs
**⚠️ Critical Issues:**
1. **First Dimension Only**: The module currently only supports returning counter values for the first hardware dimension (e.g., first shader engine, first compute unit). Multi-dimensional counter reads are not yet fully implemented.
2. **Memory Leaks on Stop**: The `stop` operation may not properly clean up resources in certain scenarios, leading to memory leaks. This occurs when:
- Multiple events are stopped in quick succession
- System shutdown interrupts the cleanup sequence
- GPU state transitions happen during stop operations
3. **GFX12 Only**: **This module currently only supports GFX12/RDNA4 GPUs**. Attempting to use on GFX9/10/11 architectures will fail. The architecture detection code exists but event mappings and register definitions are incomplete for older generations.
### Current Restrictions
1. **Hardware Integration**: Uses real GPU hardware access via:
- KFD (Kernel Fusion Driver) integration
- AMDGPU driver coordination
- GPU memory allocation for PM4 buffers
2. **Architecture Support**:
- **GFX12/RDNA4: Full support** (RX 9070 series)
- **GFX9/Vega/MI: Supported** (MI100, MI200, Vega series)
- **GFX10/11: Not supported** (framework only, missing event definitions)
4. **Kernel Compatibility**:
- Development kernels may produce `.o` instead of `.ko` files
- DKMS requires stable kernel versions
### Future Work
- [ ] Complete GFX9/10/11 support
- [ ] Interrupt-driven counter collection
- [ ] SPM (Streaming Performance Monitor) support
- [ ] Multi-GPU enumeration improvements
## References
### AMD Documentation
- [AMD GPU Performance Counters](https://www.amd.com)
- PM4 Packet Format Specifications
- GFX12/RDNA4 Architecture Documentation
### Linux Kernel
- [Perf Subsystem Documentation](https://www.kernel.org/doc/html/latest/admin-guide/perf-security.html)
- [PMU Driver Development](https://www.kernel.org/doc/Documentation/core-api/pmu.rst)
### Related Projects
- AQLProfile (C++ implementation)
- ROCm Profiler SDK
- ROCProfiler
## License
See LICENSE file for details.
## Contributing
This is a research/development module. Contributions welcome for:
- Additional GPU architecture support
- Hardware integration improvements
- Performance optimizations
- Documentation enhancements
## Contact
For issues and questions, please file a GitHub issue.