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

mimic: os/bluestore: bitmap allocator might fail to return contiguous chunk despite having enough space #27298

Merged
merged 5 commits into from
Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/os/bluestore/BitmapAllocator.cc
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
27 changes: 18 additions & 9 deletions src/os/bluestore/bluestore_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,16 @@ WRITE_CLASS_DENC(bluestore_cnode_t)

ostream& operator<<(ostream& out, const bluestore_cnode_t& l);

/// pextent: physical extent
struct bluestore_pextent_t {
template <typename OFFS_TYPE, typename LEN_TYPE>
struct bluestore_interval_t
{
static const uint64_t INVALID_OFFSET = ~0ull;

uint64_t offset = 0;
uint32_t length = 0;
OFFS_TYPE offset = 0;
LEN_TYPE length = 0;

bluestore_pextent_t() {}
bluestore_pextent_t(uint64_t o, uint64_t l) : offset(o), length(l) {}
bluestore_pextent_t(const bluestore_pextent_t &ext) :
offset(ext.offset), length(ext.length) {}
bluestore_interval_t(){}
bluestore_interval_t(uint64_t o, uint64_t l) : offset(o), length(l) {}

bool is_valid() const {
return offset != INVALID_OFFSET;
Expand All @@ -85,10 +84,20 @@ struct bluestore_pextent_t {
return offset != INVALID_OFFSET ? offset + length : INVALID_OFFSET;
}

bool operator==(const bluestore_pextent_t& other) const {
bool operator==(const bluestore_interval_t& other) const {
return offset == other.offset && length == other.length;
}

};

/// pextent: physical extent
struct bluestore_pextent_t : public bluestore_interval_t<uint64_t, uint32_t>
{
bluestore_pextent_t() {}
bluestore_pextent_t(uint64_t o, uint64_t l) : bluestore_interval_t(o, l) {}
bluestore_pextent_t(const bluestore_interval_t &ext) :
bluestore_interval_t(ext.offset, ext.length) {}

DENC(bluestore_pextent_t, v, p) {
denc_lba(v.offset, p);
denc_varint_lowz(v.length, p);
Expand Down
36 changes: 35 additions & 1 deletion src/os/bluestore/fastbmap_allocator_impl.cc
Original file line number Diff line number Diff line change
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]++;
}
}
26 changes: 23 additions & 3 deletions src/os/bluestore/fastbmap_allocator_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ typedef uint64_t slot_t;
struct interval_t
{
uint64_t offset = 0;
uint32_t length = 0;
uint64_t length = 0;

interval_t() {}
interval_t(uint64_t o, uint64_t l) : offset(o), length(l) {}
Expand All @@ -36,7 +36,7 @@ typedef std::vector<slot_t> slot_vector_t;
#include "os/bluestore/bluestore_types.h"
#include "include/mempool.h"

typedef bluestore_pextent_t interval_t;
typedef bluestore_interval_t<uint64_t, uint64_t> interval_t;
typedef PExtentVector interval_vector_t;

typedef mempool::bluestore_alloc::vector<slot_t> slot_vector_t;
Expand Down 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 @@ -152,7 +155,6 @@ class AllocatorLevel01Loose : public AllocatorLevel01
interval_vector_t* res)
{
auto it = res->rbegin();

if (max_length) {
if (it != res->rend() && it->offset + it->length == offset) {
auto l = max_length - it->length;
Expand Down Expand Up @@ -464,6 +466,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 +477,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 +510,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 Expand Up @@ -620,6 +635,11 @@ class AllocatorLevel02 : public AllocatorLevel
assert(length >= min_length);
assert((length % min_length) == 0);

uint64_t cap = 1ull << 31;
if (max_length == 0 || max_length >= cap) {
max_length = cap;
}

uint64_t l1_w = slotset_width * l1._children_per_slot();

std::lock_guard<std::mutex> l(lock);
Expand Down
Loading