When working with PCIe devices in Linux, it's crucial to understand how many lanes are actually being used between your device and the host controller. This becomes particularly important when debugging performance issues or verifying hardware capabilities.
The most straightforward way to check PCIe lane information is through the sysfs interface. Here's how to do it:
# Find your PCIe device first
lspci -nn | grep -i "your_device_name"
# Then check the current link width and speed
cat /sys/bus/pci/devices/0000:XX:YY.Z/current_link_width
cat /sys/bus/pci/devices/0000:XX:YY.Z/current_link_speed
The lspci command with verbose output can provide additional details:
lspci -vv -s 0000:XX:YY.Z
Look for these key fields in the output:
- LnkSta: Shows current link status
- LnkCap: Shows device capabilities
- LnkCtl: Shows link control information
Here's a simple bash script to monitor PCIe link width changes:
#!/bin/bash
DEVICE="0000:XX:YY.Z"
while true; do
width=$(cat /sys/bus/pci/devices/$DEVICE/current_link_width)
speed=$(cat /sys/bus/pci/devices/$DEVICE/current_link_speed)
echo "$(date) - Width: $width, Speed: $speed"
sleep 1
done
For PCIe v2 devices:
- Link width will typically show values like 1, 2, 4, 8, or 16
- Link speed will show "5 GT/s" for PCIe 2.0
For more detailed analysis, consider these tools:
- pciutils: Provides additional PCIe diagnostic utilities
- setpci: For direct PCI configuration space access
- perf: Can monitor PCIe-related performance counters
If you're not seeing the expected number of lanes:
- Check physical connection quality
- Verify BIOS settings for PCIe configuration
- Test with different PCIe slots if available
- Check for kernel messages related to PCIe (dmesg)
When working with PCIe devices in Linux, especially older PCIe 2.0 hardware, determining the actual negotiated lane count and link speed is crucial for performance analysis and debugging. Unlike Windows which provides this information in device manager, Linux requires some command-line investigation.
The primary tool for PCI device inspection is lspci
:
# Basic PCI device listing lspci # Verbose output including link capabilities lspci -vvv | less
When examining your specific device in the verbose output, look for these key sections:
LnkCap: Port #0, Speed 5GT/s, Width x16, ASPM L0s L1, Exit Latency L0s <512ns, L1 <4us LnkSta: Speed 5GT/s (downgraded), Width x8 (downgraded)
The LnkSta
field shows the actual negotiated values:
- Speed: 2.5GT/s (PCIe 1.0), 5GT/s (PCIe 2.0), or 8GT/s (PCIe 3.0)
- Width: The number of active lanes (x1, x4, x8, x16, etc.)
- "downgraded" indicates the link isn't running at maximum capability
For scripting purposes, you can access PCIe link information through sysfs:
# Find your device's PCI address first lspci | grep Your_Device_Name # Then check current link width and speed cat /sys/bus/pci/devices/0000:01:00.0/current_link_width cat /sys/bus/pci/devices/0000:01:00.0/current_link_speed
Here's a complete example for checking an NVMe SSD's PCIe link:
# Find NVMe controller lspci | grep -i nvme # Get detailed info (assuming device at 01:00.0) lspci -s 01:00.0 -vvv | grep -A 10 "LnkSta" # Or using setpci (for raw register access) setpci -s 01:00.0 CAP_EXP+0x12.l setpci -s 01:00.0 CAP_EXP+0x10.l
If your device isn't negotiating at expected speeds/lanes:
- Check physical slot configuration (some x16 slots only provide x8 electrically)
- Verify BIOS settings for PCIe configuration
- Check for BIOS updates that might improve PCIe compatibility
- Test with different PCIe slots if available