page_size vs allocation_granularity

Corinna Vinschen
Wed Jul 22 08:33:27 GMT 2020

On Jul 21 18:40, Ken Brown via Cygwin-developers wrote:
> Hi Corinna,
> I'm curious about the design decision that causes sysconf(_SC_PAGESIZE) to
> return wincap.allocation_granularity() rather than wincap.page_size().
> Changing this would improve Linux compatibility, I think, but maybe it would
> have some bad consequences that I'm not aware of.

It was a long and hard process to move from 4K to 64K pagesize, with
lots of loaded discussions.  The Cygwin mailing list archives will
show a lot of this in the 200X years.

It was the only way to make mmap 99% POSIX-conformant.  Consider, for
instance this:

  pagesize = sysconf(_SC_PAGESIZE);
  addr = mmap (NULL, pagesize, PROT_READ | PROT_WRITE,
	       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  addr2 = mmap (addr + pagesize, pagesize, PROT_READ | PROT_WRITE,

On Windows, this fails with pagesize = 4K, but it works with pagesize =
64K, because of that idiotic Windows allocation granularity.  Almost
all POSIX expectations are automagically fixed by using the granularity
as pagesize in a POSIX sense.

There's only one problem left:  While you can only allocate usefully in
64K steps, the size of the memory area allocated for a file is only 4K
aligned, thus leaving the remainder of the 64K block unmapped. 

This problem could be fixed back in 32 bit times by adding the
AT_ROUND_TO_PAGE mapping.  Very unfortunately, the 64 bit Windows
designer decided to keep the braindead 64K allocation granularity
but to drop the AT_ROUND_TO_PAGE flag, thus removing the only chance
to make this single situation POSIX-compatible as well.

> I'm asking because in my recent fooling around with php, I noticed that
> Yaakov had to apply the following Cygwin-specific patch to avoid a crash:

It would be nice to learn what kind of crash that was.

If php reads or writes in the remainder of the block constituting EOF,
or tries to change page protection, shit happens.  Every time, a process
stabs into the EOF block following the last valid 4K block, it results
in a STATUS_ACCESS_VIOLATION which in turn calls
mmap_is_attached_or_noreserve().  While this situation can be
recognized, I don't see a way to fix this from the processes POV.


Corinna Vinschen
Cygwin Maintainer

More information about the Cygwin-developers mailing list