perf(daemon): add restart backoff, process priority, and map eviction

Supervisor had zero-delay restart on crash loops — pins CPU core at
100% if daemon keeps dying. Add exponential backoff (500ms to 30s cap,
resets after 30s stable). Set nice=10 on daemon child to yield CPU
to foreground apps. Evict stale entries from fileLocks and rate limiter
ConcurrentHashMaps that grew unbounded. Upload pre-built flashable zips
in CI instead of unpacking and re-compressing loose files.
This commit is contained in:
Enginex0
2026-03-11 12:41:57 +01:00
parent 7b510a9915
commit c122ded7bf
4 changed files with 30 additions and 3 deletions
+4 -2
View File
@@ -92,8 +92,8 @@ jobs:
cp "$RELEASE_FILE" "out/TEESimulator-${VER}-Release.zip" cp "$RELEASE_FILE" "out/TEESimulator-${VER}-Release.zip"
cp "$DEBUG_FILE" "out/TEESimulator-${VER}-Debug.zip" cp "$DEBUG_FILE" "out/TEESimulator-${VER}-Debug.zip"
echo "Release: $(basename "$RELEASE_FILE") -> TEESimulator-${VER}-Release.zip" echo "Release: $(basename "$RELEASE_FILE") -> TEESimulator-${VER}-Release.zip ($(du -h "$RELEASE_FILE" | cut -f1))"
echo "Debug: $(basename "$DEBUG_FILE") -> TEESimulator-${VER}-Debug.zip" echo "Debug: $(basename "$DEBUG_FILE") -> TEESimulator-${VER}-Debug.zip ($(du -h "$DEBUG_FILE" | cut -f1))"
env: env:
VER: ${{ steps.ver.outputs.version }} VER: ${{ steps.ver.outputs.version }}
@@ -102,12 +102,14 @@ jobs:
name: TEESimulator-release-zip name: TEESimulator-release-zip
path: out/TEESimulator-*-Release.zip path: out/TEESimulator-*-Release.zip
retention-days: 30 retention-days: 30
compression-level: 0
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: TEESimulator-debug-zip name: TEESimulator-debug-zip
path: out/TEESimulator-*-Debug.zip path: out/TEESimulator-*-Debug.zip
retention-days: 7 retention-days: 7
compression-level: 0
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
+20 -1
View File
@@ -2,11 +2,13 @@
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/resource.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <time.h>
static volatile sig_atomic_t should_exit = 0; static volatile sig_atomic_t should_exit = 0;
@@ -27,7 +29,12 @@ int main(int argc, char *argv[]) {
const char *daemon_path = argv[1]; const char *daemon_path = argv[1];
char **daemon_argv = &argv[1]; char **daemon_argv = &argv[1];
int backoff_ms = 500;
while (!should_exit) { while (!should_exit) {
struct timespec child_start;
clock_gettime(CLOCK_MONOTONIC, &child_start);
pid_t pid = fork(); pid_t pid = fork();
if (pid < 0) { if (pid < 0) {
@@ -39,6 +46,7 @@ int main(int argc, char *argv[]) {
if (pid == 0) { if (pid == 0) {
// Child: become the daemon // Child: become the daemon
prctl(PR_SET_PDEATHSIG, SIGKILL); // Die if parent dies prctl(PR_SET_PDEATHSIG, SIGKILL); // Die if parent dies
setpriority(PRIO_PROCESS, 0, 10); // lower CPU priority than foreground
execv(daemon_path, daemon_argv); execv(daemon_path, daemon_argv);
perror("execv failed"); perror("execv failed");
_exit(127); _exit(127);
@@ -50,7 +58,18 @@ int main(int argc, char *argv[]) {
if (should_exit) break; if (should_exit) break;
// Instant restart - no delay // Exponential backoff on rapid crashes, reset if child was stable
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
long lived_ms = (now.tv_sec - child_start.tv_sec) * 1000 +
(now.tv_nsec - child_start.tv_nsec) / 1000000;
if (lived_ms > 30000) {
backoff_ms = 500;
} else {
usleep(backoff_ms * 1000);
if (backoff_ms < 30000) backoff_ms *= 2;
}
} }
return 0; return 0;
@@ -129,6 +129,7 @@ object GeneratedKeyPersistence {
val file = File(PERSISTENCE_DIR, keyFileName(keyId.uid, keyId.alias)) val file = File(PERSISTENCE_DIR, keyFileName(keyId.uid, keyId.alias))
if (file.exists()) { if (file.exists()) {
if (file.delete()) { if (file.delete()) {
fileLocks.remove(keyFileName(keyId.uid, keyId.alias))
SystemLogger.debug("Deleted persisted key: $keyId") SystemLogger.debug("Deleted persisted key: $keyId")
} else { } else {
SystemLogger.warning("Failed to delete persisted key file: ${file.name}") SystemLogger.warning("Failed to delete persisted key file: ${file.name}")
@@ -158,6 +159,7 @@ object GeneratedKeyPersistence {
if (file.delete()) count++ if (file.delete()) count++
} }
} }
fileLocks.clear()
SystemLogger.info("Deleted $count persisted key files") SystemLogger.info("Deleted $count persisted key files")
}.onFailure { e -> }.onFailure { e ->
SystemLogger.error("Failed to delete all persisted keys", e) SystemLogger.error("Failed to delete all persisted keys", e)
@@ -546,6 +546,10 @@ class KeyMintSecurityLevelInterceptor(
val timestamps = uidKeygenTimestamps.computeIfAbsent(uid) { mutableListOf() } val timestamps = uidKeygenTimestamps.computeIfAbsent(uid) { mutableListOf() }
synchronized(timestamps) { synchronized(timestamps) {
timestamps.removeAll { now - it > BURST_WINDOW_MS } timestamps.removeAll { now - it > BURST_WINDOW_MS }
if (timestamps.isEmpty()) {
uidKeygenTimestamps.remove(uid, timestamps)
uidHardwareKeygenCount.remove(uid)
}
return timestamps.size return timestamps.size
} }
} }