martinus
commented at 4:25 pm on November 19, 2023:
contributor
The class CTxOut has a member CAmount which is an int64_t, and on ARM 32bit int64_t are 8 byte aligned, which is larger than the pointer alignment of 4 bytes.
So for CCoinsMap to be able to use the pool, we need to use the alignment of the member instead of just alignof(void*).
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
DrahtBot added the label
UTXO Db and Indexes
on Nov 19, 2023
mzumsande
commented at 5:14 pm on November 19, 2023:
contributor
The pattern of alignof(void*) was used in 3 places in #25325 (also bench and tests) - looks like those other spots could be changed as well? (just a superficial observation, I didn’t review that PR)
fanquake added this to the milestone 26.0
on Nov 19, 2023
hebasto
commented at 5:30 pm on November 19, 2023:
member
The pattern of alignof(void*) was used in 3 places in #25325 (also bench and tests) - looks like those other spots could be changed as well? (just a superficial observation, I didn’t review that PR)
Test doesn’t fail now. Maybe replace int with int64_t?
martinus
commented at 5:40 pm on November 19, 2023:
contributor
The pattern of alignof(void*) was used in 3 places
Thanks, I forgot about these… I’ll change the PoolAllocator to default to the alignment of the given type, that makes much more sense and reduces the code.
Test doesn’t fail now. Maybe replace int with int64_t?
Good idea, I’ll change that too
pool: make sure PoolAllocator uses the correct alignment
This changes the PoolAllocator to default the alignment to the given type. This makes the code simpler, and most importantly
fixes a bug on ARM 32bit that caused OOM: The class CTxOut has a member CAmount which is an int64_t and on ARM 32bit int64_t
are 8 byte aligned which is larger than the pointer alignment of 4 bytes. So for CCoinsMap to be able to use the pool, we
need to use the alignment of the member instead of just alignof(void*).
ce881bf9fc
martinus force-pushed
on Nov 19, 2023
hebasto
commented at 6:08 pm on November 19, 2023:
member
Concept ACK.
pinheadmz
commented at 7:19 pm on November 19, 2023:
member
concept ACK
running this branch on my RPi same as #28718 (comment) will update
sipa
commented at 7:28 pm on November 19, 2023:
member
utACK486c2916a18b56d6011117077d906c1f8a81623f
DrahtBot requested review from pinheadmz
on Nov 19, 2023
DrahtBot requested review from hebasto
on Nov 19, 2023
pinheadmz
commented at 0:44 am on November 20, 2023:
member
Up to height 376554 now which is way further than I crashed at on 26rc2. htop says RAM is only about 890MB used. Are there any RPCs I should check?
maflcko added the label
Needs backport (26.x)
on Nov 20, 2023
hebasto approved
hebasto
commented at 9:39 am on November 20, 2023:
member
ACK486c2916a18b56d6011117077d906c1f8a81623f, tested on ARM 32-bit (ODROID-HC1 + Armbian 23.8.3 jammy) both native and Guix binaries.
The first commit should not introduce any behaviour change in any other release platforms as they are 64-bit and it holds that alignof(T) == alignof(void*) == 8 for all of them.
I agree with the second commit diff. It indeed handles the case where “int64_t is aligned to 8 bytes but void* is aligned to 4 bytes”. But, due do its design flaw, the test still not failing in such a case, i.e., on ARM 32-bit, if the first commit were reverted. I believe that the reason of that is the test does not cover cases where IsFreeListUsable returns false only due to the alignment <= ELEM_ALIGN_BYTES condition fails while the bytes <= MAX_BLOCK_SIZE_BYTES condition still holds. It can be improved in a follow up.
nit: The 486c2916a18b56d6011117077d906c1f8a81623f commit message has a stray substring in the end.
Suggesting for backporting to the 26.x branch. EDIT: nm, already tagged :)
martinus
commented at 10:24 am on November 20, 2023:
contributor
@pinheadmz I don’t think there’s a need to test any any RPC calls, if sync doesn’t go OOM it means it is now working :)
pinheadmz
commented at 3:16 pm on November 20, 2023:
member
confirmed unit passes on arm32 but also passes without the actual bugfix commit. so effectively this on top of d752349029:
0commit 2c7f49e83a5d05a5ba8b29d52108c14bf4d65af7 1Author: Martin Leitner-Ankerl <martin.ankerl@gmail.com>
2Date: Sun Nov 19 18:43:15 2023 +0100
3 4 pool: change memusage_test to use int64_t
5 6 If alignment of the PoolAllocator would be insufficient, then the test would fail. This also catches the issue with ARM 32bit, where int64_t is aligned to 8 bytes but void* is aligned to 4 bytes.catches cause the ARM 32bit tests to fail when a
7 8diff --git a/src/test/pool_tests.cpp b/src/test/pool_tests.cpp
9index 8a07e09a44..9590f80a33 100644
10--- a/src/test/pool_tests.cpp
11+++ b/src/test/pool_tests.cpp
12@@ -156,21 +156,21 @@ BOOST_AUTO_TEST_CASE(random_allocations)
1314 BOOST_AUTO_TEST_CASE(memusage_test)
15 {
16- auto std_map = std::unordered_map<int, int>{};
17-
18- using Map = std::unordered_map<int,
19- int,
20- std::hash<int>,
21- std::equal_to<int>,
22- PoolAllocator<std::pair<const int, int>,
23- sizeof(std::pair<const int, int>) + sizeof(void*) * 4,
24+ auto std_map = std::unordered_map<int64_t, int64_t>{};
25+
26+ using Map = std::unordered_map<int64_t,
27+ int64_t,
28+ std::hash<int64_t>,
29+ std::equal_to<int64_t>,
30+ PoolAllocator<std::pair<const int64_t, int64_t>,
31+ sizeof(std::pair<const int64_t, int64_t>) + sizeof(void*) * 4,
32 alignof(void*)>>;
33 auto resource = Map::allocator_type::ResourceType(1024);
3435 PoolResourceTester::CheckAllDataAccountedFor(resource);
3637 {
38- auto resource_map = Map{0, std::hash<int>{}, std::equal_to<int>{}, &resource};
39+ auto resource_map = Map{0, std::hash<int64_t>{}, std::equal_to<int64_t>{}, &resource};
4041 // can't have the same resource usage
42 BOOST_TEST(memusage::DynamicUsage(std_map) != memusage::DynamicUsage(resource_map));
hebasto
commented at 3:53 pm on November 20, 2023:
member
If anyone consider the second commit as a blocker, it might be dropped from this PR, no?
pool: change memusage_test to use int64_t, add allocation check
If alignment of the PoolAllocator would be insufficient, then the test would fail. This also catches the issue with ARM 32bit,
where int64_t is aligned to 8 bytes but void* is aligned to 4 bytes. The test adds a check to ensure the pool has allocated
a minimum number of chunks
d5b4c0b69e
martinus force-pushed
on Nov 20, 2023
martinus
commented at 4:14 pm on November 20, 2023:
contributor
I’ve updated the test in the PR, this time I think it should have caught the issue. It should be reproducible by adding an alignof(void*) back as the PoolAllocator’s last template argument
hebasto
commented at 4:36 pm on November 20, 2023:
member
A failure in the “Win64 native, VS 2022” CI job is unrelated. See: #28905.
theStack
commented at 5:35 pm on November 20, 2023:
contributor
Using the emulated 32-bit ARM machine using qemu and Debian bookworm for armhf,
I could both reproduce issue #28906 on master and verify the fix in this PR. Having 2GB of RAM available without swap memory, bitcoind failed due to OOM on block height 322923 on the master branch, as the coins flush never happened up to that height due to an underestimation of the cache size. On the PR branch, the flushes happen regularly before that height as expected, and the RAM usage never exceeds 0.9 GB.
The code looks correct and as mentioned by hebasto above, shouldn’t have any effect on the other architectures (all of them being 64-bit) that we support.
I also verified that the modified memusage_test succeeds on the PR branch and fails if cherry-picked on master.
Thanks for the fix!
DrahtBot requested review from pablomartin4btc
on Nov 21, 2023
fanquake merged this
on Nov 22, 2023
fanquake closed this
on Nov 22, 2023
fanquake removed the label
Needs backport (26.x)
on Nov 22, 2023
fanquake
commented at 11:33 am on November 22, 2023:
member
This is a metadata mirror of the GitHub repository
bitcoin/bitcoin.
This site is not affiliated with GitHub.
Content is generated from a GitHub metadata backup.
generated: 2024-12-21 15:12 UTC
This site is hosted by @0xB10C More mirrored repositories can be found on mirror.b10c.me