Summary
Since the AVD driver became available (linux-asahi 7.1.13.asahi3-1), H.264 hardware decoding fails intermittently and then consistently once memory is moderately fragmented. avd_init_job performs an order-10 (4 MB contiguous) kmalloc per decode job, which triggers warn_alloc page allocation failures. The decode job then never delivers frames.
User-visible symptoms in Chrome 153 (which picks up the new V4L2 stateless decoder for H.264):
- HLS/H.264 streams: solid green video with working audio
- Plain H.264 MP4 playback: player stuck at 0:00, spinner forever (the
<video> element hangs)
- VP9/AV1 content (e.g. most of YouTube) is unaffected (software decode), which makes the issue look "random" to users
Hardware / versions
- Apple MacBook Pro (16-inch, M1 Pro, 2021) — MacBookPro18,1 / J316s
- linux-asahi 7.1.13.asahi3-1
- mesa 26.1.8-1
- google-chrome 153.0.8010.47 (confirmed holding
/dev/video0 open via fuser)
Reproduction
- Boot, use the machine normally for a while (fragmentation makes it reliable; on a fresh boot it may take longer).
google-chrome --user-data-dir=$(mktemp -d) --no-first-run --autoplay-policy=no-user-gesture-required "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
- Within ~15 s, dmesg shows the allocation failure below and the video never starts (or renders green for streaming H.264 content).
Reproduced multiple times; each H.264 playback attempt logs one trace.
dmesg
[ 6963.063490] ThreadPoolSingl: page allocation failure: order:10, mode:0x40dc0(GFP_KERNEL|__GFP_ZERO|__GFP_COMP), nodemask=(null)
[ 6963.063499] CPU: 4 UID: 1001 PID: 163183 Comm: ThreadPoolSingl Tainted: G S 7.1.13-3-1-ARCH #1
[ 6963.063501] Tainted: [S]=CPU_OUT_OF_SPEC
[ 6963.063502] Hardware name: Apple Inc. MacBookPro18,1/J316s, BIOS 2026.07 07/01/2026
[ 6963.063503] Call trace:
[ 6963.063503] show_stack+0x18/0x24 (C)
[ 6963.063509] dump_stack_lvl+0x5c/0x7c
[ 6963.063511] dump_stack+0x18/0x24
[ 6963.063513] warn_alloc+0x118/0x1a0
[ 6963.063516] __alloc_frozen_pages_noprof+0xa1c/0x13a8
[ 6963.063519] ___kmalloc_large_node+0xd4/0x100
[ 6963.063520] __kmalloc_large_node_noprof+0x28/0x198
[ 6963.063521] __kmalloc_noprof+0x36c/0x448
[ 6963.063523] avd_init_job+0x2c/0x54 [apple_avd]
[ 6963.063527] avd_h264_run+0x918/0x18f4 [apple_avd]
[ 6963.063529] avd_device_run+0x48/0x108 [apple_avd]
[ 6963.063530] v4l2_m2m_try_run+0x80/0x13c [v4l2_mem2mem]
[ 6963.063533] v4l2_m2m_request_queue+0xdc/0x130 [v4l2_mem2mem]
[ 6963.063535] media_request_ioctl+0x178/0x430 [mc]
[ 6963.063539] __arm64_sys_ioctl+0x2ec/0xad4
Analysis
avd_init_job allocates a large per-job buffer with plain kmalloc (order-10 → 4 MB contiguous). Under normal desktop uptime, physically contiguous 4 MB chunks are frequently unavailable, so the allocation fails and the queued job is never completed — the m2m context stalls and userspace waits forever (Chrome's media pipeline hangs or composites empty/green frames). A kvmalloc/vmalloc or a preallocated/DMA pool for this buffer would avoid the failure mode entirely; failing that, the driver should fail the job cleanly so userspace can fall back to software decoding instead of hanging.
Workaround
--disable-accelerated-video-decode in Chrome restores software decoding and fully resolves the user-visible issue.
Summary
Since the AVD driver became available (linux-asahi 7.1.13.asahi3-1), H.264 hardware decoding fails intermittently and then consistently once memory is moderately fragmented.
avd_init_jobperforms an order-10 (4 MB contiguous)kmallocper decode job, which triggerswarn_allocpage allocation failures. The decode job then never delivers frames.User-visible symptoms in Chrome 153 (which picks up the new V4L2 stateless decoder for H.264):
<video>element hangs)Hardware / versions
/dev/video0open viafuser)Reproduction
google-chrome --user-data-dir=$(mktemp -d) --no-first-run --autoplay-policy=no-user-gesture-required "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"Reproduced multiple times; each H.264 playback attempt logs one trace.
dmesg
Analysis
avd_init_joballocates a large per-job buffer with plainkmalloc(order-10 → 4 MB contiguous). Under normal desktop uptime, physically contiguous 4 MB chunks are frequently unavailable, so the allocation fails and the queued job is never completed — the m2m context stalls and userspace waits forever (Chrome's media pipeline hangs or composites empty/green frames). Akvmalloc/vmallocor a preallocated/DMA pool for this buffer would avoid the failure mode entirely; failing that, the driver should fail the job cleanly so userspace can fall back to software decoding instead of hanging.Workaround
--disable-accelerated-video-decodein Chrome restores software decoding and fully resolves the user-visible issue.