On Dec 19 18:36, Ken Brown wrote:
> Hi Corinna,
> 
> I plan to keep working on mmap issues while you're on vacation.  A few
> questions have come up while I've been looking at the code.
> 
> 1. The function is_mmapped_region() doesn't seem to be used anywhere. Is it
> OK to remove it?

Yes.  Commit 29a126322783 ("Simplify stack allocation code in child
after fork") dropped its only usage.  I just forgot to remove
is_mmapped_region() as well.

> 2. I can't find any uses of filler pages, in spite of the comment preceding
> the definition of __PROT_FILLER.  Is it OK to remove all references to
> __PROT_FILLER and the associated methods?

Yes.  The filler pages were only used on 32 bit Windows.  This code should
have been removed when we we're going 64 bit-only.

> 3. I'm still puzzled about mmap_is_attached_or_noreserve().  See my email
> from yesterday on the cygwin ML.  I think it's broken but I may be wrong.
> If I'm right, I don't see an easy way to fix it.  As I said before, the only
> thing I can think of is to sort the mmap_list of anonymous mappings.  But
> I'm afraid that would be too expensive (in terms of time).

I copy/pasted from the cygwin ML:

===================
> I think I'm seeing a similar confusion in                                     
> mmap_is_attached_or_noreserve().  I'm tired now and am having trouble         
> sorting out exactly what that function is doing.

noreserve() pages are MAP_RESERVE pages.  Trying to read or write on them
raises a STATUS_ACCESS_VIOLATION.  The idea is basically to commit the
requested read/write region (in case of the signal: just 1 byte, which in
turn requires to commit a full page.

> But the definition of       
> commit_len looks suspicious to me.  We know from above that start_addr <=     
> u_addr. 

We do?  match() returns the intersection, independently of addr being
lower or higher than get_address().  Same goes for the length.

In case of a signal:

  start_addr is addr rounded down to the page address and len is rounded
  up to the pagesize.  So we have a single page.  rec->match() either
  returns false, or if a noreserve() record matches, it will return the
  single page in u_addr, u_len.

    commit_len = 4096 - (0x100000000 - 0x100000000) = 4096

In case we're called via fhandler_base::raw_read():

  Assuming the region to read is enclosing the noreserve() region...

  - addr = 0x100000000, len = 256K
  - rec->get_address() = 0x100010000, len = 64K

  --> start_addr = addr = 0x100000000
      len = 256K

      rec->match() returns

      u_addr = 0x100010000, u_len = 64K

      commit_len = 64K - (0x100000000 - 0x100010000)
                 = 64K - 0x0xFFFFFFFFFFFF0000
                 = 128K

      Note: commit_len is size_t, so it's unsigned!

      if (commit_len (128K) > len (256K))?  Nope!

  --> VirtualAlloc (0x100000000, 128K, MEM_COMMIT, rec->gen_protect ());

  If this VirtualAlloc fails, the process is screwed and gets a
  well-deserved SIGBUS.

I'm not saying that there's a chance I'm missing something, but
as of now, it looks ok to me.

> The only thing I can come up with immediately is that we should sort the list
> of mmap_records in order of their starting addresses.  Then if start_addr ==
> u_addr, we commit u_len bytes, otherwise we fail.

I don't understand this one.  The code loops over all records,
so where's the problem?


Thanks,
Corinna

Reply via email to