Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-117755: Fix mimalloc for huge allocation on s390x #117809

Merged
merged 2 commits into from
Apr 16, 2024

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Apr 12, 2024

Fix mimalloc allocator for huge memory allocation (around 8,589,934,592 GiB) on s390x.

  • Abort allocation early in mimalloc if the number of slices doesn't fit into uint32_t, to prevent a integer overflow (cast 64-bit size_t to uint32_t).
  • Add test_large_alloc() to test_bigaddrspace.
  • Reenable test_maxcontext_exact_arith() of test_decimal on s390x.

@vstinner
Copy link
Member Author

cc @brandtbucher @colesbury @corona10

See #117755 (comment) for the rationale for this fix.

The current https://github.com/microsoft/mimalloc upstream doesn't seem to have the concept of "slices" in mi_page_t anymore. I don't know if it's still affected by issue gh-117755 bug, but this change includes a regression test in test_bigaddrspace so we will catch such bug quicker. I cannot report the issue to mimalloc upstream since the code changes: there are no "slices" anymore (upstream is not affected by this exact bug anymore).

@colesbury
Copy link
Contributor

The current https://github.com/microsoft/mimalloc upstream doesn't seem to have the concept of "slices" in mi_page_t anymore.

They are still there. The branches are a bit confusing. dev-slice is the development branch for mimalloc 2.x.

Copy link
Contributor

@colesbury colesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should report and fix the uint32_t overflow, but I don't think we should be adding more tests that try to allocate huge amounts of memory. Especially with Linux's OOM killer, we are only setting ourselves up for more problems

@colesbury
Copy link
Contributor

I filed an issue upstream: microsoft/mimalloc#876

Fix mimalloc allocator for huge memory allocation (around
8,589,934,592 GiB) on s390x.

* Abort allocation early in mimalloc if the number of slices doesn't
  fit into uint32_t, to prevent a integer overflow (cast 64-bit
  size_t to uint32_t).
* Add test_large_alloc() to test_bigaddrspace (test skipped on 32-bit
  platforms).
* Reenable test_maxcontext_exact_arith() of test_decimal on s390x.
* Reenable test_constructor() tests of test_io on s390x.
@vstinner
Copy link
Member Author

For now, I skipped the 3 test_io tests on s390x impacted by the bug: #117801 (merged). I rebased this PR on top of it to reenable these 3 test_io tests.

@vstinner
Copy link
Member Author

I filed an issue upstream: microsoft/mimalloc#876

I proposed a fix upstream: microsoft/mimalloc#877

@vstinner
Copy link
Member Author

@colesbury: Would it be acceptable to have this downstream change for now?

I suppose the mimalloc upstream cares less about Linux s390x than Python (which has Linux s390x CIs: buildbots), and it may take a few weeks to get the fix merged upstream. At least, I already proposed the fix upstream.

Copy link
Contributor

@colesbury colesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mimalloc changes look good to me.

I'm not thrilled with the test_large_alloc test. If mimalloc fixes the bug by making the slice count 64-bits, then we'll run into problems. It strikes me as another problematic test that makes too many assumptions and won't provide enough value in terms of catching actual bugs.

I feel the same way about the test_constructor tests. We are skipping these tests on sanitizers, 32-bit builds, and previously on s390x. That's a sign that they are unreliable tests. We should get rid of them! Unreliable tests are worse than no test.

@vstinner
Copy link
Member Author

vstinner commented Apr 16, 2024

I'm not thrilled with the test_large_alloc test. If mimalloc fixes the bug by making the slice count 64-bits, then we'll run into problems.

Let me try with uint64_t... :-) In short, the Linux s390x kernel doesn't kill the process allocating an insane amount of memory. I didn't check if the process is killed later with Out Of Memory (OOM) since I tested on a shared machine.

The kernel is fine with a process allocating 822368422110644 kB of data. The strange part is "VmPTE: 26876 kB": I expected way more. I don't know which page size is used for the large allocation.

Command:

gdb -args ./python -m test test_bigaddrspace -u all -v

gdb:

(gdb) py-bt
Traceback (most recent call first):
  File "/root/vstinner/cpython/Lib/test/test_bigaddrspace.py", line 99, in allocate
    return b'x' * length
  File "/root/vstinner/cpython/Lib/test/test_bigaddrspace.py", line 113, in test_large_alloc
    allocate(size)
(...)

