Skip to content

udev: start DSP remoteprocs left offline - #372

Open
Loïc Minier (lool) wants to merge 1 commit into
qualcomm:developmentfrom
lool:udev-start-remoteproc
Open

udev: start DSP remoteprocs left offline#372
Loïc Minier (lool) wants to merge 1 commit into
qualcomm:developmentfrom
lool:udev-start-remoteproc

Conversation

@lool

@lool Loïc Minier (lool) commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

When qcom_q6v5_pas is loaded from the initramfs, rproc_add()
auto-boots the core before the root filesystem is mounted.
/lib/firmware is not reachable yet, so request_firmware() fails with
-ENOENT, and the remoteproc core has no retry path: the DSP stays
"offline" for the rest of the boot even though the firmware is
present on disk. With no DSP there is no rpmsg channel, so no
/dev/fastrpc-* node appears and none of the daemons in
60-fastrpc.rules can start.

Add a udev rule that writes "start" to the remoteproc state attribute.
The event fires twice: once in the initramfs, where the write still fails
for the same reason the kernel's did, and again from the coldplug pass
that systemd-udev-trigger.service runs after switch_root, where the
firmware is reachable and the boot succeeds. udev logs and ignores the
failed write, so the first pass is harmless.

Only cores that qcom_q6v5_pas auto-boots and that FastRPC uses are
matched. modem and wpss have .auto_boot = false: modem is absent by
design on some SoCs, and ath11k owns the wpss lifecycle.

The ATTR{state}=="offline" gate is required: rproc_boot() increments
rproc->power unconditionally, so writing to an already-running core would
pin an extra reference and prevent a later shutdown or subsystem restart
from taking effect.

This is a userspace stopgap for the kernel bug; it can be dropped once a
kernel-side retry lands.

Relates to qualcomm-linux/kernel#923
Fixes: #371

@lool

Copy link
Copy Markdown
Contributor Author

I tested this on kodiak; this is the failure mode:
https://lava.infra.foundries.io/scheduler/job/353543

I manually installed the new file in /etc/udev/rules.d/59-fastrpc-remoteproc-inline.rules, ran update-initramfs -u, rebooted, and remote cores worked. That part was local, I don't have a LAVA run for that.

Comment thread files/59-fastrpc-remoteproc.rules Outdated
# extra reference and prevents a later shutdown or subsystem restart from taking
# effect. udev sorts all match tokens ahead of all assignments within a rule
# line, so the gate is evaluated before the write even though both name state.
ACTION=="add", SUBSYSTEM=="remoteproc", ATTR{name}=="adsp|cdsp|cdsp1|gpdsp0|gpdsp1|sdsp|slpi", ATTR{state}=="offline", ATTR{state}="start"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is only one of slpi and sdsp.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch, sdsp is a fastrpc internal name; I've dropped it and kept slpi that was apparently used on rb3gen2 and updated the comment in the udev rules. Apparently qcom-next has a soccp as well, should that be here?

When qcom_q6v5_pas is loaded from the initramfs, rproc_add()
auto-boots the core before the root filesystem is mounted.
/lib/firmware is not reachable yet, so request_firmware() fails with
-ENOENT, and the remoteproc core has no retry path: the DSP stays
"offline" for the rest of the boot even though the firmware is
present on disk. With no DSP there is no rpmsg channel, so no
/dev/fastrpc-* node appears and none of the daemons in
60-fastrpc.rules can start.

Add a udev rule that writes "start" to the remoteproc state attribute.
The event fires twice: once in the initramfs, where the write still fails
for the same reason the kernel's did, and again from the coldplug pass
that systemd-udev-trigger.service runs after switch_root, where the
firmware is reachable and the boot succeeds. udev logs and ignores the
failed write, so the first pass is harmless.

Only cores that qcom_q6v5_pas auto-boots and that FastRPC uses are
matched. modem and wpss have .auto_boot = false: modem is absent by
design on some SoCs, and ath11k owns the wpss lifecycle.

The ATTR{state}=="offline" gate is required: rproc_boot() increments
rproc->power unconditionally, so writing to an already-running core would
pin an extra reference and prevent a later shutdown or subsystem restart
from taking effect.

This is a userspace stopgap for the kernel bug; it can be dropped once a
kernel-side retry lands.

Link: qualcomm-linux/kernel#923
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Loïc Minier <loic.minier@oss.qualcomm.com>
@lool

Copy link
Copy Markdown
Contributor Author

We discussed this with the FastRPC team:

  • the proper fix is in the kernel, but that might be some time away
  • workarounds can be delivered in initramfs generators, but they are also some time away; for instance for initramfs-tools: https://salsa.debian.org/kernel-team/initramfs-tools/-/merge_requests/201
  • this workaround of adding udev rules to fastrpc is a bit of a kludge in that people will have a hard time to discover how to get their DSP working, and will need the fastrpc package installed (or a similar udev rule) to start their DSP after initramfs
  • the FastRPC team is not keen to carry the workaround without an agreed timeline for the proper fix, but they are ok with distro patches carrying this change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression with fastrpc 1.0.6 on a few platforms

2 participants