User Tools

Site Tools


realtime:documentation:howto:applications:application_base

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
realtime:documentation:howto:applications:application_base [2017/07/15 01:51]
jithu [Stack prefaulting] - removing duplicate
realtime:documentation:howto:applications:application_base [2024/05/31 15:54] (current)
alison [Scheduling and priority]
Line 14: Line 14:
 ==== Scheduling and priority ==== ==== Scheduling and priority ====
  
-The [[realtime:​documentation:​technical_basics:​sched_policy_prio|scheduling policy]] as well as the priority+The [[realtime:​documentation:​technical_basics:​sched_policy_prio:start|scheduling policy]] as well as the priority
 must be set by the application explicitly. There are two possibilities must be set by the application explicitly. There are two possibilities
 for this: for this:
Line 30: Line 30:
 the pthread attributes and not to use the inherit scheduling of the the pthread attributes and not to use the inherit scheduling of the
 thread which created the real-time thread. thread which created the real-time thread.
 +</​wrap>​
 +  - **Problems with pthread condition variables** \\ <​wrap>​
 +Multithreaded applications which rely on glibc'​s libpthread are prone to unexpected latency delays since its condition variable implementation does not honor priority inheritance ([[https://​sourceware.org/​bugzilla/​show_bug.cgi?​id=11588|bugzilla]]). Unfortunately glibc'​s DNS resolver and asynchronous I/O implementations depend in turn on these condition variables.
 +[[https://​github.com/​dvhart/​librtpi|librtpi]] is an alternative LGPL-licensed pthread implementation which supports priority inheritance,​ and whose API is as close to glibc'​s as possible. ​ The alternative [[https://​www.musl-libc.org/​|MUSL libc]] has a pthread condition variable implementation similar to glibc'​s.
 </​wrap>​ </​wrap>​
  
Line 39: Line 43:
  
 See [[realtime:​documentation:​howto:​applications:​memory#​Stack Memory for RT threads | here]] See [[realtime:​documentation:​howto:​applications:​memory#​Stack Memory for RT threads | here]]
 +
 +==== Capabilities:​ running the app with RT priority as a non-root user ====
 +
 +Several of the Pthread APIs, like ''​mlockall()'',​ ''​pthread_attr_setschedpolicy()'',​ by default and convention require root in order to successfully get their work done. Thus, RT apps - which need to set an RT sched policy and priority -  are often run via ''​sudo''​. ​
 +
 +There'​s a far better approach to this; ''​sudo''​ gives the process root capabilities. This interests hackers :-).
 +Instead, you should leverage the powerful POSIX **Capabilities** model! This way, the process (and threads) get _only_ the capabilities they require and nothing more. This follows the infosec best practice, the //principle of least privilege//​.
 +
 +Apps start out with no capabilities by default; also note that capabilities are a per-thread resource (essentially translating to bitmasks with the task structure,​which is per-thread of course). Among the various capability bits, the man page on ''​capabilities(7)''​ shows that **''​CAP_SYS_NICE''​** is the appropriate capability to use in this circumstance;​ a snippet from the ''​capabilities(7)''​ man page reveals this:
 +
 +...
 +**CAP_SYS_NICE**
 +  * Lower the process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes;
 +  * **set  real-time ​ scheduling ​ policies ​ for  calling process, and set scheduling policies and priorities for arbitrary processes (sched_setscheduler(2),​ sched_setparam(2),​ sched_setattr(2));​**
 +  * set CPU affinity for arbitrary processes (sched_setaffinity(2));​
 +  * set I/O scheduling class and priority for arbitrary processes (ioprio_set(2));​
 +  * apply migrate_pages(2) to arbitrary processes and allow processes to be migrated to arbitrary nodes;
 +  * apply move_pages(2) to arbitrary processes;
 +  * use the MPOL_MF_MOVE_ALL flag with mbind(2) and move_pages(2). ...
 +
 +
 +**//Ok, great, but how exactly is this capability bit to be set on the app?//
 +**
 +  - One approach is to do so programatically,​ via the ''​capget()/​capset()''​ system calls. (Note that's it's generally easier to use the libcap library wrappers, ''​cap_[g|s]et_proc(3)'':​ [[https://​man7.org/​linux/​man-pages/​man3/​cap_get_proc.3.html]]. This man page even provides a small example of doing so).
 +  - Another easy way is to leverage systemd and run your app as a service; in the service unit, specify the capability (see the man page on systemd.exec(5);​ [[https://​www.freedesktop.org/​software/​systemd/​man/​systemd.exec.html#​Capabilities]].
 +  - Perhaps the easiest way: via the ''​setcap(8)''​ utility (it's man page: [[https://​man7.org/​linux/​man-pages/​man8/​setcap.8.html]]). The setcap/​getcap are typically part of the libcap package. For example:
 +    ''​sudo setcap CAP_SYS_NICE+eip <​your-app-binary-executable>''​
 +
 +You could put this line in the app Makefile (or equivalent).
 +(The ''​getcap(8)''​ utility can be used to verify that the '​dumb-capability'​ binary now has the ''​CAP_SYS_NICE''​ bit set)!
 +
 +And you're all set to run it as non-root now, a much more secure approach.
 +
 ===== Example ===== ===== Example =====
  
realtime/documentation/howto/applications/application_base.1500083491.txt.gz ยท Last modified: 2017/07/15 01:51 by jithu