Reduce scheduler latency for realtime processes (#1638)

* WIP: reduce boardd and other lags

* Copypasta fault

* Silence spurious startup warning

Co-authored-by: Comma Device <device@comma.ai>
pull/1648/head
Jason Young 2020-06-05 17:09:41 -04:00 committed by GitHub
parent 72cc0fc801
commit 68531b071c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 65 additions and 29 deletions

View File

@ -6,6 +6,7 @@ import subprocess
import multiprocessing
from cffi import FFI
from common.android import ANDROID
from common.common_pyx import sec_since_boot # pylint: disable=no-name-in-module, import-error
@ -20,11 +21,7 @@ ffi = FFI()
ffi.cdef("long syscall(long number, ...);")
libc = ffi.dlopen(None)
def set_realtime_priority(level):
if os.getuid() != 0:
print("not setting priority, not root")
return
def _get_tid():
if platform.machine() == "x86_64":
NR_gettid = 186
elif platform.machine() == "aarch64":
@ -32,8 +29,25 @@ def set_realtime_priority(level):
else:
raise NotImplementedError
tid = libc.syscall(NR_gettid)
return subprocess.call(['chrt', '-f', '-p', str(level), str(tid)])
return libc.syscall(NR_gettid)
def set_realtime_priority(level):
if os.getuid() != 0:
print("not setting priority, not root")
return
return subprocess.call(['chrt', '-f', '-p', str(level), str(_get_tid())])
def set_core_affinity(core):
if os.getuid() != 0:
print("not setting affinity, not root")
return
if ANDROID:
return subprocess.call(['taskset', '-p', str(core), str(_get_tid())])
else:
return -1
class Ratekeeper():

View File

@ -55,18 +55,22 @@ function launch {
fi
fi
# no cpu rationing for now
echo 0-3 > /dev/cpuset/background/cpus
echo 0-3 > /dev/cpuset/system-background/cpus
echo 0-3 > /dev/cpuset/foreground/boost/cpus
echo 0-3 > /dev/cpuset/foreground/cpus
echo 0-3 > /dev/cpuset/android/cpus
# Android and other system processes are not permitted to run on CPU 3
# NEOS installed app processes can run anywhere
echo 0-2 > /dev/cpuset/background/cpus
echo 0-2 > /dev/cpuset/system-background/cpus
[ -d "/dev/cpuset/foreground/boost/cpus" ] && echo 0-2 > /dev/cpuset/foreground/boost/cpus # Not present in < NEOS 15
echo 0-2 > /dev/cpuset/foreground/cpus
echo 0-2 > /dev/cpuset/android/cpus
echo 0-3 > /dev/cpuset/app/cpus
# change interrupt affinity
echo 3 > /proc/irq/6/smp_affinity_list # MDSS
echo 1 > /proc/irq/78/smp_affinity_list # Modem, can potentially lock up
echo 2 > /proc/irq/733/smp_affinity_list # USB
echo 2 > /proc/irq/736/smp_affinity_list # USB
# Collect RIL and other possibly long-running I/O interrupts onto CPU 1
echo 1 > /proc/irq/78/smp_affinity_list # qcom,smd-modem (LTE radio)
echo 1 > /proc/irq/33/smp_affinity_list # ufshcd (flash storage)
echo 1 > /proc/irq/35/smp_affinity_list # wifi (wlan_pci)
# USB traffic needs realtime handling on cpu 3
[ -d "/proc/irq/733" ] && echo 3 > /proc/irq/733/smp_affinity_list # USB for LeEco
[ -d "/proc/irq/736" ] && echo 3 > /proc/irq/736/smp_affinity_list # USB for OP3T
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

View File

@ -856,9 +856,11 @@ int main() {
int err;
LOGW("starting boardd");
// set process priority
err = set_realtime_priority(4);
LOG("setpriority returns %d", err);
// set process priority and affinity
err = set_realtime_priority(54);
LOG("set priority returns %d", err);
err = set_core_affinity(3);
LOG("set affinity returns %d", err);
// check the environment
if (getenv("STARTED")) {

View File

@ -342,7 +342,7 @@ void* processing_thread(void *arg) {
set_thread_name("processing");
err = set_realtime_priority(1);
err = set_realtime_priority(51);
LOG("setpriority returns %d", err);
// init cl stuff
@ -1203,7 +1203,7 @@ void party(VisionState *s) {
#endif
// priority for cameras
err = set_realtime_priority(1);
err = set_realtime_priority(51);
LOG("setpriority returns %d", err);
cameras_run(&s->cameras);
@ -1234,7 +1234,7 @@ void party(VisionState *s) {
int main(int argc, char *argv[]) {
int err;
set_realtime_priority(1);
set_realtime_priority(51);
zsys_handler_set(NULL);
signal(SIGINT, (sighandler_t)set_do_exit);

View File

@ -7,6 +7,7 @@
#ifdef __linux__
#include <sys/prctl.h>
#include <sys/syscall.h>
#define __USE_GNU
#include <sched.h>
#endif
@ -61,3 +62,16 @@ int set_realtime_priority(int level) {
#endif
}
int set_core_affinity(int core) {
#ifdef QCOM
long tid = syscall(SYS_gettid);
cpu_set_t rt_cpu;
CPU_ZERO(&rt_cpu);
CPU_SET(core, &rt_cpu);
return sched_setaffinity(tid, sizeof(rt_cpu), &rt_cpu);
#else
return -1;
#endif
}

View File

@ -44,6 +44,7 @@ void* read_file(const char* path, size_t* out_len);
void set_thread_name(const char* name);
int set_realtime_priority(int level);
int set_core_affinity(int core);
#ifdef __cplusplus
}

View File

@ -3,7 +3,7 @@ import os
import gc
from cereal import car, log
from common.numpy_fast import clip
from common.realtime import sec_since_boot, set_realtime_priority, Ratekeeper, DT_CTRL
from common.realtime import sec_since_boot, set_realtime_priority, set_core_affinity, Ratekeeper, DT_CTRL
from common.profiler import Profiler
from common.params import Params, put_nonblocking
import cereal.messaging as messaging
@ -39,7 +39,8 @@ EventName = car.CarEvent.EventName
class Controls:
def __init__(self, sm=None, pm=None, can_sock=None):
gc.disable()
set_realtime_priority(3)
set_realtime_priority(53)
set_core_affinity(3)
# Setup sockets
self.pm = pm

View File

@ -12,7 +12,7 @@ def dmonitoringd_thread(sm=None, pm=None):
gc.disable()
# start the loop
set_realtime_priority(3)
set_realtime_priority(53)
params = Params()

View File

@ -15,7 +15,7 @@ def plannerd_thread(sm=None, pm=None):
gc.disable()
# start the loop
set_realtime_priority(2)
set_realtime_priority(52)
cloudlog.info("plannerd is waiting for CarParams")
CP = car.CarParams.from_bytes(Params().get("CarParams", block=True))

View File

@ -174,7 +174,7 @@ class RadarD():
# fuses camera and radar data for best lead detection
def radard_thread(sm=None, pm=None, can_sock=None):
set_realtime_priority(2)
set_realtime_priority(52)
# wait for stats about the car to come in from controls
cloudlog.info("radard is waiting for CarParams")