Skip to content

Commit

Permalink
os/bluestore: os/bluestore: implement dump for bitmap allocator
Browse files Browse the repository at this point in the history
Signed-off-by: Igor Fedotov <ifedotov@suse.com>
(cherry picked from commit 80310d9)
  • Loading branch information
ifed01 committed Apr 1, 2019
1 parent 64524b5 commit 30f8ac4
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 12 deletions.
16 changes: 16 additions & 0 deletions src/os/bluestore/BitmapAllocator.cc
Expand Up @@ -83,3 +83,19 @@ void BitmapAllocator::shutdown()
ldout(cct, 1) << __func__ << dendl;
_shutdown();
}

void BitmapAllocator::dump()
{
// bin -> interval count
std::map<size_t, size_t> bins_overall;
collect_stats(bins_overall);
auto it = bins_overall.begin();
while (it != bins_overall.end()) {
ldout(cct, 0) << __func__
<< " bin " << it->first
<< "(< " << byte_u_t((1 << (it->first + 1)) * get_min_alloc_size()) << ")"
<< " : " << it->second << " extents"
<< dendl;
++it;
}
}
4 changes: 1 addition & 3 deletions src/os/bluestore/BitmapAllocator.h
Expand Up @@ -35,9 +35,7 @@ class BitmapAllocator : public Allocator,
return get_available();
}

void dump() override
{
}
void dump() override;
double get_fragmentation(uint64_t) override
{
return _get_fragmentation();
Expand Down
36 changes: 35 additions & 1 deletion src/os/bluestore/fastbmap_allocator_impl.cc
Expand Up @@ -32,7 +32,6 @@ inline interval_t _align2units(uint64_t offset, uint64_t len, uint64_t min_lengt
return interval_t();
}


interval_t AllocatorLevel01Loose::_get_longest_from_l0(uint64_t pos0,
uint64_t pos1, uint64_t min_length, interval_t* tail) const
{
Expand Down Expand Up @@ -508,3 +507,38 @@ bool AllocatorLevel01Loose::_allocate_l1(uint64_t length,
}
return _is_empty_l1(l1_pos_start, l1_pos_end);
}

void AllocatorLevel01Loose::collect_stats(
std::map<size_t, size_t>& bins_overall)
{
size_t free_seq_cnt = 0;
for (auto slot : l0) {
if (slot == all_slot_set) {
free_seq_cnt += CHILD_PER_SLOT_L0;
} else if(slot != all_slot_clear) {
size_t pos = 0;
do {
auto pos1 = find_next_set_bit(slot, pos);
if (pos1 == pos) {
free_seq_cnt++;
pos = pos1 + 1;
} else {
if (free_seq_cnt) {
bins_overall[cbits(free_seq_cnt) - 1]++;
free_seq_cnt = 0;
}
if (pos1 < bits_per_slot) {
free_seq_cnt = 1;
}
pos = pos1 + 1;
}
} while (pos < bits_per_slot);
} else if (free_seq_cnt) {
bins_overall[cbits(free_seq_cnt) - 1]++;
free_seq_cnt = 0;
}
}
if (free_seq_cnt) {
bins_overall[cbits(free_seq_cnt) - 1]++;
}
}
16 changes: 16 additions & 0 deletions src/os/bluestore/fastbmap_allocator_impl.h
Expand Up @@ -86,6 +86,9 @@ class AllocatorLevel
virtual ~AllocatorLevel()
{}

virtual void collect_stats(
std::map<size_t, size_t>& bins_overall) = 0;

};

class AllocatorLevel01 : public AllocatorLevel
Expand Down Expand Up @@ -464,6 +467,8 @@ class AllocatorLevel01Loose : public AllocatorLevel01
}
return res * l0_granularity;
}
void collect_stats(
std::map<size_t, size_t>& bins_overall) override;
};

class AllocatorLevel01Compact : public AllocatorLevel01
Expand All @@ -473,6 +478,11 @@ class AllocatorLevel01Compact : public AllocatorLevel01
return 8;
}
public:
void collect_stats(
std::map<size_t, size_t>& bins_overall) override
{
// not implemented
}
};

