page_size vs allocation_granularity

Ken Brown
Wed Jul 22 18:35:05 GMT 2020

On 7/22/2020 12:42 PM, Ken Brown via Cygwin-developers wrote:
> On 7/22/2020 4:33 AM, Corinna Vinschen wrote:
>> 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.
> Here's a better reference than the one I gave in my previous reply, which 
> actually explains what's going on:
>> 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.
> So that's exactly what happens when php maps a file whose size is a multiple of 
> 4K but not a multiple of 64K.  It expects that there is a zero-filled region 
> beyond EOF that it can safely read from.

Interestingly, you mentioned exactly this scenario in 2002 as a reason for 
keeping the pagesize at 4K rather than 64K:

I have nothing new to contribute, so we should probably just drop this.  My 
curiosity has been satisfied.


More information about the Cygwin-developers mailing list