perf: stop proot's kompat from trapping futex/epoll/fcntl and stripping the vDSO when only the hostname changes

This commit is contained in:
xXJsonDeruloXx committed 2026-09-29 14:39:53 -04:00
1 parent b1bb767c65
commit 4f14d396bc
2 files changed
+75

No files matched your search

+11
View File
@@ -44,3 +44,14 @@ Ported from WinNative (`main`, 53836ca9, "Fix/performance and vac"):
- `0009-tracee-relatives-sweep.patch` - tracees count their children, so a terminating thread
with no children or ptracees no longer walks every tracee; the per-stop memory collector is
emptied instead of freed and reallocated.
Added by DroidDeck:
- `0011-kompat-utsname-only.patch` - `--kernel-release` (the guest's `DroidDeck` hostname) loads
kompat, whose filter traps `futex`, `fcntl`, `epoll_pwait`, `pselect6`, `pipe2`, `eventfd2`,
`socket` and more, and which strips `AT_SYSINFO_EHDR` on every `execve`, so glibc runs without
the vDSO. When the virtual release is not older than the real kernel and the hwcap is left
alone, every one of those handlers is a no-op: kompat now traces only `uname`, `sethostname`
and `setdomainname` and leaves the auxv as the kernel wrote it. On an SD 8 Gen 2 guest this
took a futex ping-pong from 467 to 97 us, `epoll_pwait` from 60 to 0.8 us and `fcntl` from
40-107 to 0.4 us, and `clock_gettime` back to the vDSO.
@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DroidDeck <droiddeck@users.noreply.github.com>
Date: Tue, 29 Sep 2026 00:00:00 +0000
Subject: [PATCH] kompat: only trace the utsname calls when no older kernel is
emulated
---
src/extension/kompat/kompat.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/src/extension/kompat/kompat.c b/src/extension/kompat/kompat.c
index 5c39942..4cb7dec 100644
--- a/src/extension/kompat/kompat.c
+++ b/src/extension/kompat/kompat.c
@@ -985,6 +985,29 @@ static FilteredSysnum filtered_sysnums[] = {
FILTERED_SYSNUM_END,
};
+/* When the virtual kernel is not older than the actual one and the
+ * hwcap is left alone, the only thing left to emulate is the utsname
+ * itself: every other handler above returns without a change. */
+static FilteredSysnum utsname_only_sysnums[] = {
+ { PR_setdomainname, FILTER_SYSEXIT },
+ { PR_sethostname, FILTER_SYSEXIT },
+ { PR_uname, FILTER_SYSEXIT },
+ FILTERED_SYSNUM_END,
+};
+
+/**
+ * Return whether @config only renames the kernel identity (nodename,
+ * domainname, version string) without emulating an older kernel or
+ * another hwcap, in which case futex, fcntl, epoll_pwait, ... don't
+ * have to stop in the tracer and the vDSO can be left in place.
+ */
+static bool utsname_only(const Config *config)
+{
+ return config->actual_release != 0
+ && config->virtual_release >= config->actual_release
+ && config->hwcap == (word_t) -1;
+}
+
/**
* Handler for this @extension. It is triggered each time an @event
* occured. See ExtensionEvent for the meaning of @data1 and @data2.
@@ -1007,7 +1030,9 @@ int kompat_callback(Extension *extension, ExtensionEvent event,
if (status < 0)
return -1;
- extension->filtered_sysnums = filtered_sysnums;
+ extension->filtered_sysnums = utsname_only(config)
+ ? utsname_only_sysnums
+ : filtered_sysnums;
return 0;
}
@@ -1038,7 +1063,7 @@ int kompat_callback(Extension *extension, ExtensionEvent event,
/* Note: this can be done only before PRoot pushes the
* load script into tracee's stack. */
- if ((int) result >= 0 && sysnum == PR_execve)
+ if ((int) result >= 0 && sysnum == PR_execve && !utsname_only(config))
adjust_elf_auxv(tracee, config);
return 0;
}