template <class L1>
Expand Down Expand Up @@ -501,6 +511,12 @@ class AllocatorLevel02 : public AllocatorLevel
{
return l1.get_min_alloc_size();
}
void collect_stats(
std::map<size_t, size_t>& bins_overall) override {

std::lock_guard l(lock);
l1.collect_stats(bins_overall);
}

protected:
std::mutex lock;
Expand Down
102 changes: 94 additions & 8 deletions src/test/objectstore/fastbmap_allocator_test.cc
Expand Up @@ -483,6 +483,7 @@ TEST(TestAllocatorLevel01, test_l2_unaligned)
uint64_t capacity = num_l2_entries * 256 * 512 * 4096; // 3x512 MB
al2.init(capacity, 0x1000);
std::cout << "Init L2 Unaligned" << std::endl;

for (uint64_t i = 0; i < capacity; i += _1m / 2) {
uint64_t allocated4 = 0;
interval_vector_t a4;
Expand Down Expand Up @@ -589,8 +590,16 @@ TEST(TestAllocatorLevel01, test_l2_contiguous_alignment)
TestAllocatorLevel02 al2;
uint64_t num_l2_entries = 3;
uint64_t capacity = num_l2_entries * 256 * 512 * 4096; // 3x512 MB
al2.init(capacity, 0x1000);
uint64_t num_chunks = capacity / 4096;
al2.init(capacity, 4096);
std::cout << "Init L2 cont aligned" << std::endl;

std::map<size_t, size_t> bins_overall;
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 1u);
// std::cout<<bins_overall.begin()->first << std::endl;
ASSERT_EQ(bins_overall[cbits(num_chunks) - 1], 1u);

for (uint64_t i = 0; i < capacity / 2; i += _1m) {
uint64_t allocated4 = 0;
interval_vector_t a4;
Expand All @@ -602,11 +611,22 @@ TEST(TestAllocatorLevel01, test_l2_contiguous_alignment)
}
ASSERT_EQ(capacity / 2, al2.debug_get_free());

bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 1u);
ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u);

