staging: vchiq_arm: use one DMA device to map and unmap bulk pagelists#7494
Open
rachmataditiya wants to merge 1 commit into
Open
staging: vchiq_arm: use one DMA device to map and unmap bulk pagelists#7494rachmataditiya wants to merge 1 commit into
rachmataditiya wants to merge 1 commit into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.