diff --git a/common/realtime.py b/common/realtime.py index c21222e88c..e734438646 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -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(): diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index f88f6fb7d1..2d3fa39d4e 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -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 - - # 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 + # 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 + + # 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 )" diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index c6a0a7a40e..91de75a364 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -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")) { diff --git a/selfdrive/camerad/main.cc b/selfdrive/camerad/main.cc index d65913bb46..b1c6684675 100644 --- a/selfdrive/camerad/main.cc +++ b/selfdrive/camerad/main.cc @@ -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); diff --git a/selfdrive/common/util.c b/selfdrive/common/util.c index 1aed0eaae6..dce6e8ac67 100644 --- a/selfdrive/common/util.c +++ b/selfdrive/common/util.c @@ -7,6 +7,7 @@ #ifdef __linux__ #include #include +#define __USE_GNU #include #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 +} diff --git a/selfdrive/common/util.h b/selfdrive/common/util.h index ed0c88f2c8..4b0e29aada 100644 --- a/selfdrive/common/util.h +++ b/selfdrive/common/util.h @@ -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 } diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 7d4591626d..2c1a444d9f 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -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 diff --git a/selfdrive/controls/dmonitoringd.py b/selfdrive/controls/dmonitoringd.py index 0f949c2e89..2a21e920f4 100755 --- a/selfdrive/controls/dmonitoringd.py +++ b/selfdrive/controls/dmonitoringd.py @@ -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() diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 21ea32a51a..b439681a3a 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -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)) diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 3ae766281b..0ba14dcf26 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -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")