Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jan 1999 13:15:03 -0800 (PST)
From:      Julian Elischer <julian@whistle.com>
To:        current@FreeBSD.ORG
Subject:   [Commit RFC] More Threads patches.
Message-ID:  <Pine.BSF.3.95.990104125737.206D-100000@current1.whistle.com>

next in thread | raw e-mail | index | archive | help

There are soem more patches to make FreeBSD's thread support more real.
I would like to add these to those already committed.
Note that this functionality is also useful for FreeBSD native threading
and the native FreeBSD port of the Linuxthreads package.

The patches are a present conditional on the existance of VM_STACK
and VM_USE_STACK_FOR_EXEC and VM_USE_STACK. This provides a level of
safety to users who are not experimenting with this code by allowing
them to create kernels that are "unchanged".

The patches I propose to add are at:
http://lt.tar.com/vmsdiff
with 
further descriptions availabel at:
http://lt.tar.com/

promise to test them better this time :-)


here's the description:

Growable stack patches:

 These patches are not required but highly desirable.  Without them, each
thread consumes 2MB of virtual memory for its stack regardless of how much
it really needs. With them, each thread stack will grow (up to 2MB) only
as needed. However, they are also more adventuresome.  See the discussion
below to understand what they do.  These patches were updated December 29,
and should be fully compatible with COMPAT_LINUX_THREADS.  If you apply
these patches, they will only be turned on if you recompile your kernal
and do a "make world" with the option VM_STACK enabled.  It is suggested
that you add -DVM_STACK to both CFLAGS and COPTFLAGS in your
/etc/make.conf to accomplish this. 


Further discussion:

Growable Stack

The changes in this patch are designed to implement vm regions that can
"auto grow" as stacks.  As noted above, linux threads expects to be able
to mmap "auto grow" stacks that become the user stacks of its cloned
processes. More generally, I think any thread in FreeBSD, whether a "user
thread" or a "kernel thread" would benefit by having an auto grow stack. 
While linux does not appear to formally restrict the maximum size of its
autogrow stacks, I think a limit is highly desireable.

The concept of autogrow stacks is supported by adding a MAP_STACK flag to
the mmap call.  When mmap is called with this option, the region specified
(ie. from addr to addr+len)  is taken to be the maximum sized stack. The
top portion (SGROWSIZ) of the region is initially mapped, and then the
region can auto grow down to the bottom (represented by the addr passed in
to mmap).

This is supported by two new vm calls, vm_map_stack and vm_grow_stack in
vm_map.c.  The function "grow" is replaced by a similar function
"grow_stack" in vm_machdep.c

There are many ways to implement growable memory regions to be used as
stacks.  In fact, this is the second implemenation I have tried.  Both
appear to work, but the one listed here is better, I think.

In the current kernel, there is only one user stack recognised by the
kernel, and it is the only "auto grow" memory region.  It is created as
part of the execve call. When an rfork process is created that shares
memory with its creator, this stack region comes along as part of the
shared vmspace, and is the stack of the first process in the chain of
processes that share the vmspace.  When a rfork process is created it
needs its own user stack(if it executes in user space).  Currently the way
this is normally handled is that a fixed size memory region (created by
malloc or mmap) is created and grafted onto the rfork process with a
little userland assembly code magic.

My first implementation of an auto grow stack region involved pulling the
stack related elements out of the vmspace structure and making them part
of the proc structure, so that user stacks were related to processes and
not the (possibly shared) vmspace.  Each could have its own.  The autogrow
feature was implemented by mimicking the existing autogrow code using the
stack attributes that moved into the proc structure.  This worked fine,
and it was fairly easy to see by inspection what the code changes did.

However, in considering a threads model in which not every thread
corresponded to a kernel process of some kind, I felt that it would be
better if the autogrow feature was an attribute of the memory region
itself.  This way, "user threads", which the kernel might not know about
at all, could also have autogrow stacks.  This has been implemented by
adding an element to the vm_map_entry structure which represents the
amount the vm_map_entry could be extended downward.  Whenever a page fault
is generated that would have resulted in possible call to the existing
grow function, the adjoining vm_map_entry region is checked to see if the
region can be extended.  If so, the region is grown.

It is intended that this implementation will not change the existing
behaviour of any process unless it is an rforked process which "grafts" 
itself to a memory region mmaped with the MAP_STACK option (or unless it
is an execve'ed process that generates its user stack via vm_map_stack).
It is also intended that no memory region will be any different from the
existing code unless it is mmaped with the MAP_STACK option.  However, it
is not necessarily obvious (to me, anyway) that this is so without some
study. 

There are also two levels to the current implementation.  One one level
(if both VM_USE_STACK and VM_USE_STACK_FOR_EXEC are defined in vm_map.h) 
the vmspace stack that is normally created in the exec call uses the new
vm_map_stack call, and the region is managed by the new vm_grow_stack and
grow_stack calls.  On the second level (only VM_USE_STACK is defined) the
vm_map_stack call is only used for regions mmaped with the MAP_STACK
option.  The vmspace process stack is created as usual, and is managed by
the usual grow function. 

I hope people will study, critique and test this code.  I have run it
without problem for about 2 weeks. 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95.990104125737.206D-100000>