Skip to content

staging: vchiq_arm: use one DMA device to map and unmap bulk pagelists#7494

Open
rachmataditiya wants to merge 1 commit into
raspberrypi:rpi-6.18.yfrom
rachmataditiya:vchiq-pagelist-dma-dev-fix
Open

staging: vchiq_arm: use one DMA device to map and unmap bulk pagelists#7494
rachmataditiya wants to merge 1 commit into
raspberrypi:rpi-6.18.yfrom
rachmataditiya:vchiq-pagelist-dma-dev-fix

Conversation

@rachmataditiya

Copy link
Copy Markdown

Fixes #7493 — full analysis, reproducer, and oops there.

Since the pagelist code moved into vchiq_core.c, create_pagelist() maps the bulk scatterlist with instance->state->dev while free_pagelist()/cleanup_pagelistinfo() unmap with g_dma_dev (on BCM2711 the brcm,bcm2711-dma device resolved for use_36bit_addrs, with different dma-ranges), and the coherent pagelist buffer is allocated on instance->state->dev but freed on g_dma_dev. This breaks every userspace /dev/vchiq bulk 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 in free_pagelist() on the DMA_FROM_DEVICE unmap cache invalidate.

This restores the pairing rpi-6.12.y shipped (map/unmap on g_dma_dev, coherent alloc/free on instance->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_splitter payload loopback from a 64-bit userland oopses as in the issue and vc.ril.video_decode never 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.

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants