:On Wed, Feb 16, 2000 at 03:33:58PM -0800, Matthew Dillon wrote:
:>     Is anyone interested in me doing this for the 4.0 release?  It would
:>     help both our current threads model and the linux threads model a lot.
:>     I can do it in a day and it should be trivial to test, the modifications
:>     are actually quite minor.
:
:I would really like to see this change happen, and will happily make the
:necessary libc_r and linuxthreads changes to use the functionality, but
:we're well into the code freeze right now, which IMO makes this more
:appropriate for 4.1.
:
:Jason

    I agree that this is just a tad too complex to go into 4.0 ... the
    MAP_GUARDED implementation is trivial, I did it in a few lines of 
    code, but we don't want to accidently break threads at this late date 
    and we are in a freeze, so... we'll commit this stuff after the release.

    I've worked up a patch to add MAP_GUARDED, which I give a reference to
    below.  However, there are some issues:

        * MAP_GUARDED cannot be combined with MAP_STACK.  You have to manage
          the 'stack' resource yourself by calling getrlimit() and checking
          it, then using a normal anonymous mmap.

        * While you can use fixed addresses with MAP_GUARDED maps, if you
          use downward trending address the VM system can't coalesce the
          VM objects, so the vm_map_entry optimization will not occur.

    Here is how MAP_GUARDED works:

        mmap(NULL, len, prot, MAP_GUARDED|MAP_ANON, -1, 0);
        mmap(addr, len, prot, MAP_GUARDED|MAP_ANON|MAP_FIXED, -1, 0);

    The returned map will be 'len' bytes long.  The first and last
    page of this map will be guarded and accessing it will result in 
    a bus fault (you get a seg fault if you access totally unmapped 
    space, you get a bus fault if you access a guard page).

    So the offsets 0-4095 and len-4096 to len-1 will be guarded.

    I believe that this can be used in the current threads library
    but you have to pay attention to a couple of things:

        * First, you have to use mmap(NULL... ), allocating out of the
          normal mmap space rather then allocating out of the user
          stack space.

        * Second, remember that both the first AND the last page of
          the returned map is guarded.

        * Third, since we are not allocating out of the user stack space,
          you must call getrlimit() and manage the stack resource limit
          yourself.

          You might as well do this anyway, because MAP_STACK currently
          allows you to mmap() out-of-range stacks but then faults
          when you try to access them.  Broken!!!

        * Lastly, as with MAP_STACK, don't even try calling madvise()
          on a submap of any of these maps, nor use mmap() to submap
          any of these maps.  Both MAP_STACK and MAP_GUARDED break
          badly if you do that (MAP_STACK might even potentially crash
          the machine, but I haven't checked it deeply yet).

    I believe that I can fix the downward-trending optimization problem
    but it's more work then I have time for right now.  Please check out
    the patch and tell me what you think.

        http://www.backplane.com/FreeBSD4/
        http://www.backplane.com/FreeBSD4/guard-1.diff
        http://www.backplane.com/FreeBSD4/guard.c

    I also looked at the linux threads library.  They do guard pages
    in a way that is just as broken as the way we do them, but I'm not
    sure if there is a kernel resource issue for them.  It looks like
    it would be easy to patch the port to be optimal under FreeBSD.

                                                -Matt



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to