ui+selfdrived: pin UI after init, move selfdrived to core 5

Move the UI core-affinity pin to after MainWindow init so startup and
restart recovery can use all cores (pinning before init starved the
restarting UI on the contended little cores, stretching recovery from
~30s to minutes). Move selfdrived off the saturated core 4 onto core 5
so its 100 Hz loop is no longer starved, eliminating selfdrivedLagging.

Verified over a full drive: selfdrivedLagging=0, core4/core5 sustained
>=95% only 0.3%/1.2% of the time, UI restart recovery ~15s with the
device staying engaged, radar tracking unaffected.
This commit is contained in:
whoisdomi
2026-05-29 08:33:16 -05:00
committed by firestar5683
parent bd687f353f
commit 5020d33748
2 changed files with 18 additions and 10 deletions
+6 -1
View File
@@ -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()
+12 -9
View File
@@ -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();
}