News for hackers. Stuff that matters.
Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by PaulDavisThe1st on Tuesday December 31, 2019 @10:23PM (#21926451)
(reposting my comment from the original)

There’s some potentially misleading information here. Background: I’ve spent the last 20+ years writing low-latency realtime audio applications, technically cross-platform but focused on Linux.

If you care about low latency on any general purpose OS, you need to use a realtime scheduling policy. The default scheduling on these OS’s is intended to maximise some combination of bandwidth and/or fairness. Low latency requires ditching both of those in favor of limiting the maximum scheduling delay of a thread that is otherwise ready to run.

Measuring how long synchronization primitives take without SCHED_FIFO is illustrative, but only of why, if you care about scheduling latency, you need SCHED_FIFO. There are several alternative schedulers for Linux – none of them remove the need for SCHED_FIFO if latency is important.

It is absolutely not the case that using SCHED_FIFO automatically starves non-SCHED_FIFO threads. Scheduling policy is set per-thread, and SCHED_FIFO will only cause issues if the threads that use it really do “burn the CPU” (e.g. by using spinlocks). If you combine SCHED_FIFO with spinlocks you need to be absolutely certain that the locks have low contention and/or are held for extremely short periods (preferably just a few instructions). If you use mutexes (which ultimately devolve to futexes at the kernel level), the kernel will take care of you a little better, unless your SCHED_FIFO thread doesn’t block – if it doesn’t do that, that’s entirely on you. Blocking means making some sort of system call that will cause the scheduler to put the thread to sleep – could be a wait on a futex, waiting for data, or an explicit sleep.

In particular, this: “This was known for a while simply because audio can stutter on Linux when all cores are busy (which doesn’t happen on Windows)” is NOT true. Linux actually has better audio performance than Windows or macOS, but only if the app developer understands a few basic principles. One of them is using SCHED_FIFO appropriately.

Pro-audio/music creation scheduling is MUCH more demanding than video, and a bit more demanding than games. Linux handles this stuff just fine – it just gives you enough rope to shoot yourself in the foot if you don’t fully understand what you’re doing.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by segfaultbuserr on Tuesday December 31, 2019 @10:55PM (#21926545)
For the same reason, by default, PulseAudio uses rtkit to escalate its privileges and set its scheduler policy to SCHED_FIFO (then drop the privilege). Many people don't understand it and see it as another example of how Lennart's software is taking over the world (especially when you use a distribution like Arch that didn't already have rtkil configured for you), but it's essential for good audio latency (but the audio player needs SCHED_FIFO as well, there's nothing to help if the player itself is locking up).

> SCHEDULING

> high-priority= Renice the daemon after startup to become a high-priority process. This a good idea if you experience drop-outs during playback. However, this is a certain security issue, since it works when called SUID root only, or RLIMIT_NICE is used. root is dropped immediately after gaining the nice level on startup, thus it is presumably safe. See pulseaudio(1) for more information.

> Takes a boolean argument, defaults to yes. The --high-priority command line option takes precedence.

> realtime-scheduling= Try to acquire SCHED_FIFO scheduling for the IO threads. The same security concerns as mentioned above apply. However, if PA enters an endless loop, realtime scheduling causes a system lockup. Thus, realtime scheduling should only be enabled on trusted machines for now. Please note that only the IO threads of PulseAudio are made real-time. The controlling thread is left a normally scheduled thread. Thus enabling the high-priority option is orthogonal. See pulseaudio(1) for more information.

> Takes a boolean argument, defaults to yes. The --realtime command line option takes precedence.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by PaulDavisThe1st on Tuesday December 31, 2019 @11:03PM (#21926563)
On modern Linux systems, it is impossible for SCHED_FIFO to cause system lockups. A configurable percentage of CPU cycles is reserved by the (default) scheduler for non-SCHED_FIFO threads, so even a SCHED_FIFO thread that runs "while (true){}" will not be allowed to use 100% of a core's cycles.

RLIMIT_NICE is of zero use with realtime audio.

This documentation is based on (1) the state of Linux circa 2008 or so (2) a complete misunderstanding of the role of nice values for scheduling (hint; it's only useful for altering the behavior of non-RT threads, which means threads that do not have hard or semi-hard timing deadlines).

It is a notable problem that there is so much out of date information about the use of nice with audio applications still circulating online. It was never true, and it's even less true today.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by segfaultbuserr on Tuesday December 31, 2019 @11:10PM (#21926589)
Glad to see someone with industrial experience on realtime processing to respond.

> a complete misunderstanding of the role of nice values for scheduling (hint; it's only useful for altering the behavior of non-RT threads, which means threads that do not have hard or semi-hard timing deadlines).

I suspect you're misreading the quoted documentation, I believe the quoted documentation is fine. To recite, "only the IO threads of PulseAudio are made real-time. The controlling thread is left a normally scheduled thread. Thus enabling the high-priority option is orthogonal (to SCHED_FIFO)".

Nice is applied to the controller responsible for other tasks, SCHED_FIFO is applied to the I/O threads, independently.

> On modern Linux systems, it is impossible for SCHED_FIFO to cause system lockups. [...] so even a SCHED_FIFO thread that runs "while (true){}" will not be allowed to use 100% of a core's cycles.

Really? The rtkit documentation mentioned,

> If processes that have real-time scheduling privileges enter a busy loop they can freeze the entire the system. To make sure such run-away processes cannot do this RLIMIT_RTTIME has been introduced. Being a per-process limit it is however easily cirumvented by combining a fork bomb with a busy loop.

> RealtimeKit hands out RT scheduling to specific threads that ask for it -- but only to those and due to SCHED_RESET_ON_FORK it can be sure that this won't 'leak'.

> In contrast to RLIMIT_RTPRIO, the RealtimeKit logic makes sure that only a certain number of threads can be made realtime, per user, per process and per time interval.

So "while (true){}" won't lock your system up, but "while (true) { fork(); }" certainly will, so the rational of only using SCHED_FIFO on trusted processes is reasonable.

I think it's still true. Is it?

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by PaulDavisThe1st on Tuesday December 31, 2019 @11:54PM (#21926723)
Can't reply to your deepest response.

Basically, read: https://access.redhat.com/documentation/en-us/red_hat_enterp...

(This is from RH, but the kernel params are generic)

Again, RTKit is a convenience wrapper, nothing more or less. It runs with sufficient priviledge to ask for SCHED_FIFO, which by default is not permitted. The more conventional approach is to create a user group and use PAM or equivalent to set the rt priority limit for that group, thus allowing any user in the group to run any app that can then ask for SCHED_FIFO with prio up to the limit. RTKit was created by Lennart to avoid this type of sysconfig (in favor of a different type of sysconfig).

You're mistaken about the historical ordering of things too. SCHED_FIFO was available long before PulseAudio or RTKit was created.

Yes, you could shuffle the text around as you suggest, but that's far from a "trivial" edit. It's basically equivalent to saying "yeah, the old doc was basically totally wrong, here's a correct version" :)

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by segfaultbuserr on Wednesday January 01, 2020 @12:01AM (#21926737)
> Can't reply to your deepest response.

Pro-Tip: Hacker News has a "new comment cool-off timer", it gives a minute or two before allowing a comment to be answered. It gives a chance for the poster to edit the comment. Just relax when you cannot see a reply button.

> Basically, read: https://access.redhat.com/documentation/en-us/red_hat_enterp.... (This is from RH, but the kernel params are generic)

I see. "The default values for the Real-time throttling mechanism define that 95% of the CPU time can be used by real-time tasks. The remaining 5% will be devoted to non-realtime tasks (tasks running under SCHED_OTHER and similar scheduling policies). It is important to note that if a single real-time task occupies that 95% CPU time slot, the remaining real-time tasks on that CPU will not run. The remaining 5% of CPU time is used only by non-realtime tasks".

So a fork bomb is as safe is an empty loop (at least from a scheduling prospectively), as long as a strict limit is set.

I have noted it down.

> Yes, you could shuffle the text around as you suggest, but that's far from a "trivial" edit. It's basically equivalent to saying "yeah, the old doc was basically totally wrong, here's a correct version" :)

Okay, the main documentation for "man pulseaudio" was a bit better,

> To minimize the risk of drop-outs during playback it is recommended to run PulseAudio with real-time scheduling if the underlying platform supports it. This decouples the scheduling latency of the PulseAudio daemon from the system load a

You see, here it mentions real-time scheduling, not high-priority scheduling in "man pulse-daemon.conf". So I guess the explanation of " high-priority=" was more or less untouched since 2008, but the code kept moving on.

> You're mistaken about the historical ordering of things too. SCHED_FIFO was available long before PulseAudio or RTKit was created.

I meant the renicing mechanism was in PulseAudio before RLIMIT_RTPRIO, or the rtkit framework. I didn't say a word about SCHED_FIFO, which was indeed POSIX, but less useful without later improvement on scheduling policies.

Thanks for your patience and answers, all my questions have been explained.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by PaulDavisThe1st on Tuesday December 31, 2019 @11:18PM (#21926616)
No, it's not still true, and rtkit is just a convenience item that has nothing to do with core kernel policy.

The use of nice to try to adjust scheduling of audio apps (the entire application or specific threads) is completely off-base. If you use SCHED_OTHER, you're making a declaration that timing is not important. You can bump the nice value of a SCHED_OTHER thread, and that will change its behavior among the pool of the other SCHED_OTHER threads, but that's almost never useful in an audio app.

Now, ionice is another (and more complex) story ...

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by segfaultbuserr on Tuesday December 31, 2019 @11:37PM (#21926679)
> No, it's not still true

The point of rtkit is creating a convenient framework to enforce SCHED_RESET_ON_FORK and rate-throttling in a single place. So if I'm interpreting your comment correctly, running a "while (true) { fork(); }", even without restrictions of SCHED_RESET_ON_FORK, will not lock the system up in a modern system? Is it correct?

> The use of nice to try to adjust scheduling of audio apps (the entire application or specific threads) is completely off-base.

I think the renicing mechanism of "high-priority=" was historical, introduced to PulseAudio long before the system resource limit like RLIMIT_RTPRIO, or the rtkit framework has been put into place. As another document mentioned, g

> To minimize the risk of drop-outs during playback it is recommended to run PulseAudio with real-time schedulin [...] Alternatively, if the risk of locking up the machine is considered too big to enable real-time scheduling, high-priority scheduling can be enabled [...]

So while renicing is still here, PulseAudio prefers SCHED_FIFO nowadays, and the renice is only a fallback.

So, can you point out where exactly is wrong in the first documentation I quoted in the first comment? Certainly, the paragraph, "high-priority= Renice the daemon after startup to become a high-priority process. This a good idea if you experience drop-outs during playback" is outdated, but if one removes the word "Renice", and moves this paragraph from "high-priority=" to "realtime-scheduling=", it's still correct.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by edwintorok on Thursday January 02, 2020 @06:34PM (#21941184)
Note that by default kernel.sched_rt_runtime_us limits RT usage to 95% of the whole system, not an individual core. If you have 1 RT process using 100% of a core on a multicore system it won't trigger the limiting, which can cause all sorts of problems (like network interrupts not getting serviced if your process happened to hog the core used by network interrupts). This can be worked around by writing NO_RT_RUNTIME_SHARE to /sys/kernel/debug/sched_features, which then makes the 95% limit apply on each logical core, not the system as a whole.

See here for more details: https://access.redhat.com/documentation/en-us/red_hat_enterp...

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by Intermernet on Wednesday January 01, 2020 @03:47AM (#21927266)
Off topic, but thanks to you and the JACK team! I think it's one of the most underrated pieces of software around. I have used it many times over the years and I'm constantly amazed at how good it is, even compared to industry standard proprietary stuff.
Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by temac on Wednesday January 01, 2020 @08:50AM (#21927986)
Also, a yielded thread has absolutely no reason to be woken up with low latency, and this has nothing to do with the supposed scheduler quality. I'm not sure a kernel blindly prioritizing otherwise cpu-bound thread just because they yielded would give good results in the general case, esp out of microbenchmarks. If you want low wake up latency, you need a proper design, not mere reliance on magic that does not exist.

Plus highly contended critical sections should really really be avoided. So I'm not sure the author's benchmark even make any sense: if all of your workload is serialized, use a single thread.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by xenadu02 on Wednesday January 01, 2020 @02:46AM (#21927125)
> Linux actually has better audio performance than [...] macOS

That seems unlikely to me and doesn't match any experience I've ever had or known anyone to have. Can you explain what you mean by that?

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by barrkel on Wednesday January 01, 2020 @03:40AM (#21927251)
Windows automatically boosts the prio of threads playing audio, basically treats them as realtime in its prio hierarchy. What I expect GP is talking about is minimum latency achievable, i.e. that with focused tuning, you can outperform Windows.

Regular users of not so tuned apps probably experience this differently because Windows tries to do the tuning automatically and Linux doesn't.

The Windows scheduler has other issues, like random prio boosting to escape from prio inversion.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by xenadu02 on Wednesday January 01, 2020 @05:37AM (#21927509)
Right, I'm aware of the issues on Windows. I was asking about XNU-based platforms which are known for having very low latency and excellent realtime audio perf out of the box.

(Granted, the out of box behavior and the achievable latency are two separate issues)

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by jcelerier on Wednesday January 01, 2020 @06:39AM (#21927657)
> Right, I'm aware of the issues on Windows. I was asking about XNU-based platforms which are known for having very low latency and excellent realtime audio perf out of the box.

I have never seen a mac box achieving reliable lower latency than Linux or Windows on the same hardware. Macs are nice for the plug'n'play experience - even though more often than not you still want to install your soundcard's driver.

But when it comes to doing actual work... https://www.dawbench.com/win7-v-osx-6.htm

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by AdmiralBumbleB on Wednesday January 01, 2020 @10:39AM (#21928409)
I'm not sure that posting 9 year old benchmarks is particularly useful, particularly when those results have been heavily debated.

If we're talking pure latency then UA, Focusrite, Apogee and Avid have lower RTL for the same buffer size in macOS. RME is identical on both platforms and I'm unsure about antelope.

Regarding loads before under-runs that's a very tough thing to test, as it varies between products. GENERALLY: Comparing Digital Performer between platforms heavily favours macOS. Comparing Pro Tools favours macOS (currently). Comparing Reaper favours windows slightly. Cubase favours Windows... etc...

There's also load type that factors in, as with macs you get a specific build with minimal leeway. Windows builds can be planned for a given build (highly serial, highly parallel, RAM hungry, Latency performant etc...). It's not too hard to build a test suite that favours macOS everywhere on the same machine, likewise for Windows.

But to the original topic, latency, macOS is generally superior in this regard when looking at RTL specs for the same device.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by jcelerier on Wednesday January 01, 2020 @06:44AM (#21927677)
> Blocking means making some sort of system call that will cause the scheduler to put the thread to sleep – could be a wait on a futex, waiting for data, or an explicit sleep.

Speaking of which, do you know of a tool that would allow to ensure that e.g. your RT threads won't do bad things - short of putting a breakpoint on every syscall-like thing ? I wonder if at that point the audio community should not look into developing some clang-based static analyzer to enforce that.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by PaulDavisThe1st on Wednesday January 01, 2020 @09:48AM (#21928222)
There have been several such tools over the years - I regret that off the top of my head I don't recall the names of any of them.

Clang can be used for this but AFAIK you need to annotate functions/methods to indicate whether or not they are intended to be RT-safe. This gets complex if you have code that can be used in an RT context and in a non-RT context. The annotation part would be relatively simple in, say, a small audio player. In a DAW, it would be a substantial and complex task.

Re:Measuring mutexes, spinlocks and how bad the Linux schedu... by richardwhiuk on Monday January 06, 2020 @01:47PM (#21971811)
I've done things before where you shim in a library (using LD_PRELOAD) between the executable and the C standard library, and blacklist function calls which are potentially blocking, (abort if they get called in the wrong context).

It's usually sufficient to do this in testing, and then have as is, in production.