Why PipeWire ignores realtime priority despite privileges already satisfied?

Hi everyone,

I’m running Manjaro (testing branch) on an AMD 7840HS laptop with PipeWire. After resuming from S0ix sleep, I consistently experience audio buzzing. I suspect this is caused by buffer underruns due to insufficient scheduling priority.

Upon checking, I found that PipeWire processes are running with nice = -11 instead of the expected realtime priority (rt = 88).

What I’ve checked and tried:

  1. Configuration:

    • No custom overrides; only the default /usr/share/pipewire/pipewire.conf is in use.
    • The realtime-privileges package is installed.
    • My user is added to the realtime group.
    • rtkit is running normally without errors.
  2. Expected behavior:

    • According to /usr/share/pipewire/pipewire.conf, PipeWire should prefer rt.prio = 88. If privileges not satisfied, then to be nice = -11.
    • But it always prefer nice = -11. Pipewire ignores rt.prio setting and chose nice = -11.
  3. Workaround:

    • I manually set realtime priority by editing both pipewire-pulse.service and pipewire.service via:

      systemctl --user edit pipewire-pulse.service
      systemctl --user edit pipewire.service
      

      Added:

      [Service]
      CPUSchedulingPolicy=rr
      CPUSchedulingPriority=88
      
    • After this change, ps -eo user,pid,cls,rtprio,ni,pri,pcpu,comm | grep pipewire confirms the correct rt priority is applied.

    • The buzzing issue is resolved after resuming from S0ix.

Questions:

  • Is this a PipeWire bug or a compilation/configuration issue?
  • Why does PipeWire ignore the rt.prio setting in the default config?
  • Is there a better way to enforce realtime priority without manually editing systemd services?

Any insights or suggestions would be greatly appreciated!

More details

If I run pipewire in the console, not by systemd.
It also ignores rt privilege and choose nice = -11.
e.g.
systemctl --user stop pipewire.socket
systemctl --user stop pipewire
systemctl --user stop pipewire-pulse
Then run pipewire -v in console
Pipewire ignores rt.prio = 88again.
This is a wired issue, really. As it default to
{ name = libpipewire-module-rt
args = {
nice.level = -11
rt.prio = 88
#rt.time.soft = -1
#rt.time.hard = -1
#uclamp.min = 0
#uclamp.max = 1024
}
flags = [ ifexists nofail ]
condition = [ { module.rt = !false } ]
}
condition = [ { module.rt = !false } ]
And Pipewire indeed read the conf and apply the settings except rt.prio = 88

Pipewire verbose log

pipewire.log - Pastebin.com

Inxi

inxi - Pastebin.com

Is that what an LLM said?

My brain could also be wrong, but it seems more likely it has to do with the audio driver waking up the audio chipset (you didn’t say what either are), from this hybrid sleep.

But at least you have a work around! Many people are out of luck if they are forced to use modern standby/hybrid sleep/S0ix sleep mode. (And reloading does not even do anything, and have to do a full reboot.)

I avoid laptops with only that sleep mode like the plague. :face_with_peeking_eye:

1 Like

Yep. Ref that a little bit. Because the abnormal sound (like hizzzzzz or buzzzzzz) fade off after few seconds, then it get to normal state.

U’re right. It is also plausible to be a driver suspend issue.
I think the llm is correct about that for aspect of priority, because of forcing to use rr RT scheduler does solve my issue.
Also, pipewire not prefer to use rt priority is indeed a problem for profession use case (not for me…).

BTW, I do prefer s3 sleep. But the BIOS shipped with my laptop only with S0ix on…(Sad)

And, sorry for my system information not given. It is vendor: Conexant Systems driver: snd_hda_intel.

Inxi

inxi - Pastebin.com

I assume a simple pipewire restart doesn’t work. But you did restart wireplumber as well, right?

Where I was going, was just make a systemd unit to hack fix it. It still can apply this if you have to do it a more convoluted way above (via script). And nice job on fixing that, if that’s the only way.


(You can call “audio-fix” what you want obviously)..

Create the file:
/etc/systemd/user/audio-fix.service


[Unit]
Description=Fix audio after sleep
After=suspend.target

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --user restart pipewire pipewire-pulse wireplumber

[Install]
WantedBy=suspend.target

And run one time..

systemctl --user daemon-reload
systemctl --user enable audio-fix
2 Likes

Oops, my bad! Turns out the main thread of PipeWire doesn’t use RT priority, but the forked child processes do use SCHED_FIFO RT priority. I got it wrong—nevermind! :joy: