> For the complete documentation index, see [llms.txt](https://davidjosearaujo.gitbook.io/notes-miect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://davidjosearaujo.gitbook.io/notes-miect/sistemas-operativos-e-de-tempo-real/practical-class-01/real-time-services-in-linux.md).

# Real-Time Services in Linux

## Embedded Linux and real-time

Linux and other open-source software are increasingly used for developing Embedded Systems.

Many of these applications have **real-time requirements**.

Ideally we would like to:

* Have the advantages of Linux: HW support, low cost, modularity, openess, ...
* And **meet deadlines**!

Linux was developed as **generic desktop and server** time-sharing OS.

* Objectives are: optimize throughput, improve the average utilization of resources (CPU, memory, I/O), ...
* Timeliness in not a main issue.

Conversely, dedicated Real-Time Operative Systems (RTOS) are engineered for **having temporal determinism**, often at expenses of throughput.

In fact, **throughput and temporal determinism are often conflicting requirements**.

* Optimizing for one impacts negatively on the other.

## Improving the real-time performance of Linux

### Approach 1

**Modify the Linux kernel** to improve its temporal behavior.

* Bound the latency of syscalls, introduce fine-grain preemption, improve timer resolution, create specific services for real-time, proper scheduling, etc.

Many of these features have been added to the mainline Linux kernel (from the PREEMPT\_RT project).

### Approach 2

**Add a RTOS “under” linux**. Linux becomes a background task of the RTOS.

* Approach followed e.g. by RTAI, Xenomai, ...

### Hints on Linux kernel latency sources

A **typical event sequence** in a real-time application is:

* An event causes a CPU interrupt.
* The corresponding ISR is executed, activating a user-space task associated with the event.
* Eventually this task is executed and completes, thus closing the reaction to the event.
  * Time elapsed between an event and the corresponding task activation is the latency

The objective is reduce, as much as possible, the latency!

<figure><img src="https://3011170443-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxBNeQZTqLnbb3C3JTlRu%2Fuploads%2FIXnmmw1RucE7c1SxnsS7%2F2022-09-28_18-21.png?alt=media&amp;token=cfa47386-3459-498f-bdb9-18f8308d3dd6" alt=""><figcaption></figcaption></figure>

kernel latency = interrupt latency + handler duration + scheduler latency + scheduler duration

<figure><img src="https://3011170443-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxBNeQZTqLnbb3C3JTlRu%2Fuploads%2FvvR4uHZbGTv7sgVx8dZc%2F2022-09-28_18-21.png?alt=media&amp;token=587a807b-a283-49a1-9d18-44aa57737f88" alt=""><figcaption></figcaption></figure>

Interrupt latency sources:

* Linux kernel (including device-drivers) disables interrupts for certain operations.
* Interrupts can interrupt other interrupts (nesting).

Interrupt handlers are split in two parts (top/bottom; fast/slow).

<figure><img src="https://3011170443-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxBNeQZTqLnbb3C3JTlRu%2Fuploads%2FAKPaMQxoHNJQYhIZRTif%2F2022-09-28_18-21.png?alt=media&amp;token=be7addd3-defe-4ccc-9822-e59bb9fb13bb" alt=""><figcaption></figcaption></figure>

Linux kernel is **preemptive**.

* But not fully! Syscalls have variable duration and limited preemption.

<figure><img src="https://3011170443-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxBNeQZTqLnbb3C3JTlRu%2Fuploads%2FZ3sVlUrdhXpZ5clLGZW8%2F2022-09-28_18-21.png?alt=media&amp;token=74f0c9c7-1cbc-48bd-816c-2db53b0074c9" alt=""><figcaption></figcaption></figure>

In addition, there are many other sources of latency and jitter that affect real-time tasks in Linux:

* Scheduler latency.
* Linux makes intensive use of virtual memory. Access to data that is on disk takes much longer than access to data that is in RAM.
* The same applies to cache.
* Many C library functions have not been designed for deterministic execution.
* **Priority inversion**.
  * Due to shared resources.
* **Interrupt prioritization**.

<figure><img src="https://3011170443-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxBNeQZTqLnbb3C3JTlRu%2Fuploads%2FSfmTjlazMRmq7TFtT6Hv%2Fa.png?alt=media&amp;token=61041bf6-5a52-4828-90a6-f3d43fb28626" alt=""><figcaption></figcaption></figure>

## PREEMPT\_RT Project

Some of the improvements already integrated on the mainline kernel.

* O(1) scheduler.
* Fixed-priority scheduler.
* Kernel preemption.
* Improvements to the POSIX real-time API support.
* Mutexes with “Priority inheritance” support.
* High resolution timers.
* Threaded interrupts.
* sched\_deadline, EDF scheduling with CBS.
* ...

There are Linux distributions that already provide a patched kernel.

* Real-time Ubuntu 22.04 LTS Beta.
  * [https://ubuntu.com/blog/real-time-ubuntu-released](<https://ubuntu.com/blog/real-time-ubuntu-released&#xD;&#xA;>)
  * Still in beta version.
  * Production version planned for 23.04 release.
  * Can be used for free for private use (instructions in the link above).

### Example: preemption control

Linux supports different preemption levels.

* For real-time use it may require compiling the Linux kernel with the right options.

<figure><img src="https://3011170443-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxBNeQZTqLnbb3C3JTlRu%2Fuploads%2F2cJdw9spnMF1oB63ptbi%2Fa.png?alt=media&amp;token=ced0e3ba-0781-4266-b3f2-d16ea8da187c" alt=""><figcaption></figcaption></figure>

PREEMPT\_RT provides additional preemption levels.

* Preemptible Kernel or Basic RT (PREEMPT\_RTB).
* Preemptible Kernel (PREEMPT\_RT\_FULL).

Checking Linux kernel configuration.

* Linux kernel configuration can be obtained via:

```bash
#cat /boot/config-$(uname -r)
```

Preemption status can be accessed via:

```bash
pedreiras:~$ cat /boot/config-$(uname -r) | grep PREEMPT
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y
CONFIG_PREEMPT_DYNAMIC=y
CONFIG_PREEMPT_RCU=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y

```

### CONFIG\_PREEMPT\_NONE

Kernel **code** (interrupts, exceptions, system calls) **never are preempted**.

* Common default configuration in many distributions.
* Better performance for systems that carry intensive processing, if the objective is to maximize throughput.
  * Minimizes context switches and associated overheads.

### CONFIG\_PREEMPT\_VOLUNTARY

Kernel code is preemptable at specific points.

* Useful on desktop environments, as it increases the reactivity (as perceived by an human user).
* Rescheduling points are explicitly added to the kernel code.
* Low impact on throughput.

### CONFIG\_PREEMPT

Most of the kernel becomes preemptable.

* In most cases, when a process is dispatched it can start execution before the completion of pending syscalls (issued by other processes).
* However, there are non-preemptible critical sections protected by spinlocks.
  * Better option for Embedded Systems with RT requirements.
  * Low/moderate impact on throughput.

**Best RT performance (without PREEMPT\_RT patch) is obtained with this option!**
