RE: A good reason to use vfork()

David Schwartz (davids@webmaster.com)
Wed, 3 Nov 1999 01:17:36 -0800


Okay, first, assume that 'vfork' on Linux is never going to do anything but
copy-on-write. If we make 'vfork' keep only a single shared set of pages,
the rest of this argument melts away. (If we're going to have a 'vfork' that
isn't identical to 'fork', this is the right way, more or less.)

Assume also that overcommitting is turned off. If overcommitting is turned
on, it's perfectly fine to let a 'fork'/'vfork' succeed even if later on we
might not have enough pages.

Given these two assumptions, I believe it is disastrous to allow 'vfork' to
succeed if there aren't enough swap pages to back every single copy-on-write
page. The problem is, this could get us into an overcommit situation later
on down the line (when another process dirties a shared page after this one
already has), and it may not be possible to kill this particular process at
that particular time, forcing us to kill an innocent process due to memory
exhaustion.

If overcommitting has been turned off, that should be that.,

DS

> David Schwartz writes:
> > I don't follow you. Are you saying that a kernel that would fail a fork
> > should allow a vfork to succeed?
>
> In some cases, yes.
>
> > Even when it has no idea how much
> > additional memory the process that completes the 'vfork' might need?
> >
> > Consider:
> >
> > vfork();
> > execl(GetExecutableName(),...);
> >
> > Who knows how many pages 'GetExecutableName' might alter?
>
> Absolutely correct. For this and other reasons, doing a lot of work
> between vfork() and execve() (et al) is generally a BAD IDEA.
>
> It would be better to write something like:
>
> char *exeFile= GetExecutableName();
> if (!vfork()) {
> execl(exeFile, ...);
> }
>
> As soon as any of the execve(2) family succeeds, the child is no longer
> sharing memory with the parent and altering pages is no longer an issue.
>
> > If there is enough virtual memory to allow a vfork to succeed there is
> > enough to allow a fork to succeed.
>
> True, but this isn't always desirable.
>
> > Overcommitting is either on or it's off.
>
> Right. For several UNIXen, vfork() == overcommit, fork() ==
> no-overcommit.
>
> Each behavior is useful in the right situation. Both situations may arise
> in the same executable, e.g., a forking server that prints using
> relatively
> small external filters like ghostscript. Having both overcommit and
> no-overcommit behaviors available simultaneously is very useful -- as
> opposed to a global switch applied to everything.
>
> I'm not about to argue that vfork()/fork() is the best way to accomplish
> this. I'm only pointing out that this is *one* way, that it already
> happens to work on several UNIXen, and that it is a natural consequence of
> BSD's classic vfork() behavior (no page copies ever) combined with a
> copy-on-write fork().
>
> Chuck

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/