desc: Search for this many ranges in first-fit mode before switching over to
to best-fit mode. 0 to iterate through all ranges for required chunk.
default: 100
+- name: bluestore_avl_alloc_ff_max_search_bytes
+ type: size
+ level: dev
+ desc: Maximum distance to search in first-fit mode before switching over to
+ to best-fit mode. 0 to iterate through all ranges for required chunk.
+ default: 16_M
- name: bluestore_avl_alloc_bf_threshold
type: uint
level: dev
{
const auto compare = range_tree.key_comp();
uint32_t search_count = 0;
+ uint64_t search_bytes = 0;
auto rs_start = range_tree.lower_bound(range_t{*cursor, size}, compare);
for (auto rs = rs_start; rs != range_tree.end(); ++rs) {
uint64_t offset = p2roundup(rs->start, align);
if (max_search_count > 0 && ++search_count > max_search_count) {
return -1ULL;
}
+ if (search_bytes = rs->start - rs_start->start;
+ max_search_bytes > 0 && search_bytes > max_search_bytes) {
+ return -1ULL;
+ }
}
if (*cursor == 0) {
// If we already started from beginning, don't bother with searching from beginning
if (max_search_count > 0 && ++search_count > max_search_count) {
return -1ULL;
}
+ if (max_search_bytes > 0 && search_bytes + rs->start > max_search_bytes) {
+ return -1ULL;
+ }
}
return -1ULL;
}
cct->_conf.get_val<uint64_t>("bluestore_avl_alloc_bf_free_pct")),
max_search_count(
cct->_conf.get_val<uint64_t>("bluestore_avl_alloc_ff_max_search_count")),
+ max_search_bytes(
+ cct->_conf.get_val<Option::size_t>("bluestore_avl_alloc_ff_max_search_bytes")),
range_count_cap(max_mem / sizeof(range_seg_t)),
cct(cct)
{}
* becomes the performance limiting factor on high-performance storage.
*/
const uint32_t max_search_count;
+ /*
+ * Maximum distance to search forward from the last offset, without this
+ * limit, fragmented device can see lots of iterations and _block_picker()
+ * becomes the performance limiting factor on high-performance storage.
+ */
+ const uint32_t max_search_bytes;
/*
* Max amount of range entries allowed. 0 - unlimited
*/