(gdb) where
#0  0x000003fffdaa38f0 in __memset_mvcle () from /lib64/libc.so.6
#1  0x00000000010ce708 in _PyBytes_Repeat (
    dest=0x5bf70010030 'x' <repeats 200 times>..., 
    len_dest=842105263157894695, src=0x5bf31174330 "x", len_src=1)
    at Objects/bytesobject.c:3640
#2  0x00000000010c9e3a in bytes_repeat (a=0x5bf31174300, n=842105263157894695)
    at Objects/bytesobject.c:1484
(...)

(gdb) frame 1
(gdb) p len_dest
$1 = 842105263157894695
(gdb) p/x len_dest
$2 = 0xbafc24672035e27

Process:

# grep ^Vm /proc/2070842/status
VmPeak:	822368422334080 kB
VmSize:	822368422334080 kB
VmLck:	       0 kB
VmPin:	       0 kB
VmHWM:	 7319628 kB
VmRSS:	 7086188 kB
VmData:	822368422110644 kB
VmStk:	     388 kB
VmExe:	    6576 kB
VmLib:	    3624 kB
VmPTE:	   26876 kB
VmSwap:	 6529488 kB

# free -m
              total        used        free      shared  buff/cache   available
Mem:           7782        7355         102         183         324         129
Swap:          8167        6723        1444

The quantity of Swap is growing slowly... I stopped the process before most Swap was used...

vstinner added a commit to vstinner/cpython that referenced this pull request Apr 16, 2024
Remove unreliable tests on huge memory allocations:

* Remove test_maxcontext_exact_arith() of test_decimal.
  Stefan Krah, test author, agreed on removing the test:
  python#114331 (comment)
* Remove test_constructor() tests of test_io.
  Sam Gross suggests remove them:
  python#117809 (review)

On Linux, depending how overcommit is configured, especially on Linux
s390x, a huge memory allocation (half or more of the full address
space) can succeed, but then the process will eat the full system
swap and make the system slower and slower until the whole system
becomes unusable.

Moreover, these tests had to be skipped when Python is built with
sanitizers.
@vstinner
Copy link
Member Author

I'm fine with removing these tests: I created PR gh-117938 for that.

@vstinner
Copy link
Member Author

I modified this PR to restrict it to the Objects/mimalloc/segment.c change and leave tests unchanged.

Copy link
Contributor

@colesbury colesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! I've also added the PR to my tracking issue in #113141

@vstinner vstinner enabled auto-merge (squash) April 16, 2024 16:40
vstinner added a commit that referenced this pull request Apr 16, 2024
Remove unreliable tests on huge memory allocations:

* Remove test_maxcontext_exact_arith() of test_decimal.
  Stefan Krah, test author, agreed on removing the test:
  #114331 (comment)
* Remove test_constructor() tests of test_io.
  Sam Gross suggests remove them:
  #117809 (review)

On Linux, depending how overcommit is configured, especially on Linux
s390x, a huge memory allocation (half or more of the full address
space) can succeed, but then the process will eat the full system
swap and make the system slower and slower until the whole system
becomes unusable.

Moreover, these tests had to be skipped when Python is built with
sanitizers.
@vstinner vstinner merged commit 3fe03cc into python:main Apr 16, 2024
36 checks passed
@vstinner vstinner deleted the mimalloc_s390x branch April 16, 2024 20:34
diegorusso pushed a commit to diegorusso/cpython that referenced this pull request Apr 17, 2024
Remove unreliable tests on huge memory allocations:

* Remove test_maxcontext_exact_arith() of test_decimal.
  Stefan Krah, test author, agreed on removing the test:
  python#114331 (comment)
* Remove test_constructor() tests of test_io.
  Sam Gross suggests remove them:
  python#117809 (review)

On Linux, depending how overcommit is configured, especially on Linux
s390x, a huge memory allocation (half or more of the full address
space) can succeed, but then the process will eat the full system
swap and make the system slower and slower until the whole system
becomes unusable.

Moreover, these tests had to be skipped when Python is built with
sanitizers.
diegorusso pushed a commit to diegorusso/cpython that referenced this pull request Apr 17, 2024
…7809)

Fix mimalloc allocator for huge memory allocation (around
8,589,934,592 GiB) on s390x.

Abort allocation early in mimalloc if the number of slices doesn't
fit into uint32_t, to prevent a integer overflow (cast 64-bit
size_t to uint32_t).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants