From 4026365270daa8ba26c52eef01ecd0156626bfb2 Mon Sep 17 00:00:00 2001 From: "Dr. Matthew Swabey" Date: Mon, 27 Mar 2023 21:34:24 -0400 Subject: [PATCH] linux: Lock Memory and Increase Priority (#6131) Realtime programming best practice is to lock realtime code memory to prevent paging which will lead to unbounded latencies. The Linux MCU process has well bounded memory and small RAM footprint so locking the entire process' RAM has no downsides and will improve behavior when the system comes under memory pressure. (See bootlin training and Linux Foundation documentation linked below.) RT process priority ranges from 0-99 (although POSIX only requires 32), boost MCU process priority to half the max/2 to improve robustness when the system comes under pressure from other RT Kernel or user processes. Reference links: bootlin: https://bootlin.com/doc/training/preempt-rt/preempt-rt-slides.pdf Linux Foundation: https://wiki.linuxfoundation.org/realtime/documentation/howto/applications/application_base#howto_build_a_simple_rt_application Signed-off-by: Matthew Swabey --- src/linux/main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/linux/main.c b/src/linux/main.c index c8cb3dfd..f9ea3f6d 100644 --- a/src/linux/main.c +++ b/src/linux/main.c @@ -4,10 +4,11 @@ // // This file may be distributed under the terms of the GNU GPLv3 license. -#include // sched_setscheduler +#include // sched_setscheduler sched_get_priority_max #include // fprintf #include // memset #include // getopt +#include // mlockall MCL_CURRENT MCL_FUTURE #include "board/misc.h" // console_sendf #include "command.h" // DECL_CONSTANT #include "internal.h" // console_setup @@ -25,12 +26,18 @@ realtime_setup(void) { struct sched_param sp; memset(&sp, 0, sizeof(sp)); - sp.sched_priority = 1; + sp.sched_priority = sched_get_priority_max(SCHED_FIFO) / 2; int ret = sched_setscheduler(0, SCHED_FIFO, &sp); if (ret < 0) { report_errno("sched_setscheduler", ret); return -1; } + // Lock ourselves into memory + ret = mlockall(MCL_CURRENT | MCL_FUTURE); + if (ret) { + report_errno("mlockall", ret); + return -1; + } return 0; }