Configure logalloc memory size during initialization

This commit is contained in:
Gleb Natapov
2018-06-06 17:39:02 +03:00
committed by Avi Kivity
parent 894673ac14
commit b38ced0fcd
8 changed files with 21 additions and 14 deletions

View File

@@ -362,6 +362,7 @@ int main(int ac, char** av) {
read_config(opts, *cfg).get();
configurable::init_all(opts, *cfg, *ext).get();
logalloc::prime_segment_pool(memory::stats().total_memory(), memory::min_free_memory()).get();
logging::apply_settings(cfg->logging_settings(opts));
verify_rlimit(cfg->developer_mode());

Submodule seastar updated: e7275e445e...12cffef18b

View File

@@ -282,6 +282,7 @@ public:
static future<> do_with(std::function<future<>(cql_test_env&)> func, const db::config& cfg_in) {
return seastar::async([cfg_in, func] {
logalloc::prime_segment_pool(memory::stats().total_memory(), memory::min_free_memory()).get();
bool old_active = false;
if (!active.compare_exchange_strong(old_active, true)) {
throw std::runtime_error("Starting more than one cql_test_env at a time not supported due to singletons.");

View File

@@ -47,6 +47,11 @@ static auto x = [] {
using namespace logalloc;
// this test should be first in order to initialize logalloc for others
SEASTAR_TEST_CASE(test_prime_logalloc) {
return prime_segment_pool(memory::stats().total_memory(), memory::min_free_memory());
}
SEASTAR_TEST_CASE(test_compaction) {
return seastar::async([] {
region reg;
@@ -1244,7 +1249,7 @@ SEASTAR_TEST_CASE(test_zone_reclaiming_preserves_free_size) {
// No point in testing contiguous memory allocation in debug mode
#ifndef SEASTAR_DEFAULT_ALLOCATOR
SEASTAR_THREAD_TEST_CASE(test_can_reclaim_contiguous_memory_with_mixed_allocations) {
prime_segment_pool(); // if previous test cases muddied the pool
prime_segment_pool(memory::stats().total_memory(), memory::min_free_memory()).get(); // if previous test cases muddied the pool
region evictable;
region non_evictable;

View File

@@ -52,6 +52,7 @@ int main(int argc, char** argv) {
return seastar::async([reg_obj_size, std_obj_size, obj_count] {
logalloc::region r;
logalloc::prime_segment_pool(memory::stats().total_memory(), memory::min_free_memory()).get();
with_allocator(r.allocator(), [&] {
std::deque<managed_bytes> refs;

View File

@@ -474,7 +474,7 @@ private:
}
public:
segment_pool();
void prime();
void prime(size_t available_memory, size_t min_free_memory);
segment* new_segment(region::impl* r);
segment_descriptor& descriptor(const segment*);
// Returns segment containing given object or nullptr.
@@ -712,10 +712,9 @@ segment_pool::segment_pool()
, _lsa_owned_segments_bitmap(max_segments())
, _lsa_free_segments_bitmap(max_segments())
{
prime();
}
void segment_pool::prime() {
void segment_pool::prime(size_t available_memory, size_t min_free_memory) {
auto old_emergency_reserve = std::exchange(_emergency_reserve_max, std::numeric_limits<size_t>::max());
try {
// Allocate all of memory so that we occupy the top part. Afterwards, we'll start
@@ -729,8 +728,8 @@ void segment_pool::prime() {
// the frequency of expensive segment-migrating reclaim() called by the seastar allocator.
size_t min_gap = 1 * 1024 * 1024;
size_t max_gap = 64 * 1024 * 1024;
size_t gap = std::min(max_gap, std::max(memory::stats().total_memory() / 16, min_gap));
_non_lsa_reserve = memory::min_free_memory() + gap;
size_t gap = std::min(max_gap, std::max(available_memory / 16, min_gap));
_non_lsa_reserve = min_free_memory + gap;
// Since the reclaimer is not yet in place, free some low memory for general use
reclaim_segments(_non_lsa_reserve / segment::size);
}
@@ -759,7 +758,7 @@ class segment_pool {
size_t _std_memory_available = size_t(1) << 30; // emulate 1GB per shard
friend segment_deleter;
public:
void prime() {}
void prime(size_t available_memory, size_t min_free_memory) {}
segment* new_segment(region::impl* r) {
if (_free_segments.empty()) {
if (_std_memory_available < segment::size) {
@@ -2240,8 +2239,10 @@ void region_group::on_request_expiry::operator()(std::unique_ptr<allocating_func
func->fail(std::make_exception_ptr(timed_out_error()));
}
void prime_segment_pool() {
shard_segment_pool.prime();
future<> prime_segment_pool(size_t available_memory, size_t min_free_memory) {
return smp::invoke_on_all([=] {
shard_segment_pool.prime(available_memory, min_free_memory);
});
}
uint64_t memory_allocated() {

View File

@@ -730,9 +730,7 @@ public:
}
};
// for tests, make sure a new test is started with a primed segment pool (all segments
// allocated so segregated allocation can work)
void prime_segment_pool();
future<> prime_segment_pool(size_t available_memory, size_t min_free_memory);
uint64_t memory_allocated();
uint64_t memory_compacted();