CV-Bowen opened a new pull request, #18290:
URL: https://github.com/apache/nuttx/pull/18290
## Summary
This PR optimizes the VirtIO MMIO and PCI interrupt handlers by replacing
direct access to virtqueue internal fields with the proper `virtqueue_nused()`
API.
### Why this change is needed
The current implementation directly accesses virtqueue internal fields
(`vq->vq_used_cons_idx` and `vq->vq_ring.used->idx`) to determine if there are
pending buffers to process. This approach has several issues:
1. **Breaks encapsulation**: Direct field access bypasses the virtqueue
abstraction layer
2. **Cache coherency issues**: The direct comparison doesn't handle cached
memory scenarios properly
3. **Maintainability**: Changes to virtqueue internals would require updates
in multiple places
### What this PR does
- Replaces `vq->vq_used_cons_idx != vq->vq_ring.used->idx` with
`virtqueue_nused(vq) > 0`
- Reorders the condition to check `vq->callback != NULL` first
(short-circuit optimization)
- Applies the same fix to both `virtio-mmio.c` and `virtio-pci.c`
## Impact
- **Stability**: Improves reliability when using cached memory for virtqueues
- **Compatibility**: No API changes, fully backward compatible
- **Code Quality**: Better encapsulation and maintainability
## Testing
### Build Verification
```bash
# Build for qemu-armv8a with virtio support
cmake -B cmake_out -DBOARD_CONFIG=qemu-armv8a:netnsh -GNinja
cmake --build cmake_out
```
### Runtime Testing
Tested on QEMU ARM64 with virtio-net device:
VirtIO-MMIO Test
```c
❯ /data/software/qemu/qemu-9.2.3/build/qemu-system-aarch64 -cpu cortex-a53
-nographic \
-machine virt,virtualization=on,gic-version=3 \
-chardev stdio,id=con,mux=on -serial chardev:con \
-global virtio-mmio.force-legacy=false \
-device virtio-serial-device,bus=virtio-mmio-bus.0 \
-chardev
socket,telnet=on,host=127.0.0.1,port=3450,server=on,wait=off,id=foo \
-device virtconsole,chardev=foo \
-device virtio-rng-device,bus=virtio-mmio-bus.1 \
-netdev
user,id=u1,hostfwd=tcp:127.0.0.1:10023-10.0.2.15:23,hostfwd=tcp:127.0.0.1:15001-10.0.2.15:5001
\
-device virtio-net-device,netdev=u1,bus=virtio-mmio-bus.2 \
-drive file=./mydisk-1gb.img,if=none,format=raw,id=hd \
-device virtio-blk-device,bus=virtio-mmio-bus.3,drive=hd \
-fsdev
local,security_model=none,id=fsdev0,path=/data/project/code/apache/nuttx \
-device virtio-9p-device,id=fs0,fsdev=fsdev0,mount_tag=host \
-mon chardev=con,mode=readline -kernel
./nuttx/cmake_out/v8a_netnsh/nuttx \
-gdb tcp::7777
[ 0.340000] pci_scan_bus: pci_scan_bus for bus 0
[ 0.340000] pci_scan_bus: class = 00000600, hdr_type = 00000000
[ 0.340000] pci_scan_bus: 00:00 [1b36:0008]
[ 0.350000] pci_setup_device: pbar0 set bad mask
[ 0.350000] pci_setup_device: pbar1 set bad mask
[ 0.350000] pci_setup_device: pbar2 set bad mask
[ 0.350000] pci_setup_device: pbar3 set bad mask
[ 0.350000] pci_setup_device: pbar4 set bad mask
[ 0.350000] pci_setup_device: pbar5 set bad mask
telnetd [4:100]
NuttShell (NSH) NuttX-12.12.0
nsh>
nsh>
nsh> ifconfig
eth0 Link encap:Ethernet HWaddr 00:e0:de:ad:be:ef at RUNNING mtu 1500
inet addr:10.0.2.15 DRaddr:10.0.2.2 Mask:255.255.255.0
IPv4 TCP UDP ICMP
Received 0000 0000 0000 0000
Dropped 0000 0000 0000 0000
IPv4 VHL: 0000 Frg: 0000
Checksum 0000 0000 0000 ----
TCP ACK: 0000 SYN: 0000
RST: 0000 0000
Type 0000 ---- ---- 0000
Sent 0000 0000 0000 0000
Rexmit ---- 0000 ---- ----
nsh> iperf -s -i 1
IP: 10.0.2.15
mode=tcp-server sip=10.0.2.15:5001,dip=0.0.0.0:5001, interval=1, time=0
accept: 10.0.2.2:33612
Interval Transfer Bandwidth
0.00- 1.01 sec 9500924 Bytes 75.25 Mbits/sec
1.01- 2.02 sec 9568256 Bytes 75.79 Mbits/sec
2.02- 3.03 sec 9568256 Bytes 75.79 Mbits/sec
3.03- 4.04 sec 9551872 Bytes 75.66 Mbits/sec
4.04- 5.05 sec 9519104 Bytes 75.40 Mbits/sec
5.05- 6.06 sec 9519104 Bytes 75.40 Mbits/sec
6.06- 7.07 sec 9517480 Bytes 75.39 Mbits/sec
7.07- 8.08 sec 9519104 Bytes 75.40 Mbits/sec
8.08- 9.09 sec 9584640 Bytes 75.92 Mbits/sec
9.09- 10.10 sec 9583980 Bytes 75.91 Mbits/sec
closed by the peer: 10.0.2.2:33612
iperf exit
nsh> uname -a
NuttX 12.12.0 de88cf07345-dirty Jan 31 2026 00:19:08 arm64 qemu-armv8a
nsh>
nsh>
nsh>
```
VirtIO-PCI Test
```c
❯ qemu-system-aarch64 -cpu cortex-a53 -nographic \
-machine virt,virtualization=on,gic-version=3 \
-chardev stdio,id=con,mux=on -serial chardev:con \
-device virtio-rng-pci \
-netdev
user,id=u1,hostfwd=tcp:127.0.0.1:10023-10.0.2.15:23,hostfwd=tcp:127.0.0.1:15001-10.0.2.15:5001
\
-device virtio-net-pci,netdev=u1 \
-mon chardev=con,mode=readline -kernel
./nuttx/cmake_out/v8a_netnsh/nuttx \
-gdb tcp::7777
[ 0.310000] pci_scan_bus: pci_scan_bus for bus 0
[ 0.320000] pci_scan_bus: class = 00000600, hdr_type = 00000000
[ 0.320000] pci_scan_bus: 00:00 [1b36:0008]
[ 0.320000] pci_setup_device: pbar0 set bad mask
[ 0.320000] pci_setup_device: pbar1 set bad mask
[ 0.320000] pci_setup_device: pbar2 set bad mask
[ 0.320000] pci_setup_device: pbar3 set bad mask
[ 0.320000] pci_setup_device: pbar4 set bad mask
[ 0.320000] pci_setup_device: pbar5 set bad mask
[ 0.320000] pci_scan_bus: class = 000000ff, hdr_type = 00000000
[ 0.330000] pci_scan_bus: 00:08 [1af4:1005]
[ 0.330000] pci_setup_device: pbar0: mask64=fffffffe 32bytes
[ 0.330000] pci_setup_device: pbar1: mask64=fffffff0 4096bytes
[ 0.330000] pci_setup_device: pbar2 set bad mask
[ 0.330000] pci_setup_device: pbar3 set bad mask
[ 0.330000] pci_setup_device: pbar4: mask64=fffffffffffffff0 16384bytes
[ 0.330000] pci_scan_bus: class = 00000200, hdr_type = 00000000
[ 0.330000] pci_scan_bus: 00:10 [1af4:1000]
[ 0.330000] pci_setup_device: pbar0: mask64=fffffffe 32bytes
[ 0.330000] pci_setup_device: pbar1: mask64=fffffff0 4096bytes
[ 0.330000] pci_setup_device: pbar2 set bad mask
[ 0.340000] pci_setup_device: pbar3 set bad mask
[ 0.340000] pci_setup_device: pbar4: mask64=fffffffffffffff0 16384bytes
telnetd [4:100]
NuttShell (NSH) NuttX-12.12.0
nsh>
nsh>
nsh>
nsh> iperf -s -i 1
IP: 10.0.2.15
mode=tcp-server sip=10.0.2.15:5001,dip=0.0.0.0:5001, interval=1, time=0
accept: 10.0.2.2:34508
Interval Transfer Bandwidth
0.00- 1.01 sec 1680460 Bytes 13.31 Mbits/sec
1.01- 2.02 sec 1679000 Bytes 13.30 Mbits/sec
2.02- 3.03 sec 1712580 Bytes 13.56 Mbits/sec
3.03- 4.04 sec 1679000 Bytes 13.30 Mbits/sec
4.04- 5.05 sec 1712580 Bytes 13.56 Mbits/sec
5.05- 6.06 sec 1679000 Bytes 13.30 Mbits/sec
6.06- 7.07 sec 1712580 Bytes 13.56 Mbits/sec
7.07- 8.08 sec 1679000 Bytes 13.30 Mbits/sec
8.08- 9.09 sec 1712580 Bytes 13.56 Mbits/sec
9.09- 10.10 sec 1679000 Bytes 13.30 Mbits/sec
10.10- 11.11 sec 1712580 Bytes 13.56 Mbits/sec
11.11- 12.12 sec 1679000 Bytes 13.30 Mbits/sec
12.12- 13.13 sec 1712580 Bytes 13.56 Mbits/sec
closed by the peer: 10.0.2.2:34508
iperf exit
nsh> uname -a
NuttX 12.12.0 de88cf07345-dirty Jan 31 2026 00:19:08 arm64 qemu-armv8a
nsh>
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]