Is it possible to get rid of the zygote process?

1,978 views
Skip to first unread message

Ken Rockot

unread,
Feb 3, 2017, 8:19:42 PM2/3/17
to Chromium-dev
I'd like to better understand exactly if/why we really need the zygote process today.

Assuming we can resolve the myriad binary versioning issues around fork/exec using some other clever means (which only seems relevant on non-Chrome-OS Linux anyway), are there any other substantial benefits we get out of using a zygote such that the extra complexity is justified? e.g. anything related to sandbox setup or other security issues?

Elliott Sprehn

unread,
Feb 3, 2017, 9:02:33 PM2/3/17
to Ken Rockot, Justin Schuh, Chromium-dev
Sandbox setup is pretty expensive on all platforms, on my Mac I've seen it take up to 300ms to initialize the video toolbox and other various system services and then to enable the sandbox (parsing the sandbox policy file isn't free either).

Last I heard we were trying to add the zygote on Windows to improve tab launch performance as well.

On Feb 3, 2017 8:19 PM, "Ken Rockot" <roc...@chromium.org> wrote:
I'd like to better understand exactly if/why we really need the zygote process today.

Assuming we can resolve the myriad binary versioning issues around fork/exec using some other clever means (which only seems relevant on non-Chrome-OS Linux anyway), are there any other substantial benefits we get out of using a zygote such that the extra complexity is justified? e.g. anything related to sandbox setup or other security issues?

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Primiano Tucci

unread,
Feb 6, 2017, 9:05:38 AM2/6/17
to esp...@chromium.org, Ken Rockot, Justin Schuh, Chromium-dev
Some things on top of my head:

Security:
"sandbox" is a bit generic here. On Linux desktop there are at least two layers of sandbox that affect the zygote:
1) the bpf sandbox (the thing that filters syscalls). IIRC this one is pre-initialized in the zygote, to pay the cost of building the BPF tree once, but effectively entered in each child process after fork.
2) the namespace sandbox (The thing that isolates uid and pid namespaces).
It seems that right now the zygote takes also care of namespace bookkeeping, so I guess that you can't easily get rid of that without losing 2 (or refactoring all that outside of the zygote)

Run-time:
the zygote avoids to redo all the dynamic relocations on each renderer.
On Android the cost of relocations was in the ballpark of hundreds of ms. 
On Linux, if my ld-fo is correct:
$ LD_DEBUG=statistics /opt/google/chrome-beta/chrome --help 2>&1
     21610:
     21610: runtime linker statistics:
     21610:  total startup time in dynamic loader: 73899158 clock cycles
     21610:    time needed for relocation: 56836478 clock cycles (76.9%)
     21610:                 number of relocations: 4271
     21610:      number of relocations from cache: 11347
     21610:        number of relative relocations: 502740
     21610:   time needed to load objects: 15789844 clock cycles (21.3%)
so looks like roughly ~60 ms/GHz

On top of dynamic loading and relocations, on Linux, IIRC there is some further bootstrapping that the zygote does, amortizing the initialization cost and hence reducing the startup cost for a new renderer. If I am reading the code correctly, essentially anything that happens in ContentMainRunnerImpl::Initialize() (% exclusions based on process_type) is CoW-ed by all the zygote forks: things like loading the v8 snapshot, initializing ICU, early-initializing NSS, etc. 

Memory:
the aforementioned relocations have also a memory cost. In the case of the zygote, that cost is paid once and amortized over all the child processes.
Without the zygote, this would cost an extra ~6 MB per process:
$ readelf -WS /opt/google/chrome-beta/chrome
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
...
  [25] .data.rel.ro      PROGBITS        0000000006a8b590 6a8a590 5b5500 00  WA  0   0 16

0x5b5500  -> 5.98 MB

actual impact on memory usage
$ cat /proc/.../smaps 
7fbdd1c81000-7fbdd2233000 r--p 06a5d000 fc:00 665771                     /opt/google/chrome-unstable/chrome
...
Shared_Dirty:       5796 kB
(this would become private_dirty when dropping the zygote)

Similarly, if my reading above is correct, re-initializing v8, ICU, etc in each process will cause further memory to not be CoW-ed (hence shared) anymore.
A quick check suggests that the zygote shares ~8 MB of dirty memory with the other processes:
$ cat /proc/$PID_OF_ZYGOTE/smaps | grep Shared_Dirt | awk '{TOTAL += $2} END {print TOTAL}'
8092

Justin Schuh

unread,
Feb 6, 2017, 1:21:01 PM2/6/17
to Primiano Tucci, Elliott Sprehn, Ken Rockot, Justin Schuh, Chromium-dev
Just to tl;dr it, the zygote is a very good thing and it's not going away:
  • It's a significant optimization for renderer launch performance.
  • It reduces memory consumption.
  • It allows more aggressive securing of the process than would otherwise be possible without it.
  • Android is moving to a zygote with O and we have plans to eventually move both macOS and Windows to a zygote model as well.
Also, questions like this are better directed to securi...@chromium.org.

Ken Rockot

unread,
Feb 6, 2017, 1:27:31 PM2/6/17
to Justin Schuh, Primiano Tucci, Elliott Sprehn, Chromium-dev
Thanks to everyone in the thread for all the information. I didn't post to security-dev@ because it wasn't yet clear to me that security was one of the primary motivators for the zygote.

Note that when searching for some design or detailed technical rationale for the existence of the zygote, the only documentation I could find was this. Is there any other documentation available? What about more detailed docs/proposals regarding zygote plans for other platforms?

Primiano Tucci

unread,
Feb 6, 2017, 1:32:57 PM2/6/17
to Ken Rockot, Justin Schuh, Elliott Sprehn, Chromium-dev
There are more useful explanations in https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandboxing.md which mentions the Zygote and how it takes part in the sandboxing

"On Linux, for Chromium, this is not the point, and measurements suggest that the time and memory savings are minimal or negative."

Sadly without any reference to actual data. Some quick measurements (see my mail above) suggest that it is saving 8 MB per renderer process, which is arguably not minimal :)

Elliott Sprehn

unread,
Feb 6, 2017, 1:36:07 PM2/6/17
to Primiano Tucci, Chromium-dev, Ken Rockot, Justin Schuh
Can you fix the docs? :)

Primiano Tucci

unread,
Feb 6, 2017, 2:47:01 PM2/6/17
to Elliott Sprehn, Chromium-dev, Ken Rockot, Justin Schuh
This message was created automatically by mail delivery software.
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
 
Out of memory while processing the request

Can you fix the docs? 
I knew I should have just hit archive :P
Reply all
Reply to author
Forward
0 new messages