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:
@@ -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:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
+2
@@ -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)
|
||||||
|
|||||||
+4
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user