:
:> ...
:> Resource limits are still an issue. It turns out that the
:> MAP_STACK code does not deal with the stack resource limit
:> well at all -- sometimes it catches it, sometimes it doesn't.
:
:In what sense? My recollection is that resource limits are
:enforced on the "regular" process stack but not (except
:perhaps by accident of placement) on other stacks, such as
:those created by pthreads.
It's because the threads library is allocating the thread
stacks *ON* the user stack. Stacks created with MAP_STACK,
including the user stack, are not entirely reserved at
creation time. So if you have an 8m stack resource limit
your user stack is actually only as large (growing from the
top down) as the lowest address you have yet allocated from
it.
The kernel can't tell the difference between the default
user stack and new MAP_STACK stacks the threads library
allocates when they fall within the resource limit.
On the otherhand if you mmap a stack well outside the resource
limit, the kernel doesn't care either.
It's only when you try to 'grow' a stack (any MAP_STACK stack)
that is sitting within the resource such that it would grow
beyond the resource limit that an error is generated.
:At a higher level, it's not been obvious to me how the resource limit
:on stack size should be interpreted in a multithreaded program. In
:other words, I don't see one interpretation as obviously best, much
:less correct. At least three possibilies are:
:
:1. It represents the maximum size of the "legacy" process stack
:and nothing else, which is what the code currently implements.
:(pthreads stacks are bounded by other means.)
:
:2. It represents the maximum size of each and every stack, whether
:it's the "legacy" process stack or for example a pthreads stack.
:
:3. It represents the sum of the size of all of the stacks.
:
:There are problems/drawbacks to each and every possibility.
:
:So, in conclusion, I think the first order of business is
:to determine what semantics (1) there may be good precedent
:for and (2) that threads programmers are comfortable with.
:
:Alan
I think the issue is plain and simply that our implementation
is broken. I think the resource limit should only apply to
the main user stack and not to any old MAP_STACK one happens
to mmap().
Thread stacks should not in any way fall under the system
stack resource. It just doesn't apply.
I also think that a single guard page at the base of the
stack may be insufficient for some applications. I'm
considering adding yet another field to vm_map_entry
'vm_pindex_t guard_pages' which allows the number of
guard pages to be specified (we can use mmap()'s offset
argument to pass the parameter).
I also think we should get rid of the avail_ssize
field in vm_map_entry and instead simply have a flag
for the main user stack's vm_map_entry that allows it
to grow downward to be sized up to the resource limit in
size.
Should the resource limit apply to any MAP_STACK mapping
(separately and independantly)? Yes, I think so. It
shouldn't matter at all for threads but I can see using
MAP_STACK mmaping's to dynamically load programs and run
them (rather then fork/exec), in certain cases.
What do you think? The above changes would be easy to
add, I've already done the hard work of optimizing the
VM system.
-Matt
Matthew Dillon
<[EMAIL PROTECTED]>
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message