Preallocate host kernel FD table before Sentry boot.
This avoids an expensive RCU stall during the Sentry boot process, when
the Linux-side FD table needs to be expanded to accommodate the Sentry's
512-sized FD table.
The kernel imposes an RCU stall when this occurs for
multithreaded programs (which all Go programs are), but not
single-threaded ones. Hence the introduction of a minimal C binary that
does the magic. There is some storytime explanation in the C source
file itself.
Even though this is an extra `exec` in the hot startup path, the
benefits are obvious:
```
runsc do /bin/true:
│ A (baseline) │ B (prewarmer) │
RunscDo 202.8m ± 3% 147.1m ± 5% -27.45% (n=100)
docker run --rm alpine true:
│ A (baseline) │ B (prewarmer) │
DockerRunStartup 778.9m ± 2% 738.0m ± 2% -5.25% (p=0.000 n=100)
OCi operations ("total" = create + start + wait + delete):
│ A (baseline) │ B (prewarmer) │
OCICreate 145.6m ± 5% 102.3m ± 8% -29.71% (n=100)
OCIReady 165.8m ± 4% 122.6m ± 6% -26.10% (n=100)
OCITotal 178.6m ± 3% 138.3m ± 5% -22.59% (n=100)
```
I also reduced the Sentry's FD table to 256 rather than 512, which saves
one or two pages of host kernel memory per sandbox instance.
Also threw in a test to make sure the C program remains
single-page-sized to avoid potential unintended bloating down the line. E
Etienne Perot committed
0bb1666bb7f07744c7bf129dcb72ec7c508ee940
Parent: 5ceb9a5