staging: vchiq_arm: use one DMA device to map and unmap bulk pagelists#7494
Conversation
|
Looks plausible. @pelwell I assume this is still needed after a number of iterations of upstreaming? |
|
I'm confused - this patch appears to take a mismatch and reverse it, i.e. it is still unbalanced, but the other way round. |
|
|
|
There is vchiq_test in https://github.com/raspberrypi/userland/blob/master/interface/vchiq_arm/vchiq_test.c which should exercise bulk transfers fairly comprehensively. I'll try and get it running both with and without this patch on Pi4 (Pi0-3 should be identical as |
|
Testing on a Pi3 with a 64bit OS seems to work fine, so being associated with the dma device would follow. By the same logic it feels like the dma_pool added in 5252444 should probably also be allocated against |
|
Mainline 7.2.0-rc1 also fails on a Pi4. |
|
#7497 fixes vchiq-test on Pi 4/6.18 for me. |
Does it work on other mainline kernel versions? |
|
Comparing against 6.12, I think I agree with this patch.
Pass as to why vchiq_test was failing when I'd applied this before. It's working fine now. Seeing your new PR, whether |
|
It's possible the two end up being equivalent if the DMA allocations end up coming from the CMA heap, which we confine to the first 1GB. The three main vchiq_test modes - ping, bulk and functional - all pass with this patch on a 4GB Pi 4, so I'm happy to merge it and drop mine. |
|
I'm on an 8GB Pi4. Swapping |
|
I think the changes to the device used for allocation may remove the CMA constraint, even though the VPU needs it.
I've just found the same thing. |
create_pagelist() maps the bulk scatterlist with instance->state->dev
(the vchiq platform device) while free_pagelist() and
cleanup_pagelistinfo() unmap it with g_dma_dev - on BCM2711 the
brcm,bcm2711-dma device resolved for use_36bit_addrs, whose dma-ranges
differ from the vchiq node's. The coherent pagelist buffer is likewise
allocated on instance->state->dev but freed on g_dma_dev.
Mapping and unmapping with different devices breaks every userspace
bulk transfer on Pi 4 arm64:
- the 36-bit addrs[] entries handed to the VPU are computed from
sg_dma_address() under the wrong device's dma-ranges, so the VPU
reads/writes the wrong bus addresses (bulk WRITE payloads arrive
as garbage; under sustained load the VPU stops responding to
mailbox requests entirely);
- the first bulk READ oopses in free_pagelist(): the DMA_FROM_DEVICE
dma_unmap_sg() cache invalidate mis-translates the dma address back
to phys under the other device's dma-ranges (0xf41e8e80 = phys
0x341e8e80 still carrying the vchiq device's 0xc0000000 alias):
Unable to handle kernel paging request at virtual address
ffffff80f41e8e80
CPU: 0 PID: 80 Comm: vchiq-slot/0
Call trace:
dcache_inval_poc+0x28/0x58 (P)
dma_direct_unmap_sg+0x224/0x260
dma_unmap_sg_attrs+0x60/0x148
free_pagelist.isra.0+0x54/0x1f8
slot_handler_func+0x4b8/0xdf0
rpi-6.12.y paired these consistently: dma_map_sg/dma_unmap_sg both on
g_dma_dev, dma_alloc_coherent/dma_free_coherent both on
instance->state->dev. Restore that pairing.
Verified on a Pi 4B Rev 1.5: on an unpatched 6.18 kernel a
vc.ril.video_splitter payload loopback from a 64-bit userland oopses
as above and vc.ril.video_decode consumes garbage; with this change
the loopback round-trips byte-identical and decode runs at full rate.
Nothing in-tree exercises userspace vchiq bulk on arm64 (the kernel
MMAL clients use vc-sm-cma zero-copy imports), which is why this went
unnoticed.
Fixes: 35ef141 ("staging: vchiq_arm: Set up dma ranges on child devices")
Link: raspberrypi#7493
Signed-off-by: Rachmat Aditiya <raditiya@me.com>
8e6f3f7 to
fb841f0
Compare
|
Thanks both — much appreciated. I've pushed a small amend for the checkpatch bot: re-wrapped one long line in the commit message and fixed a continuation indent in On the allocation side: this patch deliberately keeps |
Not tried. |
See: raspberrypi/linux#7500 kernel: staging: vchiq_arm: use one DMA device to map and unmap bulk pagelists See: raspberrypi/linux#7494 kernel: drm/vc4: hdmi: Remove duplicate hotplug helper call See: raspberrypi/linux#7489 kernel: ASoC: hifiberry_studio: change driver name and add support for new soundcards See: raspberrypi/linux#7487 kernel: mmc: Fix MMC request issuing race condition to prevent stall See: raspberrypi/linux#7486 kernel: dmaengine: dw-axi-dmac: Wait for runtime resume before using a channel See: raspberrypi/linux#7484 kernel: overlays: i2c-fan: add compatible for upstream compatibility See: raspberrypi/linux#7483
See: raspberrypi/linux#7500 kernel: staging: vchiq_arm: use one DMA device to map and unmap bulk pagelists See: raspberrypi/linux#7494 kernel: drm/vc4: hdmi: Remove duplicate hotplug helper call See: raspberrypi/linux#7489 kernel: ASoC: hifiberry_studio: change driver name and add support for new soundcards See: raspberrypi/linux#7487 kernel: mmc: Fix MMC request issuing race condition to prevent stall See: raspberrypi/linux#7486 kernel: dmaengine: dw-axi-dmac: Wait for runtime resume before using a channel See: raspberrypi/linux#7484 kernel: overlays: i2c-fan: add compatible for upstream compatibility See: raspberrypi/linux#7483
Fixes #7493 — full analysis, reproducer, and oops there.
Since the pagelist code moved into vchiq_core.c,
create_pagelist()maps the bulk scatterlist withinstance->state->devwhilefree_pagelist()/cleanup_pagelistinfo()unmap withg_dma_dev(on BCM2711 thebrcm,bcm2711-dmadevice resolved foruse_36bit_addrs, with different dma-ranges), and the coherent pagelist buffer is allocated oninstance->state->devbut freed ong_dma_dev. This breaks every userspace/dev/vchiqbulk transfer on Pi 4 arm64: the VPU is handed 36-bit pagelist entries computed under the wrong device's dma-ranges (bulk writes arrive as garbage, sustained load wedges the VPU), and the first bulk read oopses infree_pagelist()on theDMA_FROM_DEVICEunmap cache invalidate.This restores the pairing rpi-6.12.y shipped (map/unmap on
g_dma_dev, coherent alloc/free oninstance->state->dev), which is the last known-working combination.Verified on a Pi 4B Rev 1.5 (2GB): on stock 6.18.34+rpt a
vc.ril.video_splitterpayload loopback from a 64-bit userland oopses as in the issue andvc.ril.video_decodenever decodes; on rpi-6.18.y with this patch the loopback round-trips byte-identical and H.264 decode from a 64-bit process runs at full rate (26k frames / 600 s soak, clean dmesg).Context: 64-bit userland MMAL work discussed in the "Porting Linux VCHIQ Driver To 64 Bit" forum thread.