-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
memory.cc: fix cross-shard shrinking realloc #2217
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,10 +20,12 @@ | |
*/ | ||
|
||
#include <seastar/core/memory.hh> | ||
#include <seastar/core/shard_id.hh> | ||
#include <seastar/core/smp.hh> | ||
#include <seastar/core/temporary_buffer.hh> | ||
#include <seastar/testing/perf_tests.hh> | ||
#include <seastar/testing/test_case.hh> | ||
#include <seastar/testing/thread_test_case.hh> | ||
#include <seastar/util/log.hh> | ||
#include <seastar/util/memory_diagnostics.hh> | ||
|
||
|
@@ -155,6 +157,59 @@ SEASTAR_TEST_CASE(test_memory_diagnostics) { | |
return make_ready_future<>(); | ||
} | ||
|
||
SEASTAR_THREAD_TEST_CASE(test_cross_thread_realloc) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the purpose of this test is to verify the behavior of seastar allocator, not the one provided by libc, so probably we should guard it like #ifndef SEASTAR_DEFAULT_ALLOCATOR
SEASTAR_THREAD_TEST_CASE(test_cross_thread_realloc) {
// ...
}
#endif i.e., to move the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I deliberately left in both modes, because it works in both modes. What's the harm? Leaving it in both modes has some advantages two major ones which are:
I have been mostly under the assumption that we should gate tests with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. Makes sense. As we also have tests testing |
||
// Tests that realloc seems to do the right thing with various sizes of | ||
// buffer, including cases where the initial allocation is on another | ||
// shard. | ||
// Needs at least 2 shards to usefully test the cross-shard aspect but | ||
// still passes when only 1 shard is used. | ||
auto do_xshard_realloc = [](bool cross_shard, size_t initial_size, size_t realloc_size) { | ||
BOOST_TEST_CONTEXT("cross_shard=" << cross_shard << ", initial=" | ||
<< initial_size << ", realloc_size=" << realloc_size) { | ||
|
||
auto other_shard = (this_shard_id() + cross_shard) % smp::count; | ||
|
||
char *p = static_cast<char *>(malloc(initial_size)); | ||
|
||
// write some sentinels and check them after realloc | ||
// x start of region | ||
// y end of realloc'd region (if it falls within the initial size) | ||
// z end of initial region | ||
if (initial_size > 0) { | ||
p[0] = 'x'; | ||
p[initial_size - 1] = 'z'; | ||
if (realloc_size > 0 && realloc_size <= initial_size) { | ||
p[realloc_size - 1] = 'y'; | ||
} | ||
} | ||
smp::submit_to(other_shard, [=] { | ||
char* p2 = static_cast<char *>(realloc(p, realloc_size)); | ||
if (initial_size > 0 && realloc_size > 0) { | ||
BOOST_REQUIRE_EQUAL(p2[0], 'x'); | ||
if (realloc_size <= initial_size) { | ||
BOOST_REQUIRE_EQUAL(p2[realloc_size - 1], 'y'); | ||
} | ||
if (realloc_size > initial_size) { | ||
BOOST_REQUIRE_EQUAL(p2[initial_size - 1], 'z'); | ||
} | ||
} | ||
free(p2); | ||
}).get(); | ||
} | ||
}; | ||
|
||
for (auto& cross_shard : {false, true}) { | ||
do_xshard_realloc(cross_shard, 0, 0); | ||
do_xshard_realloc(cross_shard, 0, 1); | ||
do_xshard_realloc(cross_shard, 1, 0); | ||
do_xshard_realloc(cross_shard, 50, 100); | ||
do_xshard_realloc(cross_shard, 100, 50); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This case (among others) failed with an assertion failure before the fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: In such cases I like to add a code comment (not a github comment) saying something like:
It can be useful to know why a test exists, and also if it fails on some old branch or something, you will know which fix you forgot to include. |
||
do_xshard_realloc(cross_shard, 100000, 500000); | ||
do_xshard_realloc(cross_shard, 500000, 100000); | ||
} | ||
} | ||
|
||
|
||
#ifndef SEASTAR_DEFAULT_ALLOCATOR | ||
|
||
struct thread_alloc_info { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part of the comment was obsolete after some changes to the logic above which means we don't reach here in the "original functions not available" case.