[Toybox] [PATCH] A implemetation of the 'csplit' command

Rob Landley rob at landley.net
Tue Sep 12 21:51:33 PDT 2023


On 9/12/23 14:55, enh wrote:
> On Tue, Sep 12, 2023 at 12:36 PM Rob Landley <rob at landley.net> wrote:
>> I dunno why csplit would want MAYFORK here. A normal command can just xexit()
>> and let the kernel close filehandles and free memory when the process exits. I
>> note that 95% of the overhead of fork/exec is the exec part, not the fork part,
>> so "fork and call toy_find("blah")->toy_main()" is still pretty cheap. (On
>> systems with an MMU, anyway. It's all copy on write. I'm aware Rich Felker
>> disagrees, but he's always using threads for everything, and threads have
>> _always_ combined badly with fork(). I suspect he's setting up some gratuitous
>> thread plumbing by default that he thought was free, and suddenly he noticed
>> he's penalized fork(), and now he's blaming fork(). But I haven't looked deeply
>> into the details of what he's mad about, because I dowanna. But, you know, the
>> linux-kernel guys would have NOTICED if fork() was slow. As would everybody else
>> everywhere.)
> 
> (i doubt it's him so much as people using musl in large programs. but
> the issues with fork() on large modern hardware running large modern
> programs are well known.

Which is why I switched a giant 80 thread "mono with plugins running on slow
hardware" app to use vfork() here:

  https://landley.net/notes-2018.html#26-06-2018

It's been an available optimization forever. Rich's "deprecate fork()" is
premature optimization meets defensive programming.

The people talking about using clone() like it's a new thing are basically
saying "I fear and mistrust vfork() so I'm going to call clone with the flags
that basically do vfork() but not call it that, and probably get subtle things
wrong by refusing to use the 40 year old API that works."

> https://www.microsoft.com/en-us/research/uploads/prod/2019/04/fork-hotos19.pdf

Microsoft's advice about a unix api from the Bell labs days?

> is a good recent summary, but USENIX has been talking about this stuff
> for at least 20 years.

And the solution has been known for noticeably longer than that. But doing it
everywhere always ("deprecating fork") is premature optimization meets defensive
programming.

Back when linux had the "thundering herd" problem, the kernel guys got pushed to
fix it. Back when the kernel needed an O(1) scheduler, the kernel fixed it. Back
when exit() wasn't O(1) scalabile, they fixed it:

https://www.uwsg.indiana.edu/hypermail/linux/kernel/0208.2/0528.html

And of course all the early thread work:

https://lwn.net/Articles/7577/

There's ALWAYS a scalability problem. Removing a bottleneck means something else
is now the bottleneck, by definition. There is always a slowest part, always a
part where the system is spending its time.

https://www.networkworld.com/article/2298002/kernel-space--linux-runs-into-a-scalability-problem.html

People going "we've found cases where fork() is a bottleneck: don't fix it,
abandon it". (Why are the page faults de-cowing a page at a time instead of a
mapping at a time?)

> macOS implements posix_spawn() as a syscall.
> linux still seems to be on the clone() and close_range() path of
> hacks.)

Linux is a unix. Unix has been doing it that way for 50 years, and took over the
world by doing that, so obvious it could never possibly have worked. Meanwhile
DOS and windows only ever had a spawn not a fork, and solaris had an insanely
expensive fork (which is why they thought threads were a good idea...

Sigh, Rich loved posix_spawn() and said everyone should move to it back when I
was still doing busybox. This is not an "I've evaluated new information and come
to a decision", this is someone reasserting their prior belief again. (The
refusal to yank fork() from nommu builds and instead include a version that
returns -ENOSYS at run time is a symptom of this. Having a known broken fork()
in some builds makes him happy.)

Rob


More information about the Toybox mailing list