Skip to content

Commit

Permalink
os/bluestore/StupidAllocator: be less stupid about alloc_unit
Browse files Browse the repository at this point in the history
Make sure the extent we return is aligned to alloc_unit.  If the first
extent isn't suitable, try the next one.

Signed-off-by: Sage Weil <sage@redhat.com>
  • Loading branch information
liewegas committed Dec 23, 2015
1 parent b056682 commit dbfe2ff
Showing 1 changed file with 42 additions and 14 deletions.
56 changes: 42 additions & 14 deletions src/os/bluestore/StupidAllocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,23 @@ void StupidAllocator::unreserve(uint64_t unused)
Mutex::Locker l(lock);
dout(10) << __func__ << " unused " << unused << " num_free " << num_free
<< " num_reserved " << num_reserved << dendl;
assert(unused >= num_reserved);
assert((int64_t)unused >= num_reserved);
num_reserved -= unused;
}

/// return the effective length of the extent if we align to alloc_unit
static uint64_t aligned_len(interval_set<uint64_t>::iterator p,
uint64_t alloc_unit)
{
uint64_t skew = p.get_start() % alloc_unit;
if (skew)
skew = alloc_unit - skew;
if (skew > p.get_len())
return 0;
else
return p.get_len() - skew;
}

int StupidAllocator::allocate(
uint64_t need_size, uint64_t alloc_unit, int64_t hint,
uint64_t *offset, uint32_t *length)
Expand All @@ -95,44 +108,59 @@ int StupidAllocator::allocate(
if (hint) {
for (bin = orig_bin; bin < (int)free.size(); ++bin) {
p = free[bin].lower_bound(hint);
if (p != free[bin].end()) {
goto found;
while (p != free[bin].end()) {
if (aligned_len(p, alloc_unit) >= need_size) {
goto found;
}
++p;
}
}
}

// search up (from origin)
for (bin = orig_bin; bin < (int)free.size(); ++bin) {
p = free[bin].begin();
if (p != free[bin].end()) {
goto found;
while (p != free[bin].end()) {
if (aligned_len(p, alloc_unit) >= need_size) {
goto found;
}
++p;
}
}

// search down (hint)
if (hint) {
for (bin = orig_bin-1; bin >= 0; --bin) {
for (bin = orig_bin; bin >= 0; --bin) {
p = free[bin].lower_bound(hint);
if (p != free[bin].end()) {
goto found;
while (p != free[bin].end()) {
if (aligned_len(p, alloc_unit) >= alloc_unit) {
goto found;
}
++p;
}
}
}

// search down (origin)
for (bin = orig_bin-1; bin >= 0; --bin) {
for (bin = orig_bin; bin >= 0; --bin) {
p = free[bin].begin();
if (p != free[bin].end()) {
goto found;
while (p != free[bin].end()) {
if (aligned_len(p, alloc_unit) >= alloc_unit) {
goto found;
}
++p;
}
}

assert(0 == "caller didn't reserve?");
return -ENOSPC;

found:
*offset = p.get_start();
*length = MIN(MAX(alloc_unit, need_size), p.get_len());
uint64_t skew = p.get_start() % alloc_unit;
if (skew)
skew = alloc_unit - skew;
*offset = p.get_start() + skew;
*length = MIN(MAX(alloc_unit, need_size), p.get_len() - skew);
if (g_conf->bluestore_debug_small_allocations) {
uint64_t max =
alloc_unit * (rand() % g_conf->bluestore_debug_small_allocations);
Expand All @@ -147,7 +175,7 @@ int StupidAllocator::allocate(

free[bin].erase(*offset, *length);
uint64_t off, len;
if (*offset && free[bin].contains(*offset - 1, &off, &len)) {
if (*offset && free[bin].contains(*offset - skew - 1, &off, &len)) {
int newbin = _choose_bin(len);
if (newbin != bin) {
dout(30) << __func__ << " demoting " << off << "~" << len
Expand Down

0 comments on commit dbfe2ff

Please sign in to comment.