* Apart from that extents can vary between these lower and higher limits according
* to free block search algorithm and availability of contiguous space.
*/
- virtual int alloc_extents(uint64_t want_size, uint64_t alloc_unit,
- uint64_t max_alloc_size, int64_t hint,
- AllocExtentVector *extents, int *count, uint64_t *ret_len) = 0;
+ virtual int allocate(uint64_t want_size, uint64_t alloc_unit,
+ uint64_t max_alloc_size, int64_t hint,
+ AllocExtentVector *extents, int *count, uint64_t *ret_len) = 0;
- int alloc_extents(uint64_t want_size, uint64_t alloc_unit,
- int64_t hint, AllocExtentVector *extents, int *count, uint64_t *ret_len) {
- return alloc_extents(want_size, alloc_unit, want_size, hint, extents, count, ret_len);
+ int allocate(uint64_t want_size, uint64_t alloc_unit,
+ int64_t hint, AllocExtentVector *extents, int *count, uint64_t *ret_len) {
+ return allocate(want_size, alloc_unit, want_size, hint, extents, count, ret_len);
}
virtual int release(
m_bit_alloc->unreserve_blocks(nblks);
}
-int BitMapAllocator::alloc_extents(
+int BitMapAllocator::allocate(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len)
{
<< " hint " << hint
<< dendl;
- return alloc_extents_dis(want_size, alloc_unit / m_block_size,
- max_alloc_size, hint / m_block_size, extents, count, ret_len);
+ return allocate_dis(want_size, alloc_unit / m_block_size,
+ max_alloc_size, hint / m_block_size, extents, count, ret_len);
}
-int BitMapAllocator::alloc_extents_dis(
+int BitMapAllocator::allocate_dis(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len)
{
BitAllocator *m_bit_alloc; // Bit allocator instance
void insert_free(uint64_t offset, uint64_t len);
- int alloc_extents_cont(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
- int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count);
- int alloc_extents_dis(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
+ int allocate_dis(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len);
public:
int reserve(uint64_t need);
void unreserve(uint64_t unused);
- int alloc_extents(
+ int allocate(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len);
uint64_t alloc_len = 0;;
AllocExtentVector extents = AllocExtentVector(want / g_conf->bluefs_alloc_size);
- r = alloc[id]->alloc_extents(want, g_conf->bluefs_alloc_size, 0,
- &extents, &count, &alloc_len);
+ r = alloc[id]->allocate(want, g_conf->bluefs_alloc_size, 0,
+ &extents, &count, &alloc_len);
*length = alloc_len;
assert(r >= 0);
alloc[id]->unreserve(want - *length);
for (int i = 0; i < count; i++) {
- block_all[id].erase(extents[i].offset, extents[i].length);
- block_total[id] -= extents[i].length;
- log_t.op_alloc_rm(id, extents[i].offset, extents[i].length);
+ block_all[id].erase(extents[i].offset, extents[i].length);
+ block_total[id] -= extents[i].length;
+ log_t.op_alloc_rm(id, extents[i].offset, extents[i].length);
}
r = _flush_and_sync_log(l);
uint64_t alloc_len = 0;
AllocExtentVector extents = AllocExtentVector(left / min_alloc_size);
- r = alloc[id]->alloc_extents(left, min_alloc_size, hint,
- &extents, &count, &alloc_len);
+ r = alloc[id]->allocate(left, min_alloc_size, hint,
+ &extents, &count, &alloc_len);
if (r < 0 || alloc_len < left) {
derr << __func__ << " allocate failed on 0x" << std::hex << left
<< " min_alloc_size 0x" << min_alloc_size << std::dec << dendl;
int count = 0;
uint64_t alloc_len = 0;
AllocExtentVector exts = AllocExtentVector(gift / min_alloc_size);
- r = alloc->alloc_extents(gift, g_conf->bluefs_alloc_size, 0, 0, &exts, &count, &alloc_len);
+ r = alloc->allocate(gift, g_conf->bluefs_alloc_size, 0, 0, &exts, &count, &alloc_len);
if (r < 0 || alloc_len < gift) {
derr << __func__ << " allocate failed on 0x" << std::hex << gift
uint64_t alloc_len = 0;
AllocExtentVector extents = AllocExtentVector(final_length / min_alloc_size);
- int r = alloc->alloc_extents(final_length, min_alloc_size, max_alloc_size,
- hint, &extents, &count, &alloc_len);
+ int r = alloc->allocate(final_length, min_alloc_size, max_alloc_size,
+ hint, &extents, &count, &alloc_len);
assert(r == 0 && alloc_len == final_length);
need -= final_length;
txc->statfs_delta.allocated() += final_length;
return p.get_len() - skew;
}
-int StupidAllocator::allocate(
+int StupidAllocator::allocate_int(
uint64_t want_size, uint64_t alloc_unit, int64_t hint,
uint64_t *offset, uint32_t *length)
{
return 0;
}
-int StupidAllocator::alloc_extents(
+int StupidAllocator::allocate(
uint64_t want_size,
uint64_t alloc_unit,
uint64_t max_alloc_size,
ExtentList block_list = ExtentList(extents, 1, max_alloc_size);
while (allocated_size < want_size) {
- res = allocate(MIN(max_alloc_size, (want_size - allocated_size)),
+ res = allocate_int(MIN(max_alloc_size, (want_size - allocated_size)),
alloc_unit, hint, &offset, &length);
if (res != 0) {
/*
int reserve(uint64_t need);
void unreserve(uint64_t unused);
- int alloc_extents(
+ int allocate(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len);
- int allocate(
+ int allocate_int(
uint64_t want_size, uint64_t alloc_unit, int64_t hint,
uint64_t *offset, uint32_t *length);
EXPECT_EQ(alloc->reserve(block_size), 0);
AllocExtentVector extents = AllocExtentVector
(1, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(block_size, block_size,
+ EXPECT_EQ(alloc->allocate(block_size, block_size,
0, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(alloc_len, (uint64_t) block_size);
}
AllocExtentVector extents = AllocExtentVector
(4, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
+ EXPECT_EQ(alloc->allocate(4 * (uint64_t)block_size, (uint64_t) block_size,
0, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
EXPECT_EQ(extents[0].length, 4 * block_size);
AllocExtentVector extents = AllocExtentVector
(4, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
+ EXPECT_EQ(alloc->allocate(4 * (uint64_t)block_size, (uint64_t) block_size,
0, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
EXPECT_EQ(extents[0].length, 2 * block_size);
AllocExtentVector extents = AllocExtentVector
(4, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
+ EXPECT_EQ(alloc->allocate(4 * (uint64_t)block_size, (uint64_t) block_size,
block_size, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
for (int i = 0; i < 4; i++) {
AllocExtentVector extents = AllocExtentVector
(2, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
+ EXPECT_EQ(alloc->allocate(4 * (uint64_t)block_size, (uint64_t) block_size,
2 * block_size, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
for (int i = 0; i < 2; i++) {
AllocExtentVector extents = AllocExtentVector
(1024, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(1024 * (uint64_t)block_size, (uint64_t) block_size * 4,
+ EXPECT_EQ(alloc->allocate(1024 * (uint64_t)block_size, (uint64_t) block_size * 4,
block_size * 4, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(alloc_len, 1024 * (uint64_t) block_size);
AllocExtentVector extents = AllocExtentVector
(8, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(16 * (uint64_t)block_size, (uint64_t) block_size,
+ EXPECT_EQ(alloc->allocate(16 * (uint64_t)block_size, (uint64_t) block_size,
2 * block_size, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(count, 8);
AllocExtentVector extents = AllocExtentVector
(4, AllocExtent(0, 0));
- EXPECT_EQ(alloc->alloc_extents(512 * (uint64_t)block_size, (uint64_t) block_size * 256,
+ EXPECT_EQ(alloc->allocate(512 * (uint64_t)block_size, (uint64_t) block_size * 256,
block_size * 256, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(512 * (uint64_t)block_size, alloc_len);
alloc->init_add_free(0, block_size * 256);
alloc->init_add_free(block_size * 512, block_size * 256);
EXPECT_EQ(alloc->reserve(block_size * 512), 0);
- EXPECT_EQ(alloc->alloc_extents(512 * (uint64_t)block_size, (uint64_t) block_size * 512,
+ EXPECT_EQ(alloc->allocate(512 * (uint64_t)block_size, (uint64_t) block_size * 512,
block_size * 512, (int64_t) 0, &extents, &count, &alloc_len), -ENOSPC);
EXPECT_EQ(alloc_len, (uint64_t) 0);
}
(zone_size * 4, AllocExtent(-1, -1));
alloc->reserve(blocks);
- allocated = alloc->alloc_extents(1, 1, 1, zone_size, &extents, &count, &alloc_len);
+ allocated = alloc->allocate(1, 1, 1, zone_size, &extents, &count, &alloc_len);
ASSERT_EQ(0, allocated);
ASSERT_EQ((uint64_t) 1, alloc_len);
ASSERT_EQ(1, count);
ASSERT_EQ(extents[0].offset, (uint64_t) zone_size);
- allocated = alloc->alloc_extents(1, 1, 1, zone_size * 2 - 1, &extents, &count, &alloc_len);
+ allocated = alloc->allocate(1, 1, 1, zone_size * 2 - 1, &extents, &count, &alloc_len);
ASSERT_EQ((uint64_t) 1, alloc_len);
EXPECT_EQ(0, allocated);
ASSERT_EQ(1, count);
/*
* Wrap around with hint
*/
- allocated = alloc->alloc_extents(zone_size * 2, 1, 1, blocks - zone_size * 2, &extents, &count, &alloc_len);
+ allocated = alloc->allocate(zone_size * 2, 1, 1, blocks - zone_size * 2, &extents, &count, &alloc_len);
EXPECT_EQ(0, allocated);
ASSERT_EQ((uint64_t) zone_size * 2, alloc_len);
EXPECT_EQ(zone_size * 2, count);
EXPECT_EQ((int64_t)extents[0].offset, blocks - zone_size * 2);
- allocated = alloc->alloc_extents(zone_size, 1, 1, blocks - zone_size, &extents, &count, &alloc_len);
+ allocated = alloc->allocate(zone_size, 1, 1, blocks - zone_size, &extents, &count, &alloc_len);
EXPECT_EQ(0, allocated);
ASSERT_EQ((uint64_t) zone_size, alloc_len);
EXPECT_EQ(zone_size, count);
TEST(BitAllocator, test_bmap_alloc)
{
-// const int max_iter = 2;
+ const int max_iter = 3;
for (int round = 0; round < 3; round++) {
// Test zone of different sizes: 512, 1024, 2048
int64_t total_blocks = zone_size * 4;
int64_t allocated = 0;
- //int64_t start_block = 0;
BitAllocator *alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT);
+
+ int64_t alloc_size = 2;
+ for (int64_t iter = 0; iter < max_iter; iter++) {
+ for (int64_t j = 0; alloc_size <= total_blocks; j++) {
+ int64_t blk_size = 1024;
+ auto extents = AllocExtentVector
+ (alloc->size(), AllocExtent(-1, -1));
+ ExtentList *block_list = new ExtentList(&extents, blk_size, alloc_size);
+ for (int64_t i = 0; i < total_blocks; i += alloc_size) {
+ bmap_test_assert(alloc->reserve_blocks(alloc_size) == true);
+ allocated = alloc->alloc_blocks_dis_res(alloc_size, MIN(alloc_size, zone_size),
+ 0, block_list);
+ bmap_test_assert(alloc_size == allocated);
+ bmap_test_assert(block_list->get_extent_count() ==
+ (alloc_size > zone_size? alloc_size / zone_size: 1));
+ bmap_test_assert(extents[0].offset == (uint64_t) i * blk_size);
+ bmap_test_assert((int64_t) extents[0].length ==
+ ((alloc_size > zone_size? zone_size: alloc_size) * blk_size));
+ block_list->reset();
+ }
+ for (int64_t i = 0; i < total_blocks; i += alloc_size) {
+ alloc->free_blocks(i, alloc_size);
+ }
+ alloc_size = 2 << j;
+ }
+ }
int64_t blk_size = 1024;
auto extents = AllocExtentVector
ExtentList *block_list = new ExtentList(&extents, blk_size, max_alloc);
- EXPECT_EQ(alloc->reserve_blocks(total_alloc), true);
+ EXPECT_EQ(alloc->reserve_blocks(total_alloc), true);
allocated = alloc->alloc_blocks_dis_res(total_alloc, blk_size, 0, block_list);
EXPECT_EQ(allocated, total_alloc);
alloc_extents_max_block(alloc, 32, 16);
}
-void
-verify_blocks(int64_t num_blocks, int64_t *blocks)
-{
- int64_t i = 0;
- int wraps = 0;
- for (i = 0; i < num_blocks - 1; i++) {
- if (blocks[i] > blocks[i + 1]) {
- wraps++;
- bmap_test_assert(wraps <= 1);
- }
- }
-}
-
__thread int my_tid;
void
my_tid = __sync_fetch_and_add(&tid, 1);
BitAllocator *alloc = (BitAllocator *) args;
printf("Starting thread %d", my_tid);
- do_work_dis(alloc);
+ do_work_dis(alloc);
return NULL;
}