CV-Bowen opened a new pull request, #21408:
URL: https://github.com/apache/nuttx/pull/21408
## Summary
Use the virtio buffer map API (open-amp patch 0021) in the transports and
in virtio-blk/virtio-rng, so these drivers work on a transport whose peer
can only reach shared memory:
- virtio-mmio, virtio-pci: set `map`, `unmap` and `free_largest` to
NULL. The host reaches all guest memory, so a buffer is used as is.
- rptun.h: `RPTUN_INVALIDATE()` takes a pointer and a size, and
`RPTUN_FLUSH()` is added in the same form.
- rptun: implement `map`/`unmap`/`free_largest`. A buffer outside the
carveout is bounced through a cache-line aligned buffer from the
carveout heap; `free_largest` is the largest heap block minus the
memalign overhead.
- virtio-blk: map the request, data and status buffers, and split a
transfer into chunks of `virtio_free_largest()`. A chunk that cannot
be mapped ends the transfer with the sectors already done.
- virtio-rng: map the caller's buffer instead of allocating a bounce
buffer and copying it.
## Impact
virtio-mmio/virtio-pci: no behaviour change; virtio-rng saves a copy.
rptun: virtio drivers on rptun can now pass buffers outside the
carveout. `RPTUN_INVALIDATE()` changes form; it has no user in the tree.
No Kconfig change.
## Testing
Host: Ubuntu 22.04.5 LTS x86_64, QEMU version 10.2.1, sim: cc (Ubuntu
13.1.0-8ubuntu1~22.04) 13.1.0, qemu-armv8a: aarch64-none-elf-gcc (Arm GNU
Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205
All six commits build on sim:rpserver and qemu-armv8a:netnsh.
**virtio-rng over rptun** (sim:rpserver has a virtio-rng driver on the
rptun link to sim:rpproxy's vhost-rng). The user buffer is outside the
carveout, so this goes through `rptun_map_buf()`:
```
/dev/random at 00000000:
0000: be 0c 49 82 da 25 6b 09 f6 3e 8d 90 12 58 af 17 ..I..%k..>...X..
0010: 2e 71 d1 9e 4a 8a f3 25 66 a3 15 ad 82 bc 37 34 .q..J..%f.....74
2048 bytes (8 blocks) copied, 79568 usec, 25 KB/s
server>
```
Without the rptun commit, the map API change in virtio-rng alone makes
this read hang: the peer cannot reach the user buffer.
**virtio-blk and virtio-rng over virtio-mmio**, qemu-armv8a:netnsh:
```
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-rng-device,bus=virtio-mmio-bus.1 \
-drive file=disk.img,if=none,format=raw,id=hd \
-device virtio-blk-device,bus=virtio-mmio-bus.3,drive=hd \
-mon chardev=con,mode=readline -kernel nuttx
```
The first 1 MiB of a 64 MiB image is filled with random bytes, then:
```
nsh> dd if=/dev/virtblk0 of=/dev/virtblk0 bs=65536 count=16 seek=32
nsh> dd if=/dev/virtblk0 of=/dev/virtblk0 bs=512 count=2048 skip=0 seek=6144
nsh> hexdump /dev/random count=32
nsh> dd if=/dev/random of=/dev/null bs=1024 count=64
```
The image is compared on the host after qemu exits: both copies (at
2 MiB and 3 MiB) match the source on master and with this PR.
The split path is not reached on MMIO (`free_largest` is unlimited).
To run it, a test-only change (not in this PR) makes virtio-mmio a
bouncing transport with a 16 KiB map limit. The 64 KiB transfers are
then split into chunks of 15872 bytes and both copies still match:
```
[ 0.111215] tb_map: TBOUNCE maps=1 maxlen=15872
1048576 bytes (16 blocks) copied, 7782 usec, 131585 KB/s
1048576 bytes (2048 blocks) copied, 141302 usec, 7246 KB/s
65536 bytes (64 blocks) copied, 2903 usec, 22046 KB/s
```
Baseline: No regression in rpmsg: sim:rpserver/rpproxy and
qemu-armv8a:rpserver/rpproxy boot and pass the fixed rpmsg cases (dump, ping,
rpmsgfs; 15/15). qemu-armv8a was built with LIBC_ENVPATH and BINFMT_CHECKEXEC
disabled, which current master needs for nxinit to start nsh there; unrelated
to this change.
--
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]