7-Zip Open Discussion: Windows 10 works incorrectly with Large Memory Pages (2 MB)

6 min read Original article ↗

Windows 10 works incorrectly with Large memory pages (2 MB)

This message contains information about very critical problem in some versions of Windows.
If you have any contacts with Microsoft, please notify them about this problem. Also ask Microsoft to provide information what versions affetced by that BUG, and

Now we have the following information about different Windows 10 versions:
1511 - maybe OK
1607 - maybe OK
1703 - ERROR
1709 - ERROR - including latest version 16299.371 - April 2018 Cumulative
1803 - maybe OK - but we need more tests
1809 - maybe OK

These results are not final. And we need more tests in different versions of Windows, including version 1803 (17133/17134) - Windows 10 Spring Creators Update - Redstone 4.

Description of problem

Windows supports small (4 KB) pages and large (2 MB) memory pages.
Most of programs use only 4 KB pages. And it works correctly. So there is no any problem for most programs.
But there is Windows API that allows to use 2 MB pages. And 7-Zip uses that API, if special "Large pages mode" option is enabled in 7-Zip settings.
When 7-Zip uses 2 MB pages, 7-Zip can work incorrectly, or Windows system can crash.

How to reproduce the problem

NOTE:
If you use "Large Pages" now, your system can work incorrectly and you can lose some data.
DON'T TRY IT, if you don't want to take these RISKS.
If you use "Large Pages", your system can be in CORRUPTED STATE, and you MUST REBOOT after each experiment to reduce the risk to lose your data.

1) "Large Pages" feature requires special "LockMemory" privilege.
So you need to run 7-Zip File Manager with administrator rights at least once and reboot system after that. Then you can use "large pages" without administrator rights in Windows 10.
But some previous versions of Windows require administrator rights also for programs that just use "large pages".

2) The commands with "Large Pages" for crash:
7-Zip 18.01 (x86 or x64):

7zG b -mmt1 -slp -md21
7z b -mmt1 -slp -md19 -bt 10 >19.txt 2>19_2.txt
7z b -mmt1 -slp -md22 -bt 10 >22.txt 2>22_2.txt

If you use Windows 7, you must call these commands with administator rights. So create bat files and run them with administator rights.

If 7-Zip benchmark works incorrectly with large pages, you can get
- "Decoder error" message
- 7-Zip program crash
- Windows system crash

When you run these benchmark commands, you can see "LP" string in "Memory usage" values.
It means that 7-Zip uses "Large Pages".
If you don't see "LP", then probably you have no rights to use "Large Pages".

For 7-Zip users:
If you are ready to test it, please call those benchmark commands and write report here in this forum thread:
1) Exact windows version. You can call "Run" (Windows+R): "winver" to get version number.
2) Exact name of CPU
3) If there are no errors for commands, then show 22.txt
4) If there is any error/crash, write about that error
5) REBOOT YOUR SYSTEM after commands to flush possible system corruptions.

We need to get answers for the following questions:
1) what Windows versions (and revisions) are affected with that problem?
2) what Windows versions allow to use "Large Pages" without administrator rights?
3) what another programs also use "Large Pages"? And are there any reports about problems with these programs?

Notes

There are no error reports for Windows 7 still.
Now we have error reports for Windows 10 only.

Also there were similar error reports in May-June 2017 for old revisions of Windows 10 (Version 1703). So probably it is not new BUG of latest Windows patches. And Windows 10 contains that BUG for one year at least.
If you have test systems with all Windows 10 revisions, please check all of them. But check that you see "LP" string in "Memory Usage" string in tests.

For 7-Zip users

It's recommended to switch off the option "Use large memory pages" in 7-Zip / Tools / Options / Settings, if you switched it before.

The confirmation about Windows BUG in another program

There is another program that also uses large pages - VapourSynth - http://www.vapoursynth.com/
And they also know about that BUG with large pages.

There is some code in VapourSynth that works with these bad cases:

https://github.com/vapoursynth/vapoursynth/blob/master/src/core/vscore.cpp

static bool isWindowsLargePageBroken() {
    // A Windows bug exists where a VirtualAlloc call immediately after VirtualFree
    // yields a page that has not been zeroed. The returned page is asynchronously
    // zeroed a few milliseconds later, resulting in memory corruption. The same bug
    // allows VirtualFree to return before the page has been unmapped.

Technical description

7-Zip benchmark allocates 2 (two) buffers of large pages.
Then probably it still can work OK.
But 7-Zip or system can work incorrectly after Free() operations.
It's possible that it still can work correctly, if we allocate only 1 (one) buffer with large pages.

If VapourSynth's description is correct, it can work so:
1) 7-Zip allocates large pages with VirtualAlloc(MEM_LARGE_PAGES) - OK.
2) 7-Zip asks to free large pages with VirtualFree().
3) Windows puts large pages to some queue for asynchronous filling with zeros. But Windows allows another VirtualAlloc() calls to get these pages.
4) 7-Zip, some another program or Windows calls VirtualAlloc(),
(it can be 4 KB pages or 2 MB pages). And Windows sometimes can return same pages, that are still in queue for ZEROing. So we can get situation where two different virtual addresses links to one physical space.
5) 7-Zip (or Windows) try to use new allocated virtual pages.
6) Windows asynchronously fills old 2 MB physical pages with zeros.
7) 7-Zip (or Windows) don't expect that data in allocated pages can be asynchronously changed by another process, so 7-Zip (or Windows) can crash.

VapourSynth's source code uses some workaround with Sleep() function after VirtualFree(). But actually it can help, if same application tries to allocate memory after VirtualFree(). But what about another applications or system? They also can get these "bad" physical pages after VirtualFree(). So VapourSynth's workaround will not work in that case?