{
size_t to_release = 2 * _1m + 0x1000;
// release 2M + 4K at the beginning
interval_vector_t r;
r.emplace_back(0, 2 * _1m + 0x1000);
r.emplace_back(0, to_release);
al2.free_l2(r);
bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 2u);
ASSERT_EQ(bins_overall[cbits(to_release / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u);
}
{
// allocate 4K within the deallocated range
Expand All @@ -627,22 +647,38 @@ TEST(TestAllocatorLevel01, test_l2_contiguous_alignment)
ASSERT_EQ(allocated4, _1m);
ASSERT_EQ(a4[0].offset, _1m);
ASSERT_EQ(a4[0].length, _1m);
bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 3u);
ASSERT_EQ(bins_overall[0], 1u);
ASSERT_EQ(bins_overall[cbits((_1m - 0x1000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u);
}
{
// and allocate yet another 8K within the deallocated range
uint64_t allocated4 = 0;
interval_vector_t a4;
al2.allocate_l2(0x2000, 0x1000, &allocated4, &a4);
ASSERT_EQ(a4.size(), 1);
ASSERT_EQ(allocated4, 0x2000);
ASSERT_EQ(a4[0].offset, 0x1000);
ASSERT_EQ(a4[0].length, 0x2000);
ASSERT_EQ(a4.size(), 1u);
ASSERT_EQ(allocated4, 0x2000u);
ASSERT_EQ(a4[0].offset, 0x1000u);
ASSERT_EQ(a4[0].length, 0x2000u);
bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall[0], 1u);
ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u);
}
{
// release just allocated 1M
interval_vector_t r;
r.emplace_back(_1m, _1m);
al2.free_l2(r);
bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 2u);
ASSERT_EQ(bins_overall[cbits((2 * _1m - 0x3000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u);
}
{
// allocate 3M - should go to the second 1M chunk and @capacity/2
Expand All @@ -655,22 +691,40 @@ TEST(TestAllocatorLevel01, test_l2_contiguous_alignment)
ASSERT_EQ(a4[0].length, _1m);
ASSERT_EQ(a4[1].offset, capacity / 2);
ASSERT_EQ(a4[1].length, 2 * _1m);
bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 3u);
ASSERT_EQ(bins_overall[0], 1u);
ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits((num_chunks - 512) / 2) - 1], 1u);
}
{
// release allocated 1M in the second meg chunk except
// the first 4K chunk
interval_vector_t r;
r.emplace_back(_1m + 0x1000, _1m);
al2.free_l2(r);
bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 3u);
ASSERT_EQ(bins_overall[cbits(_1m / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits((num_chunks - 512) / 2) - 1], 1u);
}
{
// release 2M @(capacity / 2)
interval_vector_t r;
r.emplace_back(capacity / 2, 2 * _1m);
al2.free_l2(r);
bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 3u);
ASSERT_EQ(bins_overall[cbits(_1m / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits((num_chunks) / 2) - 1], 1u);
}
{
// allocate 3x512K - should go to the second halves of
// allocate 4x512K - should go to the second halves of
// the first and second 1M chunks and @(capacity / 2)
uint64_t allocated4 = 0;
interval_vector_t a4;
Expand All @@ -683,18 +737,42 @@ TEST(TestAllocatorLevel01, test_l2_contiguous_alignment)
ASSERT_EQ(a4[1].length, _1m / 2);
ASSERT_EQ(a4[2].offset, capacity / 2);
ASSERT_EQ(a4[2].length, _1m);

bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 3u);
ASSERT_EQ(bins_overall[0], 1u);
// below we have 512K - 4K & 512K - 12K chunks which both fit into
// the same bin = 6
ASSERT_EQ(bins_overall[6], 2u);
ASSERT_EQ(bins_overall[cbits((num_chunks - 256) / 2) - 1], 1u);

}
{
// cleanup first 2M except except the last 4K chunk
interval_vector_t r;
r.emplace_back(0, 2 * _1m - 0x1000);
al2.free_l2(r);
bins_overall.clear();
al2.collect_stats(bins_overall);

ASSERT_EQ(bins_overall.size(), 3u);
ASSERT_EQ(bins_overall[0], 1u);
ASSERT_EQ(bins_overall[cbits((_2m - 0x1000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits((num_chunks - 256) / 2) - 1], 1u);
}
{
// release 2M @(capacity / 2)
interval_vector_t r;
r.emplace_back(capacity / 2, 2 * _1m);
al2.free_l2(r);
bins_overall.clear();
al2.collect_stats(bins_overall);

ASSERT_EQ(bins_overall.size(), 3u);
ASSERT_EQ(bins_overall[0], 1u);
ASSERT_EQ(bins_overall[cbits((_2m - 0x1000) / 0x1000) - 1], 1u);
ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u);
}
{
// allocate 132M using 4M granularity should go to (capacity / 2)
Expand All @@ -704,12 +782,20 @@ TEST(TestAllocatorLevel01, test_l2_contiguous_alignment)
ASSERT_EQ(a4.size(), 1);
ASSERT_EQ(a4[0].offset, capacity / 2);
ASSERT_EQ(a4[0].length, 132 * _1m);

bins_overall.clear();
al2.collect_stats(bins_overall);
ASSERT_EQ(bins_overall.size(), 3u);
}
{
// cleanup left 4K chunk in the first 2M
interval_vector_t r;
r.emplace_back(2 * _1m - 0x1000, 0x1000);
al2.free_l2(r);
bins_overall.clear();
al2.collect_stats(bins_overall);

ASSERT_EQ(bins_overall.size(), 2u);
}
{
// release 132M @(capacity / 2)
Expand Down Expand Up @@ -760,6 +846,6 @@ TEST(TestAllocatorLevel01, test_l2_contiguous_alignment)
}

}

std::cout << "Done L2 cont aligned" << std::endl;
}

0 comments on commit 30f8ac4

Please sign in to comment.