diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 200efa9155..1bdadf0474 100644 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -721,7 +721,12 @@ class SelfdriveD: def main(): - config_realtime_process(4, Priority.CTRL_HIGH) + # Run on core 5 (plannerd/radard, ~50% peak, FIFO prio 51) instead of sharing + # the saturated core 4 with card+controlsd. Core 4 at 100% was starving + # selfdrived's 100 Hz loop and firing selfdrivedLagging. selfdrived's higher + # FIFO prio (53 > 51) lets it preempt the 20 Hz planner/radar when needed. + # (Core 6 = camerad, core 7 = modeld are both timing-critical — avoid.) + config_realtime_process(5, Priority.CTRL_HIGH) s = SelfdriveD() s.run() diff --git a/selfdrive/ui/main.cc b/selfdrive/ui/main.cc index 35ee73528f..9c11032116 100644 --- a/selfdrive/ui/main.cc +++ b/selfdrive/ui/main.cc @@ -31,15 +31,6 @@ void waylandAwareMessageHandler(QtMsgType type, const QMessageLogContext &contex int main(int argc, char *argv[]) { setpriority(PRIO_PROCESS, 0, -20); - // Pin the UI to the little cores (0-3). The realtime control loop - // (card/controlsd/selfdrived) runs SCHED_FIFO on core 4; without this pin the - // kernel can schedule the UI there, and a UI stall/restart spike preempts - // selfdrived, starving its 100 Hz loop and firing the "System Lagging" alert. - // Set before any threads spawn so children inherit the affinity. - if (!Hardware::PC()) { - util::set_core_affinity({0, 1, 2, 3}); - } - qInstallMessageHandler(waylandAwareMessageHandler); initApp(argc, argv); @@ -55,5 +46,17 @@ int main(int argc, char *argv[]) { MainWindow w; setMainWindow(&w); a.installEventFilter(&w); + + // Pin the UI to the little cores (0-3) AFTER startup. The realtime control + // loop (card/controlsd) runs SCHED_FIFO on core 4; this keeps the steady-state + // UI off it so a UI stall can't preempt the control loop. Deliberately done + // after MainWindow init so startup — and crucially restart recovery — can use + // all cores; pinning before init starved the restarting UI on the contended + // little cores and stretched recovery from ~30s to minutes. The per-second + // reaffine in UIState::update keeps it pinned thereafter. + if (!Hardware::PC()) { + util::set_core_affinity({0, 1, 2, 3}); + } + return a.exec(); }